<commit_before>(function(){
    'use strict';

    angular
    .module('lolTot.singup')
    .controller('SingupController', SingupController);

    function SingupController(
        $log ,$timeout, leagues, maxPoints, _, Summoner, Mailchimp,
        $mdDialog
    ) {
        var vm = this;

        vm.getSummoner = getSummoner;
        vm.summoners =[];
        vm.mailchimp = {};
        vm.summonersForm = [
            {
                profileIconId: 657
            },
            {
                profileIconId: 658
            },
            {
                profileIconId: 659
            },
            {
                profileIconId: 660
            },
            {
                profileIconId: 661
            }
        ];

        vm.getTop = function(){
            return vm.summoners[4];
        };

        vm.validator = {
            maxPoints: maxPoints,
            noRepeat: function(){
                var isUndefined = 0;
                _.each(vm.summoners, function(summoner){
                    if(!summoner){
                        isUndefined++;
                    }
                });

                return (_.uniq(vm.summoners).length === 5) && !isUndefined ;
            },
            totalPoints: function(){
                var totalPoints = 0;

                _.each(vm.summonersForm, function(summoner){
                    if(summoner.data && (summoner.data.summonerLevel < 30)){
                        totalPoints += leagues.noob;
                    }
                    else if(summoner.data && (summoner.data.league === 'unranked')){
                        totalPoints += leagues.unrank;
                    }
                    else if(summoner.data && summoner.data.league[0].tier){
                        var tier = summoner.data.league[0].tier.toLowerCase();
                        var division = summoner.data.league[0].entries[0].division.toLowerCase();

                        totalPoints += leagues[tier][division];
                    }

                    totalPoints += 0;
                });

                return totalPoints;
            },
            leaguePoints: function(){

                return this.totalPoints() <= maxPoints;

            },
            all: function(){
                return this.noRepeat() && this.leaguePoints();
            }
        };

        vm.subscribeTeam = function(subscribe){
            subscribe.TOP = vm.summoners[0];
            subscribe.JUNGLE = vm.summoners[1];
            subscribe.MID = vm.summoners[2];
            subscribe.ADC = vm.summoners[3];
            subscribe.SUPPORT = vm.summoners[4];

            Mailchimp.send(subscribe).then(function(data){
                vm.mailchimp = data;
            });
        };

        vm.help = function($event){
            console.log('help');
            $mdDialog.show({
                controller: 'HelpController',
                templateUrl: 'views/singup/help.tpl.html',
                parent: angular.element(document.body),
                targetEvent: $event,
            });
        };

        function getSummoner (summoner, index){
            Summoner.get(summoner).then(function(data){
                Summoner.getLeague(data.id, true)
                .then(function(dataLeague){
                    data.league = dataLeague;
                    vm.summonersForm[index].data = data;
                    vm.summoners[index] = data.name;
                })
                .catch(function(error){
                    if(error.status === 404){
                        data.league = 'unranked';
                        vm.summonersForm[index].data = data;
                        vm.summoners[index] = data.name;
                    }
                });
            }).catch(function(){
                if(vm.summonersForm[index] && vm.summonersForm[index].data){
                    delete vm.summonersForm[index].data;
                }
            });
        }
    }
})();
<commit_msg>add controller as to mdDialog<commit_after>(function(){
    'use strict';

    angular
    .module('lolTot.singup')
    .controller('SingupController', SingupController);

    function SingupController(
        $log ,$timeout, leagues, maxPoints, _, Summoner, Mailchimp,
        $mdDialog
    ) {
        var vm = this;

        vm.getSummoner = getSummoner;
        vm.summoners =[];
        vm.mailchimp = {};
        vm.summonersForm = [
            {
                profileIconId: 657
            },
            {
                profileIconId: 658
            },
            {
                profileIconId: 659
            },
            {
                profileIconId: 660
            },
            {
                profileIconId: 661
            }
        ];

        vm.getTop = function(){
            return vm.summoners[4];
        };

        vm.validator = {
            maxPoints: maxPoints,
            noRepeat: function(){
                var isUndefined = 0;
                _.each(vm.summoners, function(summoner){
                    if(!summoner){
                        isUndefined++;
                    }
                });

                return (_.uniq(vm.summoners).length === 5) && !isUndefined ;
            },
            totalPoints: function(){
                var totalPoints = 0;

                _.each(vm.summonersForm, function(summoner){
                    if(summoner.data && (summoner.data.summonerLevel < 30)){
                        totalPoints += leagues.noob;
                    }
                    else if(summoner.data && (summoner.data.league === 'unranked')){
                        totalPoints += leagues.unrank;
                    }
                    else if(summoner.data && summoner.data.league[0].tier){
                        var tier = summoner.data.league[0].tier.toLowerCase();
                        var division = summoner.data.league[0].entries[0].division.toLowerCase();

                        totalPoints += leagues[tier][division];
                    }

                    totalPoints += 0;
                });

                return totalPoints;
            },
            leaguePoints: function(){

                return this.totalPoints() <= maxPoints;

            },
            all: function(){
                return this.noRepeat() && this.leaguePoints();
            }
        };

        vm.subscribeTeam = function(subscribe){
            subscribe.TOP = vm.summoners[0];
            subscribe.JUNGLE = vm.summoners[1];
            subscribe.MID = vm.summoners[2];
            subscribe.ADC = vm.summoners[3];
            subscribe.SUPPORT = vm.summoners[4];

            Mailchimp.send(subscribe).then(function(data){
                vm.mailchimp = data;
            });
        };

        vm.help = function($event){
            console.log('help');
            $mdDialog.show({
                controller: 'HelpController',
                controllerAs: 'vmd',
                templateUrl: 'views/singup/help.tpl.html',
                parent: angular.element(document.body),
                targetEvent: $event,
            });
        };

        function getSummoner (summoner, index){
            Summoner.get(summoner).then(function(data){
                Summoner.getLeague(data.id, true)
                .then(function(dataLeague){
                    data.league = dataLeague;
                    vm.summonersForm[index].data = data;
                    vm.summoners[index] = data.name;
                })
                .catch(function(error){
                    if(error.status === 404){
                        data.league = 'unranked';
                        vm.summonersForm[index].data = data;
                        vm.summoners[index] = data.name;
                    }
                });
            }).catch(function(){
                if(vm.summonersForm[index] && vm.summonersForm[index].data){
                    delete vm.summonersForm[index].data;
                }
            });
        }
    }
})();
<|endoftext|>


