1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/37352829fedd/ changeset: 37352829fedd user: jgoecks date: 2012-06-07 22:47:06 summary: Visualization infrastructure: (a) Backbone-ify cache and data managers; (b) push parameter value sampling code into Tool objects. Pack scripts. affected #: 10 files diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd static/scripts/mvc/tools.js --- a/static/scripts/mvc/tools.js +++ b/static/scripts/mvc/tools.js @@ -63,12 +63,47 @@ * A tool input. */ var ToolInput = Backbone.RelationalModel.extend({ + defaults: { + name: null, + type: null + }, initialize: function() { this.attributes.html = unescape(this.attributes.html); + }, + + /** + * Returns samples from a tool input. + */ + get_samples: function(num_samples) { + var + type = this.get('type'), + samples = [] + if (type === 'number') { + samples = d3.scale.linear().domain([this.get('min'), this.get('max')]).ticks(num_samples); + } + else if (type === 'select') { + samples = _.map(this.get('options'), function(option) { + return option[0]; + }); + } + + return new ParamSamples({ + param: this, + samples: samples + }); + } +}); + +/** + * A tool and parameter samples. + */ +var ParamSamples = Backbone.Model.extend({ + defaults: { + param: null, + samples: null } - -}); +}) /** * Wrap collection of tools for fast access/manipulation. diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd static/scripts/packed/mvc/tools.js --- a/static/scripts/packed/mvc/tools.js +++ b/static/scripts/packed/mvc/tools.js @@ -1,1 +1,1 @@ -var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var Tool=BaseModel.extend({defaults:{description:null,target:null,inputs:[]},relations:[{type:Backbone.HasMany,key:"inputs",relatedModel:"ToolInput",reverseRelation:{key:"tool"}}],urlRoot:galaxy_paths.attributes.root_path+"api/tools",apply_search_results:function(a){(_.indexOf(a,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()}});var ToolInput=Backbone.RelationalModel.extend({initialize:function(){this.attributes.html=unescape(this.attributes.html)}});var ToolCollection=Backbone.Collection.extend({model:Tool});var ToolPanelLabel=BaseModel.extend({});var ToolPanelSection=BaseModel.extend({defaults:{elems:[],open:false},clear_search_results:function(){_.each(this.attributes.elems,function(a){a.show()});this.show();this.set("open",false)},apply_search_results:function(b){var c=true,a;_.each(this.attributes.elems,function(d){if(d instanceof ToolPanelLabel){a=d;a.hide()}else{if(d instanceof Tool){if(d.apply_search_results(b)){c=false;if(a){a.show()}}}}});if(c){this.hide()}else{this.show();this.set("open",true)}}});var ToolSearch=BaseModel.extend({defaults:{spinner_url:"",search_url:"",visible:true,query:"",results:null},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var c=this.attributes.query;if(c.length<3){this.set("results",null);return}var b=c+"*";if(this.timer){clearTimeout(this.timer)}$("#search-spinner").show();var a=this;this.timer=setTimeout(function(){$.get(a.attributes.search_url,{query:b},function(d){a.set("results",d);$("#search-spinner").hide()},"json")},200)}});var ToolPanel=Backbone.Collection.extend({url:"/tools",tools:new ToolCollection(),parse:function(a){var b=function(e){var d=e.type;if(d==="tool"){return new Tool(e)}else{if(d==="section"){var c=_.map(e.elems,b);e.elems=c;return new ToolPanelSection(e)}else{if(d==="label"){return new ToolPanelLabel(e)}}}};return _.map(a,b)},initialize:function(a){this.tool_search=a.tool_search;this.tool_search.on("change:results",this.apply_search_results,this);this.on("reset",this.populate_tools,this)},populate_tools:function(){var a=this;a.tools=new ToolCollection();this.each(function(b){if(b instanceof ToolPanelSection){_.each(b.attributes.elems,function(c){if(c instanceof Tool){a.tools.push(c)}})}else{if(b instanceof Tool){a.tools.push(b)}}})},clear_search_results:function(){this.each(function(a){if(a instanceof ToolPanelSection){a.clear_search_results()}else{a.show()}})},apply_search_results:function(){var b=this.tool_search.attributes.results;if(b===null){this.clear_search_results();return}var a=null;this.each(function(c){if(c instanceof ToolPanelLabel){a=c;a.hide()}else{if(c instanceof Tool){if(c.apply_search_results(b)){if(a){a.show()}}}else{a=null;c.apply_search_results(b)}}})}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){(this.model.attributes.hidden?this.$el.hide():this.$el.show())}});var ToolLinkView=BaseView.extend({tagName:"div",template:Handlebars.templates.tool_link,render:function(){this.$el.append(this.template(this.model.toJSON()));return this}});var ToolPanelLabelView=BaseView.extend({tagName:"div",className:"toolPanelLabel",render:function(){this.$el.append($("<span/>").text(this.model.attributes.name));return this}});var ToolPanelSectionView=BaseView.extend({tagName:"div",className:"toolSectionWrapper",template:Handlebars.templates.panel_section,initialize:function(){BaseView.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(this.template(this.model.toJSON()));var a=this.$el.find(".toolSectionBody");_.each(this.model.attributes.elems,function(b){if(b instanceof Tool){var c=new ToolLinkView({model:b,className:"toolTitle"});c.render();a.append(c.$el)}else{if(b instanceof ToolPanelLabel){var d=new ToolPanelLabelView({model:b});d.render();a.append(d.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").slideDown("fast"):this.$el.children(".toolSectionBody").slideUp("fast"))}});var ToolSearchView=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",template:Handlebars.templates.tool_search,events:{click:"focus_and_select","keyup :input":"query_changed"},render:function(){this.$el.append(this.template(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}return this},focus_and_select:function(){this.$el.find(":input").focus().select()},query_changed:function(){this.model.set("query",this.$el.find(":input").val())}});var ToolPanelView=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(){this.collection.tool_search.on("change:results",this.handle_search_results,this)},render:function(){var a=this;var b=new ToolSearchView({model:this.collection.tool_search});b.render();a.$el.append(b.$el);this.collection.each(function(d){if(d instanceof ToolPanelSection){var c=new ToolPanelSectionView({model:d});c.render();a.$el.append(c.$el)}else{if(d instanceof Tool){var e=new ToolLinkView({model:d,className:"toolTitleNoSection"});e.render();a.$el.append(e.$el)}else{if(d instanceof ToolPanelLabel){var f=new ToolPanelLabelView({model:d});f.render();a.$el.append(f.$el)}}}});a.$el.find("a.tool-link").click(function(f){var d=$(this).attr("class").split(/\s+/)[0],c=a.collection.tools.get(d);a.trigger("tool_link_click",f,c)});return this},handle_search_results:function(){var a=this.collection.tool_search.attributes.results;if(a&&a.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}});var ToolFormView=Backbone.View.extend({className:"toolForm",template:Handlebars.templates.tool_form,render:function(){this.$el.children().remove();this.$el.append(this.template(this.model.toJSON()))}});var IntegratedToolMenuAndView=Backbone.View.extend({className:"toolMenuAndView",initialize:function(){this.tool_panel_view=new ToolPanelView({collection:this.collection});this.tool_form_view=new ToolFormView()},render:function(){this.tool_panel_view.render();this.tool_panel_view.$el.css("float","left");this.$el.append(this.tool_panel_view.$el);this.tool_form_view.$el.hide();this.$el.append(this.tool_form_view.$el);var a=this;this.tool_panel_view.on("tool_link_click",function(c,b){c.preventDefault();a.show_tool(b)})},show_tool:function(b){var a=this;b.fetch().done(function(){a.tool_form_view.model=b;a.tool_form_view.render();a.tool_form_view.$el.show();$("#left").width("650px")})}}); \ No newline at end of file +var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var Tool=BaseModel.extend({defaults:{description:null,target:null,inputs:[]},relations:[{type:Backbone.HasMany,key:"inputs",relatedModel:"ToolInput",reverseRelation:{key:"tool"}}],urlRoot:galaxy_paths.attributes.root_path+"api/tools",apply_search_results:function(a){(_.indexOf(a,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()}});var ToolInput=Backbone.RelationalModel.extend({defaults:{name:null,type:null},initialize:function(){this.attributes.html=unescape(this.attributes.html)},get_samples:function(b){var c=this.get("type"),a=[];if(c==="number"){a=d3.scale.linear().domain([this.get("min"),this.get("max")]).ticks(b)}else{if(c==="select"){a=_.map(this.get("options"),function(d){return d[0]})}}return new ParamSamples({param:this,samples:a})}});var ParamSamples=Backbone.Model.extend({defaults:{param:null,samples:null}});var ToolCollection=Backbone.Collection.extend({model:Tool});var ToolPanelLabel=BaseModel.extend({});var ToolPanelSection=BaseModel.extend({defaults:{elems:[],open:false},clear_search_results:function(){_.each(this.attributes.elems,function(a){a.show()});this.show();this.set("open",false)},apply_search_results:function(b){var c=true,a;_.each(this.attributes.elems,function(d){if(d instanceof ToolPanelLabel){a=d;a.hide()}else{if(d instanceof Tool){if(d.apply_search_results(b)){c=false;if(a){a.show()}}}}});if(c){this.hide()}else{this.show();this.set("open",true)}}});var ToolSearch=BaseModel.extend({defaults:{spinner_url:"",search_url:"",visible:true,query:"",results:null},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var c=this.attributes.query;if(c.length<3){this.set("results",null);return}var b=c+"*";if(this.timer){clearTimeout(this.timer)}$("#search-spinner").show();var a=this;this.timer=setTimeout(function(){$.get(a.attributes.search_url,{query:b},function(d){a.set("results",d);$("#search-spinner").hide()},"json")},200)}});var ToolPanel=Backbone.Collection.extend({url:"/tools",tools:new ToolCollection(),parse:function(a){var b=function(e){var d=e.type;if(d==="tool"){return new Tool(e)}else{if(d==="section"){var c=_.map(e.elems,b);e.elems=c;return new ToolPanelSection(e)}else{if(d==="label"){return new ToolPanelLabel(e)}}}};return _.map(a,b)},initialize:function(a){this.tool_search=a.tool_search;this.tool_search.on("change:results",this.apply_search_results,this);this.on("reset",this.populate_tools,this)},populate_tools:function(){var a=this;a.tools=new ToolCollection();this.each(function(b){if(b instanceof ToolPanelSection){_.each(b.attributes.elems,function(c){if(c instanceof Tool){a.tools.push(c)}})}else{if(b instanceof Tool){a.tools.push(b)}}})},clear_search_results:function(){this.each(function(a){if(a instanceof ToolPanelSection){a.clear_search_results()}else{a.show()}})},apply_search_results:function(){var b=this.tool_search.attributes.results;if(b===null){this.clear_search_results();return}var a=null;this.each(function(c){if(c instanceof ToolPanelLabel){a=c;a.hide()}else{if(c instanceof Tool){if(c.apply_search_results(b)){if(a){a.show()}}}else{a=null;c.apply_search_results(b)}}})}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){(this.model.attributes.hidden?this.$el.hide():this.$el.show())}});var ToolLinkView=BaseView.extend({tagName:"div",template:Handlebars.templates.tool_link,render:function(){this.$el.append(this.template(this.model.toJSON()));return this}});var ToolPanelLabelView=BaseView.extend({tagName:"div",className:"toolPanelLabel",render:function(){this.$el.append($("<span/>").text(this.model.attributes.name));return this}});var ToolPanelSectionView=BaseView.extend({tagName:"div",className:"toolSectionWrapper",template:Handlebars.templates.panel_section,initialize:function(){BaseView.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(this.template(this.model.toJSON()));var a=this.$el.find(".toolSectionBody");_.each(this.model.attributes.elems,function(b){if(b instanceof Tool){var c=new ToolLinkView({model:b,className:"toolTitle"});c.render();a.append(c.$el)}else{if(b instanceof ToolPanelLabel){var d=new ToolPanelLabelView({model:b});d.render();a.append(d.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").slideDown("fast"):this.$el.children(".toolSectionBody").slideUp("fast"))}});var ToolSearchView=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",template:Handlebars.templates.tool_search,events:{click:"focus_and_select","keyup :input":"query_changed"},render:function(){this.$el.append(this.template(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}return this},focus_and_select:function(){this.$el.find(":input").focus().select()},query_changed:function(){this.model.set("query",this.$el.find(":input").val())}});var ToolPanelView=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(){this.collection.tool_search.on("change:results",this.handle_search_results,this)},render:function(){var a=this;var b=new ToolSearchView({model:this.collection.tool_search});b.render();a.$el.append(b.$el);this.collection.each(function(d){if(d instanceof ToolPanelSection){var c=new ToolPanelSectionView({model:d});c.render();a.$el.append(c.$el)}else{if(d instanceof Tool){var e=new ToolLinkView({model:d,className:"toolTitleNoSection"});e.render();a.$el.append(e.$el)}else{if(d instanceof ToolPanelLabel){var f=new ToolPanelLabelView({model:d});f.render();a.$el.append(f.$el)}}}});a.$el.find("a.tool-link").click(function(f){var d=$(this).attr("class").split(/\s+/)[0],c=a.collection.tools.get(d);a.trigger("tool_link_click",f,c)});return this},handle_search_results:function(){var a=this.collection.tool_search.attributes.results;if(a&&a.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}});var ToolFormView=Backbone.View.extend({className:"toolForm",template:Handlebars.templates.tool_form,render:function(){this.$el.children().remove();this.$el.append(this.template(this.model.toJSON()))}});var IntegratedToolMenuAndView=Backbone.View.extend({className:"toolMenuAndView",initialize:function(){this.tool_panel_view=new ToolPanelView({collection:this.collection});this.tool_form_view=new ToolFormView()},render:function(){this.tool_panel_view.render();this.tool_panel_view.$el.css("float","left");this.$el.append(this.tool_panel_view.$el);this.tool_form_view.$el.hide();this.$el.append(this.tool_form_view.$el);var a=this;this.tool_panel_view.on("tool_link_click",function(c,b){c.preventDefault();a.show_tool(b)})},show_tool:function(b){var a=this;b.fetch().done(function(){a.tool_form_view.model=b;a.tool_form_view.render();a.tool_form_view.$el.show();$("#left").width("650px")})}}); \ No newline at end of file diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd static/scripts/packed/viz/paramamonster.js --- a/static/scripts/packed/viz/paramamonster.js +++ b/static/scripts/packed/viz/paramamonster.js @@ -1,1 +1,1 @@ -var ToolParameterTree=Backbone.Model.extend({defaults:{tool:null,samples:4},initialize:function(d){var c=this.get("tool"),b=this.get("samples"),a=c.get("inputs").filter(function(h){return(["number","select"].indexOf(h.get("type"))!==-1)}),f=_.map(a,function(h){return h.get("name")});sampling=_.map(a,function(h){var i=h.get("type");if(i==="number"){return d3.scale.linear().domain([h.get("min"),h.get("max")]).ticks(b)}else{if(i==="select"){return _.map(h.get("options"),function(j){return j[0]})}}});var g=function(j,h,i){if(h.length-1===i){return _.map(h[i],function(k){return{name:k}})}return _.map(h[i],function(k){return{name:j[i]+":"+k,children:g(j,h,i+1)}})};var e={name:"Parameter Tree for "+c.get("name"),children:g(f,sampling,0)};this.set("valid_inputs",a);this.set("tree_data",e)}});var TileView=Backbone.View.extend({});var ToolParameterTreeView=Backbone.View.extend({className:"paramamonster",initialize:function(a){this.model=a.model},render:function(){var e=960,b=2000;var a=d3.layout.cluster().size([b,e-160]);var d=d3.svg.diagonal().projection(function(i){return[i.y,i.x]});var h=d3.select(this.$el[0]).append("svg").attr("width",e).attr("height",b).append("g").attr("transform","translate(80, 0)");var c=a.nodes(this.model.get("tree_data"));var g=h.selectAll("path.link").data(a.links(c)).enter().append("path").attr("class","link").attr("d",d);var f=h.selectAll("g.node").data(c).enter().append("g").attr("class","node").attr("transform",function(i){return"translate("+i.y+","+i.x+")"});f.append("circle").attr("r",4.5);f.append("text").attr("dx",function(i){return i.children?-8:8}).attr("dy",3).attr("text-anchor",function(i){return i.children?"end":"start"}).text(function(i){return i.name})}}); \ No newline at end of file +var ToolParameterTree=Backbone.Model.extend({defaults:{tool:null,params:null,num_samples:4},initialize:function(d){var c=this.get("tool"),b=this.get("num_samples"),f=c.get("inputs").map(function(h){return h.get_samples(b)}),a=_.filter(f,function(h){return h.get("samples").length!==0});var g=function(j,h){var m=j[h],l=m.get("param"),k=l.get("name"),i=m.get("samples");if(j.length-1===h){return _.map(i,function(n){return{name:k+"="+n,param:l}})}return _.map(i,function(n){return{name:k+"="+n,param:l,children:g(a,h+1)}})};var e={name:"Parameter Tree for "+c.get("name"),children:g(a,0)};this.set("params",_.map(f,function(h){return h.get("param")}));this.set("tree_data",e)}});var Tile=Backbone.Model.extend({defaults:{track:null,index:null,region:null,resolution:null,data:null,stale:null,html_elt:null},initialize:function(a){}});var Track=Backbone.Model.extend({defaults:{dataset:null}});var FeatureTrack=Track.extend({defaults:{track:null},draw_tile:function(n,r,p,s,d,j,c){var q=this,b=r.canvas,y=d.get("start"),a=d.get("end"),D=25,e=this.left_offset;if(p==="summary_tree"||p==="Histogram"){if(n.dataset_type!=="summary_tree"){var k=this.get_summary_tree_data(n.data,y,a,200);if(n.max){k.max=n.max}n=k}var A=new painters.SummaryTreePainter(n,y,a,this.prefs);A.draw(r,b.width,b.height,j);return new SummaryTreeTile(q,tile_index,s,b,n.data,n.max)}var h=[],o=this.slotters[j].slots;all_slotted=true;if(n.data){var l=this.filters_manager.filters;for(var t=0,v=n.data.length;t<v;t++){var g=n.data[t];var u=false;var m;for(var x=0,C=l.length;x<C;x++){m=l[x];m.update_attrs(g);if(!m.keep(g)){u=true;break}}if(!u){h.push(g);if(!(g[0] in o)){all_slotted=false}}}}var B=(this.filters_manager.alpha_filter?new FilterScaler(this.filters_manager.alpha_filter):null);var z=(this.filters_manager.height_filter?new FilterScaler(this.filters_manager.height_filter):null);var A=new (this.painter)(h,y,a,this.prefs,p,B,z,c);var w=null;r.fillStyle=this.prefs.block_color;r.font=r.canvas.manager.default_font;r.textAlign="right";if(n.data){w=A.draw(r,b.width,b.height,j,o);w.translation=-e}return new FeatureTrackTile(q,tile_index,s,b,n.data,j,p,n.message,all_slotted,w)}});var TileView=Backbone.View.extend({});var ToolParameterTreeView=Backbone.View.extend({className:"tool-parameter-tree",initialize:function(a){this.model=a.model},render:function(){var e=960,b=2000;var a=d3.layout.cluster().size([b,e-160]);var d=d3.svg.diagonal().projection(function(i){return[i.y,i.x]});var h=d3.select(this.$el[0]).append("svg").attr("width",e).attr("height",b).append("g").attr("transform","translate(80, 0)");var c=a.nodes(this.model.get("tree_data"));var g=h.selectAll("path.link").data(a.links(c)).enter().append("path").attr("class","link").attr("d",d);var f=h.selectAll("g.node").data(c).enter().append("g").attr("class","node").attr("transform",function(i){return"translate("+i.y+","+i.x+")"});f.on("click",function(k,j){console.log(k,j)});f.append("circle").attr("r",4.5);f.append("text").attr("dx",function(i){return i.children?-8:8}).attr("dy",3).attr("text-anchor",function(i){return i.children?"end":"start"}).text(function(i){return i.name})}}); \ No newline at end of file diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd static/scripts/packed/viz/trackster.js --- a/static/scripts/packed/viz/trackster.js +++ b/static/scripts/packed/viz/trackster.js @@ -1,1 +1,1 @@ -var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var server_state_deferred=function(d,a,c,f){var b=$.Deferred(),e=function(){$.getJSON(d,a,function(g){if(f(g)){b.resolve(g)}else{setTimeout(e,c)}})};e();return b};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var is_deferred=function(a){return("isResolved" in a)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var n=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(v,u,w,s,i,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,i)-Math.min(u,i))+(Math.max(w,t)-Math.min(w,t))};var g,o,f,k,q,h,r,c,d,b,p,m=false,l=0;do{g=Math.round(Math.random()*16777215);o=(g&16711680)>>16;f=(g&65280)>>8;k=g&255;d=n(o,f,k);m=true;for(var j=0;j<a.length;j++){q=a[j];h=(q&16711680)>>16;r=(q&65280)>>8;c=q&255;b=n(h,r,c);p=e(o,f,k,h,r,c);if((Math.abs(d-b)<40)||(p<200)){m=false;break}}l++}while(!m&&l<=10);return"#"+(16777216+g).toString(16).substr(1,6)};var create_action_icon=function(c,b,a){return $("<a/>").attr("href","javascript:void(0);").attr("title",c).addClass("icon-button").addClass(b).tipsy({gravity:"s"}).click(a)};var trackster_module=function(e,U){var p=e("class").extend,s=e("slotting"),J=e("painters");var ab=function(ac,ad){this.document=ac;this.default_font=ad!==undefined?ad:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ab.prototype,{load_pattern:function(ac,ag){var ad=this.patterns,ae=this.dummy_context,af=new Image();af.src=galaxy_paths.attributes.image_path+ag;af.onload=function(){ad[ac]=ae.createPattern(af,"repeat")}},get_pattern:function(ac){return this.patterns[ac]},new_canvas:function(){var ac=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ac)}ac.manager=this;return ac}});var n={};var l=function(ac,ad){n[ac.attr("id")]=ad};var m=function(ac,ae,ag,af){ag=".group";var ad={};n[ac.attr("id")]=af;ac.bind("drag",{handle:"."+ae,relative:true},function(ao,ap){var an=$(this);var at=$(this).parent(),ak=at.children(),am=n[$(this).attr("id")],aj,ai,aq,ah,al;ai=$(this).parents(ag);if(ai.length!==0){aq=ai.position().top;ah=aq+ai.outerHeight();if(ap.offsetY<aq){$(this).insertBefore(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable_before(am,ar);return}else{if(ap.offsetY>ah){$(this).insertAfter(ai);var ar=n[ai.attr("id")];ar.remove_drawable(am);ar.container.add_drawable(am);return}}}ai=null;for(al=0;al<ak.length;al++){aj=$(ak.get(al));aq=aj.position().top;ah=aq+aj.outerHeight();if(aj.is(ag)&&this!==aj.get(0)&&ap.offsetY>=aq&&ap.offsetY<=ah){if(ap.offsetY-aq<ah-ap.offsetY){aj.find(".content-div").prepend(this)}else{aj.find(".content-div").append(this)}if(am.container){am.container.remove_drawable(am)}n[aj.attr("id")].add_drawable(am);return}}var aj;for(al=0;al<ak.length;al++){aj=$(ak.get(al));if(ap.offsetY<aj.position().top&&!(aj.hasClass("reference-track")||aj.hasClass("intro"))){break}}if(al===ak.length){if(this!==ak.get(al-1)){at.append(this);n[at.attr("id")].move_drawable(am,al)}}else{if(this!==ak.get(al)){$(this).insertBefore(ak.get(al));n[at.attr("id")].move_drawable(am,(ap.deltaY>0?al-1:al))}}}).bind("dragstart",function(){ad["border-top"]=ac.css("border-top");ad["border-bottom"]=ac.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ad)})};U.moveable=m;var aa=16,D=9,A=20,x=100,G=12000,R=400,I=5000,u=100,o="There was an error in indexing this dataset. ",H="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",B="No data for this chrom/contig.",t="Preparing data. This can take a while for a large dataset. If the visualization is saved and closed, preparation will continue in the background.",v="Tool cannot be rerun: ",a="Loading data...",V="Ready for display",O=10,F=20;function W(ad,ac){if(!ac){ac=0}var ae=Math.pow(10,ac);return Math.round(ad*ae)/ae}var c=function(ac){this.num_elements=ac;this.clear()};p(c.prototype,{get:function(ad){var ac=this.key_ary.indexOf(ad);if(ac!==-1){if(this.obj_cache[ad].stale){this.key_ary.splice(ac,1);delete this.obj_cache[ad]}else{this.move_key_to_end(ad,ac)}}return this.obj_cache[ad]},set:function(ad,ae){if(!this.obj_cache[ad]){if(this.key_ary.length>=this.num_elements){var ac=this.key_ary.shift();delete this.obj_cache[ac]}this.key_ary.push(ad)}this.obj_cache[ad]=ae;return ae},move_key_to_end:function(ad,ac){this.key_ary.splice(ac,1);this.key_ary.push(ad)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var P=function(ad,ac){c.call(this,ad);this.track=ac};p(P.prototype,c.prototype,{load_data:function(al,ag,aj,ad,ai){var ak=this.track.view.chrom,af={chrom:ak,low:al,high:ag,mode:aj,resolution:ad,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(af,ai);if(this.track.filters_manager){var am=[];var ac=this.track.filters_manager.filters;for(var ah=0;ah<ac.length;ah++){am.push(ac[ah].name)}af.filter_cols=JSON.stringify(am)}var ae=this;return $.getJSON(this.track.data_url,af,function(an){ae.set_data(al,ag,an)})},get_data:function(ak,ae,ai,ad,ah){var al=this.get(ak,ae);if(al&&(is_deferred(al)||this.track.data_and_mode_compatible(al,ai))){return al}var am,aj,ac,ag,ai,al;for(var af=0;af<this.key_ary.length;af++){am=this.key_ary[af];aj=this.split_key(am);ac=aj[0];ag=aj[1];if(ak>=ac&&ae<=ag){var al=this.obj_cache[am];if(is_deferred(al)||(this.track.data_and_mode_compatible(al,ai)&&this.track.can_subset(al))){this.move_key_to_end(am,af);return al}}}al=this.load_data(ak,ae,ai,ad,ah);this.set_data(ak,ae,al);return al},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ak,af,aj,ae,ai,ag){var al=this.get(ak,af);if(!(al&&this.track.data_and_mode_compatible(al,aj))){console.log("ERROR: no current data for: ",this.track,ak,af,aj,ae,ai);return}al.stale=true;var ad=ak;if(ag===this.DEEP_DATA_REQ){$.extend(ai,{start_val:al.data.length+1})}else{if(ag===this.BROAD_DATA_REQ){ad=(al.max_high?al.max_high:al.data[al.data.length-1][2])+1}}var ac=this,ah=this.load_data(ad,af,aj,ae,ai);new_data_available=$.Deferred();this.set_data(ak,af,new_data_available);$.when(ah).then(function(am){if(am.data){am.data=al.data.concat(am.data);if(am.max_low){am.max_low=al.max_low}if(am.message){am.message=am.message.replace(/[0-9]+/,am.data.length)}}ac.set_data(ak,af,am);new_data_available.resolve(am)});return new_data_available},get:function(ac,ad){return c.prototype.get.call(this,this.gen_key(ac,ad))},set_data:function(ad,ae,ac){return this.set(this.gen_key(ad,ae),ac)},gen_key:function(ac,ae){var ad=ac+"_"+ae;return ad},split_key:function(ac){return ac.split("_")}});var E=function(ad,ac,ae){P.call(this,ad,ac,ae)};p(E.prototype,P.prototype,c.prototype,{get:P.prototype.get,load_data:function(ac,af,ag,ad,ae){if(ad>1){return{data:null}}return P.prototype.load_data.call(this,ac,af,ag,ad,ae)}});var q=function(ad,ac,af){if(!q.id_counter){q.id_counter=0}this.id=q.id_counter++;this.name=af.name;this.view=ad;this.container=ac;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name}],saved_values:af.prefs,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=af.drag_handle_class;this.is_overview=false;this.action_icons={};this.content_visible=true;this.container_div=this.build_container_div();this.header_div=this.build_header_div();if(this.header_div){this.container_div.append(this.header_div);this.icons_div=$("<div/>").css("float","left").hide().appendTo(this.header_div);this.build_action_icons(this.action_icons_def);this.header_div.append($("<div style='clear: both'/>"));this.header_div.dblclick(function(ag){ag.stopPropagation()});var ae=this;this.container_div.hover(function(){ae.icons_div.show()},function(){ae.icons_div.hide()});$("<div style='clear: both'/>").appendTo(this.container_div)}};q.prototype.action_icons_def=[{name:"toggle_icon",title:"Hide/show content",css_class:"toggle",on_click_fn:function(ac){if(ac.content_visible){ac.action_icons.toggle_icon.addClass("toggle-expand").removeClass("toggle");ac.hide_contents();ac.content_visible=false}else{ac.action_icons.toggle_icon.addClass("toggle").removeClass("toggle-expand");ac.content_visible=true;ac.show_contents()}}},{name:"settings_icon",title:"Edit settings",css_class:"settings-icon",on_click_fn:function(ad){var af=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ac=function(){ad.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ae=function(ag){if((ag.keyCode||ag.which)===27){af()}else{if((ag.keyCode||ag.which)===13){ac()}}};$(window).bind("keypress.check_enter_esc",ae);show_modal("Configure",ad.config.build_form(),{Cancel:af,OK:ac})}},{name:"remove_icon",title:"Remove",css_class:"remove-icon",on_click_fn:function(ac){$(".tipsy").remove();ac.remove()}}];p(q.prototype,{init:function(){},changed:function(){this.view.changed()},can_draw:function(){if(this.enabled&&this.content_visible){return true}return false},request_draw:function(){},_draw:function(){},to_dict:function(){},update_icons:function(){},set_name:function(ac){this.old_name=this.name;this.name=ac;this.name_div.text(this.name)},revert_name:function(){if(this.old_name){this.name=this.old_name;this.name_div.text(this.name)}},remove:function(){this.changed();this.container.remove_drawable(this);var ac=this.view;this.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})},build_container_div:function(){},build_header_div:function(){},add_action_icon:function(ad,ai,ah,ag,ac,af){var ae=this;this.action_icons[ad]=$("<a/>").attr("href","javascript:void(0);").attr("title",ai).addClass("icon-button").addClass(ah).tipsy({gravity:"s"}).click(function(){ag(ae)}).appendTo(this.icons_div);if(af){this.action_icons[ad].hide()}},build_action_icons:function(ac){var ae;for(var ad=0;ad<ac.length;ad++){ae=ac[ad];this.add_action_icon(ae.name,ae.title,ae.css_class,ae.on_click_fn,ae.prepend,ae.hide)}},update_icons:function(){},hide_contents:function(){},show_contents:function(){}});var w=function(ad,ac,ae){q.call(this,ad,ac,ae);this.obj_type=ae.obj_type;this.drawables=[]};p(w.prototype,q.prototype,{unpack_drawables:function(ae){this.drawables=[];var ad;for(var ac=0;ac<ae.length;ac++){ad=object_from_template(ae[ac],this);this.add_drawable(ad)}},init:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].init()}},_draw:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac]._draw()}},to_dict:function(){var ad=[];for(var ac=0;ac<this.drawables.length;ac++){ad.push(this.drawables[ac].to_dict())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ad}},add_drawable:function(ac){this.drawables.push(ac);ac.container=this;this.changed()},add_drawable_before:function(ae,ac){this.changed();var ad=this.drawables.indexOf(ac);if(ad!==-1){this.drawables.splice(ad,0,ae);return true}return false},replace_drawable:function(ae,ac,ad){var af=this.drawables.indexOf(ae);if(af!==-1){this.drawables[af]=ac;if(ad){ae.container_div.replaceWith(ac.container_div)}this.changed()}return af},remove_drawable:function(ad){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);ad.container=null;this.changed();return true}return false},move_drawable:function(ad,ae){var ac=this.drawables.indexOf(ad);if(ac!==-1){this.drawables.splice(ac,1);this.drawables.splice(ae,0,ad);this.changed();return true}return false}});var N=function(ad,ac,af){p(af,{obj_type:"DrawableGroup",drag_handle_class:"group-handle"});w.call(this,ad,ac,af);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.filters_manager=new X(this);this.header_div.after(this.filters_manager.parent_div);this.saved_filters_managers=[];if("drawables" in af){this.unpack_drawables(af.drawables)}if("filters" in af){var ae=this.filters_manager;this.filters_manager=new X(this,af.filters);ae.parent_div.replaceWith(this.filters_manager.parent_div);if(af.filters.visible){this.setup_multitrack_filtering()}}};p(N.prototype,q.prototype,w.prototype,{action_icons_def:[q.prototype.action_icons_def[0],q.prototype.action_icons_def[1],{name:"composite_icon",title:"Show composite track",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_composite_track()}},{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters();ac._restore_filter_managers()}else{ac.setup_multitrack_filtering();ac.request_draw(true)}ac.filters_manager.toggle()}},q.prototype.action_icons_def[2]],build_container_div:function(){var ac=$("<div/>").addClass("group").attr("id","group_"+this.id);if(this.container){this.container.content_div.append(ac)}return ac},build_header_div:function(){var ac=$("<div/>").addClass("track-header");ac.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("track-name").text(this.name).appendTo(ac);return ac},hide_contents:function(){this.tiles_div.hide()},show_contents:function(){this.tiles_div.show();this.request_draw()},update_icons:function(){var ae=this.drawables.length;if(ae===0){this.action_icons.composite_icon.hide();this.action_icons.filters_icon.hide()}else{if(ae===1){if(this.drawables[0] instanceof h){this.action_icons.composite_icon.show()}this.action_icons.filters_icon.hide()}else{var ai,ao=true,ag=this.drawables[0].get_type(),ac=0;for(var al=0;al<ae;al++){ai=this.drawables[al];if(ai.get_type()!==ag){can_composite=false;break}if(ai instanceof d){ac++}}if(ao||ac===1){this.action_icons.composite_icon.show()}else{this.action_icons.composite_icon.hide();$(".tipsy").remove()}if(ac>1&&ac===this.drawables.length){var ap={},ad;ai=this.drawables[0];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];ap[ad.name]=[ad]}for(var al=1;al<this.drawables.length;al++){ai=this.drawables[al];for(var ak=0;ak<ai.filters_manager.filters.length;ak++){ad=ai.filters_manager.filters[ak];if(ad.name in ap){ap[ad.name].push(ad)}}}this.filters_manager.remove_all();var af,ah,aj,am;for(var an in ap){af=ap[an];if(af.length===ac){ah=new S({name:af[0].name,index:af[0].index});this.filters_manager.add_filter(ah)}}if(this.filters_manager.filters.length>0){this.action_icons.filters_icon.show()}else{this.action_icons.filters_icon.hide()}}else{this.action_icons.filters_icon.hide()}}}},_restore_filter_managers:function(){for(var ac=0;ac<this.drawables.length;ac++){this.drawables[ac].filters_manager=this.saved_filters_managers[ac]}this.saved_filters_managers=[]},setup_multitrack_filtering:function(){if(this.filters_manager.filters.length>0){this.saved_filters_managers=[];for(var ac=0;ac<this.drawables.length;ac++){drawable=this.drawables[ac];this.saved_filters_managers.push(drawable.filters_manager);drawable.filters_manager=this.filters_manager}}this.filters_manager.init_filters()},show_composite_track:function(){var ag=[];for(var ad=0;ad<this.drawables.length;ad++){ag.push(this.drawables[ad].name)}var ae="Composite Track of "+this.drawables.length+" tracks ("+ag.join(", ")+")";var af=new h(this.view,this.view,{name:ae,drawables:this.drawables});var ac=this.container.replace_drawable(this,af,true);af.request_draw()},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);this.update_icons()},remove_drawable:function(ac){w.prototype.remove_drawable.call(this,ac);this.update_icons()},to_dict:function(){if(this.filters_manager.visible()){this._restore_filter_managers()}var ac=p(w.prototype.to_dict.call(this),{filters:this.filters_manager.to_dict()});if(this.filters_manager.visible()){this.setup_multitrack_filtering()}return ac},request_draw:function(ac,ae){for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].request_draw(ac,ae)}}});var Z=function(ac){p(ac,{obj_type:"View"});w.call(this,"View",ac.container,ac);this.chrom=null;this.vis_id=ac.vis_id;this.dbkey=ac.dbkey;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ab(this.container.get(0).ownerDocument);this.reset()};_.extend(Z.prototype,Backbone.Events);p(Z.prototype,w.prototype,{init:function(){this.requested_redraw=false;var ae=this.container,ac=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ae);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ae);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ae);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,ac);this.intro_div=$("<div/>").addClass("intro").appendTo(this.viewport_container).hide();var af=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_datasets(add_datasets_url,add_track_async_url,function(ag){_.each(ag,function(ah){ac.add_drawable(object_from_template(ah,ac))})})});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("trackster-nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("trackster-nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ad=function(ag){if(ag.type==="focusout"||(ag.keyCode||ag.which)===13||(ag.keyCode||ag.which)===27){if((ag.keyCode||ag.which)!==27){ac.go_to($(this).val())}$(this).hide();$(this).val("");ac.location_span.show();ac.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ad).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("original-title","Click to change location").tipsy({gravity:"n"}).appendTo(this.nav_controls);this.location_span.click(function(){ac.location_span.hide();ac.chrom_select.hide();ac.nav_input.val(ac.chrom+":"+ac.low+"-"+ac.high);ac.nav_input.css("display","inline-block");ac.nav_input.select();ac.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tipsy({gravity:"n"}).click(function(){ac.zoom_out();ac.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tipsy({gravity:"n"}).click(function(){ac.zoom_in();ac.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ac.change_chrom(ac.chrom_select.val())});this.browser_content_div.click(function(ag){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(ag){ac.zoom_in(ag.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ag,ah){this.current_x=ah.offsetX}).bind("drag",function(ag,ai){var aj=ai.offsetX-this.current_x;this.current_x=ai.offsetX;var ah=Math.round(aj/ac.viewport_container.width()*(ac.max_high-ac.max_low));ac.move_delta(-ah)});this.overview_close.click(function(){ac.reset_overview()});this.viewport_container.bind("draginit",function(ag,ah){if(ag.clientX>ac.viewport_container.width()-16){return false}}).bind("dragstart",function(ag,ah){ah.original_low=ac.low;ah.current_height=ag.clientY;ah.current_x=ah.offsetX}).bind("drag",function(ai,ak){var ag=$(this);var al=ak.offsetX-ak.current_x;var ah=ag.scrollTop()-(ai.clientY-ak.current_height);ag.scrollTop(ah);ak.current_height=ai.clientY;ak.current_x=ak.offsetX;var aj=Math.round(al/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}).bind("mousewheel",function(ai,ak,ah,ag){if(ah){ah*=50;var aj=Math.round(-ah/ac.viewport_container.width()*(ac.high-ac.low));ac.move_delta(aj)}});this.top_labeltrack.bind("dragstart",function(ag,ah){return $("<div />").css({height:ac.browser_content_div.height()+ac.top_labeltrack.height()+ac.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ak,al){$(al.proxy).css({left:Math.min(ak.pageX,al.startX)-ac.container.offset().left,width:Math.abs(ak.pageX-al.startX)});var ah=Math.min(ak.pageX,al.startX)-ac.container.offset().left,ag=Math.max(ak.pageX,al.startX)-ac.container.offset().left,aj=(ac.high-ac.low),ai=ac.viewport_container.width();ac.update_location(Math.round(ah/ai*aj)+ac.low,Math.round(ag/ai*aj)+ac.low)}).bind("dragend",function(al,am){var ah=Math.min(al.pageX,am.startX),ag=Math.max(al.pageX,am.startX),aj=(ac.high-ac.low),ai=ac.viewport_container.width(),ak=ac.low;ac.low=Math.round(ah/ai*aj)+ak;ac.high=Math.round(ag/ai*aj)+ak;$(am.proxy).remove();ac.request_redraw()});this.add_label_track(new Y(this,{content_div:this.top_labeltrack}));this.add_label_track(new Y(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){if(this.resize_timer){clearTimeout(this.resize_timer)}this.resize_timer=setTimeout(function(){ac.resize_window()},500)});$(document).bind("redraw",function(){ac.redraw()});this.reset();$(window).trigger("resize")},changed:function(){this.has_changes=true},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.show()}else{this.intro_div.hide()}},trigger_navigate:function(ad,af,ac,ag){if(this.timer){clearTimeout(this.timer)}if(ag){var ae=this;this.timer=setTimeout(function(){ae.trigger("navigate",ad+":"+af+"-"+ac)},500)}else{view.trigger("navigate",ad+":"+af+"-"+ac)}},update_location:function(ac,ae){this.location_span.text(commatize(ac)+" - "+commatize(ae));this.nav_input.val(this.chrom+":"+commatize(ac)+"-"+commatize(ae));var ad=view.chrom_select.val();if(ad!==""){this.trigger_navigate(ad,view.low,view.high,true)}},load_chroms:function(ae){ae.num=u;ae.dbkey=this.dbkey;var ac=this,ad=$.Deferred();$.ajax({url:chrom_url,data:ae,dataType:"json",success:function(ag){if(ag.chrom_info.length===0){alert("Invalid chromosome: "+ae.chrom);return}if(ag.reference){ac.add_label_track(new y(ac))}ac.chrom_data=ag.chrom_info;var aj='<option value="">Select Chrom/Contig</option>';for(var ai=0,af=ac.chrom_data.length;ai<af;ai++){var ah=ac.chrom_data[ai].chrom;aj+='<option value="'+ah+'">'+ah+"</option>"}if(ag.prev_chroms){aj+='<option value="previous">Previous '+u+"</option>"}if(ag.next_chroms){aj+='<option value="next">Next '+u+"</option>"}ac.chrom_select.html(aj);ac.chrom_start_index=ag.start_index;ad.resolve(ag)},error:function(){alert("Could not load chroms for this dbkey:",ac.dbkey)}});return ad},change_chrom:function(ah,ad,aj){var ae=this;if(!ae.chrom_data){ae.load_chroms_deferred.then(function(){ae.change_chrom(ah,ad,aj)});return}if(!ah||ah==="None"){return}var ae=this;if(ah==="previous"){ae.load_chroms({low:this.chrom_start_index-u});return}if(ah==="next"){ae.load_chroms({low:this.chrom_start_index+u});return}var ai=$.grep(ae.chrom_data,function(ak,al){return ak.chrom===ah})[0];if(ai===undefined){ae.load_chroms({chrom:ah},function(){ae.change_chrom(ah,ad,aj)});return}else{if(ah!==ae.chrom){ae.chrom=ah;ae.chrom_select.val(ae.chrom);ae.max_high=ai.len-1;ae.reset();ae.request_redraw(true);for(var ag=0,ac=ae.drawables.length;ag<ac;ag++){var af=ae.drawables[ag];if(af.init){af.init()}}if(ae.reference_track){ae.reference_track.init()}}if(ad!==undefined&&aj!==undefined){ae.low=Math.max(ad,0);ae.high=Math.min(aj,ae.max_high)}else{ae.low=0;ae.high=ae.max_high}ae.reset_overview();ae.request_redraw()}},go_to:function(ag){ag=ag.replace(/ |,/g,"");var ak=this,ac,af,ad=ag.split(":"),ai=ad[0],aj=ad[1];if(aj!==undefined){try{var ah=aj.split("-");ac=parseInt(ah[0],10);af=parseInt(ah[1],10)}catch(ae){return false}}ak.change_chrom(ai,ac,af)},move_fraction:function(ae){var ac=this;var ad=ac.high-ac.low;this.move_delta(ae*ad)},move_delta:function(af){var ac=this;var ae=ac.high-ac.low;if(ac.low-af<ac.max_low){ac.low=ac.max_low;ac.high=ac.max_low+ae}else{if(ac.high-af>ac.max_high){ac.high=ac.max_high;ac.low=ac.max_high-ae}else{ac.high-=af;ac.low-=af}}ac.request_redraw();var ad=ac.chrom_select.val();this.trigger_navigate(ad,ac.low,ac.high,true)},add_drawable:function(ac){w.prototype.add_drawable.call(this,ac);ac.init();this.changed();this.update_intro_div()},add_label_track:function(ac){ac.view=this;ac.init();this.label_tracks.push(ac)},remove_drawable:function(ae,ad){w.prototype.remove_drawable.call(this,ae);if(ad){var ac=this;ae.container_div.hide(0,function(){$(this).remove();ac.update_intro_div()})}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ak,ac,aj,ad){var ai=this,ag=(ad?[ad]:ai.drawables),ae;var ad;for(var ah=0;ah<ag.length;ah++){ad=ag[ah];ae=-1;for(var af=0;af<ai.tracks_to_be_redrawn.length;af++){if(ai.tracks_to_be_redrawn[af][0]===ad){ae=af;break}}if(ae<0){ai.tracks_to_be_redrawn.push([ad,ac,aj])}else{ai.tracks_to_be_redrawn[ah][1]=ac;ai.tracks_to_be_redrawn[ah][2]=aj}}if(!this.requested_redraw){requestAnimationFrame(function(){ai._redraw(ak)});this.requested_redraw=true}},_redraw:function(am){this.requested_redraw=false;var aj=this.low,af=this.high;if(aj<this.max_low){aj=this.max_low}if(af>this.max_high){af=this.max_high}var al=this.high-this.low;if(this.high!==0&&al<this.min_separation){af=aj+this.min_separation}this.low=Math.floor(aj);this.high=Math.ceil(af);this.update_location(this.low,this.high);this.resolution_b_px=(this.high-this.low)/this.viewport_container.width();this.resolution_px_b=this.viewport_container.width()/(this.high-this.low);var ac=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ai=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=13;this.overview_box.css({left:ac,width:Math.max(an,ai)}).show();if(ai<an){this.overview_box.css("left",ac-(an-ai)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ac,width:ai})}if(!am){var ae,ad,ak;for(var ag=0,ah=this.tracks_to_be_redrawn.length;ag<ah;ag++){ae=this.tracks_to_be_redrawn[ag][0];ad=this.tracks_to_be_redrawn[ag][1];ak=this.tracks_to_be_redrawn[ag][2];if(ae){ae._draw(ad,ak)}}this.tracks_to_be_redrawn=[];for(ag=0,ah=this.label_tracks.length;ag<ah;ag++){this.label_tracks[ag]._draw()}}},zoom_in:function(ad,ae){if(this.max_high===0||this.high-this.low<=this.min_separation){return}var af=this.high-this.low,ag=af/2+this.low,ac=(af/this.zoom_factor)/2;if(ad){ag=ad/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ag-ac);this.high=Math.round(ag+ac);this.changed();this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ad=this.high-this.low,ae=ad/2+this.low,ac=(ad*this.zoom_factor)/2;this.low=Math.round(ae-ac);this.high=Math.round(ae+ac);this.changed();this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.request_redraw()},set_overview:function(ae){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ae.dataset_id){return}this.overview_viewport.find(".track").remove()}var ad=ae.copy({content_div:this.overview_viewport}),ac=this;ad.header_div.hide();ad.is_overview=true;ac.overview_drawable=ad;this.overview_drawable.postdraw_actions=function(){ac.overview_highlight.show().height(ac.overview_drawable.content_div.height());ac.overview_viewport.height(ac.overview_drawable.content_div.height()+ac.overview_box.outerHeight());ac.overview_close.show();ac.resize_window()};ac.overview_drawable.request_draw();this.changed()},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ae,aj,af){this.track=ae;this.name=aj.name;this.params=[];var aq=aj.params;for(var ag=0;ag<aq.length;ag++){var al=aq[ag],ad=al.name,ap=al.label,ah=unescape(al.html),ar=al.value,an=al.type;if(an==="number"){this.params.push(new f(ad,ap,ah,(ad in af?af[ad]:ar),al.min,al.max))}else{if(an==="select"){this.params.push(new L(ad,ap,ah,(ad in af?af[ad]:ar)))}else{console.log("WARNING: unrecognized tool parameter type:",ad,an)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(au){au.stopPropagation()}).click(function(au){au.stopPropagation()}).bind("dblclick",function(au){au.stopPropagation()});var ao=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var am=this.params;var ak=this;$.each(this.params,function(av,ay){var ax=$("<div>").addClass("param-row").appendTo(ak.parent_div);var au=$("<div>").addClass("param-label").text(ay.label).appendTo(ax);var aw=$("<div/>").addClass("param-input").html(ay.html).appendTo(ax);aw.find(":input").val(ay.value);$("<div style='clear: both;'/>").appendTo(ax)});this.parent_div.find("input").click(function(){$(this).select()});var at=$("<div>").addClass("param-row").appendTo(this.parent_div);var ai=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(at);var ac=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(at);var ak=this;ac.click(function(){ak.run_on_region()});ai.click(function(){ak.run_on_dataset()});if("visible" in af&&af.visible){this.parent_div.show()}};p(r.prototype,{update_params:function(){for(var ac=0;ac<this.params.length;ac++){this.params[ac].update_value()}},state_dict:function(){var ad={};for(var ac=0;ac<this.params.length;ac++){ad[this.params[ac].name]=this.params[ac].value}ad.visible=this.parent_div.is(":visible");return ad},get_param_values_dict:function(){var ac={};this.parent_div.find(":input").each(function(){var ad=$(this).attr("name"),ae=$(this).val();ac[ad]=JSON.stringify(ae)});return ac},get_param_values:function(){var ad=[];var ac={};this.parent_div.find(":input").each(function(){var ae=$(this).attr("name"),af=$(this).val();if(ae){ad[ad.length]=af}});return ad},run_on_dataset:function(){var ac=this;ac.run({dataset_id:this.track.original_dataset_id,tool_id:ac.name},null,function(ad){show_modal(ac.name+" is Running",ac.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ad={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},ah=this.track,ae=ad.tool_id+ah.tool_region_and_parameters_str(ad.chrom,ad.low,ad.high),ac;if(ah.container===view){var ag=new N(view,view,{name:this.name});var af=ah.container.replace_drawable(ah,ag,false);ag.container_div.insertBefore(ah.view.content_div.children()[af]);ag.add_drawable(ah);ah.container_div.appendTo(ag.content_div);ac=ag}else{ac=ah.container}var ai=new ah.constructor(view,ac,{name:ae,hda_ldda:"hda"});ai.init_for_tool_data();ai.change_mode(ah.mode);ai.set_filters_manager(ah.filters_manager.copy(ai));ai.update_icons();ac.add_drawable(ai);ai.tiles_div.text("Starting job.");this.update_params();this.run(ad,ai,function(aj){ai.dataset_id=aj.dataset_id;ai.tiles_div.text("Running job.");ai.init()})},run:function(ad,ae,af){$.extend(ad,this.get_param_values_dict());var ac=function(){$.getJSON(rerun_tool_url,ad,function(ag){if(ag==="no converter"){ae.container_div.addClass("error");ae.content_div.text(H)}else{if(ag.error){ae.container_div.addClass("error");ae.content_div.text(v+ag.message)}else{if(ag==="pending"){ae.container_div.addClass("pending");ae.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ac,2000)}else{af(ag)}}}})};ac()}});var L=function(ad,ac,ae,af){this.name=ad;this.label=ac;this.html=$(ae);this.value=af};p(L.prototype,{update_value:function(){this.value=$(this.html).val()}});var f=function(ae,ad,ag,ah,af,ac){L.call(this,ae,ad,ag,ah);this.min=af;this.max=ac};p(f.prototype,L.prototype,{update_value:function(){L.prototype.update_value.call(this);this.value=parseFloat(this.value)}});var g=function(ac){this.manager=null;this.name=ac.name;this.index=ac.index;this.tool_id=ac.tool_id;this.tool_exp_name=ac.tool_exp_name};p(g.prototype,{to_dict:function(){return{name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name}}});var S=function(al){g.call(this,al);this.low=("low" in al?al.low:-Number.MAX_VALUE);this.high=("high" in al?al.high:Number.MAX_VALUE);this.min=("min" in al?al.min:Number.MAX_VALUE);this.max=("max" in al?al.max:-Number.MAX_VALUE);this.container=null;this.slider=null;this.slider_label=null;var ah=function(am,an,ao){am.click(function(){var au=an.text(),ar=parseFloat(ao.slider("option","max")),aq=(ar<=1?4:ar<=1000000?ar.toString().length:6),at=false,ap=$(this).parents(".slider-row");ap.addClass("input");if(ao.slider("option","values")){aq=2*aq+1;at=true}an.text("");$("<input type='text'/>").attr("size",aq).attr("maxlength",aq).attr("value",au).appendTo(an).focus().select().click(function(av){av.stopPropagation()}).blur(function(){$(this).remove();an.text(au);ap.removeClass("input")}).keyup(function(az){if(az.keyCode===27){$(this).trigger("blur")}else{if(az.keyCode===13){var ax=ao.slider("option","min"),av=ao.slider("option","max"),ay=function(aA){return(isNaN(aA)||aA>av||aA<ax)},aw=$(this).val();if(!at){aw=parseFloat(aw);if(ay(aw)){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}else{aw=aw.split("-");aw=[parseFloat(aw[0]),parseFloat(aw[1])];if(ay(aw[0])||ay(aw[1])){alert("Parameter value must be in the range ["+ax+"-"+av+"]");return $(this)}}ao.slider((at?"values":"value"),aw);ap.removeClass("input")}}})})};var ad=this;ad.parent_div=$("<div/>").addClass("filter-row slider-row");var ac=$("<div/>").addClass("elt-label").appendTo(ad.parent_div),aj=$("<span/>").addClass("slider-name").text(ad.name+" ").appendTo(ac),ae=$("<span/>").text(this.low+"-"+this.high),af=$("<span/>").addClass("slider-value").appendTo(ac).append("[").append(ae).append("]");ad.values_span=ae;var ai=$("<div/>").addClass("slider").appendTo(ad.parent_div);ad.control_element=$("<div/>").attr("id",ad.name+"-filter-control").appendTo(ai);var ag=[0,0];ad.control_element.slider({range:true,min:this.min,max:this.max,step:this.get_slider_step(this.min,this.max),values:[this.low,this.high],slide:function(am,an){ad.slide(am,an)},change:function(am,an){ad.control_element.slider("option","slide").call(ad.control_element,am,an)}});ad.slider=ad.control_element;ad.slider_label=ae;ah(af,ae,ad.control_element);var ak=$("<div/>").addClass("display-controls").appendTo(ad.parent_div);this.transparency_icon=create_action_icon("Use filter for data transparency","layer-transparent",function(){if(ad.manager.alpha_filter!==ad){ad.manager.alpha_filter=ad;ad.manager.parent_div.find(".layer-transparent").removeClass("active").hide();ad.transparency_icon.addClass("active").show()}else{ad.manager.alpha_filter=null;ad.transparency_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();this.height_icon=create_action_icon("Use filter for data height","arrow-resize-090",function(){if(ad.manager.height_filter!==ad){ad.manager.height_filter=ad;ad.manager.parent_div.find(".arrow-resize-090").removeClass("active").hide();ad.height_icon.addClass("active").show()}else{ad.manager.height_filter=null;ad.height_icon.removeClass("active")}ad.manager.track.request_draw(true,true)}).appendTo(ak).hide();ad.parent_div.hover(function(){ad.transparency_icon.show();ad.height_icon.show()},function(){if(ad.manager.alpha_filter!==ad){ad.transparency_icon.hide()}if(ad.manager.height_filter!==ad){ad.height_icon.hide()}});$("<div style='clear: both;'/>").appendTo(ad.parent_div)};p(S.prototype,{to_dict:function(){var ac=g.prototype.to_dict.call(this);return p(ac,{type:"number",min:this.min,max:this.max,low:this.low,high:this.high})},copy:function(){return new S({name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name})},get_slider_step:function(ae,ac){var ad=ac-ae;return(ad<=2?0.01:1)},slide:function(ad,ae){var ac=ae.values;this.values_span.text(ac[0]+"-"+ac[1]);this.low=ac[0];this.high=ac[1];this.manager.track.request_draw(true,true)},applies_to:function(ac){if(ac.length>this.index){return true}return false},_keep_val:function(ac){return(isNaN(ac)||(ac>=this.low&&ac<=this.high))},keep:function(ad){if(!this.applies_to(ad)){return true}var af=this;var ag=ad[this.index];if(ag instanceof Array){var ae=true;for(var ac=0;ac<ag.length;ac++){if(!this._keep_val(ag[ac])){ae=false;break}}return ae}else{return this._keep_val(ad[this.index])}},update_attrs:function(af){var ac=false;if(!this.applies_to(af)){return ac}var ad=af[this.index];if(!(ad instanceof Array)){ad=[ad]}for(var ae=0;ae<ad.length;ae++){var ag=ad[ae];if(ag<this.min){this.min=Math.floor(ag);ac=true}if(ag>this.max){this.max=Math.ceil(ag);ac=true}}return ac},update_ui_elt:function(){if(this.min<this.max){this.parent_div.show()}else{this.parent_div.hide()}var ad=this.slider.slider("option","min"),ac=this.slider.slider("option","max");if(this.min<ad||this.max>ac){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",this.get_slider_step(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var X=function(ae,ak){this.track=ae;this.alpha_filter=null;this.height_filter=null;this.filters=[];this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(am){am.stopPropagation()}).click(function(am){am.stopPropagation()}).bind("dblclick",function(am){am.stopPropagation()}).bind("keydown",function(am){am.stopPropagation()});if(ak&&"filters" in ak){var ac=("alpha_filter" in ak?ak.alpha_filter:null),af=("height_filter" in ak?ak.height_filter:null),ah=ak.filters,ad;for(var ai=0;ai<ah.length;ai++){if(ah[ai].type==="number"){ad=new S(ah[ai]);this.add_filter(ad);if(ad.name===ac){this.alpha_filter=ad;ad.transparency_icon.addClass("active").show()}if(ad.name===af){this.height_filter=ad;ad.height_icon.addClass("active").show()}}else{console.log("ERROR: unsupported filter: ",name,type)}}if("visible" in ak&&ak.visible){this.parent_div.show()}}if(this.filters.length!==0){var al=$("<div/>").addClass("param-row").appendTo(this.parent_div);var aj=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(al);var ag=this;aj.click(function(){ag.run_on_dataset()})}};p(X.prototype,{show:function(){this.parent_div.show()},hide:function(){this.parent_div.hide()},toggle:function(){this.parent_div.toggle()},visible:function(){return this.parent_div.is(":visible")},to_dict:function(){var af={},ae=[],ad;for(var ac=0;ac<this.filters.length;ac++){ad=this.filters[ac];ae.push(ad.to_dict())}af.filters=ae;af.alpha_filter=(this.alpha_filter?this.alpha_filter.name:null);af.height_filter=(this.height_filter?this.height_filter.name:null);af.visible=this.parent_div.is(":visible");return af},copy:function(ad){var ae=new X(ad);for(var ac=0;ac<this.filters.length;ac++){ae.add_filter(this.filters[ac].copy())}return ae},add_filter:function(ac){ac.manager=this;this.parent_div.append(ac.parent_div);this.filters.push(ac)},remove_all:function(){this.filters=[];this.parent_div.children().remove()},init_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.update_ui_elt()}},clear_filters:function(){for(var ac=0;ac<this.filters.length;ac++){var ad=this.filters[ac];ad.slider.slider("option","values",[ad.min,ad.max])}this.alpha_filter=null;this.height_filter=null;this.parent_div.find(".icon-button").hide()},run_on_dataset:function(){var ak=function(ao,am,an){if(!(am in ao)){ao[am]=an}return ao[am]};var ae={},ac,ad,af;for(var ag=0;ag<this.filters.length;ag++){ac=this.filters[ag];if(ac.tool_id){if(ac.min!==ac.low){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" >= "+ac.low}if(ac.max!==ac.high){ad=ak(ae,ac.tool_id,[]);ad[ad.length]=ac.tool_exp_name+" <= "+ac.high}}}var ai=[];for(var al in ae){ai[ai.length]=[al,ae[al]]}var aj=ai.length;(function ah(at,ap){var an=ap[0],ao=an[0],ar=an[1],aq="("+ar.join(") and (")+")",am={cond:aq,input:at,target_dataset_id:at,tool_id:ao},ap=ap.slice(1);$.getJSON(run_tool_url,am,function(au){if(au.error){show_modal("Filter Dataset","Error running tool "+ao,{Close:hide_modal})}else{if(ap.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ah(au.dataset_id,ap)}}})})(this.track.dataset_id,ai)}});var z=function(ac,ad){J.Scaler.call(this,ad);this.filter=ac};z.prototype.gen_val=function(ac){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ac[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var C=function(ac){this.track=ac.track;this.params=ac.params;this.values={};this.restore_values((ac.saved_values?ac.saved_values:{}));this.onchange=ac.onchange};p(C.prototype,{restore_values:function(ac){var ad=this;$.each(this.params,function(ae,af){if(ac[af.key]!==undefined){ad.values[af.key]=ac[af.key]}else{ad.values[af.key]=af.default_value}})},build_form:function(){var af=this;var ac=$("<div />");var ae;function ad(aj,ag){for(var an=0;an<aj.length;an++){ae=aj[an];if(ae.hidden){continue}var ah="param_"+an;var ar=af.values[ae.key];var av=$("<div class='form-row' />").appendTo(ag);av.append($("<label />").attr("for",ah).text(ae.label+":"));if(ae.type==="bool"){av.append($('<input type="checkbox" />').attr("id",ah).attr("name",ah).attr("checked",ar))}else{if(ae.type==="text"){av.append($('<input type="text"/>').attr("id",ah).val(ar).click(function(){$(this).select()}))}else{if(ae.type==="select"){var ap=$("<select />").attr("id",ah);for(var al=0;al<ae.options.length;al++){$("<option/>").text(ae.options[al].label).attr("value",ae.options[al].value).appendTo(ap)}ap.val(ar);av.append(ap)}else{if(ae.type==="color"){var au=$("<div/>").appendTo(av),ao=$("<input />").attr("id",ah).attr("name",ah).val(ar).css("float","left").appendTo(au).click(function(ax){$(".tipsy").hide();var aw=$(this).siblings(".tipsy");aw.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(aw).height()/2)+($(this).height()/2)}).show();aw.click(function(ay){ay.stopPropagation()});$(document).bind("click.color-picker",function(){aw.hide();$(document).unbind("click.color-picker")});ax.stopPropagation()}),am=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(au).attr("title","Set new random color").tipsy({gravity:"s"}),aq=$("<div class='tipsy tipsy-west' style='position: absolute;' />").appendTo(au).hide(),ai=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(aq),at=$("<div/>").appendTo(ai),ak=$.farbtastic(at,{width:100,height:100,callback:ao,color:ar});au.append($("<div/>").css("clear","both"));(function(aw){am.click(function(){aw.setColor(get_random_color())})})(ak)}else{av.append($("<input />").attr("id",ah).attr("name",ah).val(ar))}}}}if(ae.help){av.append($("<div class='help'/>").text(ae.help))}}}ad(this.params,ac);return ac},update_from_form:function(ac){var ae=this;var ad=false;$.each(this.params,function(af,ah){if(!ah.hidden){var ai="param_"+af;var ag=ac.find("#"+ai).val();if(ah.type==="float"){ag=parseFloat(ag)}else{if(ah.type==="int"){ag=parseInt(ag)}else{if(ah.type==="bool"){ag=ac.find("#"+ai).is(":checked")}}}if(ag!==ae.values[ah.key]){ae.values[ah.key]=ag;ad=true}}});if(ad){this.onchange();this.track.changed()}}});var b=function(ac,af,ae,ad,ag){this.track=ac;this.index=af;var ah=this.track._get_tile_bounds(af,ae);this.low=ah[0];this.high=ah[1];this.resolution=ae;this.html_elt=$("<div class='track-tile'/>").append(ad).height($(ad).attr("height"));this.data=ag;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(ac,af,ae,ad,ag,ah){b.call(this,ac,af,ae,ad,ag);this.max_val=ah};p(k.prototype,b.prototype);var M=function(af,ak,ag,ae,ai,ao,aj,ap,ad,am){b.call(this,af,ak,ag,ae,ai);this.mode=aj;this.all_slotted=ad;this.feature_mapper=am;this.has_icons=false;if(ap){this.has_icons=true;var al=this;ae=this.html_elt.children()[0],message_div=$("<div/>").addClass("tile-message").css({height:A-1,width:ae.width}).prependTo(this.html_elt);var an=ai.length,ah=$("<a href='javascript:void(0);'/>").addClass("icon more-down").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data including depth").tipsy({gravity:"s"}).appendTo(message_div),ac=$("<a href='javascript:void(0);'/>").addClass("icon more-across").attr("title","For speed, only the first "+an+" features in this region were obtained from server. Click to get more data excluding depth").tipsy({gravity:"s"}).appendTo(message_div);ah.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.DEEP_DATA_REQ);$(".tipsy").hide();af.request_draw(true)}).dblclick(function(aq){aq.stopPropagation()});ac.click(function(){al.stale=true;af.data_manager.get_more_data(al.low,al.high,af.mode,al.resolution,{},af.data_manager.BROAD_DATA_REQ);$(".tipsy").hide();af.request_draw(true)}).dblclick(function(aq){aq.stopPropagation()})}};p(M.prototype,b.prototype);M.prototype.predisplay_actions=function(){var ad=this,ac={};if(ad.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(ao){if(!this.hovered){return}var aj=$(this).offset(),an=ao.pageX-aj.left,am=ao.pageY-aj.top,at=ad.feature_mapper.get_feature_data(an,am),ak=(at?at[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!ak||$(this).attr("id")!==ak.toString()){$(this).remove()}});if(at){var af=ac[ak];if(!af){var ak=at[0],ap={name:at[3],start:at[1],end:at[2],strand:at[4]},ai=ad.track.filters_manager.filters,ah;for(var al=0;al<ai.length;al++){ah=ai[al];ap[ah.name]=at[ah.index]}var af=$("<div/>").attr("id",ak).addClass("feature-popup"),au=$("<table/>"),ar,aq,av;for(ar in ap){aq=ap[ar];av=$("<tr/>").appendTo(au);$("<th/>").appendTo(av).text(ar);$("<td/>").attr("align","left").appendTo(av).text(typeof(aq)==="number"?W(aq,2):aq)}af.append($("<div class='feature-popup-inner'>").append(au));ac[ak]=af}af.appendTo($(this).parents(".track-content").children(".overlay"));var ag=an+parseInt(ad.html_elt.css("left"))-af.width()/2,ae=am+parseInt(ad.html_elt.css("top"))+7;af.css("left",ag+"px").css("top",ae+"px")}else{if(!ao.isPropagationStopped()){ao.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ao)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var i=function(ad,ac,ae){p(ae,{drag_handle_class:"draghandle"});q.call(this,ad,ac,ae);this.data_url=("data_url" in ae?ae.data_url:default_data_url);this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ae?ae.data_query_wait:I);this.dataset_check_url=converted_datasets_state_url;this.data_manager=("data_manager" in ae?ae.data_manager:new P(F,this));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=0;this.content_div=$("<div class='track-content'>").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ae)||ae.resize){this.add_resize_handle()}}};p(i.prototype,q.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},q.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"overview-icon",on_click_fn:function(ac){ac.view.set_overview(ac)}},q.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(ac){if(ac.filters_manager.visible()){ac.filters_manager.clear_filters()}else{ac.filters_manager.init_filters()}ac.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(ac){ac.dynamic_tool_div.toggle();if(ac.dynamic_tool_div.is(":visible")){ac.set_name(ac.name+ac.tool_region_and_parameters_str())}else{ac.revert_name()}$(".tipsy").remove()}},q.prototype.action_icons_def[2]],can_draw:function(){if(this.dataset_id&&q.prototype.can_draw.call(this)){return true}return false},build_container_div:function(){return $("<div/>").addClass("track").attr("id","track_"+this.id).css("position","relative")},build_header_div:function(){var ac=$("<div class='track-header'/>");if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(ac)}this.name_div=$("<div/>").addClass("track-name").appendTo(ac).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return ac},on_resize:function(){},add_resize_handle:function(){var ac=this;var af=false;var ae=false;var ad=$("<div class='track-resize'>");$(ac.container_div).hover(function(){if(ac.content_visible){af=true;ad.show()}},function(){af=false;if(!ae){ad.hide()}});ad.hide().bind("dragstart",function(ag,ah){ae=true;ah.original_height=$(ac.content_div).height()}).bind("drag",function(ah,ai){var ag=Math.min(Math.max(ai.original_height+ai.deltaY,ac.min_height_px),ac.max_height_px);$(ac.tiles_div).css("height",ag);ac.visible_height_px=(ac.max_height_px===ag?0:ag);ac.on_resize()}).bind("dragend",function(ag,ah){ac.tile_cache.clear();ae=false;if(!af){ad.hide()}ac.config.values.height=ac.visible_height_px;ac.changed()}).appendTo(ac.container_div)},set_display_modes:function(af,ai){this.display_modes=af;this.mode=(ai?ai:(this.config&&this.config.values.mode?this.config.values.mode:this.display_modes[0]));this.action_icons.mode_icon.attr("title","Set display mode (now: "+this.mode+")");var ad=this,ag={};for(var ae=0,ac=ad.display_modes.length;ae<ac;ae++){var ah=ad.display_modes[ae];ag[ah]=function(aj){return function(){ad.change_mode(aj);ad.icons_div.show();ad.container_div.mouseleave(function(){ad.icons_div.hide()})}}(ah)}make_popupmenu(this.action_icons.mode_icon,ag)},build_action_icons:function(){q.prototype.build_action_icons.call(this,this.action_icons_def);if(this.display_modes!==undefined){this.set_display_modes(this.display_modes)}},hide_contents:function(){this.tiles_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.tiles_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},get_type:function(){if(this instanceof Y){return"LabelTrack"}else{if(this instanceof y){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof T){return"ReadTrack"}else{if(this instanceof Q){return"VcfTrack"}else{if(this instanceof h){return"CompositeTrack"}else{if(this instanceof d){return"FeatureTrack"}}}}}}}return""},init:function(){var ad=this;ad.enabled=false;ad.tile_cache.clear();ad.data_manager.clear();ad.content_div.css("height","auto");ad.tiles_div.children().remove();ad.container_div.removeClass("nodata error pending");if(!ad.dataset_id){return}var ac=$.Deferred();$.getJSON(this.dataset_check_url,{hda_ldda:ad.hda_ldda,dataset_id:ad.dataset_id,chrom:ad.view.chrom},function(ae){if(!ae||ae==="error"||ae.kind==="error"){ad.container_div.addClass("error");ad.tiles_div.text(o);if(ae.message){var af=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ae.message+"</pre>",{Close:hide_modal})});ad.tiles_div.append(af)}}else{if(ae==="no converter"){ad.container_div.addClass("error");ad.tiles_div.text(H)}else{if(ae==="no data"||(ae.data!==undefined&&(ae.data===null||ae.data.length===0))){ad.container_div.addClass("nodata");ad.tiles_div.text(B)}else{if(ae==="pending"){ad.container_div.addClass("pending");ad.tiles_div.html(t);setTimeout(function(){ad.init()},ad.data_query_wait)}else{if(ae==="data"||ae.status==="data"){if(ae.valid_chroms){ad.valid_chroms=ae.valid_chroms;ad.update_icons()}ad.tiles_div.text(V);if(ad.view.chrom){ad.tiles_div.text("");ad.tiles_div.css("height",ad.visible_height_px+"px");ad.enabled=true;$.when(ad.predraw_init()).done(function(){ac.resolve();ad.container_div.removeClass("nodata error pending");ad.request_draw()})}else{ac.resolve()}}}}}}});this.update_icons();return ac},predraw_init:function(){}});var K=function(ae,ad,af){i.call(this,ae,ad,af);var ac=this,ae=ac.view;m(ac.container_div,ac.drag_handle_class,".group",ac);this.filters_manager=new X(this,("filters" in af?af.filters:null));this.filters_available=false;this.tool=("tool" in af&&af.tool?new r(this,af.tool,af.tool_state):null);this.tile_cache=new c(O);if(this.header_div){this.set_filters_manager(this.filters_manager);if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}this.tiles_div=$("<div/>").addClass("tiles").appendTo(this.content_div);this.overlay_div=$("<div/>").addClass("overlay").appendTo(this.content_div);if(af.mode){this.change_mode(af.mode)}};p(K.prototype,q.prototype,i.prototype,{action_icons_def:i.prototype.action_icons_def.concat([{name:"show_more_rows_icon",title:"To minimize track height, not all feature rows are displayed. Click to display more rows.",css_class:"exclamation",on_click_fn:function(ac){$(".tipsy").remove();ac.slotters[ac.view.resolution_px_b].max_rows*=2;ac.request_draw(true)},hide:true}]),copy:function(ac){var ad=this.to_dict();p(ad,{data_manager:this.data_manager});var ae=new this.constructor(this.view,ac,ad);ae.change_mode(this.mode);ae.enabled=this.enabled;return ae},set_filters_manager:function(ac){this.filters_manager=ac;this.header_div.after(this.filters_manager.parent_div)},to_dict:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,filters:this.filters_manager.to_dict(),tool_state:(this.tool?this.tool.state_dict():{})}},change_mode:function(ad){var ac=this;ac.mode=ad;ac.config.values.mode=ad;ac.tile_cache.clear();ac.request_draw();this.action_icons.mode_icon.attr("title","Set display mode (now: "+ac.mode+")");return ac},update_icons:function(){var ac=this;if(ac.filters_available){ac.action_icons.filters_icon.show()}else{ac.action_icons.filters_icon.hide()}if(ac.tool){ac.action_icons.tools_icon.show()}else{ac.action_icons.tools_icon.hide()}},_gen_tile_cache_key:function(ad,ae,ac){return ad+"_"+ae+"_"+ac},request_draw:function(ad,ac){this.view.request_redraw(false,ad,ac,this)},before_draw:function(){},_draw:function(ad,an){if(!this.can_draw()){return}var al=this.view.low,ah=this.view.high,aj=ah-al,ae=this.view.container.width(),ap=this.view.resolution_px_b,ag=this.view.resolution_b_px;if(this.is_overview){al=this.view.max_low;ah=this.view.max_high;ag=Math.pow(RESOLUTION,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(RESOLUTION)));ap=ae/(view.max_high-view.max_low)}this.before_draw();this.tiles_div.children().addClass("remove");var ac=Math.floor(al/(ag*R)),ak=true,ao=[],ai=function(aq){return(aq&&"track" in aq)};while((ac*R*ag)<ah){var am=this.draw_helper(ad,ae,ac,ag,this.tiles_div,ap);if(ai(am)){ao.push(am)}else{ak=false}ac+=1}if(!an){this.tiles_div.children(".remove").removeClass("remove").remove()}var af=this;if(ak){this.tiles_div.children(".remove").remove();af.postdraw_actions(ao,ae,ap,an)}},postdraw_actions:function(af,ag,ai,ac){var ae=this;var ah=false;for(var ad=0;ad<af.length;ad++){if(af[ad].has_icons){ah=true;break}}if(ah){for(var ad=0;ad<af.length;ad++){tile=af[ad];if(!tile.has_icons){tile.html_elt.css("padding-top",A)}}}},draw_helper:function(ac,ao,au,ar,ah,ai,ap){var an=this,ax=this._gen_tile_cache_key(ao,ai,au),af=this._get_tile_bounds(au,ar),av=af[0],ad=af[1];if(!ap){ap={}}var aw=(ac?undefined:an.tile_cache.get(ax));if(aw){an.show_tile(aw,ah,ai);return aw}var al=true;var at=an.data_manager.get_data(av,ad,an.mode,ar,an.data_url_extra_params);if(is_deferred(at)){al=false}var aj;if(view.reference_track&&ai>view.canvas_manager.char_width_px){aj=view.reference_track.data_manager.get_data(av,ad,an.mode,ar,view.reference_track.data_url_extra_params);if(is_deferred(aj)){al=false}}if(al){p(at,ap.more_tile_data);var ak=an.mode;if(ak==="Auto"){ak=an.get_mode(at);an.update_auto_mode(ak)}var ae=an.view.canvas_manager.new_canvas(),af=an._get_tile_bounds(au,ar),av=af[0],ad=af[1],ao=Math.ceil((ad-av)*ai)+an.left_offset,am=an.get_canvas_height(at,ak,ai,ao);ae.width=ao;ae.height=am;var aq=ae.getContext("2d");aq.translate(this.left_offset,0);var aw=an.draw_tile(at,aq,ak,ar,au,ai,aj);if(aw!==undefined){an.tile_cache.set(ax,aw);an.show_tile(aw,ah,ai)}return aw}var ag=$.Deferred();$.when(at,aj).then(function(){view.request_redraw(false,false,false,an);ag.resolve()});return ag},get_canvas_height:function(ac,ae,af,ad){return this.visible_height_px},draw_tile:function(ac,ae,ah,ag,ad,ai,af){console.log("Warning: TiledTrack.draw_tile() not implemented.")},show_tile:function(ae,ag,ah){var ad=this,ac=ae.html_elt;ae.predisplay_actions();var af=(ae.low-(this.is_overview?this.view.max_low:this.view.low))*ah;if(this.left_offset){af-=this.left_offset}ac.css({position:"absolute",top:0,left:af});if(ac.hasClass("remove")){ac.removeClass("remove")}else{ag.append(ac)}ad.after_show_tile(ae)},after_show_tile:function(ac){},_get_tile_bounds:function(ac,ad){var af=Math.floor(ac*R*ad),ag=Math.ceil(R*ad),ae=(af+ag<=this.view.max_high?af+ag:this.view.max_high);return[af,ae]},tool_region_and_parameters_str:function(ae,ac,af){var ad=this,ag=(ae!==undefined&&ac!==undefined&&af!==undefined?ae+":"+ac+"-"+af:"all");return" - region=["+ag+"], parameters=["+ad.tool.get_param_values().join(", ")+"]"},data_and_mode_compatible:function(ac,ad){return true},can_subset:function(ac){return false},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.normal_postdraw_actions=this.postdraw_actions;this.postdraw_actions=function(ae,af,ag,ac){var ad=this;ad.normal_postdraw_actions(ae,af,ag,ac);ad.dataset_state_url=converted_datasets_state_url;ad.data_query_wait=I;$.when(server_state_deferred(ad.dataset_state_url,{dataset_id:ad.dataset_id,hda_ldda:ad.hda_ldda},ad.data_query_wait,function(ah){return ah!=="pending"})).then(function(){ad.data_url=default_data_url});ad.postdraw_actions=ad.normal_postdraw_actions}}});var Y=function(ad,ac){var ae={resize:false};i.call(this,ad,ac,ae);this.container_div.addClass("label-track")};p(Y.prototype,i.prototype,{build_header_div:function(){},init:function(){this.enabled=true},_draw:function(){var ae=this.view,af=ae.high-ae.low,ai=Math.floor(Math.pow(10,Math.floor(Math.log(af)/Math.log(10)))),ac=Math.floor(ae.low/ai)*ai,ag=this.view.container.width(),ad=$("<div style='position: relative; height: 1.3em;'></div>");while(ac<ae.high){var ah=(ac-ae.low)/af*ag;ad.append($("<div class='label'>"+commatize(ac)+"</div>").css({position:"absolute",left:ah-1}));ac+=ai}this.content_div.children(":first").remove();this.content_div.append(ad)}});var h=function(ad,ac,ag){K.call(this,ad,ac,ag);this.drawables=[];this.left_offset=0;if("drawables" in ag){var af;for(var ae=0;ae<ag.drawables.length;ae++){af=ag.drawables[ae];this.drawables[ae]=object_from_template(af);if(af.left_offset>this.left_offset){this.left_offset=af.left_offset}}this.enabled=true}if(this.drawables.length!==0){this.set_display_modes(this.drawables[0].display_modes,this.drawables[0].mode)}this.update_icons();this.obj_type="CompositeTrack"};p(h.prototype,K.prototype,{action_icons_def:[{name:"composite_icon",title:"Show individual tracks",css_class:"layers-stack",on_click_fn:function(ac){$(".tipsy").remove();ac.show_group()}}].concat(K.prototype.action_icons_def),to_dict:w.prototype.to_dict,add_drawable:w.prototype.add_drawable,unpack_drawables:w.prototype.unpack_drawables,change_mode:function(ac){K.prototype.change_mode.call(this,ac);for(var ad=0;ad<this.drawables.length;ad++){this.drawables[ad].change_mode(ac)}},init:function(){var ae=[];for(var ad=0;ad<this.drawables.length;ad++){ae.push(this.drawables[ad].init())}var ac=this;$.when.apply($,ae).then(function(){ac.enabled=true;ac.request_draw()})},update_icons:function(){this.action_icons.filters_icon.hide();this.action_icons.tools_icon.hide()},can_draw:q.prototype.can_draw,draw_helper:function(ad,ar,ay,av,aj,al,at){var aq=this,aC=this._gen_tile_cache_key(ar,al,ay),ah=this._get_tile_bounds(ay,av),az=ah[0],ae=ah[1];if(!at){at={}}var aB=(ad?undefined:aq.tile_cache.get(aC));if(aB){aq.show_tile(aB,aj,al);return aB}var ak=[],aq,ao=true,aw,am;for(var ax=0;ax<this.drawables.length;ax++){aq=this.drawables[ax];aw=aq.data_manager.get_data(az,ae,aq.mode,av,aq.data_url_extra_params);if(is_deferred(aw)){ao=false}ak.push(aw);am=null;if(view.reference_track&&al>view.canvas_manager.char_width_px){am=view.reference_track.data_manager.get_data(az,ae,aq.mode,av,view.reference_track.data_url_extra_params);if(is_deferred(am)){ao=false}}ak.push(am)}if(ao){p(aw,at.more_tile_data);this.tile_predraw_init();var ag=aq.view.canvas_manager.new_canvas(),ah=aq._get_tile_bounds(ay,av),az=ah[0],ae=ah[1],aA=0,ar=Math.ceil((ae-az)*al)+this.left_offset,ap=0,af=[];var ac=0;for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];var an=aq.mode;if(an==="Auto"){an=aq.get_mode(aw);aq.update_auto_mode(an)}af.push(an);ac=aq.get_canvas_height(aw,an,al,ar);if(ac>ap){ap=ac}}ag.width=ar;ag.height=(at.height?at.height:ap);aA=0;var au=ag.getContext("2d");au.translate(this.left_offset,0);au.globalAlpha=0.5;au.globalCompositeOperation="source-over";for(var ax=0;ax<this.drawables.length;ax++,aA+=2){aq=this.drawables[ax];aw=ak[aA];am=ak[aA+1];aB=aq.draw_tile(aw,au,af[ax],av,ay,al,am)}this.tile_cache.set(aC,aB);this.show_tile(aB,aj,al);return aB}var ai=$.Deferred(),aq=this;$.when.apply($,ak).then(function(){view.request_redraw(false,false,false,aq);ai.resolve()});return ai},show_group:function(){var af=new N(this.view,this.container,{name:this.name}),ac;for(var ae=0;ae<this.drawables.length;ae++){ac=this.drawables[ae];af.add_drawable(ac);ac.container=af;af.content_div.append(ac.container_div)}var ad=this.container.replace_drawable(this,af,true);af.request_draw()},tile_predraw_init:function(){var af=Number.MAX_VALUE,ac=-af,ad;for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];if(ad instanceof j){if(ad.prefs.min_value<af){af=ad.prefs.min_value}if(ad.prefs.max_value>ac){ac=ad.prefs.max_value}}}for(var ae=0;ae<this.drawables.length;ae++){ad=this.drawables[ae];ad.prefs.min_value=af;ad.prefs.max_value=ac}},postdraw_actions:function(ae,ah,aj,ad){K.prototype.postdraw_actions.call(this,ae,ah,aj,ad);var ag=-1;for(var af=0;af<ae.length;af++){var ac=ae[af].html_elt.find("canvas").height();if(ac>ag){ag=ac}}for(var af=0;af<ae.length;af++){var ai=ae[af];if(ai.html_elt.find("canvas").height()!==ag){this.draw_helper(true,ah,ai.index,ai.resolution,ai.html_elt.parent(),aj,{height:ag});ai.html_elt.remove()}}}});var y=function(ac){K.call(this,ac,{content_div:ac.top_labeltrack},{resize:false});ac.reference_track=this;this.left_offset=200;this.visible_height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:ac.dbkey};this.data_manager=new E(F,this,false);this.hide_contents()};p(y.prototype,q.prototype,K.prototype,{build_header_div:function(){},init:function(){this.data_manager.clear();this.enabled=true},can_draw:q.prototype.can_draw,draw_tile:function(ak,al,ah,ag,ad,am){var af=this;if(am>this.view.canvas_manager.char_width_px){if(ak.data===null){this.hide_contents();return}var ae=al.canvas;al.font=al.canvas.manager.default_font;al.textAlign="center";ak=ak.data;for(var ai=0,aj=ak.length;ai<aj;ai++){var ac=Math.floor(ai*am);al.fillText(ak[ai],ac,10)}this.show_contents();return new b(af,ad,ag,ae,ak)}this.hide_contents()}});var j=function(ae,ad,af){var ac=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";K.call(this,ae,ad,af);this.hda_ldda=af.hda_ldda;this.dataset_id=af.dataset_id;this.original_dataset_id=this.dataset_id;this.left_offset=0;this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:32,hidden:true}],saved_values:af.prefs,onchange:function(){ac.set_name(ac.prefs.name);ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.set_min_value(ac.prefs.min_value);ac.set_max_value(ac.prefs.max_value)}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value};p(j.prototype,q.prototype,K.prototype,{on_resize:function(){this.request_draw(true)},set_min_value:function(ac){this.prefs.min_value=ac;$("#linetrack_"+this.dataset_id+"_minval").text(this.prefs.min_value);this.tile_cache.clear();this.request_draw()},set_max_value:function(ac){this.prefs.max_value=ac;$("#linetrack_"+this.dataset_id+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.request_draw()},predraw_init:function(){var ac=this;ac.vertical_range=undefined;return $.getJSON(ac.data_url,{stats:true,chrom:ac.view.chrom,low:null,high:null,hda_ldda:ac.hda_ldda,dataset_id:ac.dataset_id},function(ad){ac.container_div.addClass("line-track");var ag=ad.data;if(isNaN(parseFloat(ac.prefs.min_value))||isNaN(parseFloat(ac.prefs.max_value))){var ae=ag.min;var ai=ag.max;ae=Math.floor(Math.min(0,Math.max(ae,ag.mean-2*ag.sd)));ai=Math.ceil(Math.max(0,Math.min(ai,ag.mean+2*ag.sd)));ac.prefs.min_value=ae;ac.prefs.max_value=ai;$("#track_"+ac.dataset_id+"_minval").val(ac.prefs.min_value);$("#track_"+ac.dataset_id+"_maxval").val(ac.prefs.max_value)}ac.vertical_range=ac.prefs.max_value-ac.prefs.min_value;ac.total_frequency=ag.total_frequency;ac.container_div.find(".yaxislabel").remove();var ah=$("<div/>").text(W(ac.prefs.min_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_min_value(aj)}},help_text:"Set min value"}).addClass("yaxislabel bottom").attr("id","linetrack_"+ac.dataset_id+"_minval").prependTo(ac.container_div),af=$("<div/>").text(W(ac.prefs.max_value,3)).make_text_editable({num_cols:6,on_finish:function(aj){$(".tipsy").remove();var aj=parseFloat(aj);if(!isNaN(aj)){ac.set_max_value(aj)}},help_text:"Set max value"}).addClass("yaxislabel top").attr("id","linetrack_"+ac.dataset_id+"_maxval").prependTo(ac.container_div)})},draw_tile:function(am,ak,ah,af,ad,al){var ae=ak.canvas,ac=this._get_tile_bounds(ad,af),ag=ac[0],aj=ac[1],ai=new J.LinePainter(am.data,ag,aj,this.prefs,ah);ai.draw(ak,ae.width,ae.height,al);return new b(this,ad,af,ae,am.data)},can_subset:function(ac){return false},});var d=function(af,ae,ah){var ad=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];K.call(this,af,ae,ah);var ag=get_random_color(),ac=get_random_color([ag,"#ffffff"]);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:ag},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:ac},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.visible_height_px,hidden:true}],saved_values:ah.prefs,onchange:function(){ad.set_name(ad.prefs.name);ad.tile_cache.clear();ad.set_painter_from_config();ad.request_draw()}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.container_div.addClass("feature-track");this.hda_ldda=ah.hda_ldda;this.dataset_id=ah.dataset_id;this.original_dataset_id=ah.dataset_id;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.slotters={};this.start_end_dct={};this.left_offset=200;this.set_painter_from_config()};p(d.prototype,q.prototype,K.prototype,{set_painter_from_config:function(){if(this.config.values.connector_style==="arcs"){this.painter=J.ArcLinkedFeaturePainter}else{this.painter=J.LinkedFeaturePainter}},before_draw:function(){this.max_height_px=0},after_show_tile:function(ac){this.max_height_px=Math.max(this.max_height_px,ac.html_elt.height());ac.html_elt.parent().children().css("height",this.max_height_px+"px");var ad=this.max_height_px;if(this.visible_height_px!==0){ad=Math.min(this.max_height_px,this.visible_height_px)}this.tiles_div.css("height",ad+"px")},postdraw_actions:function(ar,am,ah,ag){K.prototype.postdraw_actions.call(this,ar,ag);var al=this;if(al.mode==="Histogram"){var ad=-1;for(var ao=0;ao<ar.length;ao++){var an=ar[ao].max_val;if(an>ad){ad=an}}for(var ao=0;ao<ar.length;ao++){var au=ar[ao];if(au.max_val!==ad){au.html_elt.remove();al.draw_helper(true,am,au.index,au.resolution,au.html_elt.parent(),ah,{more_tile_data:{max:ad}})}}}if(al.filters_manager){var ai=al.filters_manager.filters;for(var aq=0;aq<ai.length;aq++){ai[aq].update_ui_elt()}var at=false,ac,aj;for(var ao=0;ao<ar.length;ao++){if(ar[ao].data.length){ac=ar[ao].data[0];for(var aq=0;aq<ai.length;aq++){aj=ai[aq];if(aj.applies_to(ac)&&aj.min!==aj.max){at=true;break}}}}if(al.filters_available!==at){al.filters_available=at;if(!al.filters_available){al.filters_manager.hide()}al.update_icons()}}this.container_div.find(".yaxislabel").remove();var af=ar[0];if(af instanceof k){var ak=(this.prefs.histogram_max?this.prefs.histogram_max:af.max_val),ae=$("<div/>").text(ak).make_text_editable({num_cols:12,on_finish:function(av){$(".tipsy").remove();var av=parseFloat(av);al.prefs.histogram_max=(!isNaN(av)?av:null);al.tile_cache.clear();al.request_draw()},help_text:"Set max value; leave blank to use default"}).addClass("yaxislabel top").css("color",this.prefs.label_color);this.container_div.prepend(ae)}if(af instanceof M){var ap=true;for(var ao=0;ao<ar.length;ao++){if(!ar[ao].all_slotted){ap=false;break}}if(!ap){this.action_icons.show_more_rows_icon.show()}else{this.action_icons.show_more_rows_icon.hide()}}else{this.action_icons.show_more_rows_icon.hide()}},update_auto_mode:function(ac){var ac;if(this.mode==="Auto"){if(ac==="no_detail"){ac="feature spans"}else{if(ac==="summary_tree"){ac="coverage histogram"}}this.action_icons.mode_icon.attr("title","Set display mode (now: Auto/"+ac+")")}},incremental_slots:function(ag,ac,af){var ad=this.view.canvas_manager.dummy_context,ae=this.slotters[ag];if(!ae||(ae.mode!==af)){ae=new (s.FeatureSlotter)(ag,af,x,function(ah){return ad.measureText(ah)});this.slotters[ag]=ae}return ae.slot_features(ac)},get_summary_tree_data:function(ag,aj,ae,ar){if(ar>ae-aj){ar=ae-aj}var an=Math.floor((ae-aj)/ar),aq=[],af=0;var ah=0,ai=0,am,ap=0,ak=[],ao,al;var ad=function(av,au,aw,at){av[0]=au+aw*at;av[1]=au+(aw+1)*at};while(ap<ar&&ah!==ag.length){var ac=false;for(;ap<ar&&!ac;ap++){ad(ak,aj,ap,an);for(ai=ah;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ac=true;break}}if(ac){break}}data_start_index=ai;aq[aq.length]=ao=[ak[0],0];for(;ai<ag.length;ai++){am=ag[ai].slice(1,3);if(is_overlap(am,ak)){ao[1]++}else{break}}if(ao[1]>af){af=ao[1]}ap++}return{max:af,delta:an,data:aq}},get_mode:function(ac){if(ac.dataset_type==="summary_tree"){mode="summary_tree"}else{if(ac.extra_info==="no_detail"||this.is_overview){mode="no_detail"}else{if(this.view.high-this.view.low>G){mode="Squish"}else{mode="Pack"}}}return mode},get_canvas_height:function(ac,ag,ah,ad){if(ag==="summary_tree"||ag==="Histogram"){return this.summary_draw_height}else{var af=this.incremental_slots(ah,ac.data,ag);var ae=new (this.painter)(null,null,null,this.prefs,ag);return Math.max(aa,ae.get_required_height(af,ad))}},draw_tile:function(an,ar,ap,at,ax,aj,ae){var aq=this,ad=ar.canvas,ag=this._get_tile_bounds(ax,at),aA=ag[0],ac=ag[1],aF=25,af=this.left_offset;if(ap==="summary_tree"||ap==="Histogram"){if(an.dataset_type!=="summary_tree"){var ak=this.get_summary_tree_data(an.data,aA,ac,200);if(an.max){ak.max=an.max}an=ak}var aC=new J.SummaryTreePainter(an,aA,ac,this.prefs);aC.draw(ar,ad.width,ad.height,aj);return new k(aq,ax,at,ad,an.data,an.max)}var ai=[],ao=this.slotters[aj].slots;all_slotted=true;if(an.data){var al=this.filters_manager.filters;for(var au=0,aw=an.data.length;au<aw;au++){var ah=an.data[au];var av=false;var am;for(var az=0,aE=al.length;az<aE;az++){am=al[az];am.update_attrs(ah);if(!am.keep(ah)){av=true;break}}if(!av){ai.push(ah);if(!(ah[0] in ao)){all_slotted=false}}}}var aD=(this.filters_manager.alpha_filter?new z(this.filters_manager.alpha_filter):null);var aB=(this.filters_manager.height_filter?new z(this.filters_manager.height_filter):null);var aC=new (this.painter)(ai,aA,ac,this.prefs,ap,aD,aB,ae);var ay=null;ar.fillStyle=this.prefs.block_color;ar.font=ar.canvas.manager.default_font;ar.textAlign="right";if(an.data){ay=aC.draw(ar,ad.width,ad.height,aj,ao);ay.translation=-af}return new M(aq,ax,at,ad,an.data,aj,ap,an.message,all_slotted,ay)},data_and_mode_compatible:function(ac,ad){if(ad==="Auto"){return true}else{if(ac.extra_info==="no_detail"||ac.dataset_type==="summary_tree"){return false}else{return true}}},can_subset:function(ac){if(ac.dataset_type==="summary_tree"||ac.message||ac.extra_info==="no_detail"){return false}return true},});var Q=function(ad,ac,ae){d.call(this,ad,ac,ae);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ae.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter};p(Q.prototype,q.prototype,K.prototype,d.prototype);var T=function(ae,ad,ag){d.call(this,ae,ad,ag);var af=get_random_color(),ac=get_random_color([af,"#ffffff"]);this.config=new C({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block and sense strand color",type:"color",default_value:af},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:ac},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"Clear value to set automatically"},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ag.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=J.ReadPainter;this.update_icons()};p(T.prototype,q.prototype,K.prototype,d.prototype);U.View=Z;U.DrawableGroup=N;U.LineTrack=j;U.FeatureTrack=d;U.ReadTrack=T;U.VcfTrack=Q;U.CompositeTrack=h};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.mode=h;this.include_label=(h==="Pack");this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,h=this.start_end_dct,x=[],z=[],n=0,y=this.max_rows;for(var v=0,w=m.length;v<w;v++){var k=m[v],o=k[0];if(this.slots[o]!==undefined){n=Math.max(n,this.slots[o]);z.push(this.slots[o])}else{x.push(v)}}var q=function(E,F){for(var D=0;D<=y;D++){var B=false,G=h[D];if(G!==undefined){for(var A=0,C=G.length;A<C;A++){var i=G[A];if(F>i[0]&&E<i[1]){B=true;break}}}if(!B){return D}}return -1};for(var v=0,w=x.length;v<w;v++){var k=m[x[v]],o=k[0],t=k[1],f=k[2],r=k[3],g=Math.floor(t*p),l=Math.ceil(f*p),u=this.measureText(r).width,j;if(r!==undefined&&this.include_label){u+=(d+a);if(g-u>=0){g-=u;j="left"}else{l+=u;j="right"}}var s=q(g,l);if(s>=0){if(h[s]===undefined){h[s]=[]}h[s].push([g,l]);this.slots[o]=s;n=Math.max(n,s)}}return n+1}})};var painters_module=function(i,x){var u=i("class").extend;var p=function(I,A,G,z,F,D){if(D===undefined){D=4}var C=z-A;var B=F-G;var E=Math.floor(Math.sqrt(C*C+B*B)/D);var J=C/E;var H=B/E;var y;for(y=0;y<E;y++,A+=J,G+=H){if(y%2!==0){continue}I.fillRect(A,G,D,1)}};var q=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var d=function(y){this.default_val=(y?y:1)};d.prototype.gen_val=function(y){return this.default_val};var l=function(A,C,y,z,B){this.data=A;this.view_start=C;this.view_end=y;this.prefs=u({},this.default_prefs,z);this.mode=B};l.prototype.default_prefs={};l.prototype.draw=function(z,A,y,B){};var v=function(A,C,y,z,B){l.call(this,A,C,y,z,B)};v.prototype.default_prefs={show_counts:false};v.prototype.draw=function(L,z,K,M){var E=this.view_start,N=this.view_end-this.view_start,I=this.data.data,G=(this.prefs.histogram_max?this.prefs.histogram_max:this.data.max),B=K;delta_x_px=Math.ceil(this.data.delta*M);L.save();for(var C=0,D=I.length;C<D;C++){var H=Math.floor((I[C][0]-E)*M);var F=I[C][1];if(!F){continue}var J=F/G*K;if(F!==0&&J<1){J=1}L.fillStyle=this.prefs.block_color;L.fillRect(H,B-J,delta_x_px,J);var A=4;if(this.prefs.show_counts&&(L.measureText(F).width+A)<delta_x_px){L.fillStyle=this.prefs.label_color;L.textAlign="center";L.fillText(F,H+(delta_x_px/2),10)}}L.restore()};var b=function(y,C,E,F,A){l.call(this,y,C,E,F,A);if(this.prefs.min_value===undefined){var G=Infinity;for(var z=0,B=this.data.length;z<B;z++){G=Math.min(G,this.data[z][1])}this.prefs.min_value=G}if(this.prefs.max_value===undefined){var D=-Infinity;for(var z=0,B=this.data.length;z<B;z++){D=Math.max(D,this.data[z][1])}this.prefs.max_value=D}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(S,Q,N,D){var I=false,K=this.prefs.min_value,F=this.prefs.max_value,M=F-K,B=N,C=this.view_start,P=this.view_end-this.view_start,L=this.mode,aa=this.data;S.save();var ac=Math.round(N+K/M*N);if(L!=="Intensity"){S.fillStyle="#aaa";S.fillRect(0,ac,Q,1)}S.beginPath();var Y,G,E;if(aa.length>1){E=Math.ceil((aa[1][0]-aa[0][0])*D)}else{E=10}var A=parseInt(this.prefs.color.slice(1),16),H=(A&16711680)>>16,R=(A&65280)>>8,V=A&255;for(var T=0,U=aa.length;T<U;T++){S.fillStyle=S.strokeStyle=this.prefs.color;Y=Math.round((aa[T][0]-C)*D);G=aa[T][1];var W=false,J=false;if(G===null){if(I&&L==="Filled"){S.lineTo(Y,B)}I=false;continue}if(G<K){J=true;G=K}else{if(G>F){W=true;G=F}}if(L==="Histogram"){G=Math.round(G/M*B);S.fillRect(Y,ac,E,-G)}else{if(L==="Intensity"){var z=(G-K)/M,O=Math.round(H+(255-H)*(1-z)),X=Math.round(R+(255-R)*(1-z)),ab=Math.round(V+(255-V)*(1-z));S.fillStyle="rgb("+O+","+X+","+ab+")";S.fillRect(Y,0,E,B)}else{G=Math.round(B-(G-K)/M*B);if(I){S.lineTo(Y,G)}else{I=true;if(L==="Filled"){S.moveTo(Y,B);S.lineTo(Y,G)}else{S.moveTo(Y,G)}}}}S.fillStyle=this.prefs.overflow_color;if(W||J){var Z;if(L==="Histogram"||L==="Intensity"){Z=E}else{Y-=2;Z=4}if(W){S.fillRect(Y,0,Z,3)}if(J){S.fillRect(Y,B-3,Z,3)}}S.fillStyle=this.prefs.color}if(L==="Filled"){if(I){S.lineTo(Y,ac);S.lineTo(0,ac)}S.fill()}else{S.stroke()}S.restore()};var m=function(y){this.feature_positions={};this.slot_height=y;this.translation=0;this.y_translation=0};m.prototype.map_feature_data=function(z,B,y,A){if(!this.feature_positions[B]){this.feature_positions[B]=[]}this.feature_positions[B].push({data:z,x_start:y,x_end:A})};m.prototype.get_feature_data=function(z,D){var C=Math.floor((D-this.y_translation)/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var o=function(A,D,y,z,C,E,B){l.call(this,A,D,y,z,C);this.alpha_scaler=(E?E:new d());this.height_scaler=(B?B:new d())};o.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};u(o.prototype,{get_required_height:function(A,z){var y=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){y=A*y_scale}return y+this.get_top_padding(z)+this.get_bottom_padding(z)},get_top_padding:function(y){return 0},get_bottom_padding:function(y){return Math.max(Math.round(this.get_row_height()/2),5)},draw:function(K,I,G,E,F){var Q=this.data,D=this.view_start,M=this.view_end;K.save();K.fillStyle=this.prefs.block_color;K.textAlign="right";var H=this.view_end-this.view_start,L=this.get_row_height(),P=new m(L),B;for(var N=0,O=Q.length;N<O;N++){var A=Q[N],C=A[0],J=A[1],y=A[2],z=(F&&F[C]!==undefined?F[C]:null);if((J<M&&y>D)&&(this.mode==="Dense"||z!==null)){B=this.draw_element(K,this.mode,A,z,D,M,E,L,I);P.map_feature_data(A,z,B[0],B[1])}}K.restore();P.y_translation=this.get_top_padding(I);return P},draw_element:function(E,A,G,C,B,D,F,z,y){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,w=10,f=1,s=9,e=3,a=9,j=2,g="#ccc";var r=function(A,D,y,z,C,E,B){o.call(this,A,D,y,z,C,E,B);this.draw_background_connector=true;this.draw_individual_connectors=false};u(r.prototype,o.prototype,{get_row_height:function(){var z=this.mode,y;if(z==="Dense"){y=c}else{if(z==="no_detail"){y=h}else{if(z==="Squish"){y=k}else{y=w}}}return y},draw_element:function(M,D,X,H,O,ai,am,ao,y){var T=X[0],ak=X[1],ad=X[2]-1,Q=X[3],K=X[4],ae=Math.floor(Math.max(0,(ak-O)*am)),N=Math.ceil(Math.min(y,Math.max(0,(ad-O)*am))),ac=ae,an=N,aa=(D==="Dense"?0:(0+H))*ao+this.get_top_padding(y),L,ag,R=null,aq=null,B=B=(!K||K==="+"||K==="."?this.prefs.block_color:this.prefs.reverse_strand_color);label_color=this.prefs.label_color;M.globalAlpha=this.alpha_scaler.gen_val(X);if(D==="Dense"){H=1}if(D==="no_detail"){M.fillStyle=B;M.fillRect(ae,aa+5,N-ae,f)}else{var Z=X[5],af=X[6],C=X[7],V=true;if(Z&&af){R=Math.floor(Math.max(0,(Z-O)*am));aq=Math.ceil(Math.min(y,Math.max(0,(af-O)*am)))}var al,U;if(D==="Squish"){al=1;U=e;V=false}else{if(D==="Dense"){al=5;U=s}else{al=5;U=a}}if(!C){M.fillStyle=B;M.fillRect(ae,aa+1,N-ae,U);if(K&&V){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}M.fillRect(ae,aa+1,N-ae,U)}}else{var J,W;if(D==="Squish"||D==="Dense"){J=aa+Math.floor(e/2)+1;W=1}else{if(K){J=aa;W=U}else{J+=(e/2)+1;W=1}}if(this.draw_background_connector){if(D==="Squish"||D==="Dense"){M.fillStyle=g}else{if(K){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand")}}}else{M.fillStyle=g}}M.fillRect(ae,J,N-ae,W)}var E;for(var aj=0,A=C.length;aj<A;aj++){var F=C[aj],z=Math.floor(Math.max(0,(F[0]-O)*am)),Y=Math.ceil(Math.min(y,Math.max((F[1]-1-O)*am))),S,ab;if(z>Y){continue}M.fillStyle=B;M.fillRect(z,aa+(U-al)/2+1,Y-z,al);if(R!==undefined&&af>Z&&!(z>aq||Y<R)){var ah=Math.max(z,R),I=Math.min(Y,aq);M.fillRect(ah,aa+1,I-ah,U)}if(this.draw_individual_connectors&&S){this.draw_connector(M,S,ab,z,Y,aa)}S=z;ab=Y}if(D==="Pack"){M.globalAlpha=1;M.fillStyle="white";var G=this.height_scaler.gen_val(X),P=Math.ceil(U*G),ap=Math.round((U-P)/2);if(G!==1){M.fillRect(ae,J+1,N-ae,ap);M.fillRect(ae,J+U-ap+1,N-ae,ap)}}}M.globalAlpha=1;if(D==="Pack"&&ak>O){M.fillStyle=label_color;if(O===0&&ae-M.measureText(Q).width<0){M.textAlign="left";M.fillText(Q,N+j,aa+8);an+=M.measureText(Q).width+j}else{M.textAlign="right";M.fillText(Q,ae-j,aa+8);ac-=M.measureText(Q).width+j}}}M.globalAlpha=1;return[ac,an]}});var t=function(B,E,y,A,D,F,C,z){o.call(this,B,E,y,A,D,F,C);this.ref_seq=(z?z.data:null)};u(t.prototype,o.prototype,{get_row_height:function(){var y,z=this.mode;if(z==="Dense"){y=c}else{if(z==="Squish"){y=k}else{y=w;if(this.prefs.show_insertions){y*=2}}}return y},draw_read:function(K,A,ag,V,L,aa,ad,C,B,M){K.textAlign="center";var J=this,R=[L,aa],Z=0,W=0,D=0,F=K.canvas.manager.char_width_px,y=(B==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);var O=[];if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){D=Math.round(ag/2)}if(!C){C=[[0,M.length]]}for(var G=0,I=C.length;G<I;G++){var z=C[G],E="MIDNSHP=X"[z[0]],S=z[1];if(E==="H"||E==="S"){Z-=S}var U=ad+Z,Y=Math.floor(Math.max(0,(U-L)*ag)),ab=Math.floor(Math.max(0,(U+S-L)*ag));if(Y===ab){ab+=1}switch(E){case"H":break;case"S":case"M":case"=":if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(D>0){K.fillStyle=y;K.fillRect(Y-D,V+1,ab-Y,9);K.fillStyle=g;for(var af=0,H=N.length;af<H;af++){if(this.prefs.show_differences){if(this.ref_seq){var P=this.ref_seq[U-L+af];if(!P||P.toLowerCase()===N[af].toLowerCase()){continue}}else{continue}}if(U+af>=L&&U+af<=aa){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X,V+9)}}}else{K.fillStyle=y;K.fillRect(Y,V+4,ab-Y,e)}}W+=S;Z+=S;break;case"N":K.fillStyle=g;K.fillRect(Y-D,V+5,ab-Y,1);Z+=S;break;case"D":K.fillStyle="red";K.fillRect(Y-D,V+4,ab-Y,3);Z+=S;break;case"P":break;case"I":var ah=Y-D;if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(this.prefs.show_insertions){var T=Y-(ab-Y)/2;if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){K.fillStyle="yellow";K.fillRect(T-D,V-9,ab-Y,9);O[O.length]={type:"triangle",data:[ah,V+4,5]};K.fillStyle=g;switch(compute_overlap([U,U+S],R)){case (OVERLAP_START):N=N.slice(L-U);break;case (OVERLAP_END):N=N.slice(0,U-aa);break;case (CONTAINED_BY):break;case (CONTAINS):N=N.slice(L-U,U-aa);break}for(var af=0,H=N.length;af<H;af++){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X-(ab-Y)/2,V)}}else{K.fillStyle="yellow";K.fillRect(T,V+(this.mode!=="Dense"?2:5),ab-Y,(A!=="Dense"?e:s))}}else{if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){O.push({type:"text",data:[N.length,ah,V+9]})}else{}}}W+=S;break;case"X":W+=S;break}}K.fillStyle="yellow";var Q,ai,ae;for(var ac=0;ac<O.length;ac++){Q=O[ac];ai=Q.type;ae=Q.data;if(ai==="text"){K.save();K.font="bold "+K.font;K.fillText(ae[0],ae[1],ae[2]);K.restore()}else{if(ai==="triangle"){q(K,ae[0],ae[1],ae[2])}}}},draw_element:function(R,M,E,B,U,z,I,S,P){var H=E[0],Q=E[1],A=E[2],J=E[3],D=Math.floor(Math.max(0,(Q-U)*I)),F=Math.ceil(Math.min(P,Math.max(0,(A-U)*I))),C=(M==="Dense"?0:(0+B))*S,G=this.prefs.label_color,O=0;if((M==="Pack"||this.mode==="Auto")&&I>R.canvas.manager.char_width_px){var O=Math.round(I/2)}if(E[5] instanceof Array){var N=Math.floor(Math.max(0,(E[4][0]-U)*I)),L=Math.ceil(Math.min(P,Math.max(0,(E[4][1]-U)*I))),K=Math.floor(Math.max(0,(E[5][0]-U)*I)),y=Math.ceil(Math.min(P,Math.max(0,(E[5][1]-U)*I)));if(E[4][1]>=U&&E[4][0]<=z&&E[4][2]){this.draw_read(R,M,I,C,U,z,E[4][0],E[4][2],E[4][3],E[4][4])}if(E[5][1]>=U&&E[5][0]<=z&&E[5][2]){this.draw_read(R,M,I,C,U,z,E[5][0],E[5][2],E[5][3],E[5][4])}if(K>L){R.fillStyle=g;p(R,L-O,C+5,K-O,C+5)}}else{this.draw_read(R,M,I,C,U,z,Q,E[4],E[5],E[6])}if(M==="Pack"&&Q>U&&J!=="."){R.fillStyle=this.prefs.label_color;var T=1;if(T===0&&D-R.measureText(J).width<0){R.textAlign="left";R.fillText(J,F+j-O,C+8)}else{R.textAlign="right";R.fillText(J,D-j-O,C+8)}}return[0,0]}});var n=function(A,D,y,z,C,E,B){r.call(this,A,D,y,z,C,E,B);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};u(n.prototype,o.prototype,r.prototype,{calculate_longest_feature_length:function(){var z=0;for(var C=0,y=this.data.length;C<y;C++){var B=this.data[C],A=B[1],D=B[2];z=Math.max(z,D-A)}return z},get_top_padding:function(z){var y=this.view_end-this.view_start,A=z/y;return Math.min(128,Math.ceil((this.longest_feature_length/2)*A))},draw_connector:function(G,B,F,H,E,D){var y=(F+H)/2,C=H-y;var A=Math.PI,z=0;if(C>0){G.beginPath();G.arc(y,D,H-y,Math.PI,0);G.stroke()}}});x.Scaler=d;x.SummaryTreePainter=v;x.LinePainter=b;x.LinkedFeaturePainter=r;x.ReadPainter=t;x.ArcLinkedFeaturePainter=n};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window); \ No newline at end of file +var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var server_state_deferred=function(d,a,c,f){var b=$.Deferred(),e=function(){$.getJSON(d,a,function(g){if(f(g)){b.resolve(g)}else{setTimeout(e,c)}})};e();return b};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var is_deferred=function(a){return("isResolved" in a)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var n=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(v,u,w,s,i,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,i)-Math.min(u,i))+(Math.max(w,t)-Math.min(w,t))};var g,o,f,k,q,h,r,c,d,b,p,m=false,l=0;do{g=Math.round(Math.random()*16777215);o=(g&16711680)>>16;f=(g&65280)>>8;k=g&255;d=n(o,f,k);m=true;for(var j=0;j<a.length;j++){q=a[j];h=(q&16711680)>>16;r=(q&65280)>>8;c=q&255;b=n(h,r,c);p=e(o,f,k,h,r,c);if((Math.abs(d-b)<40)||(p<200)){m=false;break}}l++}while(!m&&l<=10);return"#"+(16777216+g).toString(16).substr(1,6)};var create_action_icon=function(c,b,a){return $("<a/>").attr("href","javascript:void(0);").attr("title",c).addClass("icon-button").addClass(b).tipsy({gravity:"s"}).click(a)};var trackster_module=function(d,R){var o=d("class").extend,r=d("slotting"),H=d("painters");var Y=function(Z,aa){this.document=Z;this.default_font=aa!==undefined?aa:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};o(Y.prototype,{load_pattern:function(Z,ad){var aa=this.patterns,ab=this.dummy_context,ac=new Image();ac.src=galaxy_paths.attributes.image_path+ad;ac.onload=function(){aa[Z]=ab.createPattern(ac,"repeat")}},get_pattern:function(Z){return this.patterns[Z]},new_canvas:function(){var Z=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(Z)}Z.manager=this;return Z}});var m={};var k=function(Z,aa){m[Z.attr("id")]=aa};var l=function(Z,ab,ad,ac){ad=".group";var aa={};m[Z.attr("id")]=ac;Z.bind("drag",{handle:"."+ab,relative:true},function(al,am){var ak=$(this);var ap=$(this).parent(),ah=ap.children(),aj=m[$(this).attr("id")],ag,af,an,ae,ai;af=$(this).parents(ad);if(af.length!==0){an=af.position().top;ae=an+af.outerHeight();if(am.offsetY<an){$(this).insertBefore(af);var ao=m[af.attr("id")];ao.remove_drawable(aj);ao.container.add_drawable_before(aj,ao);return}else{if(am.offsetY>ae){$(this).insertAfter(af);var ao=m[af.attr("id")];ao.remove_drawable(aj);ao.container.add_drawable(aj);return}}}af=null;for(ai=0;ai<ah.length;ai++){ag=$(ah.get(ai));an=ag.position().top;ae=an+ag.outerHeight();if(ag.is(ad)&&this!==ag.get(0)&&am.offsetY>=an&&am.offsetY<=ae){if(am.offsetY-an<ae-am.offsetY){ag.find(".content-div").prepend(this)}else{ag.find(".content-div").append(this)}if(aj.container){aj.container.remove_drawable(aj)}m[ag.attr("id")].add_drawable(aj);return}}var ag;for(ai=0;ai<ah.length;ai++){ag=$(ah.get(ai));if(am.offsetY<ag.position().top&&!(ag.hasClass("reference-track")||ag.hasClass("intro"))){break}}if(ai===ah.length){if(this!==ah.get(ai-1)){ap.append(this);m[ap.attr("id")].move_drawable(aj,ai)}}else{if(this!==ah.get(ai)){$(this).insertBefore(ah.get(ai));m[ap.attr("id")].move_drawable(aj,(am.deltaY>0?ai-1:ai))}}}).bind("dragstart",function(){aa["border-top"]=Z.css("border-top");aa["border-bottom"]=Z.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(aa)})};R.moveable=l;var X=16,C=9,z=20,w=100,E=12000,O=400,G=5000,t=100,n="There was an error in indexing this dataset. ",F="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",A="No data for this chrom/contig.",s="Preparing data. This can take a while for a large dataset. If the visualization is saved and closed, preparation will continue in the background.",u="Tool cannot be rerun: ",a="Loading data...",S="Ready for display",M=10,D=20;function T(aa,Z){if(!Z){Z=0}var ab=Math.pow(10,Z);return Math.round(aa*ab)/ab}var p=function(aa,Z,ac){if(!p.id_counter){p.id_counter=0}this.id=p.id_counter++;this.name=ac.name;this.view=aa;this.container=Z;this.config=new B({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name}],saved_values:ac.prefs,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=ac.drag_handle_class;this.is_overview=false;this.action_icons={};this.content_visible=true;this.container_div=this.build_container_div();this.header_div=this.build_header_div();if(this.header_div){this.container_div.append(this.header_div);this.icons_div=$("<div/>").css("float","left").hide().appendTo(this.header_div);this.build_action_icons(this.action_icons_def);this.header_div.append($("<div style='clear: both'/>"));this.header_div.dblclick(function(ad){ad.stopPropagation()});var ab=this;this.container_div.hover(function(){ab.icons_div.show()},function(){ab.icons_div.hide()});$("<div style='clear: both'/>").appendTo(this.container_div)}};p.prototype.action_icons_def=[{name:"toggle_icon",title:"Hide/show content",css_class:"toggle",on_click_fn:function(Z){if(Z.content_visible){Z.action_icons.toggle_icon.addClass("toggle-expand").removeClass("toggle");Z.hide_contents();Z.content_visible=false}else{Z.action_icons.toggle_icon.addClass("toggle").removeClass("toggle-expand");Z.content_visible=true;Z.show_contents()}}},{name:"settings_icon",title:"Edit settings",css_class:"settings-icon",on_click_fn:function(aa){var ac=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},Z=function(){aa.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ab=function(ad){if((ad.keyCode||ad.which)===27){ac()}else{if((ad.keyCode||ad.which)===13){Z()}}};$(window).bind("keypress.check_enter_esc",ab);show_modal("Configure",aa.config.build_form(),{Cancel:ac,OK:Z})}},{name:"remove_icon",title:"Remove",css_class:"remove-icon",on_click_fn:function(Z){$(".tipsy").remove();Z.remove()}}];o(p.prototype,{init:function(){},changed:function(){this.view.changed()},can_draw:function(){if(this.enabled&&this.content_visible){return true}return false},request_draw:function(){},_draw:function(){},to_dict:function(){},update_icons:function(){},set_name:function(Z){this.old_name=this.name;this.name=Z;this.name_div.text(this.name)},revert_name:function(){if(this.old_name){this.name=this.old_name;this.name_div.text(this.name)}},remove:function(){this.changed();this.container.remove_drawable(this);var Z=this.view;this.container_div.hide(0,function(){$(this).remove();Z.update_intro_div()})},build_container_div:function(){},build_header_div:function(){},add_action_icon:function(aa,af,ae,ad,Z,ac){var ab=this;this.action_icons[aa]=$("<a/>").attr("href","javascript:void(0);").attr("title",af).addClass("icon-button").addClass(ae).tipsy({gravity:"s"}).click(function(){ad(ab)}).appendTo(this.icons_div);if(ac){this.action_icons[aa].hide()}},build_action_icons:function(Z){var ab;for(var aa=0;aa<Z.length;aa++){ab=Z[aa];this.add_action_icon(ab.name,ab.title,ab.css_class,ab.on_click_fn,ab.prepend,ab.hide)}},update_icons:function(){},hide_contents:function(){},show_contents:function(){}});var v=function(aa,Z,ab){p.call(this,aa,Z,ab);this.obj_type=ab.obj_type;this.drawables=[]};o(v.prototype,p.prototype,{unpack_drawables:function(ab){this.drawables=[];var aa;for(var Z=0;Z<ab.length;Z++){aa=object_from_template(ab[Z],this);this.add_drawable(aa)}},init:function(){for(var Z=0;Z<this.drawables.length;Z++){this.drawables[Z].init()}},_draw:function(){for(var Z=0;Z<this.drawables.length;Z++){this.drawables[Z]._draw()}},to_dict:function(){var aa=[];for(var Z=0;Z<this.drawables.length;Z++){aa.push(this.drawables[Z].to_dict())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:aa}},add_drawable:function(Z){this.drawables.push(Z);Z.container=this;this.changed()},add_drawable_before:function(ab,Z){this.changed();var aa=this.drawables.indexOf(Z);if(aa!==-1){this.drawables.splice(aa,0,ab);return true}return false},replace_drawable:function(ab,Z,aa){var ac=this.drawables.indexOf(ab);if(ac!==-1){this.drawables[ac]=Z;if(aa){ab.container_div.replaceWith(Z.container_div)}this.changed()}return ac},remove_drawable:function(aa){var Z=this.drawables.indexOf(aa);if(Z!==-1){this.drawables.splice(Z,1);aa.container=null;this.changed();return true}return false},move_drawable:function(aa,ab){var Z=this.drawables.indexOf(aa);if(Z!==-1){this.drawables.splice(Z,1);this.drawables.splice(ab,0,aa);this.changed();return true}return false}});var L=function(aa,Z,ac){o(ac,{obj_type:"DrawableGroup",drag_handle_class:"group-handle"});v.call(this,aa,Z,ac);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);k(this.container_div,this);k(this.content_div,this);l(this.container_div,this.drag_handle_class,".group",this);this.filters_manager=new U(this);this.header_div.after(this.filters_manager.parent_div);this.saved_filters_managers=[];if("drawables" in ac){this.unpack_drawables(ac.drawables)}if("filters" in ac){var ab=this.filters_manager;this.filters_manager=new U(this,ac.filters);ab.parent_div.replaceWith(this.filters_manager.parent_div);if(ac.filters.visible){this.setup_multitrack_filtering()}}};o(L.prototype,p.prototype,v.prototype,{action_icons_def:[p.prototype.action_icons_def[0],p.prototype.action_icons_def[1],{name:"composite_icon",title:"Show composite track",css_class:"layers-stack",on_click_fn:function(Z){$(".tipsy").remove();Z.show_composite_track()}},{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(Z){if(Z.filters_manager.visible()){Z.filters_manager.clear_filters();Z._restore_filter_managers()}else{Z.setup_multitrack_filtering();Z.request_draw(true)}Z.filters_manager.toggle()}},p.prototype.action_icons_def[2]],build_container_div:function(){var Z=$("<div/>").addClass("group").attr("id","group_"+this.id);if(this.container){this.container.content_div.append(Z)}return Z},build_header_div:function(){var Z=$("<div/>").addClass("track-header");Z.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("track-name").text(this.name).appendTo(Z);return Z},hide_contents:function(){this.tiles_div.hide()},show_contents:function(){this.tiles_div.show();this.request_draw()},update_icons:function(){var ab=this.drawables.length;if(ab===0){this.action_icons.composite_icon.hide();this.action_icons.filters_icon.hide()}else{if(ab===1){if(this.drawables[0] instanceof g){this.action_icons.composite_icon.show()}this.action_icons.filters_icon.hide()}else{var af,al=true,ad=this.drawables[0].get_type(),Z=0;for(var ai=0;ai<ab;ai++){af=this.drawables[ai];if(af.get_type()!==ad){can_composite=false;break}if(af instanceof c){Z++}}if(al||Z===1){this.action_icons.composite_icon.show()}else{this.action_icons.composite_icon.hide();$(".tipsy").remove()}if(Z>1&&Z===this.drawables.length){var am={},aa;af=this.drawables[0];for(var ah=0;ah<af.filters_manager.filters.length;ah++){aa=af.filters_manager.filters[ah];am[aa.name]=[aa]}for(var ai=1;ai<this.drawables.length;ai++){af=this.drawables[ai];for(var ah=0;ah<af.filters_manager.filters.length;ah++){aa=af.filters_manager.filters[ah];if(aa.name in am){am[aa.name].push(aa)}}}this.filters_manager.remove_all();var ac,ae,ag,aj;for(var ak in am){ac=am[ak];if(ac.length===Z){ae=new P({name:ac[0].name,index:ac[0].index});this.filters_manager.add_filter(ae)}}if(this.filters_manager.filters.length>0){this.action_icons.filters_icon.show()}else{this.action_icons.filters_icon.hide()}}else{this.action_icons.filters_icon.hide()}}}},_restore_filter_managers:function(){for(var Z=0;Z<this.drawables.length;Z++){this.drawables[Z].filters_manager=this.saved_filters_managers[Z]}this.saved_filters_managers=[]},setup_multitrack_filtering:function(){if(this.filters_manager.filters.length>0){this.saved_filters_managers=[];for(var Z=0;Z<this.drawables.length;Z++){drawable=this.drawables[Z];this.saved_filters_managers.push(drawable.filters_manager);drawable.filters_manager=this.filters_manager}}this.filters_manager.init_filters()},show_composite_track:function(){var ad=[];for(var aa=0;aa<this.drawables.length;aa++){ad.push(this.drawables[aa].name)}var ab="Composite Track of "+this.drawables.length+" tracks ("+ad.join(", ")+")";var ac=new g(this.view,this.view,{name:ab,drawables:this.drawables});var Z=this.container.replace_drawable(this,ac,true);ac.request_draw()},add_drawable:function(Z){v.prototype.add_drawable.call(this,Z);this.update_icons()},remove_drawable:function(Z){v.prototype.remove_drawable.call(this,Z);this.update_icons()},to_dict:function(){if(this.filters_manager.visible()){this._restore_filter_managers()}var Z=o(v.prototype.to_dict.call(this),{filters:this.filters_manager.to_dict()});if(this.filters_manager.visible()){this.setup_multitrack_filtering()}return Z},request_draw:function(Z,ab){for(var aa=0;aa<this.drawables.length;aa++){this.drawables[aa].request_draw(Z,ab)}}});var W=function(Z){o(Z,{obj_type:"View"});v.call(this,"View",Z.container,Z);this.chrom=null;this.vis_id=Z.vis_id;this.dbkey=Z.dbkey;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new Y(this.container.get(0).ownerDocument);this.reset()};_.extend(W.prototype,Backbone.Events);o(W.prototype,v.prototype,{init:function(){this.requested_redraw=false;var ab=this.container,Z=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ab);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ab);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ab);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;k(this.viewport_container,Z);this.intro_div=$("<div/>").addClass("intro").appendTo(this.viewport_container).hide();var ac=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_datasets(add_datasets_url,add_track_async_url,function(ad){_.each(ad,function(ae){Z.add_drawable(object_from_template(ae,Z))})})});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("trackster-nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("trackster-nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var aa=function(ad){if(ad.type==="focusout"||(ad.keyCode||ad.which)===13||(ad.keyCode||ad.which)===27){if((ad.keyCode||ad.which)!==27){Z.go_to($(this).val())}$(this).hide();$(this).val("");Z.location_span.show();Z.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",aa).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("original-title","Click to change location").tipsy({gravity:"n"}).appendTo(this.nav_controls);this.location_span.click(function(){Z.location_span.hide();Z.chrom_select.hide();Z.nav_input.val(Z.chrom+":"+Z.low+"-"+Z.high);Z.nav_input.css("display","inline-block");Z.nav_input.select();Z.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tipsy({gravity:"n"}).click(function(){Z.zoom_out();Z.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tipsy({gravity:"n"}).click(function(){Z.zoom_in();Z.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){Z.change_chrom(Z.chrom_select.val())});this.browser_content_div.click(function(ad){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(ad){Z.zoom_in(ad.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(ad,ae){this.current_x=ae.offsetX}).bind("drag",function(ad,af){var ag=af.offsetX-this.current_x;this.current_x=af.offsetX;var ae=Math.round(ag/Z.viewport_container.width()*(Z.max_high-Z.max_low));Z.move_delta(-ae)});this.overview_close.click(function(){Z.reset_overview()});this.viewport_container.bind("draginit",function(ad,ae){if(ad.clientX>Z.viewport_container.width()-16){return false}}).bind("dragstart",function(ad,ae){ae.original_low=Z.low;ae.current_height=ad.clientY;ae.current_x=ae.offsetX}).bind("drag",function(af,ah){var ad=$(this);var ai=ah.offsetX-ah.current_x;var ae=ad.scrollTop()-(af.clientY-ah.current_height);ad.scrollTop(ae);ah.current_height=af.clientY;ah.current_x=ah.offsetX;var ag=Math.round(ai/Z.viewport_container.width()*(Z.high-Z.low));Z.move_delta(ag)}).bind("mousewheel",function(af,ah,ae,ad){if(ae){ae*=50;var ag=Math.round(-ae/Z.viewport_container.width()*(Z.high-Z.low));Z.move_delta(ag)}});this.top_labeltrack.bind("dragstart",function(ad,ae){return $("<div />").css({height:Z.browser_content_div.height()+Z.top_labeltrack.height()+Z.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ah,ai){$(ai.proxy).css({left:Math.min(ah.pageX,ai.startX)-Z.container.offset().left,width:Math.abs(ah.pageX-ai.startX)});var ae=Math.min(ah.pageX,ai.startX)-Z.container.offset().left,ad=Math.max(ah.pageX,ai.startX)-Z.container.offset().left,ag=(Z.high-Z.low),af=Z.viewport_container.width();Z.update_location(Math.round(ae/af*ag)+Z.low,Math.round(ad/af*ag)+Z.low)}).bind("dragend",function(ai,aj){var ae=Math.min(ai.pageX,aj.startX),ad=Math.max(ai.pageX,aj.startX),ag=(Z.high-Z.low),af=Z.viewport_container.width(),ah=Z.low;Z.low=Math.round(ae/af*ag)+ah;Z.high=Math.round(ad/af*ag)+ah;$(aj.proxy).remove();Z.request_redraw()});this.add_label_track(new V(this,{content_div:this.top_labeltrack}));this.add_label_track(new V(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){if(this.resize_timer){clearTimeout(this.resize_timer)}this.resize_timer=setTimeout(function(){Z.resize_window()},500)});$(document).bind("redraw",function(){Z.redraw()});this.reset();$(window).trigger("resize")},changed:function(){this.has_changes=true},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.show()}else{this.intro_div.hide()}},trigger_navigate:function(aa,ac,Z,ad){if(this.timer){clearTimeout(this.timer)}if(ad){var ab=this;this.timer=setTimeout(function(){ab.trigger("navigate",aa+":"+ac+"-"+Z)},500)}else{view.trigger("navigate",aa+":"+ac+"-"+Z)}},update_location:function(Z,ab){this.location_span.text(commatize(Z)+" - "+commatize(ab));this.nav_input.val(this.chrom+":"+commatize(Z)+"-"+commatize(ab));var aa=view.chrom_select.val();if(aa!==""){this.trigger_navigate(aa,view.low,view.high,true)}},load_chroms:function(ab){ab.num=t;ab.dbkey=this.dbkey;var Z=this,aa=$.Deferred();$.ajax({url:chrom_url,data:ab,dataType:"json",success:function(ad){if(ad.chrom_info.length===0){alert("Invalid chromosome: "+ab.chrom);return}if(ad.reference){Z.add_label_track(new x(Z))}Z.chrom_data=ad.chrom_info;var ag='<option value="">Select Chrom/Contig</option>';for(var af=0,ac=Z.chrom_data.length;af<ac;af++){var ae=Z.chrom_data[af].chrom;ag+='<option value="'+ae+'">'+ae+"</option>"}if(ad.prev_chroms){ag+='<option value="previous">Previous '+t+"</option>"}if(ad.next_chroms){ag+='<option value="next">Next '+t+"</option>"}Z.chrom_select.html(ag);Z.chrom_start_index=ad.start_index;aa.resolve(ad)},error:function(){alert("Could not load chroms for this dbkey:",Z.dbkey)}});return aa},change_chrom:function(ae,aa,ag){var ab=this;if(!ab.chrom_data){ab.load_chroms_deferred.then(function(){ab.change_chrom(ae,aa,ag)});return}if(!ae||ae==="None"){return}var ab=this;if(ae==="previous"){ab.load_chroms({low:this.chrom_start_index-t});return}if(ae==="next"){ab.load_chroms({low:this.chrom_start_index+t});return}var af=$.grep(ab.chrom_data,function(ah,ai){return ah.chrom===ae})[0];if(af===undefined){ab.load_chroms({chrom:ae},function(){ab.change_chrom(ae,aa,ag)});return}else{if(ae!==ab.chrom){ab.chrom=ae;ab.chrom_select.val(ab.chrom);ab.max_high=af.len-1;ab.reset();ab.request_redraw(true);for(var ad=0,Z=ab.drawables.length;ad<Z;ad++){var ac=ab.drawables[ad];if(ac.init){ac.init()}}if(ab.reference_track){ab.reference_track.init()}}if(aa!==undefined&&ag!==undefined){ab.low=Math.max(aa,0);ab.high=Math.min(ag,ab.max_high)}else{ab.low=0;ab.high=ab.max_high}ab.reset_overview();ab.request_redraw()}},go_to:function(ad){ad=ad.replace(/ |,/g,"");var ah=this,Z,ac,aa=ad.split(":"),af=aa[0],ag=aa[1];if(ag!==undefined){try{var ae=ag.split("-");Z=parseInt(ae[0],10);ac=parseInt(ae[1],10)}catch(ab){return false}}ah.change_chrom(af,Z,ac)},move_fraction:function(ab){var Z=this;var aa=Z.high-Z.low;this.move_delta(ab*aa)},move_delta:function(ac){var Z=this;var ab=Z.high-Z.low;if(Z.low-ac<Z.max_low){Z.low=Z.max_low;Z.high=Z.max_low+ab}else{if(Z.high-ac>Z.max_high){Z.high=Z.max_high;Z.low=Z.max_high-ab}else{Z.high-=ac;Z.low-=ac}}Z.request_redraw();var aa=Z.chrom_select.val();this.trigger_navigate(aa,Z.low,Z.high,true)},add_drawable:function(Z){v.prototype.add_drawable.call(this,Z);Z.init();this.changed();this.update_intro_div()},add_label_track:function(Z){Z.view=this;Z.init();this.label_tracks.push(Z)},remove_drawable:function(ab,aa){v.prototype.remove_drawable.call(this,ab);if(aa){var Z=this;ab.container_div.hide(0,function(){$(this).remove();Z.update_intro_div()})}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ah,Z,ag,aa){var af=this,ad=(aa?[aa]:af.drawables),ab;var aa;for(var ae=0;ae<ad.length;ae++){aa=ad[ae];ab=-1;for(var ac=0;ac<af.tracks_to_be_redrawn.length;ac++){if(af.tracks_to_be_redrawn[ac][0]===aa){ab=ac;break}}if(ab<0){af.tracks_to_be_redrawn.push([aa,Z,ag])}else{af.tracks_to_be_redrawn[ae][1]=Z;af.tracks_to_be_redrawn[ae][2]=ag}}if(!this.requested_redraw){requestAnimationFrame(function(){af._redraw(ah)});this.requested_redraw=true}},_redraw:function(aj){this.requested_redraw=false;var ag=this.low,ac=this.high;if(ag<this.max_low){ag=this.max_low}if(ac>this.max_high){ac=this.max_high}var ai=this.high-this.low;if(this.high!==0&&ai<this.min_separation){ac=ag+this.min_separation}this.low=Math.floor(ag);this.high=Math.ceil(ac);this.update_location(this.low,this.high);this.resolution_b_px=(this.high-this.low)/this.viewport_container.width();this.resolution_px_b=this.viewport_container.width()/(this.high-this.low);var Z=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var af=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var ak=13;this.overview_box.css({left:Z,width:Math.max(ak,af)}).show();if(af<ak){this.overview_box.css("left",Z-(ak-af)/2)}if(this.overview_highlight){this.overview_highlight.css({left:Z,width:af})}if(!aj){var ab,aa,ah;for(var ad=0,ae=this.tracks_to_be_redrawn.length;ad<ae;ad++){ab=this.tracks_to_be_redrawn[ad][0];aa=this.tracks_to_be_redrawn[ad][1];ah=this.tracks_to_be_redrawn[ad][2];if(ab){ab._draw(aa,ah)}}this.tracks_to_be_redrawn=[];for(ad=0,ae=this.label_tracks.length;ad<ae;ad++){this.label_tracks[ad]._draw()}}},zoom_in:function(aa,ab){if(this.max_high===0||this.high-this.low<=this.min_separation){return}var ac=this.high-this.low,ad=ac/2+this.low,Z=(ac/this.zoom_factor)/2;if(aa){ad=aa/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(ad-Z);this.high=Math.round(ad+Z);this.changed();this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var aa=this.high-this.low,ab=aa/2+this.low,Z=(aa*this.zoom_factor)/2;this.low=Math.round(ab-Z);this.high=Math.round(ab+Z);this.changed();this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.request_redraw()},set_overview:function(ab){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ab.dataset_id){return}this.overview_viewport.find(".track").remove()}var aa=ab.copy({content_div:this.overview_viewport}),Z=this;aa.header_div.hide();aa.is_overview=true;Z.overview_drawable=aa;this.overview_drawable.postdraw_actions=function(){Z.overview_highlight.show().height(Z.overview_drawable.content_div.height());Z.overview_viewport.height(Z.overview_drawable.content_div.height()+Z.overview_box.outerHeight());Z.overview_close.show();Z.resize_window()};Z.overview_drawable.request_draw();this.changed()},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var q=function(ab,ag,ac){this.track=ab;this.name=ag.name;this.params=[];var an=ag.params;for(var ad=0;ad<an.length;ad++){var ai=an[ad],aa=ai.name,am=ai.label,ae=unescape(ai.html),ao=ai.value,ak=ai.type;if(ak==="number"){this.params.push(new e(aa,am,ae,(aa in ac?ac[aa]:ao),ai.min,ai.max))}else{if(ak==="select"){this.params.push(new J(aa,am,ae,(aa in ac?ac[aa]:ao)))}else{console.log("WARNING: unrecognized tool parameter type:",aa,ak)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aq){aq.stopPropagation()}).click(function(aq){aq.stopPropagation()}).bind("dblclick",function(aq){aq.stopPropagation()});var al=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aj=this.params;var ah=this;$.each(this.params,function(ar,av){var au=$("<div>").addClass("param-row").appendTo(ah.parent_div);var aq=$("<div>").addClass("param-label").text(av.label).appendTo(au);var at=$("<div/>").addClass("param-input").html(av.html).appendTo(au);at.find(":input").val(av.value);$("<div style='clear: both;'/>").appendTo(au)});this.parent_div.find("input").click(function(){$(this).select()});var ap=$("<div>").addClass("param-row").appendTo(this.parent_div);var af=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ap);var Z=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ap);var ah=this;Z.click(function(){ah.run_on_region()});af.click(function(){ah.run_on_dataset()});if("visible" in ac&&ac.visible){this.parent_div.show()}};o(q.prototype,{update_params:function(){for(var Z=0;Z<this.params.length;Z++){this.params[Z].update_value()}},state_dict:function(){var aa={};for(var Z=0;Z<this.params.length;Z++){aa[this.params[Z].name]=this.params[Z].value}aa.visible=this.parent_div.is(":visible");return aa},get_param_values_dict:function(){var Z={};this.parent_div.find(":input").each(function(){var aa=$(this).attr("name"),ab=$(this).val();Z[aa]=JSON.stringify(ab)});return Z},get_param_values:function(){var aa=[];var Z={};this.parent_div.find(":input").each(function(){var ab=$(this).attr("name"),ac=$(this).val();if(ab){aa[aa.length]=ac}});return aa},run_on_dataset:function(){var Z=this;Z.run({dataset_id:this.track.original_dataset_id,tool_id:Z.name},null,function(aa){show_modal(Z.name+" is Running",Z.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var aa={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},ae=this.track,ab=aa.tool_id+ae.tool_region_and_parameters_str(aa.chrom,aa.low,aa.high),Z;if(ae.container===view){var ad=new L(view,view,{name:this.name});var ac=ae.container.replace_drawable(ae,ad,false);ad.container_div.insertBefore(ae.view.content_div.children()[ac]);ad.add_drawable(ae);ae.container_div.appendTo(ad.content_div);Z=ad}else{Z=ae.container}var af=new ae.constructor(view,Z,{name:ab,hda_ldda:"hda"});af.init_for_tool_data();af.change_mode(ae.mode);af.set_filters_manager(ae.filters_manager.copy(af));af.update_icons();Z.add_drawable(af);af.tiles_div.text("Starting job.");this.update_params();this.run(aa,af,function(ag){af.dataset_id=ag.dataset_id;af.tiles_div.text("Running job.");af.init()})},run:function(aa,ab,ac){$.extend(aa,this.get_param_values_dict());var Z=function(){$.getJSON(rerun_tool_url,aa,function(ad){if(ad==="no converter"){ab.container_div.addClass("error");ab.content_div.text(F)}else{if(ad.error){ab.container_div.addClass("error");ab.content_div.text(u+ad.message)}else{if(ad==="pending"){ab.container_div.addClass("pending");ab.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(Z,2000)}else{ac(ad)}}}})};Z()}});var J=function(aa,Z,ab,ac){this.name=aa;this.label=Z;this.html=$(ab);this.value=ac};o(J.prototype,{update_value:function(){this.value=$(this.html).val()}});var e=function(ab,aa,ad,ae,ac,Z){J.call(this,ab,aa,ad,ae);this.min=ac;this.max=Z};o(e.prototype,J.prototype,{update_value:function(){J.prototype.update_value.call(this);this.value=parseFloat(this.value)}});var f=function(Z){this.manager=null;this.name=Z.name;this.index=Z.index;this.tool_id=Z.tool_id;this.tool_exp_name=Z.tool_exp_name};o(f.prototype,{to_dict:function(){return{name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name}}});var P=function(ai){f.call(this,ai);this.low=("low" in ai?ai.low:-Number.MAX_VALUE);this.high=("high" in ai?ai.high:Number.MAX_VALUE);this.min=("min" in ai?ai.min:Number.MAX_VALUE);this.max=("max" in ai?ai.max:-Number.MAX_VALUE);this.container=null;this.slider=null;this.slider_label=null;var ae=function(aj,ak,al){aj.click(function(){var aq=ak.text(),ao=parseFloat(al.slider("option","max")),an=(ao<=1?4:ao<=1000000?ao.toString().length:6),ap=false,am=$(this).parents(".slider-row");am.addClass("input");if(al.slider("option","values")){an=2*an+1;ap=true}ak.text("");$("<input type='text'/>").attr("size",an).attr("maxlength",an).attr("value",aq).appendTo(ak).focus().select().click(function(ar){ar.stopPropagation()}).blur(function(){$(this).remove();ak.text(aq);am.removeClass("input")}).keyup(function(aw){if(aw.keyCode===27){$(this).trigger("blur")}else{if(aw.keyCode===13){var au=al.slider("option","min"),ar=al.slider("option","max"),av=function(ax){return(isNaN(ax)||ax>ar||ax<au)},at=$(this).val();if(!ap){at=parseFloat(at);if(av(at)){alert("Parameter value must be in the range ["+au+"-"+ar+"]");return $(this)}}else{at=at.split("-");at=[parseFloat(at[0]),parseFloat(at[1])];if(av(at[0])||av(at[1])){alert("Parameter value must be in the range ["+au+"-"+ar+"]");return $(this)}}al.slider((ap?"values":"value"),at);am.removeClass("input")}}})})};var aa=this;aa.parent_div=$("<div/>").addClass("filter-row slider-row");var Z=$("<div/>").addClass("elt-label").appendTo(aa.parent_div),ag=$("<span/>").addClass("slider-name").text(aa.name+" ").appendTo(Z),ab=$("<span/>").text(this.low+"-"+this.high),ac=$("<span/>").addClass("slider-value").appendTo(Z).append("[").append(ab).append("]");aa.values_span=ab;var af=$("<div/>").addClass("slider").appendTo(aa.parent_div);aa.control_element=$("<div/>").attr("id",aa.name+"-filter-control").appendTo(af);var ad=[0,0];aa.control_element.slider({range:true,min:this.min,max:this.max,step:this.get_slider_step(this.min,this.max),values:[this.low,this.high],slide:function(aj,ak){aa.slide(aj,ak)},change:function(aj,ak){aa.control_element.slider("option","slide").call(aa.control_element,aj,ak)}});aa.slider=aa.control_element;aa.slider_label=ab;ae(ac,ab,aa.control_element);var ah=$("<div/>").addClass("display-controls").appendTo(aa.parent_div);this.transparency_icon=create_action_icon("Use filter for data transparency","layer-transparent",function(){if(aa.manager.alpha_filter!==aa){aa.manager.alpha_filter=aa;aa.manager.parent_div.find(".layer-transparent").removeClass("active").hide();aa.transparency_icon.addClass("active").show()}else{aa.manager.alpha_filter=null;aa.transparency_icon.removeClass("active")}aa.manager.track.request_draw(true,true)}).appendTo(ah).hide();this.height_icon=create_action_icon("Use filter for data height","arrow-resize-090",function(){if(aa.manager.height_filter!==aa){aa.manager.height_filter=aa;aa.manager.parent_div.find(".arrow-resize-090").removeClass("active").hide();aa.height_icon.addClass("active").show()}else{aa.manager.height_filter=null;aa.height_icon.removeClass("active")}aa.manager.track.request_draw(true,true)}).appendTo(ah).hide();aa.parent_div.hover(function(){aa.transparency_icon.show();aa.height_icon.show()},function(){if(aa.manager.alpha_filter!==aa){aa.transparency_icon.hide()}if(aa.manager.height_filter!==aa){aa.height_icon.hide()}});$("<div style='clear: both;'/>").appendTo(aa.parent_div)};o(P.prototype,{to_dict:function(){var Z=f.prototype.to_dict.call(this);return o(Z,{type:"number",min:this.min,max:this.max,low:this.low,high:this.high})},copy:function(){return new P({name:this.name,index:this.index,tool_id:this.tool_id,tool_exp_name:this.tool_exp_name})},get_slider_step:function(ab,Z){var aa=Z-ab;return(aa<=2?0.01:1)},slide:function(aa,ab){var Z=ab.values;this.values_span.text(Z[0]+"-"+Z[1]);this.low=Z[0];this.high=Z[1];this.manager.track.request_draw(true,true)},applies_to:function(Z){if(Z.length>this.index){return true}return false},_keep_val:function(Z){return(isNaN(Z)||(Z>=this.low&&Z<=this.high))},keep:function(aa){if(!this.applies_to(aa)){return true}var ac=this;var ad=aa[this.index];if(ad instanceof Array){var ab=true;for(var Z=0;Z<ad.length;Z++){if(!this._keep_val(ad[Z])){ab=false;break}}return ab}else{return this._keep_val(aa[this.index])}},update_attrs:function(ac){var Z=false;if(!this.applies_to(ac)){return Z}var aa=ac[this.index];if(!(aa instanceof Array)){aa=[aa]}for(var ab=0;ab<aa.length;ab++){var ad=aa[ab];if(ad<this.min){this.min=Math.floor(ad);Z=true}if(ad>this.max){this.max=Math.ceil(ad);Z=true}}return Z},update_ui_elt:function(){if(this.min<this.max){this.parent_div.show()}else{this.parent_div.hide()}var aa=this.slider.slider("option","min"),Z=this.slider.slider("option","max");if(this.min<aa||this.max>Z){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",this.get_slider_step(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var U=function(ab,ah){this.track=ab;this.alpha_filter=null;this.height_filter=null;this.filters=[];this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aj){aj.stopPropagation()}).click(function(aj){aj.stopPropagation()}).bind("dblclick",function(aj){aj.stopPropagation()}).bind("keydown",function(aj){aj.stopPropagation()});if(ah&&"filters" in ah){var Z=("alpha_filter" in ah?ah.alpha_filter:null),ac=("height_filter" in ah?ah.height_filter:null),ae=ah.filters,aa;for(var af=0;af<ae.length;af++){if(ae[af].type==="number"){aa=new P(ae[af]);this.add_filter(aa);if(aa.name===Z){this.alpha_filter=aa;aa.transparency_icon.addClass("active").show()}if(aa.name===ac){this.height_filter=aa;aa.height_icon.addClass("active").show()}}else{console.log("ERROR: unsupported filter: ",name,type)}}if("visible" in ah&&ah.visible){this.parent_div.show()}}if(this.filters.length!==0){var ai=$("<div/>").addClass("param-row").appendTo(this.parent_div);var ag=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(ai);var ad=this;ag.click(function(){ad.run_on_dataset()})}};o(U.prototype,{show:function(){this.parent_div.show()},hide:function(){this.parent_div.hide()},toggle:function(){this.parent_div.toggle()},visible:function(){return this.parent_div.is(":visible")},to_dict:function(){var ac={},ab=[],aa;for(var Z=0;Z<this.filters.length;Z++){aa=this.filters[Z];ab.push(aa.to_dict())}ac.filters=ab;ac.alpha_filter=(this.alpha_filter?this.alpha_filter.name:null);ac.height_filter=(this.height_filter?this.height_filter.name:null);ac.visible=this.parent_div.is(":visible");return ac},copy:function(aa){var ab=new U(aa);for(var Z=0;Z<this.filters.length;Z++){ab.add_filter(this.filters[Z].copy())}return ab},add_filter:function(Z){Z.manager=this;this.parent_div.append(Z.parent_div);this.filters.push(Z)},remove_all:function(){this.filters=[];this.parent_div.children().remove()},init_filters:function(){for(var Z=0;Z<this.filters.length;Z++){var aa=this.filters[Z];aa.update_ui_elt()}},clear_filters:function(){for(var Z=0;Z<this.filters.length;Z++){var aa=this.filters[Z];aa.slider.slider("option","values",[aa.min,aa.max])}this.alpha_filter=null;this.height_filter=null;this.parent_div.find(".icon-button").hide()},run_on_dataset:function(){var ah=function(al,aj,ak){if(!(aj in al)){al[aj]=ak}return al[aj]};var ab={},Z,aa,ac;for(var ad=0;ad<this.filters.length;ad++){Z=this.filters[ad];if(Z.tool_id){if(Z.min!==Z.low){aa=ah(ab,Z.tool_id,[]);aa[aa.length]=Z.tool_exp_name+" >= "+Z.low}if(Z.max!==Z.high){aa=ah(ab,Z.tool_id,[]);aa[aa.length]=Z.tool_exp_name+" <= "+Z.high}}}var af=[];for(var ai in ab){af[af.length]=[ai,ab[ai]]}var ag=af.length;(function ae(ap,am){var ak=am[0],al=ak[0],ao=ak[1],an="("+ao.join(") and (")+")",aj={cond:an,input:ap,target_dataset_id:ap,tool_id:al},am=am.slice(1);$.getJSON(run_tool_url,aj,function(aq){if(aq.error){show_modal("Filter Dataset","Error running tool "+al,{Close:hide_modal})}else{if(am.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ae(aq.dataset_id,am)}}})})(this.track.dataset_id,af)}});var y=function(Z,aa){H.Scaler.call(this,aa);this.filter=Z};y.prototype.gen_val=function(Z){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(Z[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var B=function(Z){this.track=Z.track;this.params=Z.params;this.values={};this.restore_values((Z.saved_values?Z.saved_values:{}));this.onchange=Z.onchange};o(B.prototype,{restore_values:function(Z){var aa=this;$.each(this.params,function(ab,ac){if(Z[ac.key]!==undefined){aa.values[ac.key]=Z[ac.key]}else{aa.values[ac.key]=ac.default_value}})},build_form:function(){var ac=this;var Z=$("<div />");var ab;function aa(ag,ad){for(var ak=0;ak<ag.length;ak++){ab=ag[ak];if(ab.hidden){continue}var ae="param_"+ak;var ao=ac.values[ab.key];var ar=$("<div class='form-row' />").appendTo(ad);ar.append($("<label />").attr("for",ae).text(ab.label+":"));if(ab.type==="bool"){ar.append($('<input type="checkbox" />').attr("id",ae).attr("name",ae).attr("checked",ao))}else{if(ab.type==="text"){ar.append($('<input type="text"/>').attr("id",ae).val(ao).click(function(){$(this).select()}))}else{if(ab.type==="select"){var am=$("<select />").attr("id",ae);for(var ai=0;ai<ab.options.length;ai++){$("<option/>").text(ab.options[ai].label).attr("value",ab.options[ai].value).appendTo(am)}am.val(ao);ar.append(am)}else{if(ab.type==="color"){var aq=$("<div/>").appendTo(ar),al=$("<input />").attr("id",ae).attr("name",ae).val(ao).css("float","left").appendTo(aq).click(function(au){$(".tipsy").hide();var at=$(this).siblings(".tipsy");at.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(at).height()/2)+($(this).height()/2)}).show();at.click(function(av){av.stopPropagation()});$(document).bind("click.color-picker",function(){at.hide();$(document).unbind("click.color-picker")});au.stopPropagation()}),aj=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(aq).attr("title","Set new random color").tipsy({gravity:"s"}),an=$("<div class='tipsy tipsy-west' style='position: absolute;' />").appendTo(aq).hide(),af=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(an),ap=$("<div/>").appendTo(af),ah=$.farbtastic(ap,{width:100,height:100,callback:al,color:ao});aq.append($("<div/>").css("clear","both"));(function(at){aj.click(function(){at.setColor(get_random_color())})})(ah)}else{ar.append($("<input />").attr("id",ae).attr("name",ae).val(ao))}}}}if(ab.help){ar.append($("<div class='help'/>").text(ab.help))}}}aa(this.params,Z);return Z},update_from_form:function(Z){var ab=this;var aa=false;$.each(this.params,function(ac,ae){if(!ae.hidden){var af="param_"+ac;var ad=Z.find("#"+af).val();if(ae.type==="float"){ad=parseFloat(ad)}else{if(ae.type==="int"){ad=parseInt(ad)}else{if(ae.type==="bool"){ad=Z.find("#"+af).is(":checked")}}}if(ad!==ab.values[ae.key]){ab.values[ae.key]=ad;aa=true}}});if(aa){this.onchange();this.track.changed()}}});var b=function(Z,ac,ab,aa,ad){this.track=Z;this.index=ac;var ae=this.track._get_tile_bounds(ac,ab);this.low=ae[0];this.high=ae[1];this.resolution=ab;this.html_elt=$("<div class='track-tile'/>").append(aa).height($(aa).attr("height"));this.data=ad;this.stale=false};b.prototype.predisplay_actions=function(){};var j=function(Z,ac,ab,aa,ad,ae){b.call(this,Z,ac,ab,aa,ad);this.max_val=ae};o(j.prototype,b.prototype);var K=function(ac,ah,ad,ab,af,am,ag,an,aa,ak){b.call(this,ac,ah,ad,ab,af);this.mode=ag;this.all_slotted=aa;this.feature_mapper=ak;this.has_icons=false;if(an){this.has_icons=true;var ai=this;ab=this.html_elt.children()[0],message_div=$("<div/>").addClass("tile-message").css({height:z-1,width:ab.width}).prependTo(this.html_elt);var aj=new GenomeRegion({chrom:ac.view.chrom,start:this.low,end:this.high}),al=af.length,ae=$("<a href='javascript:void(0);'/>").addClass("icon more-down").attr("title","For speed, only the first "+al+" features in this region were obtained from server. Click to get more data including depth").tipsy({gravity:"s"}).appendTo(message_div),Z=$("<a href='javascript:void(0);'/>").addClass("icon more-across").attr("title","For speed, only the first "+al+" features in this region were obtained from server. Click to get more data excluding depth").tipsy({gravity:"s"}).appendTo(message_div);ae.click(function(){ai.stale=true;ac.data_manager.get_more_data(aj,ac.mode,ai.resolution,{},ac.data_manager.DEEP_DATA_REQ);$(".tipsy").hide();ac.request_draw(true)}).dblclick(function(ao){ao.stopPropagation()});Z.click(function(){ai.stale=true;ac.data_manager.get_more_data(aj,ac.mode,ai.resolution,{},ac.data_manager.BROAD_DATA_REQ);$(".tipsy").hide();ac.request_draw(true)}).dblclick(function(ao){ao.stopPropagation()})}};o(K.prototype,b.prototype);K.prototype.predisplay_actions=function(){var aa=this,Z={};if(aa.mode!=="Pack"){return}$(this.html_elt).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()}).mousemove(function(al){if(!this.hovered){return}var ag=$(this).offset(),ak=al.pageX-ag.left,aj=al.pageY-ag.top,ap=aa.feature_mapper.get_feature_data(ak,aj),ah=(ap?ap[0]:null);$(this).parents(".track-content").children(".overlay").children(".feature-popup").each(function(){if(!ah||$(this).attr("id")!==ah.toString()){$(this).remove()}});if(ap){var ac=Z[ah];if(!ac){var ah=ap[0],am={name:ap[3],start:ap[1],end:ap[2],strand:ap[4]},af=aa.track.filters_manager.filters,ae;for(var ai=0;ai<af.length;ai++){ae=af[ai];am[ae.name]=ap[ae.index]}var ac=$("<div/>").attr("id",ah).addClass("feature-popup"),aq=$("<table/>"),ao,an,ar;for(ao in am){an=am[ao];ar=$("<tr/>").appendTo(aq);$("<th/>").appendTo(ar).text(ao);$("<td/>").attr("align","left").appendTo(ar).text(typeof(an)==="number"?T(an,2):an)}ac.append($("<div class='feature-popup-inner'>").append(aq));Z[ah]=ac}ac.appendTo($(this).parents(".track-content").children(".overlay"));var ad=ak+parseInt(aa.html_elt.css("left"))-ac.width()/2,ab=aj+parseInt(aa.html_elt.css("top"))+7;ac.css("left",ad+"px").css("top",ab+"px")}else{if(!al.isPropagationStopped()){al.stopPropagation();$(this).siblings().each(function(){$(this).trigger(al)})}}}).mouseleave(function(){$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove()})};var h=function(aa,Z,ac){o(ac,{drag_handle_class:"draghandle"});p.call(this,aa,Z,ac);this.data_url=("data_url" in ac?ac.data_url:default_data_url);this.data_url_extra_params={};this.data_query_wait=("data_query_wait" in ac?ac.data_query_wait:G);this.dataset_check_url=converted_datasets_state_url;var ab=new Dataset({id:ac.dataset_id,hda_ldda:ac.hda_ldda});this.data_manager=("data_manager" in ac?ac.data_manager:new GenomeDataManager({dataset:ab,data_url:default_data_url,data_mode_compatible:this.data_and_mode_compatible,can_subset:this.can_subset,}));this.min_height_px=16;this.max_height_px=800;this.visible_height_px=0;this.content_div=$("<div class='track-content'>").appendTo(this.container_div);if(this.container){this.container.content_div.append(this.container_div);if(!("resize" in ac)||ac.resize){this.add_resize_handle()}}};o(h.prototype,p.prototype,{action_icons_def:[{name:"mode_icon",title:"Set display mode",css_class:"chevron-expand",on_click_fn:function(){}},p.prototype.action_icons_def[0],{name:"overview_icon",title:"Set as overview",css_class:"overview-icon",on_click_fn:function(Z){Z.view.set_overview(Z)}},p.prototype.action_icons_def[1],{name:"filters_icon",title:"Filters",css_class:"filters-icon",on_click_fn:function(Z){if(Z.filters_manager.visible()){Z.filters_manager.clear_filters()}else{Z.filters_manager.init_filters()}Z.filters_manager.toggle()}},{name:"tools_icon",title:"Tool",css_class:"hammer",on_click_fn:function(Z){Z.dynamic_tool_div.toggle();if(Z.dynamic_tool_div.is(":visible")){Z.set_name(Z.name+Z.tool_region_and_parameters_str())}else{Z.revert_name()}$(".tipsy").remove()}},p.prototype.action_icons_def[2]],can_draw:function(){if(this.dataset_id&&p.prototype.can_draw.call(this)){return true}return false},build_container_div:function(){return $("<div/>").addClass("track").attr("id","track_"+this.id).css("position","relative")},build_header_div:function(){var Z=$("<div class='track-header'/>");if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(Z)}this.name_div=$("<div/>").addClass("track-name").appendTo(Z).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());return Z},on_resize:function(){},add_resize_handle:function(){var Z=this;var ac=false;var ab=false;var aa=$("<div class='track-resize'>");$(Z.container_div).hover(function(){if(Z.content_visible){ac=true;aa.show()}},function(){ac=false;if(!ab){aa.hide()}});aa.hide().bind("dragstart",function(ad,ae){ab=true;ae.original_height=$(Z.content_div).height()}).bind("drag",function(ae,af){var ad=Math.min(Math.max(af.original_height+af.deltaY,Z.min_height_px),Z.max_height_px);$(Z.tiles_div).css("height",ad);Z.visible_height_px=(Z.max_height_px===ad?0:ad);Z.on_resize()}).bind("dragend",function(ad,ae){Z.tile_cache.clear();ab=false;if(!ac){aa.hide()}Z.config.values.height=Z.visible_height_px;Z.changed()}).appendTo(Z.container_div)},set_display_modes:function(ac,af){this.display_modes=ac;this.mode=(af?af:(this.config&&this.config.values.mode?this.config.values.mode:this.display_modes[0]));this.action_icons.mode_icon.attr("title","Set display mode (now: "+this.mode+")");var aa=this,ad={};for(var ab=0,Z=aa.display_modes.length;ab<Z;ab++){var ae=aa.display_modes[ab];ad[ae]=function(ag){return function(){aa.change_mode(ag);aa.icons_div.show();aa.container_div.mouseleave(function(){aa.icons_div.hide()})}}(ae)}make_popupmenu(this.action_icons.mode_icon,ad)},build_action_icons:function(){p.prototype.build_action_icons.call(this,this.action_icons_def);if(this.display_modes!==undefined){this.set_display_modes(this.display_modes)}},hide_contents:function(){this.tiles_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.tiles_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},get_type:function(){if(this instanceof V){return"LabelTrack"}else{if(this instanceof x){return"ReferenceTrack"}else{if(this instanceof i){return"LineTrack"}else{if(this instanceof Q){return"ReadTrack"}else{if(this instanceof N){return"VcfTrack"}else{if(this instanceof g){return"CompositeTrack"}else{if(this instanceof c){return"FeatureTrack"}}}}}}}return""},init:function(){var aa=this;aa.enabled=false;aa.tile_cache.clear();aa.data_manager.clear();aa.content_div.css("height","auto");aa.tiles_div.children().remove();aa.container_div.removeClass("nodata error pending");if(!aa.dataset_id){return}var Z=$.Deferred();$.getJSON(this.dataset_check_url,{hda_ldda:aa.hda_ldda,dataset_id:aa.dataset_id,chrom:aa.view.chrom},function(ab){if(!ab||ab==="error"||ab.kind==="error"){aa.container_div.addClass("error");aa.tiles_div.text(n);if(ab.message){var ac=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ab.message+"</pre>",{Close:hide_modal})});aa.tiles_div.append(ac)}}else{if(ab==="no converter"){aa.container_div.addClass("error");aa.tiles_div.text(F)}else{if(ab==="no data"||(ab.data!==undefined&&(ab.data===null||ab.data.length===0))){aa.container_div.addClass("nodata");aa.tiles_div.text(A)}else{if(ab==="pending"){aa.container_div.addClass("pending");aa.tiles_div.html(s);setTimeout(function(){aa.init()},aa.data_query_wait)}else{if(ab==="data"||ab.status==="data"){if(ab.valid_chroms){aa.valid_chroms=ab.valid_chroms;aa.update_icons()}aa.tiles_div.text(S);if(aa.view.chrom){aa.tiles_div.text("");aa.tiles_div.css("height",aa.visible_height_px+"px");aa.enabled=true;$.when(aa.predraw_init()).done(function(){Z.resolve();aa.container_div.removeClass("nodata error pending");aa.request_draw()})}else{Z.resolve()}}}}}}});this.update_icons();return Z},predraw_init:function(){}});var I=function(ab,aa,ac){h.call(this,ab,aa,ac);var Z=this,ab=Z.view;l(Z.container_div,Z.drag_handle_class,".group",Z);this.filters_manager=new U(this,("filters" in ac?ac.filters:null));this.data_manager.set("filters_manager",this.filters_manager);this.filters_available=false;this.tool=("tool" in ac&&ac.tool?new q(this,ac.tool,ac.tool_state):null);this.tile_cache=new Cache(M);if(this.header_div){this.set_filters_manager(this.filters_manager);if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}this.tiles_div=$("<div/>").addClass("tiles").appendTo(this.content_div);this.overlay_div=$("<div/>").addClass("overlay").appendTo(this.content_div);if(ac.mode){this.change_mode(ac.mode)}};o(I.prototype,p.prototype,h.prototype,{action_icons_def:h.prototype.action_icons_def.concat([{name:"show_more_rows_icon",title:"To minimize track height, not all feature rows are displayed. Click to display more rows.",css_class:"exclamation",on_click_fn:function(Z){$(".tipsy").remove();Z.slotters[Z.view.resolution_px_b].max_rows*=2;Z.request_draw(true)},hide:true}]),copy:function(Z){var aa=this.to_dict();o(aa,{data_manager:this.data_manager});var ab=new this.constructor(this.view,Z,aa);ab.change_mode(this.mode);ab.enabled=this.enabled;return ab},set_filters_manager:function(Z){this.filters_manager=Z;this.header_div.after(this.filters_manager.parent_div)},to_dict:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,filters:this.filters_manager.to_dict(),tool_state:(this.tool?this.tool.state_dict():{})}},change_mode:function(aa){var Z=this;Z.mode=aa;Z.config.values.mode=aa;Z.tile_cache.clear();Z.request_draw();this.action_icons.mode_icon.attr("title","Set display mode (now: "+Z.mode+")");return Z},update_icons:function(){var Z=this;if(Z.filters_available){Z.action_icons.filters_icon.show()}else{Z.action_icons.filters_icon.hide()}if(Z.tool){Z.action_icons.tools_icon.show()}else{Z.action_icons.tools_icon.hide()}},_gen_tile_cache_key:function(aa,ab,Z){return aa+"_"+ab+"_"+Z},request_draw:function(aa,Z){this.view.request_redraw(false,aa,Z,this)},before_draw:function(){},_draw:function(aa,ak){if(!this.can_draw()){return}var ai=this.view.low,ae=this.view.high,ag=ae-ai,ab=this.view.container.width(),am=this.view.resolution_px_b,ad=this.view.resolution_b_px;if(this.is_overview){ai=this.view.max_low;ae=this.view.max_high;ad=Math.pow(RESOLUTION,Math.ceil(Math.log((view.max_high-view.max_low)/O)/Math.log(RESOLUTION)));am=ab/(view.max_high-view.max_low)}this.before_draw();this.tiles_div.children().addClass("remove");var Z=Math.floor(ai/(ad*O)),ah=true,al=[],af=function(an){return(an&&"track" in an)};while((Z*O*ad)<ae){var aj=this.draw_helper(aa,ab,Z,ad,this.tiles_div,am);if(af(aj)){al.push(aj)}else{ah=false}Z+=1}if(!ak){this.tiles_div.children(".remove").removeClass("remove").remove()}var ac=this;if(ah){this.tiles_div.children(".remove").remove();ac.postdraw_actions(al,ab,am,ak)}},postdraw_actions:function(ac,ad,af,Z){var ab=this;var ae=false;for(var aa=0;aa<ac.length;aa++){if(ac[aa].has_icons){ae=true;break}}if(ae){for(var aa=0;aa<ac.length;aa++){tile=ac[aa];if(!tile.has_icons){tile.html_elt.css("padding-top",z)}}}},draw_helper:function(Z,am,ar,ap,af,ag,an){var al=this,av=this._gen_tile_cache_key(am,ag,ar),ad=this._get_tile_bounds(ar,ap),ac=new GenomeRegion({chrom:this.view.chrom,start:ad[0],end:ad[1]});if(!an){an={}}var au=(Z?undefined:al.tile_cache.get_elt(av));if(au){al.show_tile(au,af,ag);return au}var aj=true;var aq=al.data_manager.get_data(ac,al.mode,ap,al.data_url_extra_params);if(is_deferred(aq)){aj=false}var ah;if(view.reference_track&&ag>view.canvas_manager.char_width_px){ah=view.reference_track.data_manager.get_data(ac,al.mode,ap,view.reference_track.data_url_extra_params);if(is_deferred(ah)){aj=false}}if(aj){o(aq,an.more_tile_data);var ai=al.mode;if(ai==="Auto"){ai=al.get_mode(aq);al.update_auto_mode(ai)}var ab=al.view.canvas_manager.new_canvas(),at=ac.get("start"),aa=ac.get("end"),am=Math.ceil((aa-at)*ag)+al.left_offset,ak=al.get_canvas_height(aq,ai,ag,am);ab.width=am;ab.height=ak;var ao=ab.getContext("2d");ao.translate(this.left_offset,0);var au=al.draw_tile(aq,ao,ai,ap,ar,ag,ah);if(au!==undefined){al.tile_cache.set_elt(av,au);al.show_tile(au,af,ag)}return au}var ae=$.Deferred();$.when(aq,ah).then(function(){view.request_redraw(false,false,false,al);ae.resolve()});return ae},get_canvas_height:function(Z,ab,ac,aa){return this.visible_height_px},draw_tile:function(Z,ab,ae,ad,aa,af,ac){console.log("Warning: TiledTrack.draw_tile() not implemented.")},show_tile:function(ab,ad,ae){var aa=this,Z=ab.html_elt;ab.predisplay_actions();var ac=(ab.low-(this.is_overview?this.view.max_low:this.view.low))*ae;if(this.left_offset){ac-=this.left_offset}Z.css({position:"absolute",top:0,left:ac});if(Z.hasClass("remove")){Z.removeClass("remove")}else{ad.append(Z)}aa.after_show_tile(ab)},after_show_tile:function(Z){},_get_tile_bounds:function(Z,aa){var ac=Math.floor(Z*O*aa),ad=Math.ceil(O*aa),ab=(ac+ad<=this.view.max_high?ac+ad:this.view.max_high);return[ac,ab]},tool_region_and_parameters_str:function(ab,Z,ac){var aa=this,ad=(ab!==undefined&&Z!==undefined&&ac!==undefined?ab+":"+Z+"-"+ac:"all");return" - region=["+ad+"], parameters=["+aa.tool.get_param_values().join(", ")+"]"},data_and_mode_compatible:function(Z,aa){return true},can_subset:function(Z){return false},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.normal_postdraw_actions=this.postdraw_actions;this.postdraw_actions=function(ab,ac,ad,Z){var aa=this;aa.normal_postdraw_actions(ab,ac,ad,Z);aa.dataset_state_url=converted_datasets_state_url;aa.data_query_wait=G;$.when(server_state_deferred(aa.dataset_state_url,{dataset_id:aa.dataset_id,hda_ldda:aa.hda_ldda},aa.data_query_wait,function(ae){return ae!=="pending"})).then(function(){aa.data_url=default_data_url});aa.postdraw_actions=aa.normal_postdraw_actions}}});var V=function(aa,Z){var ab={resize:false};h.call(this,aa,Z,ab);this.container_div.addClass("label-track")};o(V.prototype,h.prototype,{build_header_div:function(){},init:function(){this.enabled=true},_draw:function(){var ab=this.view,ac=ab.high-ab.low,af=Math.floor(Math.pow(10,Math.floor(Math.log(ac)/Math.log(10)))),Z=Math.floor(ab.low/af)*af,ad=this.view.container.width(),aa=$("<div style='position: relative; height: 1.3em;'></div>");while(Z<ab.high){var ae=(Z-ab.low)/ac*ad;aa.append($("<div class='label'>"+commatize(Z)+"</div>").css({position:"absolute",left:ae-1}));Z+=af}this.content_div.children(":first").remove();this.content_div.append(aa)}});var g=function(aa,Z,ad){I.call(this,aa,Z,ad);this.drawables=[];this.left_offset=0;if("drawables" in ad){var ac;for(var ab=0;ab<ad.drawables.length;ab++){ac=ad.drawables[ab];this.drawables[ab]=object_from_template(ac);if(ac.left_offset>this.left_offset){this.left_offset=ac.left_offset}}this.enabled=true}if(this.drawables.length!==0){this.set_display_modes(this.drawables[0].display_modes,this.drawables[0].mode)}this.update_icons();this.obj_type="CompositeTrack"};o(g.prototype,I.prototype,{action_icons_def:[{name:"composite_icon",title:"Show individual tracks",css_class:"layers-stack",on_click_fn:function(Z){$(".tipsy").remove();Z.show_group()}}].concat(I.prototype.action_icons_def),to_dict:v.prototype.to_dict,add_drawable:v.prototype.add_drawable,unpack_drawables:v.prototype.unpack_drawables,change_mode:function(Z){I.prototype.change_mode.call(this,Z);for(var aa=0;aa<this.drawables.length;aa++){this.drawables[aa].change_mode(Z)}},init:function(){var ab=[];for(var aa=0;aa<this.drawables.length;aa++){ab.push(this.drawables[aa].init())}var Z=this;$.when.apply($,ab).then(function(){Z.enabled=true;Z.request_draw()})},update_icons:function(){this.action_icons.filters_icon.hide();this.action_icons.tools_icon.hide()},can_draw:p.prototype.can_draw,draw_helper:function(aa,ao,av,ar,ag,ai,ap){var an=this,az=this._gen_tile_cache_key(ao,ai,av),ae=this._get_tile_bounds(av,ar),aw=ae[0],ab=ae[1];if(!ap){ap={}}var ay=(aa?undefined:an.tile_cache.get_elt(az));if(ay){an.show_tile(ay,ag,ai);return ay}var ah=[],an,al=true,at,aj;for(var au=0;au<this.drawables.length;au++){an=this.drawables[au];at=an.data_manager.get_data(aw,ab,an.mode,ar,an.data_url_extra_params);if(is_deferred(at)){al=false}ah.push(at);aj=null;if(view.reference_track&&ai>view.canvas_manager.char_width_px){aj=view.reference_track.data_manager.get_data(aw,ab,an.mode,ar,view.reference_track.data_url_extra_params);if(is_deferred(aj)){al=false}}ah.push(aj)}if(al){o(at,ap.more_tile_data);this.tile_predraw_init();var ad=an.view.canvas_manager.new_canvas(),ae=an._get_tile_bounds(av,ar),aw=ae[0],ab=ae[1],ax=0,ao=Math.ceil((ab-aw)*ai)+this.left_offset,am=0,ac=[];var Z=0;for(var au=0;au<this.drawables.length;au++,ax+=2){an=this.drawables[au];at=ah[ax];var ak=an.mode;if(ak==="Auto"){ak=an.get_mode(at);an.update_auto_mode(ak)}ac.push(ak);Z=an.get_canvas_height(at,ak,ai,ao);if(Z>am){am=Z}}ad.width=ao;ad.height=(ap.height?ap.height:am);ax=0;var aq=ad.getContext("2d");aq.translate(this.left_offset,0);aq.globalAlpha=0.5;aq.globalCompositeOperation="source-over";for(var au=0;au<this.drawables.length;au++,ax+=2){an=this.drawables[au];at=ah[ax];aj=ah[ax+1];ay=an.draw_tile(at,aq,ac[au],ar,av,ai,aj)}this.tile_cache.set_elt(az,ay);this.show_tile(ay,ag,ai);return ay}var af=$.Deferred(),an=this;$.when.apply($,ah).then(function(){view.request_redraw(false,false,false,an);af.resolve()});return af},show_group:function(){var ac=new L(this.view,this.container,{name:this.name}),Z;for(var ab=0;ab<this.drawables.length;ab++){Z=this.drawables[ab];ac.add_drawable(Z);Z.container=ac;ac.content_div.append(Z.container_div)}var aa=this.container.replace_drawable(this,ac,true);ac.request_draw()},tile_predraw_init:function(){var ac=Number.MAX_VALUE,Z=-ac,aa;for(var ab=0;ab<this.drawables.length;ab++){aa=this.drawables[ab];if(aa instanceof i){if(aa.prefs.min_value<ac){ac=aa.prefs.min_value}if(aa.prefs.max_value>Z){Z=aa.prefs.max_value}}}for(var ab=0;ab<this.drawables.length;ab++){aa=this.drawables[ab];aa.prefs.min_value=ac;aa.prefs.max_value=Z}},postdraw_actions:function(ab,ae,ag,aa){I.prototype.postdraw_actions.call(this,ab,ae,ag,aa);var ad=-1;for(var ac=0;ac<ab.length;ac++){var Z=ab[ac].html_elt.find("canvas").height();if(Z>ad){ad=Z}}for(var ac=0;ac<ab.length;ac++){var af=ab[ac];if(af.html_elt.find("canvas").height()!==ad){this.draw_helper(true,ae,af.index,af.resolution,af.html_elt.parent(),ag,{height:ad});af.html_elt.remove()}}}});var x=function(Z){I.call(this,Z,{content_div:Z.top_labeltrack},{resize:false});Z.reference_track=this;this.left_offset=200;this.visible_height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:Z.dbkey};this.data_manager=new ReferenceTrackDataManager({data_url:reference_url});this.hide_contents()};o(x.prototype,p.prototype,I.prototype,{build_header_div:function(){},init:function(){this.data_manager.clear();this.enabled=true},can_draw:p.prototype.can_draw,draw_tile:function(ah,ai,ae,ad,aa,aj){var ac=this;if(aj>this.view.canvas_manager.char_width_px){if(ah.data===null){this.hide_contents();return}var ab=ai.canvas;ai.font=ai.canvas.manager.default_font;ai.textAlign="center";ah=ah.data;for(var af=0,ag=ah.length;af<ag;af++){var Z=Math.floor(af*aj);ai.fillText(ah[af],Z,10)}this.show_contents();return new b(ac,aa,ad,ab,ah)}this.hide_contents()}});var i=function(ab,aa,ac){var Z=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";I.call(this,ab,aa,ac);this.hda_ldda=ac.hda_ldda;this.dataset_id=ac.dataset_id;this.original_dataset_id=this.dataset_id;this.left_offset=0;this.config=new B({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:32,hidden:true}],saved_values:ac.prefs,onchange:function(){Z.set_name(Z.prefs.name);Z.vertical_range=Z.prefs.max_value-Z.prefs.min_value;Z.set_min_value(Z.prefs.min_value);Z.set_max_value(Z.prefs.max_value)}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value};o(i.prototype,p.prototype,I.prototype,{on_resize:function(){this.request_draw(true)},set_min_value:function(Z){this.prefs.min_value=Z;$("#linetrack_"+this.dataset_id+"_minval").text(this.prefs.min_value);this.tile_cache.clear();this.request_draw()},set_max_value:function(Z){this.prefs.max_value=Z;$("#linetrack_"+this.dataset_id+"_maxval").text(this.prefs.max_value);this.tile_cache.clear();this.request_draw()},predraw_init:function(){var Z=this;Z.vertical_range=undefined;return $.getJSON(Z.data_url,{stats:true,chrom:Z.view.chrom,low:null,high:null,hda_ldda:Z.hda_ldda,dataset_id:Z.dataset_id},function(aa){Z.container_div.addClass("line-track");var ad=aa.data;if(isNaN(parseFloat(Z.prefs.min_value))||isNaN(parseFloat(Z.prefs.max_value))){var ab=ad.min;var af=ad.max;ab=Math.floor(Math.min(0,Math.max(ab,ad.mean-2*ad.sd)));af=Math.ceil(Math.max(0,Math.min(af,ad.mean+2*ad.sd)));Z.prefs.min_value=ab;Z.prefs.max_value=af;$("#track_"+Z.dataset_id+"_minval").val(Z.prefs.min_value);$("#track_"+Z.dataset_id+"_maxval").val(Z.prefs.max_value)}Z.vertical_range=Z.prefs.max_value-Z.prefs.min_value;Z.total_frequency=ad.total_frequency;Z.container_div.find(".yaxislabel").remove();var ae=$("<div/>").text(T(Z.prefs.min_value,3)).make_text_editable({num_cols:6,on_finish:function(ag){$(".tipsy").remove();var ag=parseFloat(ag);if(!isNaN(ag)){Z.set_min_value(ag)}},help_text:"Set min value"}).addClass("yaxislabel bottom").attr("id","linetrack_"+Z.dataset_id+"_minval").prependTo(Z.container_div),ac=$("<div/>").text(T(Z.prefs.max_value,3)).make_text_editable({num_cols:6,on_finish:function(ag){$(".tipsy").remove();var ag=parseFloat(ag);if(!isNaN(ag)){Z.set_max_value(ag)}},help_text:"Set max value"}).addClass("yaxislabel top").attr("id","linetrack_"+Z.dataset_id+"_maxval").prependTo(Z.container_div)})},draw_tile:function(aj,ah,ae,ac,aa,ai){var ab=ah.canvas,Z=this._get_tile_bounds(aa,ac),ad=Z[0],ag=Z[1],af=new H.LinePainter(aj.data,ad,ag,this.prefs,ae);af.draw(ah,ab.width,ab.height,ai);return new b(this,aa,ac,ab,aj.data)},can_subset:function(Z){return false},});var c=function(ac,ab,ae){var aa=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];I.call(this,ac,ab,ae);var ad=get_random_color(),Z=get_random_color([ad,"#ffffff"]);this.config=new B({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:ad},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:Z},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"clear value to set automatically"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.visible_height_px,hidden:true}],saved_values:ae.prefs,onchange:function(){aa.set_name(aa.prefs.name);aa.tile_cache.clear();aa.set_painter_from_config();aa.request_draw()}});this.prefs=this.config.values;this.visible_height_px=this.config.values.height;this.container_div.addClass("feature-track");this.hda_ldda=ae.hda_ldda;this.dataset_id=ae.dataset_id;this.original_dataset_id=ae.dataset_id;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.slotters={};this.start_end_dct={};this.left_offset=200;this.set_painter_from_config()};o(c.prototype,p.prototype,I.prototype,{set_painter_from_config:function(){if(this.config.values.connector_style==="arcs"){this.painter=H.ArcLinkedFeaturePainter}else{this.painter=H.LinkedFeaturePainter}},before_draw:function(){this.max_height_px=0},after_show_tile:function(Z){this.max_height_px=Math.max(this.max_height_px,Z.html_elt.height());Z.html_elt.parent().children().css("height",this.max_height_px+"px");var aa=this.max_height_px;if(this.visible_height_px!==0){aa=Math.min(this.max_height_px,this.visible_height_px)}this.tiles_div.css("height",aa+"px")},postdraw_actions:function(ao,aj,ae,ad){I.prototype.postdraw_actions.call(this,ao,ad);var ai=this;if(ai.mode==="Histogram"){var aa=-1;for(var al=0;al<ao.length;al++){var ak=ao[al].max_val;if(ak>aa){aa=ak}}for(var al=0;al<ao.length;al++){var aq=ao[al];if(aq.max_val!==aa){aq.html_elt.remove();ai.draw_helper(true,aj,aq.index,aq.resolution,aq.html_elt.parent(),ae,{more_tile_data:{max:aa}})}}}if(ai.filters_manager){var af=ai.filters_manager.filters;for(var an=0;an<af.length;an++){af[an].update_ui_elt()}var ap=false,Z,ag;for(var al=0;al<ao.length;al++){if(ao[al].data.length){Z=ao[al].data[0];for(var an=0;an<af.length;an++){ag=af[an];if(ag.applies_to(Z)&&ag.min!==ag.max){ap=true;break}}}}if(ai.filters_available!==ap){ai.filters_available=ap;if(!ai.filters_available){ai.filters_manager.hide()}ai.update_icons()}}this.container_div.find(".yaxislabel").remove();var ac=ao[0];if(ac instanceof j){var ah=(this.prefs.histogram_max?this.prefs.histogram_max:ac.max_val),ab=$("<div/>").text(ah).make_text_editable({num_cols:12,on_finish:function(ar){$(".tipsy").remove();var ar=parseFloat(ar);ai.prefs.histogram_max=(!isNaN(ar)?ar:null);ai.tile_cache.clear();ai.request_draw()},help_text:"Set max value; leave blank to use default"}).addClass("yaxislabel top").css("color",this.prefs.label_color);this.container_div.prepend(ab)}if(ac instanceof K){var am=true;for(var al=0;al<ao.length;al++){if(!ao[al].all_slotted){am=false;break}}if(!am){this.action_icons.show_more_rows_icon.show()}else{this.action_icons.show_more_rows_icon.hide()}}else{this.action_icons.show_more_rows_icon.hide()}},update_auto_mode:function(Z){var Z;if(this.mode==="Auto"){if(Z==="no_detail"){Z="feature spans"}else{if(Z==="summary_tree"){Z="coverage histogram"}}this.action_icons.mode_icon.attr("title","Set display mode (now: Auto/"+Z+")")}},incremental_slots:function(ad,Z,ac){var aa=this.view.canvas_manager.dummy_context,ab=this.slotters[ad];if(!ab||(ab.mode!==ac)){ab=new (r.FeatureSlotter)(ad,ac,w,function(ae){return aa.measureText(ae)});this.slotters[ad]=ab}return ab.slot_features(Z)},get_summary_tree_data:function(ad,ag,ab,ao){if(ao>ab-ag){ao=ab-ag}var ak=Math.floor((ab-ag)/ao),an=[],ac=0;var ae=0,af=0,aj,am=0,ah=[],al,ai;var aa=function(ar,aq,at,ap){ar[0]=aq+at*ap;ar[1]=aq+(at+1)*ap};while(am<ao&&ae!==ad.length){var Z=false;for(;am<ao&&!Z;am++){aa(ah,ag,am,ak);for(af=ae;af<ad.length;af++){aj=ad[af].slice(1,3);if(is_overlap(aj,ah)){Z=true;break}}if(Z){break}}data_start_index=af;an[an.length]=al=[ah[0],0];for(;af<ad.length;af++){aj=ad[af].slice(1,3);if(is_overlap(aj,ah)){al[1]++}else{break}}if(al[1]>ac){ac=al[1]}am++}return{max:ac,delta:ak,data:an}},get_mode:function(Z){if(Z.dataset_type==="summary_tree"){mode="summary_tree"}else{if(Z.extra_info==="no_detail"||this.is_overview){mode="no_detail"}else{if(this.view.high-this.view.low>E){mode="Squish"}else{mode="Pack"}}}return mode},get_canvas_height:function(Z,ad,ae,aa){if(ad==="summary_tree"||ad==="Histogram"){return this.summary_draw_height}else{var ac=this.incremental_slots(ae,Z.data,ad);var ab=new (this.painter)(null,null,null,this.prefs,ad);return Math.max(X,ab.get_required_height(ac,aa))}},draw_tile:function(ak,ao,am,ap,au,ag,ab){var an=this,aa=ao.canvas,ad=this._get_tile_bounds(au,ap),ax=ad[0],Z=ad[1],aC=25,ac=this.left_offset;if(am==="summary_tree"||am==="Histogram"){if(ak.dataset_type!=="summary_tree"){var ah=this.get_summary_tree_data(ak.data,ax,Z,200);if(ak.max){ah.max=ak.max}ak=ah}var az=new H.SummaryTreePainter(ak,ax,Z,this.prefs);az.draw(ao,aa.width,aa.height,ag);return new j(an,au,ap,aa,ak.data,ak.max)}var af=[],al=this.slotters[ag].slots;all_slotted=true;if(ak.data){var ai=this.filters_manager.filters;for(var aq=0,at=ak.data.length;aq<at;aq++){var ae=ak.data[aq];var ar=false;var aj;for(var aw=0,aB=ai.length;aw<aB;aw++){aj=ai[aw];aj.update_attrs(ae);if(!aj.keep(ae)){ar=true;break}}if(!ar){af.push(ae);if(!(ae[0] in al)){all_slotted=false}}}}var aA=(this.filters_manager.alpha_filter?new y(this.filters_manager.alpha_filter):null);var ay=(this.filters_manager.height_filter?new y(this.filters_manager.height_filter):null);var az=new (this.painter)(af,ax,Z,this.prefs,am,aA,ay,ab);var av=null;ao.fillStyle=this.prefs.block_color;ao.font=ao.canvas.manager.default_font;ao.textAlign="right";if(ak.data){av=az.draw(ao,aa.width,aa.height,ag,al);av.translation=-ac}return new K(an,au,ap,aa,ak.data,ag,am,ak.message,all_slotted,av)},data_and_mode_compatible:function(Z,aa){if(aa==="Auto"){return true}else{if(Z.extra_info==="no_detail"||Z.dataset_type==="summary_tree"){return false}else{return true}}},can_subset:function(Z){if(Z.dataset_type==="summary_tree"||Z.message||Z.extra_info==="no_detail"){return false}return true},});var N=function(aa,Z,ab){c.call(this,aa,Z,ab);this.config=new B({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ab.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=H.ReadPainter};o(N.prototype,p.prototype,I.prototype,c.prototype);var Q=function(ab,aa,ad){c.call(this,ab,aa,ad);var ac=get_random_color(),Z=get_random_color([ac,"#ffffff"]);this.config=new B({track:this,params:[{key:"name",label:"Name",type:"text",default_value:this.name},{key:"block_color",label:"Block and sense strand color",type:"color",default_value:ac},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:Z},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"Clear value to set automatically"},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ad.prefs,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=H.ReadPainter;this.update_icons()};o(Q.prototype,p.prototype,I.prototype,c.prototype);R.View=W;R.DrawableGroup=L;R.LineTrack=i;R.FeatureTrack=c;R.ReadTrack=Q;R.VcfTrack=N;R.CompositeTrack=g};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.mode=h;this.include_label=(h==="Pack");this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,h=this.start_end_dct,x=[],z=[],n=0,y=this.max_rows;for(var v=0,w=m.length;v<w;v++){var k=m[v],o=k[0];if(this.slots[o]!==undefined){n=Math.max(n,this.slots[o]);z.push(this.slots[o])}else{x.push(v)}}var q=function(E,F){for(var D=0;D<=y;D++){var B=false,G=h[D];if(G!==undefined){for(var A=0,C=G.length;A<C;A++){var i=G[A];if(F>i[0]&&E<i[1]){B=true;break}}}if(!B){return D}}return -1};for(var v=0,w=x.length;v<w;v++){var k=m[x[v]],o=k[0],t=k[1],f=k[2],r=k[3],g=Math.floor(t*p),l=Math.ceil(f*p),u=this.measureText(r).width,j;if(r!==undefined&&this.include_label){u+=(d+a);if(g-u>=0){g-=u;j="left"}else{l+=u;j="right"}}var s=q(g,l);if(s>=0){if(h[s]===undefined){h[s]=[]}h[s].push([g,l]);this.slots[o]=s;n=Math.max(n,s)}}return n+1}})};var painters_module=function(i,x){var u=i("class").extend;var p=function(I,A,G,z,F,D){if(D===undefined){D=4}var C=z-A;var B=F-G;var E=Math.floor(Math.sqrt(C*C+B*B)/D);var J=C/E;var H=B/E;var y;for(y=0;y<E;y++,A+=J,G+=H){if(y%2!==0){continue}I.fillRect(A,G,D,1)}};var q=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var d=function(y){this.default_val=(y?y:1)};d.prototype.gen_val=function(y){return this.default_val};var l=function(A,C,y,z,B){this.data=A;this.view_start=C;this.view_end=y;this.prefs=u({},this.default_prefs,z);this.mode=B};l.prototype.default_prefs={};l.prototype.draw=function(z,A,y,B){};var v=function(A,C,y,z,B){l.call(this,A,C,y,z,B)};v.prototype.default_prefs={show_counts:false};v.prototype.draw=function(L,z,K,M){var E=this.view_start,N=this.view_end-this.view_start,I=this.data.data,G=(this.prefs.histogram_max?this.prefs.histogram_max:this.data.max),B=K;delta_x_px=Math.ceil(this.data.delta*M);L.save();for(var C=0,D=I.length;C<D;C++){var H=Math.floor((I[C][0]-E)*M);var F=I[C][1];if(!F){continue}var J=F/G*K;if(F!==0&&J<1){J=1}L.fillStyle=this.prefs.block_color;L.fillRect(H,B-J,delta_x_px,J);var A=4;if(this.prefs.show_counts&&(L.measureText(F).width+A)<delta_x_px){L.fillStyle=this.prefs.label_color;L.textAlign="center";L.fillText(F,H+(delta_x_px/2),10)}}L.restore()};var b=function(y,C,E,F,A){l.call(this,y,C,E,F,A);if(this.prefs.min_value===undefined){var G=Infinity;for(var z=0,B=this.data.length;z<B;z++){G=Math.min(G,this.data[z][1])}this.prefs.min_value=G}if(this.prefs.max_value===undefined){var D=-Infinity;for(var z=0,B=this.data.length;z<B;z++){D=Math.max(D,this.data[z][1])}this.prefs.max_value=D}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(S,Q,N,D){var I=false,K=this.prefs.min_value,F=this.prefs.max_value,M=F-K,B=N,C=this.view_start,P=this.view_end-this.view_start,L=this.mode,aa=this.data;S.save();var ac=Math.round(N+K/M*N);if(L!=="Intensity"){S.fillStyle="#aaa";S.fillRect(0,ac,Q,1)}S.beginPath();var Y,G,E;if(aa.length>1){E=Math.ceil((aa[1][0]-aa[0][0])*D)}else{E=10}var A=parseInt(this.prefs.color.slice(1),16),H=(A&16711680)>>16,R=(A&65280)>>8,V=A&255;for(var T=0,U=aa.length;T<U;T++){S.fillStyle=S.strokeStyle=this.prefs.color;Y=Math.round((aa[T][0]-C)*D);G=aa[T][1];var W=false,J=false;if(G===null){if(I&&L==="Filled"){S.lineTo(Y,B)}I=false;continue}if(G<K){J=true;G=K}else{if(G>F){W=true;G=F}}if(L==="Histogram"){G=Math.round(G/M*B);S.fillRect(Y,ac,E,-G)}else{if(L==="Intensity"){var z=(G-K)/M,O=Math.round(H+(255-H)*(1-z)),X=Math.round(R+(255-R)*(1-z)),ab=Math.round(V+(255-V)*(1-z));S.fillStyle="rgb("+O+","+X+","+ab+")";S.fillRect(Y,0,E,B)}else{G=Math.round(B-(G-K)/M*B);if(I){S.lineTo(Y,G)}else{I=true;if(L==="Filled"){S.moveTo(Y,B);S.lineTo(Y,G)}else{S.moveTo(Y,G)}}}}S.fillStyle=this.prefs.overflow_color;if(W||J){var Z;if(L==="Histogram"||L==="Intensity"){Z=E}else{Y-=2;Z=4}if(W){S.fillRect(Y,0,Z,3)}if(J){S.fillRect(Y,B-3,Z,3)}}S.fillStyle=this.prefs.color}if(L==="Filled"){if(I){S.lineTo(Y,ac);S.lineTo(0,ac)}S.fill()}else{S.stroke()}S.restore()};var m=function(y){this.feature_positions={};this.slot_height=y;this.translation=0;this.y_translation=0};m.prototype.map_feature_data=function(z,B,y,A){if(!this.feature_positions[B]){this.feature_positions[B]=[]}this.feature_positions[B].push({data:z,x_start:y,x_end:A})};m.prototype.get_feature_data=function(z,D){var C=Math.floor((D-this.y_translation)/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var o=function(A,D,y,z,C,E,B){l.call(this,A,D,y,z,C);this.alpha_scaler=(E?E:new d());this.height_scaler=(B?B:new d())};o.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};u(o.prototype,{get_required_height:function(A,z){var y=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){y=A*y_scale}return y+this.get_top_padding(z)+this.get_bottom_padding(z)},get_top_padding:function(y){return 0},get_bottom_padding:function(y){return Math.max(Math.round(this.get_row_height()/2),5)},draw:function(K,I,G,E,F){var Q=this.data,D=this.view_start,M=this.view_end;K.save();K.fillStyle=this.prefs.block_color;K.textAlign="right";var H=this.view_end-this.view_start,L=this.get_row_height(),P=new m(L),B;for(var N=0,O=Q.length;N<O;N++){var A=Q[N],C=A[0],J=A[1],y=A[2],z=(F&&F[C]!==undefined?F[C]:null);if((J<M&&y>D)&&(this.mode==="Dense"||z!==null)){B=this.draw_element(K,this.mode,A,z,D,M,E,L,I);P.map_feature_data(A,z,B[0],B[1])}}K.restore();P.y_translation=this.get_top_padding(I);return P},draw_element:function(E,A,G,C,B,D,F,z,y){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,w=10,f=1,s=9,e=3,a=9,j=2,g="#ccc";var r=function(A,D,y,z,C,E,B){o.call(this,A,D,y,z,C,E,B);this.draw_background_connector=true;this.draw_individual_connectors=false};u(r.prototype,o.prototype,{get_row_height:function(){var z=this.mode,y;if(z==="Dense"){y=c}else{if(z==="no_detail"){y=h}else{if(z==="Squish"){y=k}else{y=w}}}return y},draw_element:function(M,D,X,H,O,ai,am,ao,y){var T=X[0],ak=X[1],ad=X[2]-1,Q=X[3],K=X[4],ae=Math.floor(Math.max(0,(ak-O)*am)),N=Math.ceil(Math.min(y,Math.max(0,(ad-O)*am))),ac=ae,an=N,aa=(D==="Dense"?0:(0+H))*ao+this.get_top_padding(y),L,ag,R=null,aq=null,B=B=(!K||K==="+"||K==="."?this.prefs.block_color:this.prefs.reverse_strand_color);label_color=this.prefs.label_color;M.globalAlpha=this.alpha_scaler.gen_val(X);if(D==="Dense"){H=1}if(D==="no_detail"){M.fillStyle=B;M.fillRect(ae,aa+5,N-ae,f)}else{var Z=X[5],af=X[6],C=X[7],V=true;if(Z&&af){R=Math.floor(Math.max(0,(Z-O)*am));aq=Math.ceil(Math.min(y,Math.max(0,(af-O)*am)))}var al,U;if(D==="Squish"){al=1;U=e;V=false}else{if(D==="Dense"){al=5;U=s}else{al=5;U=a}}if(!C){M.fillStyle=B;M.fillRect(ae,aa+1,N-ae,U);if(K&&V){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}M.fillRect(ae,aa+1,N-ae,U)}}else{var J,W;if(D==="Squish"||D==="Dense"){J=aa+Math.floor(e/2)+1;W=1}else{if(K){J=aa;W=U}else{J+=(e/2)+1;W=1}}if(this.draw_background_connector){if(D==="Squish"||D==="Dense"){M.fillStyle=g}else{if(K){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand")}}}else{M.fillStyle=g}}M.fillRect(ae,J,N-ae,W)}var E;for(var aj=0,A=C.length;aj<A;aj++){var F=C[aj],z=Math.floor(Math.max(0,(F[0]-O)*am)),Y=Math.ceil(Math.min(y,Math.max((F[1]-1-O)*am))),S,ab;if(z>Y){continue}M.fillStyle=B;M.fillRect(z,aa+(U-al)/2+1,Y-z,al);if(R!==undefined&&af>Z&&!(z>aq||Y<R)){var ah=Math.max(z,R),I=Math.min(Y,aq);M.fillRect(ah,aa+1,I-ah,U)}if(this.draw_individual_connectors&&S){this.draw_connector(M,S,ab,z,Y,aa)}S=z;ab=Y}if(D==="Pack"){M.globalAlpha=1;M.fillStyle="white";var G=this.height_scaler.gen_val(X),P=Math.ceil(U*G),ap=Math.round((U-P)/2);if(G!==1){M.fillRect(ae,J+1,N-ae,ap);M.fillRect(ae,J+U-ap+1,N-ae,ap)}}}M.globalAlpha=1;if(D==="Pack"&&ak>O){M.fillStyle=label_color;if(O===0&&ae-M.measureText(Q).width<0){M.textAlign="left";M.fillText(Q,N+j,aa+8);an+=M.measureText(Q).width+j}else{M.textAlign="right";M.fillText(Q,ae-j,aa+8);ac-=M.measureText(Q).width+j}}}M.globalAlpha=1;return[ac,an]}});var t=function(B,E,y,A,D,F,C,z){o.call(this,B,E,y,A,D,F,C);this.ref_seq=(z?z.data:null)};u(t.prototype,o.prototype,{get_row_height:function(){var y,z=this.mode;if(z==="Dense"){y=c}else{if(z==="Squish"){y=k}else{y=w;if(this.prefs.show_insertions){y*=2}}}return y},draw_read:function(K,A,ag,V,L,aa,ad,C,B,M){K.textAlign="center";var J=this,R=[L,aa],Z=0,W=0,D=0,F=K.canvas.manager.char_width_px,y=(B==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);var O=[];if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){D=Math.round(ag/2)}if(!C){C=[[0,M.length]]}for(var G=0,I=C.length;G<I;G++){var z=C[G],E="MIDNSHP=X"[z[0]],S=z[1];if(E==="H"||E==="S"){Z-=S}var U=ad+Z,Y=Math.floor(Math.max(0,(U-L)*ag)),ab=Math.floor(Math.max(0,(U+S-L)*ag));if(Y===ab){ab+=1}switch(E){case"H":break;case"S":case"M":case"=":if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(D>0){K.fillStyle=y;K.fillRect(Y-D,V+1,ab-Y,9);K.fillStyle=g;for(var af=0,H=N.length;af<H;af++){if(this.prefs.show_differences){if(this.ref_seq){var P=this.ref_seq[U-L+af];if(!P||P.toLowerCase()===N[af].toLowerCase()){continue}}else{continue}}if(U+af>=L&&U+af<=aa){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X,V+9)}}}else{K.fillStyle=y;K.fillRect(Y,V+4,ab-Y,e)}}W+=S;Z+=S;break;case"N":K.fillStyle=g;K.fillRect(Y-D,V+5,ab-Y,1);Z+=S;break;case"D":K.fillStyle="red";K.fillRect(Y-D,V+4,ab-Y,3);Z+=S;break;case"P":break;case"I":var ah=Y-D;if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(this.prefs.show_insertions){var T=Y-(ab-Y)/2;if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){K.fillStyle="yellow";K.fillRect(T-D,V-9,ab-Y,9);O[O.length]={type:"triangle",data:[ah,V+4,5]};K.fillStyle=g;switch(compute_overlap([U,U+S],R)){case (OVERLAP_START):N=N.slice(L-U);break;case (OVERLAP_END):N=N.slice(0,U-aa);break;case (CONTAINED_BY):break;case (CONTAINS):N=N.slice(L-U,U-aa);break}for(var af=0,H=N.length;af<H;af++){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X-(ab-Y)/2,V)}}else{K.fillStyle="yellow";K.fillRect(T,V+(this.mode!=="Dense"?2:5),ab-Y,(A!=="Dense"?e:s))}}else{if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){O.push({type:"text",data:[N.length,ah,V+9]})}else{}}}W+=S;break;case"X":W+=S;break}}K.fillStyle="yellow";var Q,ai,ae;for(var ac=0;ac<O.length;ac++){Q=O[ac];ai=Q.type;ae=Q.data;if(ai==="text"){K.save();K.font="bold "+K.font;K.fillText(ae[0],ae[1],ae[2]);K.restore()}else{if(ai==="triangle"){q(K,ae[0],ae[1],ae[2])}}}},draw_element:function(R,M,E,B,U,z,I,S,P){var H=E[0],Q=E[1],A=E[2],J=E[3],D=Math.floor(Math.max(0,(Q-U)*I)),F=Math.ceil(Math.min(P,Math.max(0,(A-U)*I))),C=(M==="Dense"?0:(0+B))*S,G=this.prefs.label_color,O=0;if((M==="Pack"||this.mode==="Auto")&&I>R.canvas.manager.char_width_px){var O=Math.round(I/2)}if(E[5] instanceof Array){var N=Math.floor(Math.max(0,(E[4][0]-U)*I)),L=Math.ceil(Math.min(P,Math.max(0,(E[4][1]-U)*I))),K=Math.floor(Math.max(0,(E[5][0]-U)*I)),y=Math.ceil(Math.min(P,Math.max(0,(E[5][1]-U)*I)));if(E[4][1]>=U&&E[4][0]<=z&&E[4][2]){this.draw_read(R,M,I,C,U,z,E[4][0],E[4][2],E[4][3],E[4][4])}if(E[5][1]>=U&&E[5][0]<=z&&E[5][2]){this.draw_read(R,M,I,C,U,z,E[5][0],E[5][2],E[5][3],E[5][4])}if(K>L){R.fillStyle=g;p(R,L-O,C+5,K-O,C+5)}}else{this.draw_read(R,M,I,C,U,z,Q,E[4],E[5],E[6])}if(M==="Pack"&&Q>U&&J!=="."){R.fillStyle=this.prefs.label_color;var T=1;if(T===0&&D-R.measureText(J).width<0){R.textAlign="left";R.fillText(J,F+j-O,C+8)}else{R.textAlign="right";R.fillText(J,D-j-O,C+8)}}return[0,0]}});var n=function(A,D,y,z,C,E,B){r.call(this,A,D,y,z,C,E,B);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};u(n.prototype,o.prototype,r.prototype,{calculate_longest_feature_length:function(){var z=0;for(var C=0,y=this.data.length;C<y;C++){var B=this.data[C],A=B[1],D=B[2];z=Math.max(z,D-A)}return z},get_top_padding:function(z){var y=this.view_end-this.view_start,A=z/y;return Math.min(128,Math.ceil((this.longest_feature_length/2)*A))},draw_connector:function(G,B,F,H,E,D){var y=(F+H)/2,C=H-y;var A=Math.PI,z=0;if(C>0){G.beginPath();G.arc(y,D,H-y,Math.PI,0);G.stroke()}}});x.Scaler=d;x.SummaryTreePainter=v;x.LinePainter=b;x.LinkedFeaturePainter=r;x.ReadPainter=t;x.ArcLinkedFeaturePainter=n};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window); \ No newline at end of file diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd static/scripts/packed/viz/visualization.js --- a/static/scripts/packed/viz/visualization.js +++ b/static/scripts/packed/viz/visualization.js @@ -1,1 +1,1 @@ -var Genome=Backbone.Model.extend({defaults:{name:null,key:null,chroms_info:null},get_chroms_info:function(){return this.attributes.chroms_info.chrom_info}});var BrowserBookmark=Backbone.Model.extend({defaults:{chrom:null,start:0,end:0,note:""}});var BrowserBookmarks=Backbone.Collection.extend({model:BrowserBookmark});var Visualization=Backbone.RelationalModel.extend({defaults:{id:"",title:"",type:"",dbkey:"",datasets:[]},url:function(){return galaxy_paths.get("visualization_url")},save:function(){return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{vis_json:JSON.stringify(this)}})}});var TracksterVisualization=Visualization.extend({defaults:{bookmarks:[],viewport:{}}});var CircsterVisualization=Visualization.extend({});var Dataset=Backbone.Model.extend({defaults:{id:"",type:"",name:"",hda_ldda:""}});var HistogramDataset=Backbone.Model.extend({initialize:function(a){this.attributes.data=a;this.attributes.max=_.max(a,function(b){if(!b||typeof b==="string"){return 0}return b[1]})[1]}});var TrackConfig=Backbone.Model.extend({});var CircsterHistogramDatasetLayout=Backbone.Model.extend({chroms_layout:function(){var b=this.attributes.genome.get_chroms_info(),d=d3.layout.pie().value(function(f){return f.len}).sort(null),e=d(b),a=this.attributes.total_gap/b.length,c=_.map(e,function(h,g){var f=h.endAngle-a;h.endAngle=(f>h.startAngle?f:h.startAngle);return h});return c},chrom_data_layout:function(j,b,g,f,h){if(!b||typeof b==="string"){return null}var d=b[0],i=b[3],c=d3.scale.linear().domain([0,h]).range([g,f]),e=d3.layout.pie().value(function(k){return i}).startAngle(j.startAngle).endAngle(j.endAngle),a=e(d);_.each(d,function(k,l){a[l].outerRadius=c(k[1])});return a}});var CircsterView=Backbone.View.extend({className:"circster",initialize:function(a){this.width=a.width;this.height=a.height;this.total_gap=a.total_gap;this.genome=a.genome;this.dataset=a.dataset;this.radius_start=a.radius_start;this.dataset_arc_height=a.dataset_arc_height},render:function(){var d=this.radius_start,e=this.dataset_arc_height,j=new CircsterHistogramDatasetLayout({genome:this.genome,total_gap:this.total_gap}),i=j.chroms_layout(),g=_.zip(i,this.dataset.attributes.data),h=this.dataset.attributes.max,b=_.map(g,function(m){var n=m[0],l=m[1];return j.chrom_data_layout(n,l,d,d+e,h)});var c=d3.select(this.$el[0]).append("svg").attr("width",this.width).attr("height",this.height).append("g").attr("transform","translate("+this.width/2+","+this.height/2+")");var k=c.append("g").attr("id","inner-arc"),f=d3.svg.arc().innerRadius(d).outerRadius(d+e),a=k.selectAll("#inner-arc>path").data(i).enter().append("path").attr("d",f).style("stroke","#ccc").style("fill","#ccc").append("title").text(function(l){return l.data.chrom});_.each(b,function(l){if(!l){return}var o=c.append("g"),n=d3.svg.arc().innerRadius(d),m=o.selectAll("path").data(l).enter().append("path").attr("d",n).style("stroke","red").style("fill","red")})}});var TrackBrowserRouter=Backbone.Router.extend({initialize:function(b){this.view=b.view;this.route(/([\w]+)$/,"change_location");this.route(/([\w]+\:[\d,]+-[\d,]+)$/,"change_location");var a=this;a.view.on("navigate",function(c){a.navigate(c)})},change_location:function(a){this.view.go_to(a)}});var add_datasets=function(a,c,b){$.ajax({url:a,data:{"f-dbkey":view.dbkey},error:function(){alert("Grid failed")},success:function(d){show_modal("Select datasets for new tracks",d,{Cancel:function(){hide_modal()},Add:function(){var e=[];$("input[name=id]:checked,input[name=ldda_ids]:checked").each(function(){var f,g=$(this).val();if($(this).attr("name")==="id"){f={hda_id:g}}else{f={ldda_id:g}}e[e.length]=$.ajax({url:c,data:f,dataType:"json",})});$.when.apply($,e).then(function(){var f=(arguments[0] instanceof Array?$.map(arguments,function(g){return g[0]}):[arguments[0]]);b(f)});hide_modal()}})}})}; \ No newline at end of file +var Cache=Backbone.Model.extend({defaults:{num_elements:20,obj_cache:{},key_ary:[]},get_elt:function(b){var c=this.attributes.obj_cache,d=this.attributes.key_ary,a=d.indexOf(b);if(a!==-1){if(c[b].stale){d.splice(a,1);delete c[b]}else{this.move_key_to_end(b,a)}}return c[b]},set_elt:function(b,d){var e=this.attributes.obj_cache,f=this.attributes.key_ary,c=this.attributes.num_elements;if(!e[b]){if(f.length>=c){var a=f.shift();delete e[a]}f.push(b)}e[b]=d;return d},move_key_to_end:function(b,a){this.attributes.key_ary.splice(a,1);this.attributes.key_ary.push(b)},clear:function(){this.attributes.obj_cache={};this.attributes.key_ary=[]},size:function(){return this.attributes.key_ary.length}});var GenomeDataManager=Cache.extend({defaults:_.extend({},Cache.prototype.defaults,{dataset:null,filters_manager:null,data_url:null,data_mode_compatible:function(a,b){return true},can_subset:function(a){return false}}),load_data:function(h,g,b,f){var d={chrom:h.get("chrom"),low:h.get("start"),high:h.get("end"),mode:g,resolution:b};dataset=this.get("dataset");if(dataset){d.dataset_id=dataset.id;d.hda_ldda=dataset.get("hda_ldda")}$.extend(d,f);var j=this.get("filters_manager");if(j){var k=[];var a=j.filters;for(var e=0;e<a.length;e++){k.push(a[e].name)}d.filter_cols=JSON.stringify(k)}var c=this;return $.getJSON(this.get("data_url"),d,function(i){c.set_data(h,i)})},get_data:function(g,f,c,e){var h=this.get_elt(g);if(h&&(is_deferred(h)||this.get("data_mode_compatible")(h,f))){return h}var j=this.get("key_ary"),b=this.get("obj_cache"),k,g,a,f,h;for(var d=0;d<j.length;d++){a=new GenomeRegion(j[d]);if(a.contains(g)){var h=b[k];if(is_deferred(h)||(this.get("data_mode_compatible")(h,f)&&this.get("can_subset")(h))){this.move_key_to_end(k,d);return h}}}h=this.load_data(g,f,c,e);this.set_data(g,h);return h},set_data:function(b,a){this.set_elt(b,a)},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(h,g,c,f,d){var j=this.get_elt(h);if(!(j&&this.get("data_mode_compatible")(j,g))){console.log("ERROR: no current data for: ",dataset,h.toString(),g,c,f);return}j.stale=true;var b=h.get("start");if(d===this.DEEP_DATA_REQ){$.extend(f,{start_val:j.data.length+1})}else{if(d===this.BROAD_DATA_REQ){b=(j.max_high?j.max_high:j.data[j.data.length-1][2])+1}}var i=h.copy().set("start",b);var a=this,e=this.load_data(i,g,c,f);new_data_available=$.Deferred();this.set_data(h,new_data_available);$.when(e).then(function(k){if(k.data){k.data=j.data.concat(k.data);if(k.max_low){k.max_low=j.max_low}if(k.message){k.message=k.message.replace(/[0-9]+/,k.data.length)}}a.set_data(h,k);new_data_available.resolve(k)});return new_data_available},get_elt:function(a){return Cache.prototype.get_elt.call(this,a.toString())},set_elt:function(b,a){return Cache.prototype.set_elt.call(this,b.toString(),a)}});var ReferenceTrackDataManager=GenomeDataManager.extend({load_data:function(a,d,e,b,c){if(b>1){return{data:null}}return GenomeDataManager.prototype.load_data.call(this,a,d,e,b,c)}});var Genome=Backbone.Model.extend({defaults:{name:null,key:null,chroms_info:null},get_chroms_info:function(){return this.attributes.chroms_info.chrom_info}});var GenomeRegion=Backbone.Model.extend({defaults:{chrom:null,start:0,end:0,DIF_CHROMS:1000,BEFORE:1001,CONTAINS:1002,OVERLAP_START:1003,OVERLAP_END:1004,CONTAINED_BY:1005,AFTER:1006},initialize:function(b){if(!this.get("chrom")&&!this.get("start")&&!this.get("end")&&"as_str" in b){var d=b.as_str.split(":"),c=d[0],d=d.split("-"),e=d[0],a=d[1];this.set("chrom",c);this.set("start",e);this.set("end",a)}},copy:function(){return new GenomeRegion({chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")})},toString:function(){return this.get("chrom")+":"+this.get("start")+"-"+this.get("end")},compute_overlap:function(h){var b=this.get("chrom"),g=h.get("chrom"),f=this.get("start"),d=h.get("start"),e=this.get("end"),c=h.get("end"),a;if(b&&g&&b!==g){return this.get("DIF_CHROMS")}if(f<d){if(e<d){a=this.get("BEFORE")}else{if(e<=c){a=this.get("OVERLAP_START")}else{a=this.get("CONTAINS")}}}else{if(f>c){a=this.get("AFTER")}else{if(e<=c){a=this.get("CONTAINED_BY")}else{a=this.get("OVERLAP_END")}}}return a},contains:function(a){return this.compute_overlap(a)===this.get("CONTAINS")},overlaps:function(a){return _.intersection([this.compute_overlap(a)],[this.get("DIF_CHROMS"),this.get("BEFORE"),this.get("AFTER")]).length===0}});var BrowserBookmark=Backbone.Model.extend({defaults:{region:null,note:""}});var BrowserBookmarks=Backbone.Collection.extend({model:BrowserBookmark});var Visualization=Backbone.RelationalModel.extend({defaults:{id:"",title:"",type:"",dbkey:"",datasets:[]},url:function(){return galaxy_paths.get("visualization_url")},save:function(){return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{vis_json:JSON.stringify(this)}})}});var TracksterVisualization=Visualization.extend({defaults:{bookmarks:[],viewport:{}}});var CircsterVisualization=Visualization.extend({});var Dataset=Backbone.Model.extend({defaults:{id:"",type:"",name:"",hda_ldda:""}});var HistogramDataset=Backbone.Model.extend({initialize:function(a){this.attributes.data=a;this.attributes.max=_.max(a,function(b){if(!b||typeof b==="string"){return 0}return b[1]})[1]}});var TrackConfig=Backbone.Model.extend({});var CircsterHistogramDatasetLayout=Backbone.Model.extend({chroms_layout:function(){var b=this.attributes.genome.get_chroms_info(),d=d3.layout.pie().value(function(f){return f.len}).sort(null),e=d(b),a=this.attributes.total_gap/b.length,c=_.map(e,function(h,g){var f=h.endAngle-a;h.endAngle=(f>h.startAngle?f:h.startAngle);return h});return c},chrom_data_layout:function(j,b,g,f,h){if(!b||typeof b==="string"){return null}var d=b[0],i=b[3],c=d3.scale.linear().domain([0,h]).range([g,f]),e=d3.layout.pie().value(function(k){return i}).startAngle(j.startAngle).endAngle(j.endAngle),a=e(d);_.each(d,function(k,l){a[l].outerRadius=c(k[1])});return a}});var CircsterView=Backbone.View.extend({className:"circster",initialize:function(a){this.width=a.width;this.height=a.height;this.total_gap=a.total_gap;this.genome=a.genome;this.dataset=a.dataset;this.radius_start=a.radius_start;this.dataset_arc_height=a.dataset_arc_height},render:function(){var d=this.radius_start,e=this.dataset_arc_height,j=new CircsterHistogramDatasetLayout({genome:this.genome,total_gap:this.total_gap}),i=j.chroms_layout(),g=_.zip(i,this.dataset.attributes.data),h=this.dataset.attributes.max,b=_.map(g,function(m){var n=m[0],l=m[1];return j.chrom_data_layout(n,l,d,d+e,h)});var c=d3.select(this.$el[0]).append("svg").attr("width",this.width).attr("height",this.height).append("g").attr("transform","translate("+this.width/2+","+this.height/2+")");var k=c.append("g").attr("id","inner-arc"),f=d3.svg.arc().innerRadius(d).outerRadius(d+e),a=k.selectAll("#inner-arc>path").data(i).enter().append("path").attr("d",f).style("stroke","#ccc").style("fill","#ccc").append("title").text(function(l){return l.data.chrom});_.each(b,function(l){if(!l){return}var o=c.append("g"),n=d3.svg.arc().innerRadius(d),m=o.selectAll("path").data(l).enter().append("path").attr("d",n).style("stroke","red").style("fill","red")})}});var TrackBrowserRouter=Backbone.Router.extend({initialize:function(b){this.view=b.view;this.route(/([\w]+)$/,"change_location");this.route(/([\w]+\:[\d,]+-[\d,]+)$/,"change_location");var a=this;a.view.on("navigate",function(c){a.navigate(c)})},change_location:function(a){this.view.go_to(a)}});var add_datasets=function(a,c,b){$.ajax({url:a,data:{"f-dbkey":view.dbkey},error:function(){alert("Grid failed")},success:function(d){show_modal("Select datasets for new tracks",d,{Cancel:function(){hide_modal()},Add:function(){var e=[];$("input[name=id]:checked,input[name=ldda_ids]:checked").each(function(){var f,g=$(this).val();if($(this).attr("name")==="id"){f={hda_id:g}}else{f={ldda_id:g}}e[e.length]=$.ajax({url:c,data:f,dataType:"json",})});$.when.apply($,e).then(function(){var f=(arguments[0] instanceof Array?$.map(arguments,function(g){return g[0]}):[arguments[0]]);b(f)});hide_modal()}})}})}; \ No newline at end of file diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd static/scripts/viz/paramamonster.js --- a/static/scripts/viz/paramamonster.js +++ b/static/scripts/viz/paramamonster.js @@ -3,10 +3,15 @@ * genomic visualization. */ +/** + * --- Models --- + */ + var ToolParameterTree = Backbone.Model.extend({ defaults: { tool: null, - samples: 4 + params: null, + num_samples: 4 }, @@ -17,64 +22,189 @@ // Valid inputs for tree are number, select parameters. var tool = this.get('tool'), - samples = this.get('samples'), - inputs = tool.get('inputs').filter(function(input) { - return ( ['number', 'select'].indexOf(input.get('type')) !== -1 ); + num_samples = this.get('num_samples'), + params_samples = tool.get('inputs').map(function(input) { + return input.get_samples(num_samples); }), - inputs_names = _.map(inputs, function(i) { return i.get('name')}); - // Sample from all valid inputs. - sampling = _.map(inputs, function(input) { - var type = input.get('type'); - if (type === 'number') { - return d3.scale.linear().domain([input.get('min'), input.get('max')]).ticks(samples); - } - else if (type === 'select') { - return _.map(input.get('options'), function(option) { - return option[0]; - }); - } + filtered_params_samples = _.filter(params_samples, function(param_sample) { + return param_sample.get('samples').length !== 0; }); /** - * Returns tree data. + * Returns tree data. Params_sampling is an array of + * */ - var create_tree_data = function(param_names, param_settings, index) { - // Terminate when last parameter setting is reached. - if (param_settings.length - 1 === index) { - return _.map(param_settings[index], function(setting) { + var create_tree_data = function(params_samples, index) { + var + param_samples = params_samples[index], + param = param_samples.get('param'), + param_name = param.get('name'), + settings = param_samples.get('samples'); + + // Create leaves when last parameter setting is reached. + if (params_samples.length - 1 === index) { + return _.map(settings, function(setting) { return { - name: setting + name: param_name + '=' + setting, + param: param } }); } // Recurse to handle other parameters. - return _.map(param_settings[index], function(setting) { + return _.map(settings, function(setting) { return { - name: param_names[index] + ':' + setting, - children: create_tree_data(param_names, param_settings, index + 1) + name: param_name + '=' + setting, + param: param, + children: create_tree_data(filtered_params_samples, index + 1) } }); }; var tree_data = { name: 'Parameter Tree for ' + tool.get('name'), - children: create_tree_data(inputs_names, sampling, 0) + children: create_tree_data(filtered_params_samples, 0) }; // Set valid inputs, tree data for later use. - this.set('valid_inputs', inputs); + this.set('params', _.map(params_samples, function(s) { return s.get('param') })); this.set('tree_data', tree_data); } }); +/** + * Tile of rendered genomic data. + */ +var Tile = Backbone.Model.extend({ + defaults: { + track: null, + index: null, + region: null, + resolution: null, + data: null, + stale: null, + html_elt: null + }, + + initialize: function(options) { + + } + +}); + +/** + * A track in a genome browser. + */ +var Track = Backbone.Model.extend({ + defaults: { + dataset: null + } +}); + +var FeatureTrack = Track.extend({ + defaults: { + track: null + }, + + /** + * Draw FeatureTrack tile. + * @param result result from server + * @param cxt canvas context to draw on + * @param mode mode to draw in + * @param resolution view resolution + * @param region region to draw + * @param w_scale pixels per base + * @param ref_seq reference sequence data + */ + draw_tile: function(result, ctx, mode, resolution, region, w_scale, ref_seq) { + var track = this, + canvas = ctx.canvas, + tile_low = region.get('start'), + tile_high = region.get('end'), + min_height = 25, + left_offset = this.left_offset; + + // Drawing the summary tree (feature coverage histogram) + if (mode === "summary_tree" || mode === "Histogram") { + // Get summary tree data if necessary and set max if there is one. + if (result.dataset_type !== "summary_tree") { + var st_data = this.get_summary_tree_data(result.data, tile_low, tile_high, 200); + if (result.max) { + st_data.max = result.max; + } + result = st_data; + } + // Paint summary tree into canvas + var painter = new painters.SummaryTreePainter(result, tile_low, tile_high, this.prefs); + painter.draw(ctx, canvas.width, canvas.height, w_scale); + return new SummaryTreeTile(track, tile_index, resolution, canvas, result.data, result.max); + } + + // Handle row-by-row tracks + + // Preprocessing: filter features and determine whether all unfiltered features have been slotted. + var + filtered = [], + slots = this.slotters[w_scale].slots; + all_slotted = true; + if ( result.data ) { + var filters = this.filters_manager.filters; + for (var i = 0, len = result.data.length; i < len; i++) { + var feature = result.data[i]; + var hide_feature = false; + var filter; + for (var f = 0, flen = filters.length; f < flen; f++) { + filter = filters[f]; + filter.update_attrs(feature); + if (!filter.keep(feature)) { + hide_feature = true; + break; + } + } + if (!hide_feature) { + // Feature visible. + filtered.push(feature); + // Set flag if not slotted. + if ( !(feature[0] in slots) ) { + all_slotted = false; + } + } + } + } + + // Create painter. + var filter_alpha_scaler = (this.filters_manager.alpha_filter ? new FilterScaler(this.filters_manager.alpha_filter) : null); + var filter_height_scaler = (this.filters_manager.height_filter ? new FilterScaler(this.filters_manager.height_filter) : null); + // HACK: ref_seq will only be defined for ReadTracks, and only the ReadPainter accepts that argument + var painter = new (this.painter)(filtered, tile_low, tile_high, this.prefs, mode, filter_alpha_scaler, filter_height_scaler, ref_seq); + var feature_mapper = null; + + // console.log(( tile_low - this.view.low ) * w_scale, tile_index, w_scale); + ctx.fillStyle = this.prefs.block_color; + ctx.font = ctx.canvas.manager.default_font; + ctx.textAlign = "right"; + + if (result.data) { + // Draw features. + feature_mapper = painter.draw(ctx, canvas.width, canvas.height, w_scale, slots); + feature_mapper.translation = -left_offset; + } + + return new FeatureTrackTile(track, tile_index, resolution, canvas, result.data, w_scale, mode, result.message, all_slotted, feature_mapper); + } +}); + +/** + * --- Views --- + */ + var TileView = Backbone.View.extend({ }); var ToolParameterTreeView = Backbone.View.extend({ - className: 'paramamonster', + className: 'tool-parameter-tree', initialize: function(options) { this.model = options.model; @@ -84,12 +214,14 @@ var width = 960, height = 2000; + // Layout tree. var cluster = d3.layout.cluster() .size([height, width - 160]); var diagonal = d3.svg.diagonal() .projection(function(d) { return [d.y, d.x]; }); + // Set up vis element. var vis = d3.select(this.$el[0]) .append("svg") .attr("width", width) @@ -97,27 +229,32 @@ .append("g") .attr("transform", "translate(80, 0)"); - var nodes = cluster.nodes(this.model.get('tree_data')); + // Set up nodes, links. + var nodes = cluster.nodes(this.model.get('tree_data')); - var link = vis.selectAll("path.link") - .data(cluster.links(nodes)) - .enter().append("path") - .attr("class", "link") - .attr("d", diagonal); + var link = vis.selectAll("path.link") + .data(cluster.links(nodes)) + .enter().append("path") + .attr("class", "link") + .attr("d", diagonal); - var node = vis.selectAll("g.node") - .data(nodes) - .enter().append("g") - .attr("class", "node") - .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }) + var node = vis.selectAll("g.node") + .data(nodes) + .enter().append("g") + .attr("class", "node") + .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); + + node.on("click", function(d, i) { + console.log(d, i); + }); - node.append("circle") - .attr("r", 4.5); + node.append("circle") + .attr("r", 4.5); - node.append("text") - .attr("dx", function(d) { return d.children ? -8 : 8; }) - .attr("dy", 3) - .attr("text-anchor", function(d) { return d.children ? "end" : "start"; }) - .text(function(d) { return d.name; }); + node.append("text") + .attr("dx", function(d) { return d.children ? -8 : 8; }) + .attr("dy", 3) + .attr("text-anchor", function(d) { return d.children ? "end" : "start"; }) + .text(function(d) { return d.name; }); } }); \ No newline at end of file diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd static/scripts/viz/trackster.js --- a/static/scripts/viz/trackster.js +++ b/static/scripts/viz/trackster.js @@ -437,249 +437,6 @@ } /** - * Generic cache that handles key/value pairs. - */ -var Cache = function( num_elements ) { - this.num_elements = num_elements; - this.clear(); -}; -extend(Cache.prototype, { - get: function(key) { - var index = this.key_ary.indexOf(key); - if (index !== -1) { - if (this.obj_cache[key].stale) { - // Object is stale, so remove key and object. - this.key_ary.splice(index, 1); - delete this.obj_cache[key]; - } - else { - this.move_key_to_end(key, index); - } - } - return this.obj_cache[key]; - }, - set: function(key, value) { - if (!this.obj_cache[key]) { - if (this.key_ary.length >= this.num_elements) { - // Remove first element - var deleted_key = this.key_ary.shift(); - delete this.obj_cache[deleted_key]; - } - this.key_ary.push(key); - } - this.obj_cache[key] = value; - return value; - }, - // Move key to end of cache. Keys are removed from the front, so moving a key to the end - // delays the key's removal. - move_key_to_end: function(key, index) { - this.key_ary.splice(index, 1); - this.key_ary.push(key); - }, - clear: function() { - this.obj_cache = {}; - this.key_ary = []; - }, - // Returns the number of elements in the cache. - size: function() { - return this.key_ary.length; - } -}); - -/** - * Data manager for a track. - */ -var DataManager = function(num_elements, track) { - Cache.call(this, num_elements); - this.track = track; -}; -extend(DataManager.prototype, Cache.prototype, { - /** - * Load data from server; returns AJAX object so that use of Deferred is possible. - */ - load_data: function(low, high, mode, resolution, extra_params) { - // Setup data request params. - var - chrom = this.track.view.chrom, - params = {"chrom": chrom, "low": low, "high": high, "mode": mode, - "resolution": resolution, "dataset_id" : this.track.dataset_id, - "hda_ldda": this.track.hda_ldda}; - $.extend(params, extra_params); - - // Add track filters to params. - if (this.track.filters_manager) { - var filter_names = []; - var filters = this.track.filters_manager.filters; - for (var i = 0; i < filters.length; i++) { - filter_names.push(filters[i].name); - } - params.filter_cols = JSON.stringify(filter_names); - } - - // Do request. - var manager = this; - return $.getJSON(this.track.data_url, params, function (result) { - manager.set_data(low, high, result); - }); - }, - /** - * Get track data. - */ - get_data: function(low, high, mode, resolution, extra_params) { - // Debugging: - //console.log("get_data", low, high, mode); - /* - console.log("cache contents:") - for (var i = 0; i < this.key_ary.length; i++) { - console.log("\t", this.key_ary[i], this.obj_cache[this.key_ary[i]]); - } - */ - - // Look for entry and return if it's a deferred or if data available is compatible with mode. - var entry = this.get(low, high); - if ( entry && - ( is_deferred(entry) || this.track.data_and_mode_compatible(entry, mode) ) ) { - return entry; - } - - // - // Look in cache for data that can be used. Data can be reused if it - // has the requested data and is not summary tree and has details. - // TODO: this logic could be improved if the visualization knew whether - // the data was "index" or "data." - // - var key, split_key, entry_low, entry_high, mode, entry; - for (var i = 0; i < this.key_ary.length; i++) { - key = this.key_ary[i]; - split_key = this.split_key(key); - entry_low = split_key[0]; - entry_high = split_key[1]; - - if (low >= entry_low && high <= entry_high) { - // This entry has data in the requested range. Return if data - // is compatible and can be subsetted. - var entry = this.obj_cache[key]; - if ( is_deferred(entry) || - ( this.track.data_and_mode_compatible(entry, mode) && this.track.can_subset(entry) ) ) { - this.move_key_to_end(key, i); - return entry; - } - } - } - - // Load data from server. The deferred is immediately saved until the - // data is ready, it then replaces itself with the actual data. - entry = this.load_data(low, high, mode, resolution, extra_params); - this.set_data(low, high, entry); - return entry; - }, - /** "Deep" data request; used as a parameter for DataManager.get_more_data() */ - DEEP_DATA_REQ: "deep", - /** "Broad" data request; used as a parameter for DataManager.get_more_data() */ - BROAD_DATA_REQ: "breadth", - /** - * Gets more data for a region using either a depth-first or a breadth-first approach. - */ - get_more_data: function(low, high, mode, resolution, extra_params, req_type) { - // - // Get current data from cache and mark as stale. - // - var cur_data = this.get(low, high); - if ( !(cur_data && this.track.data_and_mode_compatible(cur_data, mode)) ) { - console.log("ERROR: no current data for: ", this.track, low, high, mode, resolution, extra_params); - return; - } - cur_data.stale = true; - - // - // Set parameters based on request type. - // - var query_low = low; - if (req_type === this.DEEP_DATA_REQ) { - // Use same interval but set start_val to skip data that's already in cur_data. - $.extend(extra_params, {start_val: cur_data.data.length + 1}); - } - else if (req_type === this.BROAD_DATA_REQ) { - // To get past an area of extreme feature depth, set query low to be after either - // (a) the maximum high or HACK/FIXME (b) the end of the last feature returned. - query_low = (cur_data.max_high ? cur_data.max_high : cur_data.data[cur_data.data.length - 1][2]) + 1; - } - - // - // Get additional data, append to current data, and set new data. Use a custom deferred object - // to signal when new data is available. - // - var - data_manager = this, - new_data_request = this.load_data(query_low, high, mode, resolution, extra_params) - new_data_available = $.Deferred(); - // load_data sets cache to new_data_request, but use custom deferred object so that signal and data - // is all data, not just new data. - this.set_data(low, high, new_data_available); - $.when(new_data_request).then(function(result) { - // Update data and message. - if (result.data) { - result.data = cur_data.data.concat(result.data); - if (result.max_low) { - result.max_low = cur_data.max_low; - } - if (result.message) { - // HACK: replace number in message with current data length. Works but is ugly. - result.message = result.message.replace(/[0-9]+/, result.data.length); - } - } - data_manager.set_data(low, high, result); - new_data_available.resolve(result); - }); - return new_data_available; - }, - /** - * Get data from the cache. - */ - get: function(low, high) { - return Cache.prototype.get.call( this, this.gen_key(low, high) ); - }, - /** - * Sets data in the cache. - */ - set_data: function(low, high, result) { - return this.set(this.gen_key(low, high), result); - }, - /** - * Generate key for cache. - */ - // TODO: use chrom in key so that (a) data is not thrown away when changing chroms and (b) - // manager does not need to be cleared when changing chroms. - // TODO: use resolution in key b/c summary tree data is dependent on resolution -- is this - // necessary, i.e. will resolution change but not low/high/mode? - gen_key: function(low, high) { - var key = low + "_" + high; - return key; - }, - /** - * Split key from cache into array with format [low, high] - */ - split_key: function(key) { - return key.split("_"); - } -}); - -var ReferenceTrackDataManager = function(num_elements, track, subset) { - DataManager.call(this, num_elements, track, subset); -}; -extend(ReferenceTrackDataManager.prototype, DataManager.prototype, Cache.prototype, { - get: DataManager.prototype.get, - load_data: function(low, high, mode, resolution, extra_params) { - if (resolution > 1) { - // Now that data is pre-fetched before draw, we don't load reference tracks - // unless it's at the bottom level. - return { data: null }; - } - return DataManager.prototype.load_data.call(this, low, high, mode, resolution, extra_params); - } -}); - -/** * Drawables hierarchy: * * Drawable @@ -3082,7 +2839,11 @@ .css({'height': ERROR_PADDING-1, 'width': canvas.width}).prependTo(this.html_elt); // Handle message; only message currently is that only the first N elements are displayed. - var + var tile_region = new GenomeRegion({ + chrom: track.view.chrom, + start: this.low, + end: this.high + }), num_features = data.length, more_down_icon = $("<a href='javascript:void(0);'/>").addClass("icon more-down") .attr("title", "For speed, only the first " + num_features + " features in this region were obtained from server. Click to get more data including depth") @@ -3095,7 +2856,7 @@ more_down_icon.click(function() { // Mark tile as stale, request more data, and redraw track. tile.stale = true; - track.data_manager.get_more_data(tile.low, tile.high, track.mode, tile.resolution, {}, track.data_manager.DEEP_DATA_REQ); + track.data_manager.get_more_data(tile_region, track.mode, tile.resolution, {}, track.data_manager.DEEP_DATA_REQ); $(".tipsy").hide(); track.request_draw(true); }).dblclick(function(e) { @@ -3106,7 +2867,7 @@ more_across_icon.click(function() { // Mark tile as stale, request more data, and redraw track. tile.stale = true; - track.data_manager.get_more_data(tile.low, tile.high, track.mode, tile.resolution, {}, track.data_manager.BROAD_DATA_REQ); + track.data_manager.get_more_data(tile_region, track.mode, tile.resolution, {}, track.data_manager.BROAD_DATA_REQ); $(".tipsy").hide(); track.request_draw(true); }).dblclick(function(e) { @@ -3245,7 +3006,20 @@ this.data_url_extra_params = {} this.data_query_wait = ('data_query_wait' in obj_dict ? obj_dict.data_query_wait : DEFAULT_DATA_QUERY_WAIT); this.dataset_check_url = converted_datasets_state_url; - this.data_manager = ('data_manager' in obj_dict ? obj_dict.data_manager : new DataManager(DATA_CACHE_SIZE, this)); + + // A little ugly creating data manager right now due to transition to Backbone-based objects. + var dataset = new Dataset({ + id: obj_dict.dataset_id, + hda_ldda: obj_dict.hda_ldda + }); + this.data_manager = ('data_manager' in obj_dict ? + obj_dict.data_manager : + new GenomeDataManager({ + dataset: dataset, + data_url: default_data_url, + data_mode_compatible: this.data_and_mode_compatible, + can_subset: this.can_subset, + })); // Height attributes: min height, max height, and visible height. this.min_height_px = 16; @@ -3560,6 +3334,9 @@ // Attribute init. this.filters_manager = new FiltersManager(this, ('filters' in obj_dict ? obj_dict.filters : null)); + // HACK: set filters manager for data manager. + // FIXME: prolly need function to set filters and update data_manager reference. + this.data_manager.set('filters_manager', this.filters_manager); this.filters_available = false; this.tool = ('tool' in obj_dict && obj_dict.tool ? new Tool(this, obj_dict.tool, obj_dict.tool_state) : null); this.tile_cache = new Cache(TILE_CACHE_SIZE); @@ -3810,15 +3587,18 @@ var track = this, key = this._gen_tile_cache_key(width, w_scale, tile_index), tile_bounds = this._get_tile_bounds(tile_index, resolution), - tile_low = tile_bounds[0], - tile_high = tile_bounds[1]; + region = new GenomeRegion({ + chrom: this.view.chrom, + start: tile_bounds[0], + end: tile_bounds[1] + }); // Init kwargs if necessary to avoid having to check if kwargs defined. if (!kwargs) { kwargs = {}; } // Check tile cache, if found show existing tile in correct position - var tile = (force ? undefined : track.tile_cache.get(key)); - if (tile) { + var tile = (force ? undefined : track.tile_cache.get_elt(key)); + if (tile) { track.show_tile(tile, parent_element, w_scale); return tile; } @@ -3827,7 +3607,7 @@ var can_draw_now = true // Get the track data, maybe a deferred - var tile_data = track.data_manager.get_data( tile_low, tile_high, track.mode, resolution, track.data_url_extra_params ); + var tile_data = track.data_manager.get_data( region, track.mode, resolution, track.data_url_extra_params ); if ( is_deferred( tile_data ) ) { can_draw_now = false; } @@ -3835,7 +3615,7 @@ // Get seq data if needed, maybe a deferred var seq_data; if ( view.reference_track && w_scale > view.canvas_manager.char_width_px ) { - seq_data = view.reference_track.data_manager.get_data(tile_low, tile_high, track.mode, resolution, view.reference_track.data_url_extra_params) + seq_data = view.reference_track.data_manager.get_data(region, track.mode, resolution, view.reference_track.data_url_extra_params) if ( is_deferred( seq_data ) ) { can_draw_now = false; } @@ -3857,9 +3637,8 @@ // Draw canvas. var canvas = track.view.canvas_manager.new_canvas(), - tile_bounds = track._get_tile_bounds(tile_index, resolution), - tile_low = tile_bounds[0], - tile_high = tile_bounds[1], + tile_low = region.get('start'), + tile_high = region.get('end'), width = Math.ceil( (tile_high - tile_low) * w_scale ) + track.left_offset, height = track.get_canvas_height(tile_data, mode, w_scale, width); @@ -3871,7 +3650,7 @@ // Don't cache, show if no tile. if (tile !== undefined) { - track.tile_cache.set(key, tile); + track.tile_cache.set_elt(key, tile); track.show_tile(tile, parent_element, w_scale); } return tile; @@ -4158,7 +3937,7 @@ if (!kwargs) { kwargs = {}; } // Check tile cache, if found show existing tile in correct position - var tile = (force ? undefined : track.tile_cache.get(key)); + var tile = (force ? undefined : track.tile_cache.get_elt(key)); if (tile) { track.show_tile(tile, parent_element, w_scale); return tile; @@ -4246,7 +4025,7 @@ } // Don't cache, show if no tile. - this.tile_cache.set(key, tile); + this.tile_cache.set_elt(key, tile); this.show_tile(tile, parent_element, w_scale); return tile; } @@ -4353,7 +4132,9 @@ this.content_div.css("border", "none"); this.data_url = reference_url; this.data_url_extra_params = {dbkey: view.dbkey}; - this.data_manager = new ReferenceTrackDataManager(DATA_CACHE_SIZE, this, false); + this.data_manager = new ReferenceTrackDataManager({ + data_url: reference_url + }); this.hide_contents(); }; extend(ReferenceTrack.prototype, Drawable.prototype, TiledTrack.prototype, { diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd static/scripts/viz/visualization.js --- a/static/scripts/viz/visualization.js +++ b/static/scripts/viz/visualization.js @@ -6,9 +6,271 @@ * and models can be used without views. */ +// --------- Models --------- + /** - * -- Models -- + * Generic cache that handles key/value pairs. + */ +var Cache = Backbone.Model.extend({ + defaults: { + num_elements: 20, + obj_cache: {}, + key_ary: [] + }, + + get_elt: function(key) { + var obj_cache = this.attributes.obj_cache, + key_ary = this.attributes.key_ary, + index = key_ary.indexOf(key); + if (index !== -1) { + if (obj_cache[key].stale) { + // Object is stale, so remove key and object. + key_ary.splice(index, 1); + delete obj_cache[key]; + } + else { + this.move_key_to_end(key, index); + } + } + return obj_cache[key]; + }, + + set_elt: function(key, value) { + var obj_cache = this.attributes.obj_cache, + key_ary = this.attributes.key_ary, + num_elements = this.attributes.num_elements; + if (!obj_cache[key]) { + if (key_ary.length >= num_elements) { + // Remove first element + var deleted_key = key_ary.shift(); + delete obj_cache[deleted_key]; + } + key_ary.push(key); + } + obj_cache[key] = value; + return value; + }, + + // Move key to end of cache. Keys are removed from the front, so moving a key to the end + // delays the key's removal. + move_key_to_end: function(key, index) { + this.attributes.key_ary.splice(index, 1); + this.attributes.key_ary.push(key); + }, + + clear: function() { + this.attributes.obj_cache = {}; + this.attributes.key_ary = []; + }, + + // Returns the number of elements in the cache. + size: function() { + return this.attributes.key_ary.length; + } +}); + +/** + * Data manager for genomic data. Data is connected to and queryable by genomic regions. */ +var GenomeDataManager = Cache.extend({ + defaults: _.extend({}, Cache.prototype.defaults, { + dataset: null, + filters_manager: null, + data_url: null, + data_mode_compatible: function(entry, mode) { return true; }, + can_subset: function(entry) { return false; } + }), + + /** + * Load data from server; returns AJAX object so that use of Deferred is possible. + */ + load_data: function(region, mode, resolution, extra_params) { + // Setup data request params. + var params = { + "chrom": region.get('chrom'), + "low": region.get('start'), + "high": region.get('end'), + "mode": mode, + "resolution": resolution + }; + dataset = this.get('dataset'); + + // ReferenceDataManager does not have dataset. + if (dataset) { + params['dataset_id'] = dataset.id; + params['hda_ldda'] = dataset.get('hda_ldda'); + } + + $.extend(params, extra_params); + + // Add track filters to params. + var filters_manager = this.get('filters_manager'); + if (filters_manager) { + var filter_names = []; + var filters = filters_manager.filters; + for (var i = 0; i < filters.length; i++) { + filter_names.push(filters[i].name); + } + params.filter_cols = JSON.stringify(filter_names); + } + + // Do request. + var manager = this; + return $.getJSON(this.get('data_url'), params, function (result) { + manager.set_data(region, result); + }); + }, + + /** + * Get data from dataset. + */ + get_data: function(region, mode, resolution, extra_params) { + // Debugging: + //console.log("get_data", low, high, mode); + /* + console.log("cache contents:") + for (var i = 0; i < this.key_ary.length; i++) { + console.log("\t", this.key_ary[i], this.obj_cache[this.key_ary[i]]); + } + */ + + // Look for entry and return if it's a deferred or if data available is compatible with mode. + var entry = this.get_elt(region); + if ( entry && + ( is_deferred(entry) || this.get('data_mode_compatible')(entry, mode) ) ) { + return entry; + } + + // + // Look in cache for data that can be used. Data can be reused if it + // has the requested data and is not summary tree and has details. + // TODO: this logic could be improved if the visualization knew whether + // the data was "index" or "data." + // + var + key_ary = this.get('key_ary'), + obj_cache = this.get('obj_cache'), + key, region, entry_region, mode, entry; + for (var i = 0; i < key_ary.length; i++) { + entry_region = new GenomeRegion(key_ary[i]); + + if (entry_region.contains(region)) { + // This entry has data in the requested range. Return if data + // is compatible and can be subsetted. + var entry = obj_cache[key]; + if ( is_deferred(entry) || + ( this.get('data_mode_compatible')(entry, mode) && this.get('can_subset')(entry) ) ) { + this.move_key_to_end(key, i); + return entry; + } + } + } + + // Load data from server. The deferred is immediately saved until the + // data is ready, it then replaces itself with the actual data. + entry = this.load_data(region, mode, resolution, extra_params); + this.set_data(region, entry); + return entry; + }, + + /** + * Alias for set_elt for readbility. + */ + set_data: function(region, entry) { + this.set_elt(region, entry); + }, + + /** + + /** "Deep" data request; used as a parameter for DataManager.get_more_data() */ + DEEP_DATA_REQ: "deep", + + /** "Broad" data request; used as a parameter for DataManager.get_more_data() */ + BROAD_DATA_REQ: "breadth", + + /** + * Gets more data for a region using either a depth-first or a breadth-first approach. + */ + get_more_data: function(region, mode, resolution, extra_params, req_type) { + // + // Get current data from cache and mark as stale. + // + var cur_data = this.get_elt(region); + if ( !(cur_data && this.get('data_mode_compatible')(cur_data, mode)) ) { + console.log("ERROR: no current data for: ", dataset, region.toString(), mode, resolution, extra_params); + return; + } + cur_data.stale = true; + + // + // Set parameters based on request type. + // + var query_low = region.get('start'); + if (req_type === this.DEEP_DATA_REQ) { + // Use same interval but set start_val to skip data that's already in cur_data. + $.extend(extra_params, {start_val: cur_data.data.length + 1}); + } + else if (req_type === this.BROAD_DATA_REQ) { + // To get past an area of extreme feature depth, set query low to be after either + // (a) the maximum high or HACK/FIXME (b) the end of the last feature returned. + query_low = (cur_data.max_high ? cur_data.max_high : cur_data.data[cur_data.data.length - 1][2]) + 1; + } + var query_region = region.copy().set('start', query_low); + + // + // Get additional data, append to current data, and set new data. Use a custom deferred object + // to signal when new data is available. + // + var + data_manager = this, + new_data_request = this.load_data(query_region, mode, resolution, extra_params) + new_data_available = $.Deferred(); + // load_data sets cache to new_data_request, but use custom deferred object so that signal and data + // is all data, not just new data. + this.set_data(region, new_data_available); + $.when(new_data_request).then(function(result) { + // Update data and message. + if (result.data) { + result.data = cur_data.data.concat(result.data); + if (result.max_low) { + result.max_low = cur_data.max_low; + } + if (result.message) { + // HACK: replace number in message with current data length. Works but is ugly. + result.message = result.message.replace(/[0-9]+/, result.data.length); + } + } + data_manager.set_data(region, result); + new_data_available.resolve(result); + }); + return new_data_available; + }, + + /** + * Get data from the cache. + */ + get_elt: function(region) { + return Cache.prototype.get_elt.call(this, region.toString()); + }, + + /** + * Sets data in the cache. + */ + set_elt: function(region, result) { + return Cache.prototype.set_elt.call(this, region.toString(), result); + } +}); + +var ReferenceTrackDataManager = GenomeDataManager.extend({ + load_data: function(low, high, mode, resolution, extra_params) { + if (resolution > 1) { + // Now that data is pre-fetched before draw, we don't load reference tracks + // unless it's at the bottom level. + return { data: null }; + } + return GenomeDataManager.prototype.load_data.call(this, low, high, mode, resolution, extra_params); + } +}); /** * A genome build. @@ -26,13 +288,117 @@ }); /** + * A genomic region. + */ +var GenomeRegion = Backbone.Model.extend({ + defaults: { + chrom: null, + start: 0, + end: 0, + DIF_CHROMS: 1000, + BEFORE: 1001, + CONTAINS: 1002, + OVERLAP_START: 1003, + OVERLAP_END: 1004, + CONTAINED_BY: 1005, + AFTER: 1006 + }, + + /** + * as_str attribute using the format chrom:start-end can be + * used to set object's attributes. + */ + initialize: function(options) { + if (!this.get('chrom') && !this.get('start') && + !this.get('end') && 'as_str' in options) { + var pieces = options.as_str.split(':'), + chrom = pieces[0], + pieces = pieces.split('-'), + start = pieces[0], + end = pieces[1]; + this.set('chrom', chrom); + this.set('start', start); + this.set('end', end); + } + }, + + copy: function() { + return new GenomeRegion({ + chrom: this.get('chrom'), + start: this.get('start'), + end: this.get('end') + }); + }, + + /** Returns region in canonical form chrom:start-end */ + toString: function() { + return this.get('chrom') + ":" + this.get('start') + "-" + this.get('end'); + }, + + /** + * Compute the type of overlap between this region and another region. The overlap is computed relative to the given/second region; + * hence, OVERLAP_START indicates that the first region overlaps the start (but not the end) of the second region. + */ + compute_overlap: function(a_region) { + var first_chrom = this.get('chrom'), second_chrom = a_region.get('chrom'), + first_start = this.get('start'), second_start = a_region.get('start'), + first_end = this.get('end'), second_end = a_region.get('end'), + overlap; + + // Look at chroms. + if (first_chrom && second_chrom && first_chrom !== second_chrom) { + return this.get('DIF_CHROMS'); + } + + // Look at regions. + if (first_start < second_start) { + if (first_end < second_start) { + overlap = this.get('BEFORE'); + } + else if (first_end <= second_end) { + overlap = this.get('OVERLAP_START'); + } + else { // first_end > second_end + overlap = this.get('CONTAINS'); + } + } + else { // first_start >= second_start + if (first_start > second_end) { + overlap = this.get('AFTER'); + } + else if (first_end <= second_end) { + overlap = this.get('CONTAINED_BY'); + } + else { + overlap = this.get('OVERLAP_END'); + } + } + + return overlap; + }, + + /** + * Returns true if this region contains a given region. + */ + contains: function(a_region) { + return this.compute_overlap(a_region) === this.get('CONTAINS'); + }, + + /** + * Returns true if regions overlap. + */ + overlaps: function(a_region) { + return _.intersection( [this.compute_overlap(a_region)], + [this.get('DIF_CHROMS'), this.get('BEFORE'), this.get('AFTER')] ).length === 0; + } +}); + +/** * A genome browser bookmark. */ var BrowserBookmark = Backbone.Model.extend({ defaults: { - chrom: null, - start: 0, - end: 0, + region: null, note: "" } }); @@ -100,7 +466,7 @@ id: "", type: "", name: "", - hda_ldda: "" + hda_ldda: "" } }); @@ -232,7 +598,7 @@ var chrom_arc = chrom_info[0], chrom_data = chrom_info[1]; return arcs_layout.chrom_data_layout(chrom_arc, chrom_data, radius_start, radius_start + dataset_arc_height, dataset_max); - }); + }); // -- Render viz. -- diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd templates/tracks/browser.mako --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -42,7 +42,7 @@ <script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script><![endif]--> -${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.event.hover","jquery.mousewheel", "jquery.autocomplete", "viz/trackster", "viz/trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "viz/visualization" )} +${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.event.hover","jquery.mousewheel", "jquery.autocomplete", "viz/visualization", "viz/trackster", "viz/trackster_ui", "jquery.ui.sortable.slider", "farbtastic" )} <script type="text/javascript"> // diff -r 8872e75d8d4321c491ee43aca91d149362585ca6 -r 37352829fedd8ef5df912281b91471302cd6e5dd templates/visualization/paramamonster.mako --- a/templates/visualization/paramamonster.mako +++ b/templates/visualization/paramamonster.mako @@ -46,7 +46,7 @@ tool_param_tree_view = new ToolParameterTreeView({ model: tool_param_tree }); tool_param_tree_view.render(); - $('#vis').append(tool_param_tree_view.$el); + $('#param-tree').append(tool_param_tree_view.$el); }); </script></%def> @@ -58,5 +58,8 @@ </div><div style="clear: both"></div></div> - <div id="vis" class="unified-panel-body"></div> + <div class="unified-panel-body"> + <div id="param-tree"></div> + <div id="tile-view"></div> + </div></%def> 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.