<commit_before>var frequencies, pivots;
var gene = 'nuc'
/**
 * for each node, calculate the derivative of the frequency tranjectory. if none exists, copy parent
**/
function calcDfreq(node, freq_ii){
	if (typeof node.children != "undefined") {
		for (var i1=0; i1<node.children.length; i1++) {
			if (typeof node.children[i1].freq != "undefined") {
				if (node.children[i1].freq["global"] != "undefined"){
					var tmp_freq = node.children[i1].freq["global"]
					node.children[i1].dfreq = 0.5*(tmp_freq[freq_ii] - tmp_freq[freq_ii-dfreq_dn])/(tmp_freq[freq_ii] + tmp_freq[freq_ii-dfreq_dn] + 0.1);
				} else {
					node.children[i1].dfreq = node.dfreq;
				}
			}
			calcDfreq(node.children[i1], freq_ii);
		}
	}
};
function parse_gt_string(gt){
	mutations = [];
	gt.split(',').map( function (d) {
		var tmp = d.split(/[\s//]/); //FIXME: make more inclusive
		var region;
		var positions = [];
		for (var i=0; i<tmp.length; i++){
			if (contains(["EU","NA","AS","OC"], tmp[i])){
				region = tmp[i];
			}else{
				if (tmp[i].length>0) positions.push(tmp[i]);
			}
		}
		if (typeof region == "undefined") region="global";
		// sort of this is a multi mutation genotype
		if (positions.length>1){
			positions.sort(function (a,b){
				return parseInt(a.substring(0,a.length-1)) - parseInt(b.substring(0,b.length-1));
			});
		}
		mutations.push([region, positions.join('/')]);
	});
	return mutations;
};

/**
loops over all genotypes from a certain region and sums the frequency contributions
of the genotype matches at the specified positions
**/
function get_frequencies(region, gt){
	var freq = [];
	for (var pi=0; pi<pivots.length; pi++){freq[freq.length]=0;}
	if (frequencies["clades"][region][gt.toLowerCase()]!=undefined) {
		console.log(gt+" found as clade");
		for (var pi=0; pi<freq.length; pi++){
			freq[pi]+=frequencies["clades"][region][gt.toLowerCase()][pi];
		}
	}
	else if ((typeof frequencies["genotypes"] !="undefined") && (frequencies["genotypes"][region][gt]!=undefined)) {
		console.log(gt+" found as genotype");
		for (var pi=0; pi<freq.length; pi++){
			freq[pi]+=frequencies["genotypes"][region][gt][pi];
		}
	}else if (frequencies["mutations"][region][gt]!=undefined) {
		console.log(gt+" found as mutation");
		for (var pi=0; pi<freq.length; pi++){
			freq[pi]+=frequencies["mutations"][region][gt][pi];
		}
	}
	return freq.map(function (d) {return Math.round(d*100)/100;});
};

function make_gt_chart(gt){
	var tmp_data = [];
	var tmp_trace = ['x'];
	var tmp_colors = {};
	tmp_data.push(tmp_trace.concat(pivots));
	gt.forEach(function (d, i) {
		var region = d[0];
		var genotype = d[1];
		var freq = get_frequencies(region, genotype);
		if (d3.max(freq)>0) {
			var tmp_trace = genotype.toString().replace(/,/g, ', ');
			if (region != "global") {
				tmp_trace = region + ':\t' + tmp_trace;
			}
			tmp_data.push([tmp_trace].concat(freq));
			tmp_colors[tmp_trace] = genotypeColors[i];
		}
	});
	console.log(tmp_colors);
	gt_chart.load({
       	columns: tmp_data,
       	unload: true
	});
	gt_chart.data.colors(tmp_colors);
}

function addClade(d) {
	if (typeof gt_chart != "undefined"){
		var plot_data = [['x'].concat(rootNode["pivots"])];
		var reg = "global";
		if ((typeof d.target.freq !="undefined" )&&(d.target.freq[reg] != "undefined")){
			plot_data[plot_data.length] = [reg].concat(d.target.freq[reg]);
		}
		if (plot_data.length > 1) {
			if (plot_data[1][0] == "global") {
				plot_data[1][0] = "clade";
			}
		}
		gt_chart.load({
	       	columns: plot_data
		});
	}
}

function removeClade() {
	if (typeof gt_chart != "undefined"){
		gt_chart.unload({
	       	ids: ["clade"]
		});
	}
}

width = parseInt(d3.select(".freqplot-container").style("width"), 10);
height = 250;
var position = "inset";

var gt_chart = c3.generate({
	bindto: '#gtchart',
	size: {width: width-10, height: height},
	onresize: function() {
		width = parseInt(d3.select(".freqplot-container").style("width"), 10);
		height = 250;
		gt_chart.resize({height: height, width: width});
	},
	legend: {
		position: position,
		inset: {
    		anchor: 'top-right',
    		x: 10,
    		y: -15,
    		step: 1
    	}
	},
  	color: {
        pattern: genotypeColors
    },
	axis: {
		y: {
			label: {
				text: 'frequency',
				position: 'outer-middle'
			},
			tick: {
				values: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0],
				outer: false
			},
            min: 0,
			max: 1
		},
		x: {
			label: {
				text: 'time',
				position: 'outer-center'
			},
			tick: {
				values: time_ticks,
				outer: false
			}
		}
	},
	data: {
		x: 'x',
		columns: [],
	}
});

function contains(arr, obj) {
    for(var i=0; i<arr.length; i++) {
        if (arr[i] == obj) return true;
    }
}

d3.json(path + file_prefix + "frequencies.json", function(error, json){
	console.log(error);
	frequencies = json;
	pivots= frequencies["mutations"]["global"]["pivots"].map(function (d) {return Math.round(parseFloat(d)*100)/100;});
	var ticks = [Math.round(pivots[0])];
	var tick_step = Math.round((pivots[pivots.length-1]-pivots[0])/6*10)/10;
	while (ticks[ticks.length-1]<pivots[pivots.length-1]){
		ticks.push(Math.round((ticks[ticks.length-1]+tick_step)*10)/10);
	}
	//gt_chart.axis.x.values = ticks;
	/**
		parses a genotype string into region and positions
	**/

	var chart_data = {}
	var chart_types = {}
	var chart_xaxis = {}
	var ymin = 0;
	if (typeof genome_annotation !== 'undefined') {
		for (x in genome_annotation){
			chart_data['x'+x+'anno'] = genome_annotation[x][1];
			chart_data[x+'anno'] = genome_annotation[x][0].map(function(d) {return -0.1*d;});
			if (ymin>chart_data[x+'anno'][0]){
				ymin = chart_data[x+'anno'][0];
			}
			chart_types[x+'anno'] = 'line';
			chart_xaxis[x+'anno'] = 'x'+x+'anno';
		}
		ymin-=0.08;
	}

	for (gene in frequencies["entropy"]){
		chart_data[gene]=[];
		chart_data['x'+gene]=[];
		chart_types[gene]='bar';
		chart_xaxis[gene]='x'+gene;
		if 	(typeof chart_data['x'+gene+'anno']!="undefined"){
			var offset= chart_data['x'+gene+'anno'][0];
		}else{
			var offset=1;
		}
		for (var ii=0;ii<frequencies["entropy"][gene].length;ii+=1){
			if (Math.round(10000*frequencies["entropy"][gene][ii][1])/10000>0.05){
				chart_data[gene].push(Math.round(10000*frequencies["entropy"][gene][ii][1])/10000);
				chart_data['x'+gene].push(ii*3+offset);
			}
		}
	}
	console.log(chart_data);
	console.log(chart_types);
	console.log(chart_xaxis);
	var entropy_chart = c3.generate({
		bindto: '#entropy',
		size: {width: width-10, height: height},
		onresize: function() {
			width = parseInt(d3.select(".entropy-container").style("width"), 10);
			height = 250;
			entropy_chart.resize({height: height, width: width});
		},
		legend: {show: false},
		color: {pattern: ["#AAA"]},
		axis: {
			y: {
				label: {
					text: 'variability',
					position: 'outer-middle'
				},
				tick: {
					values: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6],
					outer: false
				},
				min:ymin,
			},
			x: {
				label: {
					text: 'position',
					position: 'outer-center'
				},
				tick: {
					outer: false,
					values: [100,200,300,400,500]
				}
			},
		},
		data: {
			xs: chart_xaxis,
			json: chart_data,
			types: chart_types,
			onclick: function (d,i) {
				console.log(d);
				if (frequencies["entropy"][d.x-1][2].length>1){
					var tmp = [];
					for (var ii=0;ii<frequencies["entropy"][d.x-1][2].length;ii+=1){
						tmp.push(["global",d.x+frequencies["entropy"][d.x-1][2][ii]]);
					}
					colorBy = "genotype";
					colorByGenotypePosition([d.x-1]);
					d3.select("#gt-color").property("value", d.x);
				}
		    },
		    onmouseover: function (d){
		    	document.body.style.cursor = "pointer";
		    },
		    onmouseout: function (d){
		    	document.body.style.cursor = "default";
		    },
			labels:{
				format:function (v, id, i, j){
					if ((id.substring(-4)=='anno')&&(i==1)){
						return id.substring(0,-4);
					}else{return '';}
			},
		},
		bar: {width: 2},
	    grid: {
    	    y: {
        	    lines: [{value: 0}]
        	}
    	},
	    tooltip: {
	        format: {
	            title: function (d) {
	            	return 'Position ' + d + frequencies["entropy"][d-1][2].join(","); },
	            value: function (value, ratio, id) {
	                return id==''?"Variability: "+value:"start/stop";
	            }
	        }
		},
	});

	d3.select("#plotfreq")
		.on("click", function (){
			gt = parse_gt_string(document.getElementById("gtspec").value);
			make_gt_chart(gt);
		});
	make_gt_chart(parse_gt_string(document.getElementById("gtspec").value));
});
<commit_msg>fixed }<commit_after>var frequencies, pivots;
var gene = 'nuc'
/**
 * for each node, calculate the derivative of the frequency tranjectory. if none exists, copy parent
**/
function calcDfreq(node, freq_ii){
	if (typeof node.children != "undefined") {
		for (var i1=0; i1<node.children.length; i1++) {
			if (typeof node.children[i1].freq != "undefined") {
				if (node.children[i1].freq["global"] != "undefined"){
					var tmp_freq = node.children[i1].freq["global"]
					node.children[i1].dfreq = 0.5*(tmp_freq[freq_ii] - tmp_freq[freq_ii-dfreq_dn])/(tmp_freq[freq_ii] + tmp_freq[freq_ii-dfreq_dn] + 0.1);
				} else {
					node.children[i1].dfreq = node.dfreq;
				}
			}
			calcDfreq(node.children[i1], freq_ii);
		}
	}
};
function parse_gt_string(gt){
	mutations = [];
	gt.split(',').map( function (d) {
		var tmp = d.split(/[\s//]/); //FIXME: make more inclusive
		var region;
		var positions = [];
		for (var i=0; i<tmp.length; i++){
			if (contains(["EU","NA","AS","OC"], tmp[i])){
				region = tmp[i];
			}else{
				if (tmp[i].length>0) positions.push(tmp[i]);
			}
		}
		if (typeof region == "undefined") region="global";
		// sort of this is a multi mutation genotype
		if (positions.length>1){
			positions.sort(function (a,b){
				return parseInt(a.substring(0,a.length-1)) - parseInt(b.substring(0,b.length-1));
			});
		}
		mutations.push([region, positions.join('/')]);
	});
	return mutations;
};

/**
loops over all genotypes from a certain region and sums the frequency contributions
of the genotype matches at the specified positions
**/
function get_frequencies(region, gt){
	var freq = [];
	for (var pi=0; pi<pivots.length; pi++){freq[freq.length]=0;}
	if (frequencies["clades"][region][gt.toLowerCase()]!=undefined) {
		console.log(gt+" found as clade");
		for (var pi=0; pi<freq.length; pi++){
			freq[pi]+=frequencies["clades"][region][gt.toLowerCase()][pi];
		}
	}
	else if ((typeof frequencies["genotypes"] !="undefined") && (frequencies["genotypes"][region][gt]!=undefined)) {
		console.log(gt+" found as genotype");
		for (var pi=0; pi<freq.length; pi++){
			freq[pi]+=frequencies["genotypes"][region][gt][pi];
		}
	}else if (frequencies["mutations"][region][gt]!=undefined) {
		console.log(gt+" found as mutation");
		for (var pi=0; pi<freq.length; pi++){
			freq[pi]+=frequencies["mutations"][region][gt][pi];
		}
	}
	return freq.map(function (d) {return Math.round(d*100)/100;});
};

function make_gt_chart(gt){
	var tmp_data = [];
	var tmp_trace = ['x'];
	var tmp_colors = {};
	tmp_data.push(tmp_trace.concat(pivots));
	gt.forEach(function (d, i) {
		var region = d[0];
		var genotype = d[1];
		var freq = get_frequencies(region, genotype);
		if (d3.max(freq)>0) {
			var tmp_trace = genotype.toString().replace(/,/g, ', ');
			if (region != "global") {
				tmp_trace = region + ':\t' + tmp_trace;
			}
			tmp_data.push([tmp_trace].concat(freq));
			tmp_colors[tmp_trace] = genotypeColors[i];
		}
	});
	console.log(tmp_colors);
	gt_chart.load({
       	columns: tmp_data,
       	unload: true
	});
	gt_chart.data.colors(tmp_colors);
}

function addClade(d) {
	if (typeof gt_chart != "undefined"){
		var plot_data = [['x'].concat(rootNode["pivots"])];
		var reg = "global";
		if ((typeof d.target.freq !="undefined" )&&(d.target.freq[reg] != "undefined")){
			plot_data[plot_data.length] = [reg].concat(d.target.freq[reg]);
		}
		if (plot_data.length > 1) {
			if (plot_data[1][0] == "global") {
				plot_data[1][0] = "clade";
			}
		}
		gt_chart.load({
	       	columns: plot_data
		});
	}
}

function removeClade() {
	if (typeof gt_chart != "undefined"){
		gt_chart.unload({
	       	ids: ["clade"]
		});
	}
}

width = parseInt(d3.select(".freqplot-container").style("width"), 10);
height = 250;
var position = "inset";

var gt_chart = c3.generate({
	bindto: '#gtchart',
	size: {width: width-10, height: height},
	onresize: function() {
		width = parseInt(d3.select(".freqplot-container").style("width"), 10);
		height = 250;
		gt_chart.resize({height: height, width: width});
	},
	legend: {
		position: position,
		inset: {
    		anchor: 'top-right',
    		x: 10,
    		y: -15,
    		step: 1
    	}
	},
  	color: {
        pattern: genotypeColors
    },
	axis: {
		y: {
			label: {
				text: 'frequency',
				position: 'outer-middle'
			},
			tick: {
				values: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0],
				outer: false
			},
            min: 0,
			max: 1
		},
		x: {
			label: {
				text: 'time',
				position: 'outer-center'
			},
			tick: {
				values: time_ticks,
				outer: false
			}
		}
	},
	data: {
		x: 'x',
		columns: [],
	}
});

function contains(arr, obj) {
    for(var i=0; i<arr.length; i++) {
        if (arr[i] == obj) return true;
    }
}

d3.json(path + file_prefix + "frequencies.json", function(error, json){
	console.log(error);
	frequencies = json;
	pivots= frequencies["mutations"]["global"]["pivots"].map(function (d) {return Math.round(parseFloat(d)*100)/100;});
	var ticks = [Math.round(pivots[0])];
	var tick_step = Math.round((pivots[pivots.length-1]-pivots[0])/6*10)/10;
	while (ticks[ticks.length-1]<pivots[pivots.length-1]){
		ticks.push(Math.round((ticks[ticks.length-1]+tick_step)*10)/10);
	}
	//gt_chart.axis.x.values = ticks;
	/**
		parses a genotype string into region and positions
	**/

	var chart_data = {}
	var chart_types = {}
	var chart_xaxis = {}
	var ymin = 0;
	if (typeof genome_annotation !== 'undefined') {
		for (x in genome_annotation){
			chart_data['x'+x+'anno'] = genome_annotation[x][1];
			chart_data[x+'anno'] = genome_annotation[x][0].map(function(d) {return -0.1*d;});
			if (ymin>chart_data[x+'anno'][0]){
				ymin = chart_data[x+'anno'][0];
			}
			chart_types[x+'anno'] = 'line';
			chart_xaxis[x+'anno'] = 'x'+x+'anno';
		}
		ymin-=0.08;
	}

	for (gene in frequencies["entropy"]){
		chart_data[gene]=[];
		chart_data['x'+gene]=[];
		chart_types[gene]='bar';
		chart_xaxis[gene]='x'+gene;
		if 	(typeof chart_data['x'+gene+'anno']!="undefined"){
			var offset= chart_data['x'+gene+'anno'][0];
		}else{
			var offset=1;
		}
		for (var ii=0;ii<frequencies["entropy"][gene].length;ii+=1){
			if (Math.round(10000*frequencies["entropy"][gene][ii][1])/10000>0.05){
				chart_data[gene].push(Math.round(10000*frequencies["entropy"][gene][ii][1])/10000);
				chart_data['x'+gene].push(ii*3+offset);
			}
		}
	}
	console.log(chart_data);
	console.log(chart_types);
	console.log(chart_xaxis);
	var entropy_chart = c3.generate({
		bindto: '#entropy',
		size: {width: width-10, height: height},
		onresize: function() {
			width = parseInt(d3.select(".entropy-container").style("width"), 10);
			height = 250;
			entropy_chart.resize({height: height, width: width});
		},
		legend: {show: false},
		color: {pattern: ["#AAA"]},
		axis: {
			y: {
				label: {
					text: 'variability',
					position: 'outer-middle'
				},
				tick: {
					values: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6],
					outer: false
				},
				min:ymin,
			},
			x: {
				label: {
					text: 'position',
					position: 'outer-center'
				},
				tick: {
					outer: false,
					values: [100,200,300,400,500]
				}
			},
		},
		data: {
			xs: chart_xaxis,
			json: chart_data,
			types: chart_types,
			onclick: function (d,i) {
				console.log(d);
				if (frequencies["entropy"][d.x-1][2].length>1){
					var tmp = [];
					for (var ii=0;ii<frequencies["entropy"][d.x-1][2].length;ii+=1){
						tmp.push(["global",d.x+frequencies["entropy"][d.x-1][2][ii]]);
					}
					colorBy = "genotype";
					colorByGenotypePosition([d.x-1]);
					d3.select("#gt-color").property("value", d.x);
				}
		    },
		    onmouseover: function (d){
		    	document.body.style.cursor = "pointer";
		    },
		    onmouseout: function (d){
		    	document.body.style.cursor = "default";
		    },
			labels:{
				format:function (v, id, i, j){
					if ((id.substring(-4)=='anno')&&(i==1)){
						return id.substring(0,-4);
					}else{return '';}
				}
			},
		},
		bar: {width: 2},
	    grid: {
    	    y: {
        	    lines: [{value: 0}]
        	}
    	},
	    tooltip: {
	        format: {
	            title: function (d) {
	            	return 'Position ' + d + frequencies["entropy"][d-1][2].join(","); },
	            value: function (value, ratio, id) {
	                return id==''?"Variability: "+value:"start/stop";
	            }
	        }
		},
	});

	d3.select("#plotfreq")
		.on("click", function (){
			gt = parse_gt_string(document.getElementById("gtspec").value);
			make_gt_chart(gt);
		});
	make_gt_chart(parse_gt_string(document.getElementById("gtspec").value));
});
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as CmsEditorActionCreators from './actions';
import cssModules from 'react-css-modules';
import styles from './index.module.scss';
import { CmsEditor, ToastMessage } from 'components';

class CmsEditorContainer extends Component {
  constructor() {
    super();
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleCloseToast = this.handleCloseToast.bind(this);
  }
  handleSubmit(data) {
    const {
      submitArticleRequest,
    } = this.props.actions;
    submitArticleRequest(data);
  }
  handleCloseToast({ type }) {
    const {
      handleClearingToast,
    } = this.props.actions;
    handleClearingToast(type);
  }
  render() {
    const {
      error,
      message,
    } = this.props;
    return (

        {error &&
          <ToastMessage
            message={error.message}
            onClose={this.handleCloseToast({ type: 'error' })}
            status="critical"
          />
        }
        {message &&
          <ToastMessage
            message={message}
            onClose={this.handleCloseToast({ type: 'message' })}
          />
        }
        <CmsEditor
          onSubmit={this.handleSubmit}
        />

    );
  }
}

CmsEditorContainer.propTypes = {
  actions: PropTypes.object.isRequired,
  error: PropTypes.object,
  message: PropTypes.string,
};

// mapStateToProps :: {State} -> {Props}
const mapStateToProps = (state) => ({
  error: state.cmsEditorContainer.error,
  message: state.cmsEditorContainer.message,
  isSubmitting: state.cmsEditorContainer.isSubmitting,
});

// mapDispatchToProps :: Dispatch -> {Action}
const mapDispatchToProps = (dispatch) => ({
  actions: bindActionCreators(
    CmsEditorActionCreators,
    dispatch
  ),
});

const Container = cssModules(CmsEditorContainer, styles);

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Container);
<commit_msg>Feat: update cms editor actions<commit_after>import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as CmsEditorActionCreators from './actions';
import cssModules from 'react-css-modules';
import styles from './index.module.scss';
import { CmsEditor, ToastMessage } from 'components';

class CmsEditorContainer extends Component {
  constructor() {
    super();
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleCloseToast = this.handleCloseToast.bind(this);
  }
  handleSubmit(data) {
    const {
      submitArticleRequest,
    } = this.props.actions;
    submitArticleRequest(data);
  }
  handleCloseToast({ type }) {
    const {
      handleClearingToast,
    } = this.props.actions;
    handleClearingToast(type);
  }
  render() {
    const {
      error,
      message,
    } = this.props;
    return (

        {error &&
          <ToastMessage
            message={error.message}
            onClose={() => this.handleCloseToast({ type: 'error' })}
            status="critical"
          />
        }
        {message &&
          <ToastMessage
            message={message}
            onClose={() => this.handleCloseToast({ type: 'message' })}
          />
        }
        <CmsEditor
          onSubmit={this.handleSubmit}
        />

    );
  }
}

CmsEditorContainer.propTypes = {
  actions: PropTypes.object.isRequired,
  error: PropTypes.object,
  message: PropTypes.string,
};

// mapStateToProps :: {State} -> {Props}
const mapStateToProps = (state) => ({
  error: state.cmsEditorContainer.error,
  message: state.cmsEditorContainer.message,
  isSubmitting: state.cmsEditorContainer.isSubmitting,
});

// mapDispatchToProps :: Dispatch -> {Action}
const mapDispatchToProps = (dispatch) => ({
  actions: bindActionCreators(
    CmsEditorActionCreators,
    dispatch
  ),
});

const Container = cssModules(CmsEditorContainer, styles);

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Container);
<|endoftext|>


<commit_before>'use strict';
const _ = require('lodash');
const Base = require('yeoman-generator').Base;
const {writeTemplates, patchPackageJSON, stringifyAble} = require('../../utils');

const known = require('../../utils/known');

function toLibraryAliasMap(moduleNames, libraryNames) {
  var r = {};
  moduleNames.forEach((m) => {
    const plugin = known.plugin.byName(m);
    if (!plugin) {
      this.log('cant find plugin: ', m);
      return;
    }
    libraryNames.push(...(plugin.libraries || []));
  });
  libraryNames.forEach((l) => {
    const lib = known.lib.byName(l);
    if (!lib) {
      this.log('cant find library: ', l);
      return;
    }
    _.merge(r, lib.aliases);
  });
  return r;
}

function toLibraryExternals(moduleNames, libraryNames) {
  var r = [];
  moduleNames.forEach((m) => {
    const plugin = known.plugin.byName(m);
    if (!plugin) {
      this.log('cant find plugin: ', m);
      return;
    }
    r.push(...(plugin.externals || []));
    libraryNames.push(...(plugin.libraries || []));
  });
  libraryNames.forEach((l) => {
    const lib = known.lib.byName(l);
    if (!lib) {
      this.log('cant find library: ', l);
      return;
    }
    r.push(lib.name);
    r.push(...(lib.externals || []));
  });
  return Array.from(new Set(r));
}

class PluginGenerator extends Base {

  constructor(args, options) {
    super(args, options);

    // readme content
    this.option('install');
    this.option('readme');
    this.option('longDescription');
    this.option('useDefaults');
  }

  initializing() {
    this.config.defaults({
      type: 'lib',
      libraries: [],
      libraryAliases: {},
      libraryExternals: [],
      modules: ['phovea_core'],
      entries: './index.js',
      ignores: [],
      extensions: []
    });
  }

  prompting() {
    return this.prompt([{
      type: 'checkbox',
      name: 'modules',
      message: 'Included Modules',
      choices: known.plugin.listWebNamesWithDescription,
      default: this.config.get('modules'),
      when: !this.options.useDefaults
    }, {
      type: 'checkbox',
      name: 'libraries',
      message: 'Included Libraries',
      choices: known.lib.listWebNamesWithDescription,
      default: this.config.get('libraries'),
      when: !this.options.useDefaults
    }]).then((props) => {
      if (!this.options.useDefaults) {
        this.config.set('modules', props.modules);
        this.config.set('libraries', props.libraries);
      }
      this.config.set('libraryAliases', toLibraryAliasMap.call(this, this.config.get('modules'), this.config.get('libraries')));
      this.config.set('libraryExternals', toLibraryExternals.call(this, this.config.get('modules'), this.config.get('libraries')));
    });
  }

  default() {
    this.composeWith('phovea:_node', {
      options: this.options
    }, {
      local: require.resolve('../_node')
    });
  }

  _generateDependencies() {
    var r = {};
    // merge dependencies
    this.config.get('modules').filter(known.plugin.isTypeWeb).forEach((m) => {
      _.assign(r, known.plugin.byName(m).dependencies);
    });
    this.config.get('libraries').filter(known.lib.isTypeWeb).forEach((m) => {
      _.assign(r, known.lib.byName(m).dependencies);
    });
    return r;
  }

  writing() {
    const config = this.config.getAll();
    patchPackageJSON.call(this, config, [], {
      dependencies: this._generateDependencies()
    });
    writeTemplates.call(this, config);
    // don't overwrite existing registry file
    if (!this.fs.exists(this.destinationPath('phovea.js'))) {
      this.fs.copyTpl(this.templatePath('phovea.tmpl.js'), this.destinationPath('phovea.js'), stringifyAble(config));
    }
  }

  install() {
    if (this.options.install) {
      this.installDependencies({
        bower: false
      });
    }
  }
}

module.exports = PluginGenerator;
module.exports.toLibraryAliasMap = toLibraryAliasMap;
module.exports.toLibraryExternals = toLibraryExternals;
<commit_msg>var -> let<commit_after>'use strict';
const _ = require('lodash');
const Base = require('yeoman-generator').Base;
const {writeTemplates, patchPackageJSON, stringifyAble} = require('../../utils');

const known = require('../../utils/known');

function toLibraryAliasMap(moduleNames, libraryNames) {
  let r = {};
  moduleNames.forEach((m) => {
    const plugin = known.plugin.byName(m);
    if (!plugin) {
      this.log('cant find plugin: ', m);
      return;
    }
    libraryNames.push(...(plugin.libraries || []));
  });
  libraryNames.forEach((l) => {
    const lib = known.lib.byName(l);
    if (!lib) {
      this.log('cant find library: ', l);
      return;
    }
    _.merge(r, lib.aliases);
  });
  return r;
}

function toLibraryExternals(moduleNames, libraryNames) {
  let r = [];
  moduleNames.forEach((m) => {
    const plugin = known.plugin.byName(m);
    if (!plugin) {
      this.log('cant find plugin: ', m);
      return;
    }
    r.push(...(plugin.externals || []));
    libraryNames.push(...(plugin.libraries || []));
  });
  libraryNames.forEach((l) => {
    const lib = known.lib.byName(l);
    if (!lib) {
      this.log('cant find library: ', l);
      return;
    }
    r.push(lib.name);
    r.push(...(lib.externals || []));
  });
  return Array.from(new Set(r));
}

class PluginGenerator extends Base {

  constructor(args, options) {
    super(args, options);

    // readme content
    this.option('install');
    this.option('readme');
    this.option('longDescription');
    this.option('useDefaults');
  }

  initializing() {
    this.config.defaults({
      type: 'lib',
      libraries: [],
      libraryAliases: {},
      libraryExternals: [],
      modules: ['phovea_core'],
      entries: './index.js',
      ignores: [],
      extensions: []
    });
  }

  prompting() {
    return this.prompt([{
      type: 'checkbox',
      name: 'modules',
      message: 'Included Modules',
      choices: known.plugin.listWebNamesWithDescription,
      default: this.config.get('modules'),
      when: !this.options.useDefaults
    }, {
      type: 'checkbox',
      name: 'libraries',
      message: 'Included Libraries',
      choices: known.lib.listWebNamesWithDescription,
      default: this.config.get('libraries'),
      when: !this.options.useDefaults
    }]).then((props) => {
      if (!this.options.useDefaults) {
        this.config.set('modules', props.modules);
        this.config.set('libraries', props.libraries);
      }
      this.config.set('libraryAliases', toLibraryAliasMap.call(this, this.config.get('modules'), this.config.get('libraries')));
      this.config.set('libraryExternals', toLibraryExternals.call(this, this.config.get('modules'), this.config.get('libraries')));
    });
  }

  default() {
    this.composeWith('phovea:_node', {
      options: this.options
    }, {
      local: require.resolve('../_node')
    });
  }

  _generateDependencies() {
    let r = {};
    // merge dependencies
    this.config.get('modules').filter(known.plugin.isTypeWeb).forEach((m) => {
      _.assign(r, known.plugin.byName(m).dependencies);
    });
    this.config.get('libraries').filter(known.lib.isTypeWeb).forEach((m) => {
      _.assign(r, known.lib.byName(m).dependencies);
    });
    return r;
  }

  writing() {
    const config = this.config.getAll();
    patchPackageJSON.call(this, config, [], {
      dependencies: this._generateDependencies()
    });
    writeTemplates.call(this, config);
    // don't overwrite existing registry file
    if (!this.fs.exists(this.destinationPath('phovea.js'))) {
      this.fs.copyTpl(this.templatePath('phovea.tmpl.js'), this.destinationPath('phovea.js'), stringifyAble(config));
    }
  }

  install() {
    if (this.options.install) {
      this.installDependencies({
        bower: false
      });
    }
  }
}

module.exports = PluginGenerator;
module.exports.toLibraryAliasMap = toLibraryAliasMap;
module.exports.toLibraryExternals = toLibraryExternals;
<|endoftext|>


<commit_before>/*
 * mobile
 * Convert data to the API version as expected by mobile app
 */
'use strict';

var fs = require('fs');
var ent = require('ent');
var YAML = require('yamljs');
var deHtml = function(s) {
  if (s) {
    s = s.replace(/
/g, '\n');
    s = s.replace(//g, '');
    s = s.replace(/<\/[a-zA-Z]*>/g, '');
    s = ent.decode(s);
  }
  return s;
};

var src = '_data';
var trg = '_site/api';
// load files from src: speakers.yml, sessions.yml, schedule-data.yml
var speakers = YAML.load(src + '/speakers.yml');
var sessions = YAML.load(src + '/sessions.yml');
var schedule = YAML.load(src + '/schedule.yml');
// give each speaker a unique number
// create output arrays
var i, j, k;
var speakerNum = {};
var speakersOut = [];
var aSpeaker;
for (i=0; i<speakers.length; i++) {
  if (!speakers[i].active) continue;
  speakerNum[speakers[i].id] = i+1;
  aSpeaker = {
    'bio': deHtml(speakers[i].bio),
    'id': i+1,
    'name': speakers[i].name + ' ' + speakers[i].surname,
    'photo': 'https://www.womentechmakers.at/img/speakers/' + speakers[i].thumbnailUrl
  }
  if (speakers[i].title && speakers[i].company) {
    aSpeaker.title = speakers[i].title + ', ' + speakers[i].company;
  }
  else if (speakers[i].title) {
    aSpeaker.title = speakers[i].title;
  }
  else {
    aSpeaker.title = speakers[i].company;
  }
  if (speakers[i].social) {
    for (j=0; j<speakers[i].social.length; j++) {
      var aLink = speakers[i].social[j];
      if (aLink.name == "twitter") {
        aSpeaker.twitter = aLink.link.replace(/https?:\/\/w?w?w?.?twitter.com\//, '');
      }
      else if (aLink.name == "google-plus") {
        aSpeaker.gplus = aLink.link;
      }
      else if (aLink.name == "linkedin") {
        aSpeaker.linkedin = aLink.link;
      }
      else if (aLink.name == "github") {
        aSpeaker.github = aLink.link.replace(/https?:\/\/w?w?w?.?github.com\//, '');
      }
      else if (aLink.link.indexOf("xing.com") !== -1) {
        aSpeaker.xing = aLink.link;
      }
      else {
        aSpeaker.website = aLink.link;
      }
    }
  }
  speakersOut[i] = aSpeaker;
}
// create assoc of sessions by id
var sessionsById = {};
for (i=0; i<sessions.length; i++) {
  sessionsById[sessions[i].id] = sessions[i];
}
var x = 1;
var sessionsOut = [];
// create output sessions
for (i=0; i<schedule.length; i++) {
  for (j=0; j<schedule[i].timeslots.length; j++) {
    for (k=0; k<schedule[i].timeslots[j].sessionIds.length; k++) {
      var sessionId = schedule[i].timeslots[j].sessionIds[k];
      if (sessionId in sessionsById) {
        var aSession = {
          'description': deHtml(sessionsById[sessionId].description),
          'id': x,
          'title': deHtml(sessionsById[sessionId].title)
        };
        x++;
        // get session image (if exists)
        if ('imageUrl' in sessionsById[sessionId]) {
          aSession.photo = 'https://www.womentechmakers.at/img/' + sessionsById[sessionId].imageUrl;
        }
        // get the duration
        var date1 = schedule[i].date + ' ' + schedule[i].timeslots[j].startTime;
        var date2 = schedule[i].date + ' ' + schedule[i].timeslots[j].endTime;
        var duration = ((new Date(date2).getTime()) - (new Date(date1).getTime())) / (1000 * 60);
        aSession.startAt = date1;
        aSession.duration = duration;
        var sessionSpeakers = [];
        if ('speakers' in sessionsById[sessionId]) {
          for (var t=0; t<sessionsById[sessionId].speakers.length; t++) {
            var speakerStrId = sessionsById[sessionId].speakers[t];
            if (speakerStrId in speakerNum) {
              sessionSpeakers.push(speakerNum[speakerStrId]);
            }
          }
        }
        if (sessionSpeakers.length) {
          aSession.speakersId = sessionSpeakers;
        }
        // get the room id
        if (schedule[i].timeslots[j].sessionIds.length == 1) {
          if (sessionsById[sessionId].service) {
            // we have a service session
            aSession.roomId = 0;
          }
          else {
            // we have a content session
            aSession.roomId = 1;
          }
        }
        else if (schedule[i].timeslots[j].sessionIds.length == 2) {
          // first session in room 1, second in room 2
          if (k == 0) {
            aSession.roomId = 1;
          }
          else {
            aSession.roomId = 2;
          }
        }
        else {
          aSession.roomId = k + 1;
        }
        // add session
        sessionsOut.push(aSession);
      }
    }
  }
}
// serialize sessions & speakers to file
try {
  fs.accessSync(trg);
}
catch(e) {
  fs.mkdirSync(trg);
}
try {
  fs.accessSync(trg + '/v1');
}
catch(e) {
  fs.mkdirSync(trg + '/v1');
}
fs.writeFileSync(trg + '/v1/speakers', JSON.stringify(speakersOut));
fs.writeFileSync(trg + '/v1/sessions', JSON.stringify(sessionsOut));
<commit_msg>Avoid null speakers<commit_after>/*
 * mobile
 * Convert data to the API version as expected by mobile app
 */
'use strict';

var fs = require('fs');
var ent = require('ent');
var YAML = require('yamljs');
var deHtml = function(s) {
  if (s) {
    s = s.replace(/
/g, '\n');
    s = s.replace(//g, '');
    s = s.replace(/<\/[a-zA-Z]*>/g, '');
    s = ent.decode(s);
  }
  return s;
};

var src = '_data';
var trg = '_site/api';
// load files from src: speakers.yml, sessions.yml, schedule-data.yml
var speakers = YAML.load(src + '/speakers.yml');
var sessions = YAML.load(src + '/sessions.yml');
var schedule = YAML.load(src + '/schedule.yml');
// give each speaker a unique number
// create output arrays
var i, j, k;
var speakerNum = {};
var speakersOut = [];
var aSpeaker;
for (i=0; i<speakers.length; i++) {
  if (!speakers[i].active) continue;
  speakerNum[speakers[i].id] = i+1;
  aSpeaker = {
    'bio': deHtml(speakers[i].bio),
    'id': i+1,
    'name': speakers[i].name + ' ' + speakers[i].surname,
    'photo': 'https://www.womentechmakers.at/img/speakers/' + speakers[i].thumbnailUrl
  }
  if (speakers[i].title && speakers[i].company) {
    aSpeaker.title = speakers[i].title + ', ' + speakers[i].company;
  }
  else if (speakers[i].title) {
    aSpeaker.title = speakers[i].title;
  }
  else {
    aSpeaker.title = speakers[i].company;
  }
  if (speakers[i].social) {
    for (j=0; j<speakers[i].social.length; j++) {
      var aLink = speakers[i].social[j];
      if (aLink.name == "twitter") {
        aSpeaker.twitter = aLink.link.replace(/https?:\/\/w?w?w?.?twitter.com\//, '');
      }
      else if (aLink.name == "google-plus") {
        aSpeaker.gplus = aLink.link;
      }
      else if (aLink.name == "linkedin") {
        aSpeaker.linkedin = aLink.link;
      }
      else if (aLink.name == "github") {
        aSpeaker.github = aLink.link.replace(/https?:\/\/w?w?w?.?github.com\//, '');
      }
      else if (aLink.link.indexOf("xing.com") !== -1) {
        aSpeaker.xing = aLink.link;
      }
      else {
        aSpeaker.website = aLink.link;
      }
    }
  }
  if (aSpeaker) {
    speakersOut[i] = aSpeaker;
  }
}
// create assoc of sessions by id
var sessionsById = {};
for (i=0; i<sessions.length; i++) {
  sessionsById[sessions[i].id] = sessions[i];
}
var x = 1;
var sessionsOut = [];
// create output sessions
for (i=0; i<schedule.length; i++) {
  for (j=0; j<schedule[i].timeslots.length; j++) {
    for (k=0; k<schedule[i].timeslots[j].sessionIds.length; k++) {
      var sessionId = schedule[i].timeslots[j].sessionIds[k];
      if (sessionId in sessionsById) {
        var aSession = {
          'description': deHtml(sessionsById[sessionId].description),
          'id': x,
          'title': deHtml(sessionsById[sessionId].title)
        };
        x++;
        // get session image (if exists)
        if ('imageUrl' in sessionsById[sessionId]) {
          aSession.photo = 'https://www.womentechmakers.at/img/' + sessionsById[sessionId].imageUrl;
        }
        // get the duration
        var date1 = schedule[i].date + ' ' + schedule[i].timeslots[j].startTime;
        var date2 = schedule[i].date + ' ' + schedule[i].timeslots[j].endTime;
        var duration = ((new Date(date2).getTime()) - (new Date(date1).getTime())) / (1000 * 60);
        aSession.startAt = date1;
        aSession.duration = duration;
        var sessionSpeakers = [];
        if ('speakers' in sessionsById[sessionId]) {
          for (var t=0; t<sessionsById[sessionId].speakers.length; t++) {
            var speakerStrId = sessionsById[sessionId].speakers[t];
            if (speakerStrId in speakerNum) {
              sessionSpeakers.push(speakerNum[speakerStrId]);
            }
          }
        }
        if (sessionSpeakers.length) {
          aSession.speakersId = sessionSpeakers;
        }
        // get the room id
        if (schedule[i].timeslots[j].sessionIds.length == 1) {
          if (sessionsById[sessionId].service) {
            // we have a service session
            aSession.roomId = 0;
          }
          else {
            // we have a content session
            aSession.roomId = 1;
          }
        }
        else if (schedule[i].timeslots[j].sessionIds.length == 2) {
          // first session in room 1, second in room 2
          if (k == 0) {
            aSession.roomId = 1;
          }
          else {
            aSession.roomId = 2;
          }
        }
        else {
          aSession.roomId = k + 1;
        }
        // add session
        sessionsOut.push(aSession);
      }
    }
  }
}
// serialize sessions & speakers to file
try {
  fs.accessSync(trg);
}
catch(e) {
  fs.mkdirSync(trg);
}
try {
  fs.accessSync(trg + '/v1');
}
catch(e) {
  fs.mkdirSync(trg + '/v1');
}
fs.writeFileSync(trg + '/v1/speakers', JSON.stringify(speakersOut));
fs.writeFileSync(trg + '/v1/sessions', JSON.stringify(sessionsOut));
<|endoftext|>


<commit_before>// @flow
import * as React from 'react'
import {FlatList, StyleSheet, Text} from 'react-native'
import {ListSeparator, ListRow} from '../../../components/list'
import {NoticeView} from '../../../components/notice'
import * as c from '../../../components/colors'

type Props = {
	onQueryPress: (query: string) => any,
	queries: string[],
}

export class RecentSearchList extends React.PureComponent<Props> {
	renderSeparator = () => <ListSeparator spacing={{left: 20, right: 20}} />

	renderItem = ({item}: {item: string}) => (
		<ListRow arrowPosition="none" onPress={() => this.onPressRow(item)}>
			<Text style={styles.listItem}>{item}</Text>
		</ListRow>
	)

	onPressRow = (query: string) => {
		this.props.onQueryPress(query)
	}

	keyExtractor = (item: string) => item

	render() {
		const {queries} = this.props
		return (
			<FlatList
				ItemSeparatorComponent={this.renderSeparator}
				ListEmptyComponent={<NoticeView text="No recent searches" />}
				data={queries}
				keyExtractor={this.keyExtractor}
				renderItem={this.renderItem}
				scrollEnabled={false}
			/>
		)
	}
}

const styles = StyleSheet.create({
	listItem: {
		paddingVertical: 5,
		paddingLeft: 5,
		fontSize: 18,
		color: c.olevilleGold,
	},
})
<commit_msg>fixed spacing in empty recent searches list<commit_after>// @flow
import * as React from 'react'
import {FlatList, StyleSheet, Text} from 'react-native'
import {ListSeparator, ListRow} from '../../../components/list'
import {NoticeView} from '../../../components/notice'
import * as c from '../../../components/colors'

type Props = {
	onQueryPress: (query: string) => any,
	queries: string[],
}

export class RecentSearchList extends React.PureComponent<Props> {
	renderSeparator = () => <ListSeparator spacing={{left: 20, right: 20}} />

	renderItem = ({item}: {item: string}) => (
		<ListRow arrowPosition="none" onPress={() => this.onPressRow(item)}>
			<Text style={styles.listItem}>{item}</Text>
		</ListRow>
	)

	onPressRow = (query: string) => {
		this.props.onQueryPress(query)
	}

	keyExtractor = (item: string) => item

	render() {
		const {queries} = this.props
		return (
			<FlatList
				ItemSeparatorComponent={this.renderSeparator}
				ListEmptyComponent={
					<NoticeView
						header="No recent searches"
						style={styles.notice}
						text="Your recent searches will appear here."
					/>
				}
				data={queries}
				keyExtractor={this.keyExtractor}
				renderItem={this.renderItem}
				scrollEnabled={false}
			/>
		)
	}
}

const styles = StyleSheet.create({
	listItem: {
		paddingVertical: 5,
		paddingLeft: 5,
		fontSize: 18,
		color: c.olevilleGold,
	},
	notice: {
		paddingBottom: 35,
	},
})
<|endoftext|>


<commit_before>module.exports = function(Event) {
  // model operation hook
  Event.observe('before save', function(ctx, next) {
    if (ctx.instance) {
      //ctx.instance.clientIP = (require("domain")).active.members[1].req.ip;
      ctx.instance.clientIP = (require('loopback')).getCurrentContext().active.http.req.ip;
    }
    next();
  });
};
<commit_msg>Add automatic recording of server URL on posted event.<commit_after>module.exports = function(Event) {
  // model operation hook
  Event.observe('before save', function(ctx, next) {
    if (ctx.instance) {
      //ctx.instance.clientIP = (require("domain")).active.members[1].req.ip;
      loopback = require('loopback');
      req = loopback.getCurrentContext().active.http.req
      ctx.instance.clientIP = req.ip;
      ctx.instance.serverURL = req.headers.origin;
    }
    next();
  });
};
<|endoftext|>


<commit_before>/**
 * The Jazzcat client is a library for loading JavaScript from the Jazzcat
 * webservice. Jazzcat provides a JSONP HTTP endpoint for fetching multiple HTTP
 * resources with a single HTTP request. This is handy if you'd to request a
 * number of JavaScript files in a single request.
 *
 * The client is designed to work with Capturing in a "drop in" manner and as such is
 * optimized for loading collections of scripts on a page through Jazzcat,
 * rather than fetching specific scripts.
 *
 * The client cannot rely on the browser's cache to store Jazzcat responses. Imagine
 * page one with external scripts a and b and page two with script a. Visitng
 * page one and then page two results in a cache miss because each set of scripts
 * generate different requests to Jazzcat.
 *
 * To work around this, the client implements a cache over localStorage for caching
 * the results of requests to Jazzcat.
 *
 * Scripts that should use the client must be passed to `Jazzcat.combineScripts`
 * during the capturing phase. During execution, uncached scripts are loaded
 * into the cache using a bootloader request to Jazzcat. Scripts are then
 * executed directly from the cache.
 */
define(["utils", "capture"], function(Utils, Capture) {
    /**
     * An HTTP 1.1 compliant localStorage backed cache.
     */
    var cache = {};

    var localStorageKey = 'Mobify-Combo-Cache-v1.0';

    /**
     * Reset the cache, optionally to `val`. Useful for testing.
     */
    var reset = function(val) {
        cache = val || {};
    };

    /**
     * Returns value of `key` if it is in the cache.
     */
    var get = function(key, touch) {
        // Ignore anchors.
        var resource = cache[key.split('#')[0]];
        if (resource && touch) {
            resource.lastUsed = Date.now();
        }
        return resource;
    };

    /**
     * Set `key` to `val` in the cache.
     */
    var set = function(key, val) {
        cache[key] = val;
    };

    /**
     * Load the cache into memory, skipping stale resources.
     */
    var load = function() {
        var data = localStorage.getItem(localStorageKey)
        var key;

        if (!data) {
            return;
        }

        try {
            data = JSON.parse(data);
        } catch(err) {
            return;
        }

        for (key in data) {
            if (data.hasOwnProperty(key) && !isStale(data[key])) {
                set(key, data[key]);
            }
        }
    };

    /**
     * Save the cache to `localStorage`. If it won't fit, evict the least
     * recently used items.
     */
    var save = function(callback) {
        var resources = {};
        var resource;
        var attempts = 10;
        var key;
        var serialized;
        // End of time.
        var lruTime = 9007199254740991;
        var lruKey;

        for (key in cache) {
            if (cache.hasOwnProperty(key)) {
                resources[key] = cache[key];
            }
        }

        // Serialize the cache for storage. If the serialized data won't fit,
        // evict an item and try again. Use `setTimeout` to ensure the UI stays
        // responsive even if a number of resources are evicted.
        (function persist() {
            var store = function() {
                try {
                    serialized = JSON.stringify(resources);
                } catch(e) {
                    return callback && callback(e);
                }

                try {
                    localStorage.setItem(localStorageKey, serialized);
                // The serialized data won't fix. Remove the least recently used
                // resource and try again.
                } catch(e) {
                    if (!--attempts) {
                        return callback && callback(e);
                    }

                    // Find the least recently used resource.
                    for (key in resources) {
                        if (!resources.hasOwnProperty(key)) continue;
                        resource = resources[key];

                        if (resource.lastUsed) {
                            if (resource.lastUsed <= lruTime) {
                                lruKey = key;
                                lruTime = resource.lastUsed;
                            }
                        // If a resource has not been used, it's the LRU.
                        } else {
                            lruKey = key;
                            lruTime = 0;
                            break;
                        }
                    }

                    delete resources[lruKey];

                    return persist();
                }

                callback && callback();
            };

            setTimeout(store, 0);
        })();
    };

    // Regular expressions for cache-control directives.
    // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
    var ccDirectives = /^\s*(public|private|no-cache|no-store)\s*$/;
    var ccMaxAge = /^\s*(max-age)\s*=\s*(\d+)\s*$/;

    /**
     * Returns a parsed HTTP 1.1 Cache-Control directive from a string `directives`.
     */
    var ccParse = function(directives) {
        var obj = {};
        var match;

        directives.split(',').forEach(function(directive) {
            if (match = ccDirectives.exec(directive)) {
                obj[match[1]] = true;
            } else if (match = ccMaxAge.exec(directive)) {
                obj[match[1]] = parseInt(match[2]);
            }
        });

        return obj;
    };

    /**
     * Returns `true` if `resource` is stale by HTTP/1.1 caching rules.
     * Treats invalid headers as stale.
     */
    var isStale = function(resource) {
        var headers = resource.headers || {};
        var cacheControl = headers['cache-control'];
        var now = Date.now();
        var date;

        // If `max-age` and `date` are present, and no other no other cache
        // directives exist, then we are stale if we are older.
        if (cacheControl && (date = Date.parse(headers.date))) {
            cacheControl = ccParse(cacheControl);

            if ((cacheControl['max-age']) &&
                (!cacheControl['private']) &&
                (!cacheControl['no-store']) &&
                (!cacheControl['no-cache'])) {
                // Convert the max-age directive to ms.
                return now > (date + (cacheControl['max-age'] * 1000));
            }
        }

        // If `expires` is present, we are stale if we are older.
        if (date = Date.parse(headers.expires)) {
            return now > date;
        }

        // Otherwise, we are stale.
        return true;
    };

    var httpCache = {
        get: get,
        set: set,
        load: load,
        save: save,
        reset: reset,
        cache: cache,
        utils: {isStale: isStale}
    };

    /**
     * Returns `true` if `localStorage` is supported:
     * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js
     */
    var supportsLocalStorage = function() {
        var mod = 'modernizr';
        try {
            localStorage.setItem(mod, mod);
            localStorage.removeItem(mod);
            return true;
        } catch(e) {
            return false;
        }
    };

    var absolutify = document.createElement('a');

    var Jazzcat = window.Jazzcat = {
        httpCache: httpCache,
        // Cache a reference to `document.write` in case it is reassigned.
        write: document.write
    };

    /**
     * Alter the array of scripts, `scripts`, into calls that use the Jazzcat
     * service. Roughly:
     *
     *   Before:
     *
     *   <script src="http://code.jquery.com/jquery.js"></script>
     *   <script>$(function() { alert("helo joe"); })</script>
     *
     *   After:
     *
     *   <script>true,Jazzcat.combo.exec("http://code.jquery.com/jquery.js")</script>
     *   <script>$(function() { alert("helo joe"); })</script>
     *
     * Note that this only the first part of the Jazzcat transformation. The
     * bootloader script is inserted by the overriden `Capture.enabled` function.
     */
    Jazzcat.combineScripts = function(scripts, options) {
        // Fastfail if there are no scripts or if required features are missing.
        if (!scripts.length || !window.JSON || !supportsLocalStorage()) {
            return scripts;
        }

        var script;
        var url;
        var i = 0

        options = Utils.extend(defaults, options || {});

        httpCache.load();

        while (script = scripts[i++]) {
            url = script.getAttribute(options.attribute)
            if (!url) continue;
            script.removeAttribute(options.attribute);
            absolutify.href = url;
            url = absolutify.href;
            script.innerHTML = !!httpCache.get(url) + ',' + options.execCallback + "('" + url + "');";
        }

        return scripts;
    };

    var defaults = Jazzcat.combineScripts.defaults = {
        selector: 'script',
        attribute: 'x-src',
        base: '//jazzcat.mobify.com',
        endpoint: 'jsonp',
        execCallback: 'Jazzcat.combo.exec',
        loadCallback: 'Jazzcat.combo.load',
        projectName: ''
    };

    Jazzcat.combo = {
        /**
         * Execute the script at `url` using `document.write`. If the scripts
         * can't be retrieved from the cache, load it using an external script.
         */
        exec: function(url) {
            var resource = httpCache.get(url, true);
            var out;

            if (!resource) {
                out = 'src="' + url + '">';
            } else {
                out = 'data-orig-src="' + url + '"';
                // Explanation below uses [] to stand for <>.
                // Inline scripts appear to work faster than data URIs on many OSes
                // (e.g. Android 2.3.x, iOS 5, likely most of early 2013 device market)
                //
                // However, it is not safe to directly convert a remote script into an
                // inline one. If there is a closing script tag inside the script,
                // the script element will be closed prematurely.
                //
                // To guard against this, we need to prevent script element spillage.
                // This is done by replacing [/script] with [/scr\ipt] inside script
                // content. This transformation renders closing [/script] inert.
                //
                // The transformation is safe. There are three ways for a valid JS file
                // to end up with a [/script] character sequence:
                // * Inside a comment - safe to alter
                // * Inside a string - replacing 'i' with '\i' changes nothing, as
                //   backslash in front of characters that need no escaping is ignored.
                // * Inside a regular expression starting with '/script' - '\i' has no
                //   meaning inside regular expressions, either, so it is treated just
                //   like 'i' when expression is matched.
                //
                // Talk to Roman if you want to know more about this.
                out += '>' + resource.body.replace(/(<\/scr)(ipt\s*>)/ig, '$1\\$2');
            }

            // `document.write` is used to ensure scripts are executed in order,
            // as opposed to "as fast as possible"
            // http://hsivonen.iki.fi/script-execution/
            // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
            // This call seems to do nothing in Opera 11/12
            Jazzcat.write.call(document, '<script ' + out + '<\/script>');
        },

        /**
         * Load the cache and populate it with the results of the Jazzcat
         * response `resources`.
         */
        load: function(resources) {
            var resource;
            var i = 0;
            var save = false;

            httpCache.load();

            // All the resources are already in the cache.
            if (!resources) {
                return;
            }

            while (resource = resources[i++]) {
                if (resource.status == 'ready') {
                    save = true;
                    httpCache.set(encodeURI(resource.url), resource);
                }
            }

            if (save) {
                httpCache.save();
            }
        }
    };

    /**
     * Returns a script suitable for loading `urls` from Jazzcat, calling the
     * function `jsonpCallback` on complete.
     */
    Jazzcat.getLoaderScript = function(urls, jsonpCallback) {
        var bootstrap = document.createElement('script');
        if (urls.length) {
            bootstrap.src = Jazzcat.getURL(urls, jsonpCallback);
        } else {
            bootstrap.innerHTML = jsonpCallback + '();';
        }
        return bootstrap;
    };

    /**
     * Returns a URL suitable for loading `urls` from Jazzcat, calling the
     * function `jsonpCallback` on complete. `urls` are sorted to generate
     * consistent URLs.
     */
    Jazzcat.getURL = function(urls, jsonpCallback) {
        return defaults.base + (defaults.projectName ? '/project-' + defaults.projectName : '') +
               '/' + defaults.endpoint + '/' + jsonpCallback + '/' +
               Jazzcat.JSONURIencode(urls.slice().sort());
    };

    Jazzcat.JSONURIencode = function(obj) {
        return encodeURIComponent(JSON.stringify(obj));
    };

    // Used to find Jazzcat calls in an HTML string.
    var execRe = new RegExp("<script[^>]*?>(true|false)," +
      defaults.execCallback.replace(/\./g, '\\.') +
      "\\('([\\s\\S]*?)'\\);<\\/script", "gi");

    /**
     * Insert the loader before the first Jazzcat call in the HTML string
     * `html`.
     */
    Jazzcat.insertLoaderIntoHTMLString = function(html) {
        var match;
        var bootstrap;
        var firstIndex = -1;
        var uncached = [];

        // Find the first Jazzcat call and gather all the uncached scripts.
        while (match = execRe.exec(html)) {
            if (firstIndex == -1) firstIndex = match.index;
            if (match[1] === "false") uncached.push(match[2]);
        };

        if (firstIndex == -1) {
            return html;
        }

        bootstrap = Jazzcat.getLoaderScript(uncached, defaults.loadCallback);

        return html.substr(0, firstIndex) + Utils.outerHTML(bootstrap) + html.substr(firstIndex);
    };

    /**
     * Overrides `Capture.enable` to insert a Jazzcat bootloader to fetch all
     * uncached scripts from the Jazzcat service before executing any Jazzcat calls.
     */
    var oldEnable = Capture.enable;
    Capture.enable = function() {
        var htmlStr = oldEnable.apply(Capture, arguments);
        return Jazzcat.insertLoaderIntoHTMLString(htmlStr);
    };

    return Jazzcat;

});<commit_msg>initial implementation of an option to override caching time for jazzcat<commit_after>/**
 * The Jazzcat client is a library for loading JavaScript from the Jazzcat
 * webservice. Jazzcat provides a JSONP HTTP endpoint for fetching multiple HTTP
 * resources with a single HTTP request. This is handy if you'd to request a
 * number of JavaScript files in a single request.
 *
 * The client is designed to work with Capturing in a "drop in" manner and as such is
 * optimized for loading collections of scripts on a page through Jazzcat,
 * rather than fetching specific scripts.
 *
 * The client cannot rely on the browser's cache to store Jazzcat responses. Imagine
 * page one with external scripts a and b and page two with script a. Visitng
 * page one and then page two results in a cache miss because each set of scripts
 * generate different requests to Jazzcat.
 *
 * To work around this, the client implements a cache over localStorage for caching
 * the results of requests to Jazzcat.
 *
 * Scripts that should use the client must be passed to `Jazzcat.combineScripts`
 * during the capturing phase. During execution, uncached scripts are loaded
 * into the cache using a bootloader request to Jazzcat. Scripts are then
 * executed directly from the cache.
 */
define(["utils", "capture"], function(Utils, Capture) {
    /**
     * An HTTP 1.1 compliant localStorage backed cache.
     */
    var cache = {};

    var localStorageKey = 'Mobify-Combo-Cache-v1.0';

    var httpCacheOptions = {};

    /**
     * Reset the cache, optionally to `val`. Useful for testing.
     */
    var reset = function(val) {
        cache = val || {};
    };

    /**
     * Returns value of `key` if it is in the cache.
     */
    var get = function(key, touch) {
        // Ignore anchors.
        var resource = cache[key.split('#')[0]];
        if (resource && touch) {
            resource.lastUsed = Date.now();
        }
        return resource;
    };

    /**
     * Set `key` to `val` in the cache.
     */
    var set = function(key, val) {
        cache[key] = val;
    };

    /**
     * Load the cache into memory, skipping stale resources.
     */
    var load = function() {
        var data = localStorage.getItem(localStorageKey)
        var key;

        if (!data) {
            return;
        }

        try {
            data = JSON.parse(data);
        } catch(err) {
            return;
        }

        for (key in data) {
            if (data.hasOwnProperty(key) && !isStale(data[key])) {
                set(key, data[key]);
            }
        }
    };

    /**
     * Save the cache to `localStorage`. If it won't fit, evict the least
     * recently used items.
     */
    var save = function(callback) {
        var resources = {};
        var resource;
        var attempts = 10;
        var key;
        var serialized;
        // End of time.
        var lruTime = 9007199254740991;
        var lruKey;

        for (key in cache) {
            if (cache.hasOwnProperty(key)) {
                resources[key] = cache[key];
            }
        }

        // Serialize the cache for storage. If the serialized data won't fit,
        // evict an item and try again. Use `setTimeout` to ensure the UI stays
        // responsive even if a number of resources are evicted.
        (function persist() {
            var store = function() {
                try {
                    serialized = JSON.stringify(resources);
                } catch(e) {
                    return callback && callback(e);
                }

                try {
                    localStorage.setItem(localStorageKey, serialized);
                // The serialized data won't fix. Remove the least recently used
                // resource and try again.
                } catch(e) {
                    if (!--attempts) {
                        return callback && callback(e);
                    }

                    // Find the least recently used resource.
                    for (key in resources) {
                        if (!resources.hasOwnProperty(key)) continue;
                        resource = resources[key];

                        if (resource.lastUsed) {
                            if (resource.lastUsed <= lruTime) {
                                lruKey = key;
                                lruTime = resource.lastUsed;
                            }
                        // If a resource has not been used, it's the LRU.
                        } else {
                            lruKey = key;
                            lruTime = 0;
                            break;
                        }
                    }

                    delete resources[lruKey];

                    return persist();
                }

                callback && callback();
            };

            setTimeout(store, 0);
        })();
    };

    // Regular expressions for cache-control directives.
    // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
    var ccDirectives = /^\s*(public|private|no-cache|no-store)\s*$/;
    var ccMaxAge = /^\s*(max-age)\s*=\s*(\d+)\s*$/;

    /**
     * Returns a parsed HTTP 1.1 Cache-Control directive from a string `directives`.
     */
    var ccParse = function(directives) {
        var obj = {};
        var match;

        directives.split(',').forEach(function(directive) {
            if (match = ccDirectives.exec(directive)) {
                obj[match[1]] = true;
            } else if (match = ccMaxAge.exec(directive)) {
                obj[match[1]] = parseInt(match[2]);
            }
        });

        return obj;
    };

    /**
     * Returns `true` if `resource` is stale by HTTP/1.1 caching rules.
     * Treats invalid headers as stale.
     */
    var isStale = function(resource) {
        var headers = resource.headers || {};
        var cacheControl = headers['cache-control'];
        var now = Date.now();
        var date;
        var cacheOverrideTime;

        // If a cache override parameter is present, see if the age of the
        // response is less than the override, cacheOverrideTime is in minutes
        if ((httpCacheOptions.cacheOverrideTime !== undefined) &&
            (cacheOverrideTime = httpCacheOptions.cachOverrideTime) &&
          (date = Date.parse(headers.date))) {
            return (now > (date + (cacheOverrideTime * 60 * 1000)));
        }

        // If `max-age` and `date` are present, and no other cache
        // directives exist, then we are stale if we are older.
        if (cacheControl && (date = Date.parse(headers.date))) {
            cacheControl = ccParse(cacheControl);

            if ((cacheControl['max-age']) &&
                (!cacheControl['private']) &&
                (!cacheControl['no-store']) &&
                (!cacheControl['no-cache'])) {
                // Convert the max-age directive to ms.
                return now > (date + (cacheControl['max-age'] * 1000));
            }
        }

        // If `expires` is present, we are stale if we are older.
        if (date = Date.parse(headers.expires)) {
            return now > date;
        }

        // Otherwise, we are stale.
        return true;
    };

    var httpCache = {
        get: get,
        set: set,
        load: load,
        save: save,
        reset: reset,
        cache: cache,
        utils: {isStale: isStale},
        options: httpCacheOptions
    };

    /**
     * Returns `true` if `localStorage` is supported:
     * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js
     */
    var supportsLocalStorage = function() {
        var mod = 'modernizr';
        try {
            localStorage.setItem(mod, mod);
            localStorage.removeItem(mod);
            return true;
        } catch(e) {
            return false;
        }
    };

    var absolutify = document.createElement('a');

    var Jazzcat = window.Jazzcat = {
        httpCache: httpCache,
        // Cache a reference to `document.write` in case it is reassigned.
        write: document.write
    };

    /**
     * Alter the array of scripts, `scripts`, into calls that use the Jazzcat
     * service. Roughly:
     *
     *   Before:
     *
     *   <script src="http://code.jquery.com/jquery.js"></script>
     *   <script>$(function() { alert("helo joe"); })</script>
     *
     *   After:
     *
     *   <script>true,Jazzcat.combo.exec("http://code.jquery.com/jquery.js")</script>
     *   <script>$(function() { alert("helo joe"); })</script>
     *
     * Note that this only the first part of the Jazzcat transformation. The
     * bootloader script is inserted by the overriden `Capture.enabled` function.
     */
    Jazzcat.combineScripts = function(scripts, options) {
        // Fastfail if there are no scripts or if required features are missing.
        if (!scripts.length || !window.JSON || !supportsLocalStorage()) {
            return scripts;
        }

        var script;
        var url;
        var i = 0;

        if (options && options.cacheOverrideTime) {
            Utils.extend(httpCache.options,
              {cacheOverrideTime: options.cacheOverrideTime});
        }

        options = Utils.extend({}, defaults, options || {});

        httpCache.load();

        while (script = scripts[i++]) {
            url = script.getAttribute(options.attribute)
            if (!url) continue;
            script.removeAttribute(options.attribute);
            absolutify.href = url;
            url = absolutify.href;
            script.innerHTML = !!httpCache.get(url) + ',' + options.execCallback + "('" + url + "');";
        }

        return scripts;
    };

    var defaults = Jazzcat.combineScripts.defaults = {
        selector: 'script',
        attribute: 'x-src',
        base: '//jazzcat.mobify.com',
        endpoint: 'jsonp',
        execCallback: 'Jazzcat.combo.exec',
        loadCallback: 'Jazzcat.combo.load',
        projectName: ''
    };

    Jazzcat.combo = {
        /**
         * Execute the script at `url` using `document.write`. If the scripts
         * can't be retrieved from the cache, load it using an external script.
         */
        exec: function(url) {
            var resource = httpCache.get(url, true);
            var out;

            if (!resource) {
                out = 'src="' + url + '">';
            } else {
                out = 'data-orig-src="' + url + '"';
                // Explanation below uses [] to stand for <>.
                // Inline scripts appear to work faster than data URIs on many OSes
                // (e.g. Android 2.3.x, iOS 5, likely most of early 2013 device market)
                //
                // However, it is not safe to directly convert a remote script into an
                // inline one. If there is a closing script tag inside the script,
                // the script element will be closed prematurely.
                //
                // To guard against this, we need to prevent script element spillage.
                // This is done by replacing [/script] with [/scr\ipt] inside script
                // content. This transformation renders closing [/script] inert.
                //
                // The transformation is safe. There are three ways for a valid JS file
                // to end up with a [/script] character sequence:
                // * Inside a comment - safe to alter
                // * Inside a string - replacing 'i' with '\i' changes nothing, as
                //   backslash in front of characters that need no escaping is ignored.
                // * Inside a regular expression starting with '/script' - '\i' has no
                //   meaning inside regular expressions, either, so it is treated just
                //   like 'i' when expression is matched.
                //
                // Talk to Roman if you want to know more about this.
                out += '>' + resource.body.replace(/(<\/scr)(ipt\s*>)/ig, '$1\\$2');
            }

            // `document.write` is used to ensure scripts are executed in order,
            // as opposed to "as fast as possible"
            // http://hsivonen.iki.fi/script-execution/
            // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
            // This call seems to do nothing in Opera 11/12
            Jazzcat.write.call(document, '<script ' + out + '<\/script>');
        },

        /**
         * Load the cache and populate it with the results of the Jazzcat
         * response `resources`.
         */
        load: function(resources) {
            var resource;
            var i = 0;
            var save = false;

            httpCache.load();

            // All the resources are already in the cache.
            if (!resources) {
                return;
            }

            while (resource = resources[i++]) {
                if (resource.status == 'ready') {
                    save = true;
                    httpCache.set(encodeURI(resource.url), resource);
                }
            }

            if (save) {
                httpCache.save();
            }
        }
    };

    /**
     * Returns a script suitable for loading `urls` from Jazzcat, calling the
     * function `jsonpCallback` on complete.
     */
    Jazzcat.getLoaderScript = function(urls, jsonpCallback) {
        var bootstrap = document.createElement('script');
        if (urls.length) {
            bootstrap.src = Jazzcat.getURL(urls, jsonpCallback);
        } else {
            bootstrap.innerHTML = jsonpCallback + '();';
        }
        return bootstrap;
    };

    /**
     * Returns a URL suitable for loading `urls` from Jazzcat, calling the
     * function `jsonpCallback` on complete. `urls` are sorted to generate
     * consistent URLs.
     */
    Jazzcat.getURL = function(urls, jsonpCallback) {
        return defaults.base + (defaults.projectName ? '/project-' + defaults.projectName : '') +
               '/' + defaults.endpoint + '/' + jsonpCallback + '/' +
               Jazzcat.JSONURIencode(urls.slice().sort());
    };

    Jazzcat.JSONURIencode = function(obj) {
        return encodeURIComponent(JSON.stringify(obj));
    };

    // Used to find Jazzcat calls in an HTML string.
    var execRe = new RegExp("<script[^>]*?>(true|false)," +
      defaults.execCallback.replace(/\./g, '\\.') +
      "\\('([\\s\\S]*?)'\\);<\\/script", "gi");

    /**
     * Insert the loader before the first Jazzcat call in the HTML string
     * `html`.
     */
    Jazzcat.insertLoaderIntoHTMLString = function(html) {
        var match;
        var bootstrap;
        var firstIndex = -1;
        var uncached = [];

        // Find the first Jazzcat call and gather all the uncached scripts.
        while (match = execRe.exec(html)) {
            if (firstIndex == -1) firstIndex = match.index;
            if (match[1] === "false") uncached.push(match[2]);
        };

        if (firstIndex == -1) {
            return html;
        }

        bootstrap = Jazzcat.getLoaderScript(uncached, defaults.loadCallback);

        return html.substr(0, firstIndex) + Utils.outerHTML(bootstrap) + html.substr(firstIndex);
    };

    /**
     * Overrides `Capture.enable` to insert a Jazzcat bootloader to fetch all
     * uncached scripts from the Jazzcat service before executing any Jazzcat calls.
     */
    var oldEnable = Capture.enable;
    Capture.enable = function() {
        var htmlStr = oldEnable.apply(Capture, arguments);
        return Jazzcat.insertLoaderIntoHTMLString(htmlStr);
    };

    return Jazzcat;

});<|endoftext|>


<commit_before>export default {
  title: 'Components|Modals',
};
<commit_msg>starting modal stories<commit_after>import { useEffect } from '@storybook/client-api';
import { modals } from './modals';

export default {
  title: 'Components|Modals',
};

export const choice = () => {
  useEffect(() => {
    modals();
  });

  return `

        Are you sure?

      <button
        class="sprk-c-Modal__icon"
        data-sprk-modal-cancel="exampleChoiceModal"
        type="button" aria-label="Close Modal">
        <svg class="sprk-c-Icon sprk-c-Icon--stroke-current-color" viewBox="0 0 64 64" aria-hidden="true" focusable="false">
          <use xlink:href="#close"></use>
        </svg>
      </button>

      This is some content that is in a modal. It explains what the modal is for. There will also be a way to close the modal.

      <button class="sprk-c-Button sprk-u-mrm">
        Confirm
      </button>

      <button class="sprk-c-Button sprk-c-Button--tertiary" data-sprk-modal-cancel="exampleChoiceModal">
        Cancel
      </button>

  `
};

choice.story = {
  name: 'Choice',
};
<|endoftext|>