<commit_before>var data = [],
    solo = [],
    MAX_BARS = 10,
    lang = document.documentElement.lang,
    dataset = $("#bar").attr("dataset"),
    options = $("#bar").attr("options").split(","),
    x = $("#bar").attr("x").split(","),
    currentX = x[0],
    y = $("#bar").attr("y").split(","),
    currentY = y[0],
    filters = $("#bar").attr("filters"),
    url = "http://api.staging.dataviva.info/" +
        dataset + "/year/" + ( options.indexOf('month') != -1 ? 'month/' : '' ) + y.join("/") + ( filters ? "?" + filters : '');

// TODO: Title creator
var title = 'Title';

var visualization;

var uis = [];

if(x.length > 1){
    uis.push({
        'value': x,
        'type': 'drop',
        'label': 'xaxis',
        'method': function(value, viz){
            currentX = value;
            viz.x(value)
               .order({
                    'value': currentX,
                    'sort': 'asc'
                })
               .draw();
               totalOfCurrentX()
        }
    });
}

if(y.length > 1){
    uis.push({
        'value': y,
        'type': 'drop',
        'label': 'yaxis',
        'method': function(value, viz){
            currentY = value;
            viz.y(value).id(value).draw();
        }
    });
}

var textHelper = {
    'loading': {
        'en': 'loading ...',
        'pt': 'carregando ...'
    },
    'average_wage': {
        'en': 'Salário Médio Mensal',
        'pt': 'Average Monthly Wage'
    },
    'jobs': {
        'en': 'Jobs',
        'pt': 'Empregos'
    },
    'year': {
        'en': 'Year',
        'pt': 'Ano'
    },
    'scale': {
        'en': "Scale",
        'pt': "Escala"
    },
    'yaxis': {
        'en': "Y-Axis",
        'pt': "Eixo Y"
    },
    'xaxis': {
        'en': "X-Axis",
        'pt': "Eixo X"
    },
    'locale': {
        'en': 'en_US',
        'pt': 'pt_BR'
    },
    'average_wage': {
        'en': "Average Wage",
        'pt': "Salário Médio"
    },
    'kg': {
        'en': 'kg',
        'pt': 'kg'
    },
    'value': {
        'en': "US$",
        'pt': "US$"
    },
    'kg_label': {
        'en': 'Amount [kg]',
        'pt': 'Quantidade [kg]'
    },
    'value_label': {
        'en': "Value [$ USD]",
        'pt': "Valor [$ USD]"
    },
    'average_wage_label': {
        'en': "Average Monthly Wage [$ USD]",
        'pt': "Salário Médio Mensal [$ USD]"
    },
    'jobs_label': {
        'en': "Jobs",
        'pt': "Empregos"
    },
    'kg_pct': {
        'en': "% of kg",
        'pt': "% de kg"
    },
    'value_pct': {
        'en': "% of US$",
        'pt': "% de US$"
    },
    'simple': {
        'en': "Simples",
        'pt': "Simples"
    },
    'establishment_size': {
        'en': "Establishment Size",
        'pt': "Tamanho do Estabelecimento"
    },
    'wage': {
        'en': "Salary Mass",
        'pt': "Massa Salarial"
    },
    'gender': {
        'en': "Gender",
        'pt': "Gênero"
    },
    'ethnicity': {
        'en': "Ethnicity",
        'pt': "Etnia"
    },
    'literacy': {
        'en': "Literacy",
        'pt': "Escolaridade"
    },
    'month': {
        'en': "Month",
        'pt': "Mês"
    },
    'port': {
        'en': "Port",
        'pt': "Porto"
    },
    'legal_nature': {
        'en': "Legal Nature",
        'pt': "Natureza Jurídica"
    },
    'size_establishment': {
        'en': "Establishment Size ",
        'pt': "Tamanho do Estabelecimento"
    },
    'time_resolution': {
        'en': "Time Resolution",
        'pt': "Resolução Temporal"
    },
    'total_of': {
        'en': "Total in selected years: ",
        'pt': "Total nos anos selecionados: ",
    },
    'data_provided_by': {
        'en': "Data provided by ",
        'pt': "Dados fornecidos por ",
    }

};

var formatHelper = {
    "text": function(text, params) {
        if(params.labels == false)
            return text;

        if (textHelper[text] != undefined)
            return textHelper[text][lang];

        return d3plus.string.title(text, params);
    },

    "number": function(number, params) {
        var formatted = d3plus.number.format(number, params);

        if (params.key == "value" && params.labels == undefined)
            return "$" + formatted + " USD";

        if (params.key == "kg" && params.labels == undefined)
            return formatted + " kg";

        if (params.key == "wage" && params.labels == undefined)
            return "$" + formatted + " BRL";

        if (params.key == "average_wage" && params.labels == undefined)
            return "$" + formatted + " BRL";

        if (params.key == "kg_pct" && params.labels == undefined)
            return parseFloat(formatted * 100).toFixed(1) + "%";

        if (params.key == "value_pct" && params.labels == undefined)
            return parseFloat(formatted * 100).toFixed(1) + "%";

        return formatted;
    }
};

var loadViz = function(data){
     visualization = d3plus.viz()
        .container("#bar")
        .data(data)
        .background("transparent")
        .type("bar")
        .font({
            'size': 13
        })
        .id({
            'value': currentY,
            'solo': solo
        })
        .y({
            "value": currentY,
            "scale": "discrete",
            'label': {
                'font': {
                    'size': 22
                }
            }
        })
        .x({
            "value": currentX,
            'label': {
                'font': {
                    'size': 16
                }
            }
        })
        .ui(uis)
        .format(formatHelper)
        .time({
            'value': 'year',
            'solo': {
                'value': [lastYear(data)],
                'callback': totalOfCurrentX
            }
        })
        .aggs({
            'average_wage': 'mean'
        })
        .order({
            'value': currentX,
            'sort': 'asc'
        })
        .footer({
            "value": textHelper["data_provided_by"][lang] + dataset.toUpperCase()
        })

        if(options.indexOf('singlecolor') != -1){
            visualization.color({
                "value" : function(d){
                    return "#4d90fe";
                }
            }).legend(false)
        }

        visualization.draw()
};

var getSelectedYears = function() {
    var years = $('#timeline #labels [fill="rgba(68,68,68,1)"]').map(function (index, item){
        return +item.innerHTML
    })

    years = Array.from(years);
    years = years.filter(function(item){
        return item > 0;
    });
    return years;
}

var totalOfCurrentX = function(){
    if (currentX.endsWith('_pct')){
        var years = getSelectedYears();
        var key = currentX.slice(0, currentX.indexOf('_pct'));
        var total = data.reduce(function(acc, item){
            if(years.indexOf(item.year) != -1){
                acc += item[key];
            }
            return acc;
        }, 0);
        visualization.title({
            'sub': {
                'value': textHelper["total_of"][lang] + ' ' +  formatHelper.number(total, {key: key}),
                'font': {
                    'align': 'left'
                }
            }
        })
    }
    else{
        visualization.title({
            'sub': false
        })
    }
};

var buildData = function(responseApi){

    var getAttrByName = function(item, attr){
        var index = headers.indexOf(attr);
        return item[index];
    }

    var data = [];
    var headers = responseApi.headers;

    responseApi.data.forEach(function(item){
        var dataItem = {};

        headers.forEach(function(header){
            dataItem[header] = getAttrByName(item, header);
        });

        data.push(dataItem);
    });

    return data;
}

var addPercentage = function(data){
    if(options.indexOf('percentage') == -1)
        return data;

    var groupBy = options.indexOf('month') != -1 ? 'date' : 'year';

    var total = {};

    data.forEach(function(item){
        x.forEach(function(xValue){
            if(total[xValue] == undefined)
                total[xValue] = {};

            if(total[xValue][item.year] == undefined)
                total[xValue][item.year] = 0;

            total[xValue][item.year] += item[xValue];
        });
    });

    data = data.map(function(item){
        x.forEach(function(xValue){
            item[xValue + '_pct'] = item[xValue] / total[xValue][item.year];
        });

        return item;
    });

    x.forEach(function(xValue){
        x.push(xValue + '_pct')
    });

    return data;
}

var addNameToData = function(data){
    y.forEach(function(itemY){
        data = data.map(function(item){
            if(metadatas[itemY][item[itemY]] == undefined){
                // console.log("Not found name to: " + itemY + ' - ' + item[itemY]);
                item[itemY] = 'NOT FOUND!';
            }
            else{
                item[itemY] = metadatas[itemY][item[itemY]]['name_' + lang];
            }

            return item;
        });
    });

    data = data.map(function(item){
        if(item['wage'] != undefined)
            item['wage'] = +item['wage'];

        if(item['average_wage'] != undefined)
            item['average_wage'] = +item['average_wage'];

        if(item['month'] != undefined)
            item['date'] = item['year'] + '/' + item['month'];

        return item;
    });

    if(options.indexOf('month') != -1){
        uis.push({
            'method': 'time',
            'label': 'time_resolution',
            'value': [
                {'month': 'date'},
                {'year': 'year'}
            ]
        });
    }

    return data;
};

var groupDataByCurrentY = function(data){
    var sumByItem = {};

    data.forEach(function(item){
        if(sumByItem[item[currentY]] == undefined)
            sumByItem[item[currentY]] = {
                "sum": 0,
                "name": item[currentY]
            };

        sumByItem[item[currentY]].sum += item[currentX];
    });

    var list = [];

    for(var item in sumByItem){
        list.push({
            name: sumByItem[item].name,
            sum: sumByItem[item].sum
        });
    }

    return list;
}

var getTopCurrentYNames = function(groupedData){
    var compare = function(a, b){
        if(a.sum < b.sum)
            return 1;
        if(a.sum > b.sum)
            return -1;

        return 0;
    }

    var list = groupedData.sort(compare).slice(0, MAX_BARS);

    var selected = list.map(function(item){
        return item.name;
    });

    return selected;
}

var updateSolo = function(data){
    var copiedData = (JSON.parse(JSON.stringify(data)));
    var groupedData = groupDataByCurrentY(copiedData);
    solo = getTopCurrentYNames(groupedData);

    return solo;
};

var lastYear = function(data){
    var year = 0;

    data.forEach(function(item){
        if(item.year > year)
            year = item.year;
    });

    return year;
};

var loading = dataviva.ui.loading('.loading').text(textHelper.loading[lang]);

$(document).ready(function(){
    var urls = [url];

    y.forEach(function(item){
        urls.push("http://api.staging.dataviva.info/metadata/" + item);
    });

    ajaxQueue(
        urls,
        function(responses){
            api = responses.shift();
            metadatas = {};

            y.forEach(function(item, index){
                metadatas[item] = responses[index];
            });

            data = buildData(api);
            data = addNameToData(data);
            data = addPercentage(data);
            solo = updateSolo(data);

            loading.hide();
            loadViz(data);
        }
    );
});<commit_msg>Fix percentage values<commit_after>var data = [],
    solo = [],
    MAX_BARS = 10,
    lang = document.documentElement.lang,
    dataset = $("#bar").attr("dataset"),
    options = $("#bar").attr("options").split(","),
    x = $("#bar").attr("x").split(","),
    currentX = x[0],
    y = $("#bar").attr("y").split(","),
    currentY = y[0],
    filters = $("#bar").attr("filters"),
    url = "http://api.staging.dataviva.info/" +
        dataset + "/year/" + ( options.indexOf('month') != -1 ? 'month/' : '' ) + y.join("/") + ( filters ? "?" + filters : '');

// TODO: Title creator
var title = 'Title';

var visualization;

var uis = [];

if(x.length > 1){
    uis.push({
        'value': x,
        'type': 'drop',
        'label': 'xaxis',
        'method': function(value, viz){
            currentX = value;
            viz.x(value)
               .order({
                    'value': currentX,
                    'sort': 'asc'
                })
               .draw();
               totalOfCurrentX()
        }
    });
}

if(y.length > 1){
    uis.push({
        'value': y,
        'type': 'drop',
        'label': 'yaxis',
        'method': function(value, viz){
            currentY = value;
            viz.y(value).id(value).draw();
        }
    });
}

var textHelper = {
    'loading': {
        'en': 'loading ...',
        'pt': 'carregando ...'
    },
    'average_wage': {
        'en': 'Salário Médio Mensal',
        'pt': 'Average Monthly Wage'
    },
    'jobs': {
        'en': 'Jobs',
        'pt': 'Empregos'
    },
    'year': {
        'en': 'Year',
        'pt': 'Ano'
    },
    'scale': {
        'en': "Scale",
        'pt': "Escala"
    },
    'yaxis': {
        'en': "Y-Axis",
        'pt': "Eixo Y"
    },
    'xaxis': {
        'en': "X-Axis",
        'pt': "Eixo X"
    },
    'locale': {
        'en': 'en_US',
        'pt': 'pt_BR'
    },
    'average_wage': {
        'en': "Average Wage",
        'pt': "Salário Médio"
    },
    'kg': {
        'en': 'kg',
        'pt': 'kg'
    },
    'value': {
        'en': "US$",
        'pt': "US$"
    },
    'kg_label': {
        'en': 'Amount [kg]',
        'pt': 'Quantidade [kg]'
    },
    'value_label': {
        'en': "Value [$ USD]",
        'pt': "Valor [$ USD]"
    },
    'average_wage_label': {
        'en': "Average Monthly Wage [$ USD]",
        'pt': "Salário Médio Mensal [$ USD]"
    },
    'jobs_label': {
        'en': "Jobs",
        'pt': "Empregos"
    },
    'kg_pct': {
        'en': "% of kg",
        'pt': "% de kg"
    },
    'value_pct': {
        'en': "% of US$",
        'pt': "% de US$"
    },
    'simple': {
        'en': "Simples",
        'pt': "Simples"
    },
    'establishment_size': {
        'en': "Establishment Size",
        'pt': "Tamanho do Estabelecimento"
    },
    'wage': {
        'en': "Salary Mass",
        'pt': "Massa Salarial"
    },
    'gender': {
        'en': "Gender",
        'pt': "Gênero"
    },
    'ethnicity': {
        'en': "Ethnicity",
        'pt': "Etnia"
    },
    'literacy': {
        'en': "Literacy",
        'pt': "Escolaridade"
    },
    'month': {
        'en': "Month",
        'pt': "Mês"
    },
    'port': {
        'en': "Port",
        'pt': "Porto"
    },
    'legal_nature': {
        'en': "Legal Nature",
        'pt': "Natureza Jurídica"
    },
    'size_establishment': {
        'en': "Establishment Size ",
        'pt': "Tamanho do Estabelecimento"
    },
    'time_resolution': {
        'en': "Time Resolution",
        'pt': "Resolução Temporal"
    },
    'total_of': {
        'en': "Total in selected years: ",
        'pt': "Total nos anos selecionados: ",
    },
    'data_provided_by': {
        'en': "Data provided by ",
        'pt': "Dados fornecidos por ",
    }

};

var formatHelper = {
    "text": function(text, params) {
        if(params.labels == false)
            return text;

        if (textHelper[text] != undefined)
            return textHelper[text][lang];

        return d3plus.string.title(text, params);
    },

    "number": function(number, params) {
        var formatted = d3plus.number.format(number, params);

        if (params.key == "value" && params.labels == undefined)
            return "$" + formatted + " USD";

        if (params.key == "kg" && params.labels == undefined)
            return formatted + " kg";

        if (params.key == "wage" && params.labels == undefined)
            return "$" + formatted + " BRL";

        if (params.key == "average_wage" && params.labels == undefined)
            return "$" + formatted + " BRL";

        if (params.key == "kg_pct" && params.labels == undefined)
            return parseFloat(formatted).toFixed(1) + "%";

        if (params.key == "value_pct" && params.labels == undefined)
            return parseFloat(formatted).toFixed(1) + "%";

        return formatted;
    }
};

var loadViz = function(data){
     visualization = d3plus.viz()
        .container("#bar")
        .data(data)
        .background("transparent")
        .type("bar")
        .font({
            'size': 13
        })
        .id({
            'value': currentY,
            'solo': solo
        })
        .y({
            "value": currentY,
            "scale": "discrete",
            'label': {
                'font': {
                    'size': 22
                }
            }
        })
        .x({
            "value": currentX,
            'label': {
                'font': {
                    'size': 16
                }
            }
        })
        .ui(uis)
        .format(formatHelper)
        .time({
            'value': 'year',
            'solo': {
                'value': [lastYear(data)],
                'callback': totalOfCurrentX
            }
        })
        .aggs({
            'average_wage': 'mean'
        })
        .order({
            'value': currentX,
            'sort': 'asc'
        })
        .footer({
            "value": textHelper["data_provided_by"][lang] + dataset.toUpperCase()
        })

        if(options.indexOf('singlecolor') != -1){
            visualization.color({
                "value" : function(d){
                    return "#4d90fe";
                }
            }).legend(false)
        }

        visualization.draw()
};

var getSelectedYears = function() {
    var years = $('#timeline #labels [fill="rgba(68,68,68,1)"]').map(function (index, item){
        return +item.innerHTML
    })

    years = Array.from(years);
    years = years.filter(function(item){
        return item > 0;
    });
    return years;
}

var totalOfCurrentX = function(){
    if (currentX.endsWith('_pct')){
        var years = getSelectedYears();
        var key = currentX.slice(0, currentX.indexOf('_pct'));
        var total = data.reduce(function(acc, item){
            if(years.indexOf(item.year) != -1){
                acc += item[key];
            }
            return acc;
        }, 0);
        visualization.title({
            'sub': {
                'value': textHelper["total_of"][lang] + ' ' +  formatHelper.number(total, {key: key}),
                'font': {
                    'align': 'left'
                }
            }
        })
    }
    else{
        visualization.title({
            'sub': false
        })
    }
};

var buildData = function(responseApi){

    var getAttrByName = function(item, attr){
        var index = headers.indexOf(attr);
        return item[index];
    }

    var data = [];
    var headers = responseApi.headers;

    responseApi.data.forEach(function(item){
        var dataItem = {};

        headers.forEach(function(header){
            dataItem[header] = getAttrByName(item, header);
        });

        data.push(dataItem);
    });

    return data;
}

var addPercentage = function(data){
    if(options.indexOf('percentage') == -1)
        return data;

    var groupBy = options.indexOf('month') != -1 ? 'date' : 'year';

    var total = {};

    data.forEach(function(item){
        x.forEach(function(xValue){
            if(total[xValue] == undefined)
                total[xValue] = {};

            if(total[xValue][item.year] == undefined)
                total[xValue][item.year] = 0;

            total[xValue][item.year] += item[xValue];
        });
    });

    data = data.map(function(item){
        x.forEach(function(xValue){
            item[xValue + '_pct'] = 100 * (item[xValue] / total[xValue][item.year]);
        });

        return item;
    });

    x.forEach(function(xValue){
        x.push(xValue + '_pct')
    });

    return data;
}

var addNameToData = function(data){
    y.forEach(function(itemY){
        data = data.map(function(item){
            if(metadatas[itemY][item[itemY]] == undefined){
                // console.log("Not found name to: " + itemY + ' - ' + item[itemY]);
                item[itemY] = 'NOT FOUND!';
            }
            else{
                item[itemY] = metadatas[itemY][item[itemY]]['name_' + lang];
            }

            return item;
        });
    });

    data = data.map(function(item){
        if(item['wage'] != undefined)
            item['wage'] = +item['wage'];

        if(item['average_wage'] != undefined)
            item['average_wage'] = +item['average_wage'];

        if(item['month'] != undefined)
            item['date'] = item['year'] + '/' + item['month'];

        return item;
    });

    if(options.indexOf('month') != -1){
        uis.push({
            'method': 'time',
            'label': 'time_resolution',
            'value': [
                {'month': 'date'},
                {'year': 'year'}
            ]
        });
    }

    return data;
};

var groupDataByCurrentY = function(data){
    var sumByItem = {};

    data.forEach(function(item){
        if(sumByItem[item[currentY]] == undefined)
            sumByItem[item[currentY]] = {
                "sum": 0,
                "name": item[currentY]
            };

        sumByItem[item[currentY]].sum += item[currentX];
    });

    var list = [];

    for(var item in sumByItem){
        list.push({
            name: sumByItem[item].name,
            sum: sumByItem[item].sum
        });
    }

    return list;
}

var getTopCurrentYNames = function(groupedData){
    var compare = function(a, b){
        if(a.sum < b.sum)
            return 1;
        if(a.sum > b.sum)
            return -1;

        return 0;
    }

    var list = groupedData.sort(compare).slice(0, MAX_BARS);

    var selected = list.map(function(item){
        return item.name;
    });

    return selected;
}

var updateSolo = function(data){
    var copiedData = (JSON.parse(JSON.stringify(data)));
    var groupedData = groupDataByCurrentY(copiedData);
    solo = getTopCurrentYNames(groupedData);

    return solo;
};

var lastYear = function(data){
    var year = 0;

    data.forEach(function(item){
        if(item.year > year)
            year = item.year;
    });

    return year;
};

var loading = dataviva.ui.loading('.loading').text(textHelper.loading[lang]);

$(document).ready(function(){
    var urls = [url];

    y.forEach(function(item){
        urls.push("http://api.staging.dataviva.info/metadata/" + item);
    });

    ajaxQueue(
        urls,
        function(responses){
            api = responses.shift();
            metadatas = {};

            y.forEach(function(item, index){
                metadatas[item] = responses[index];
            });

            data = buildData(api);
            data = addNameToData(data);
            data = addPercentage(data);
            solo = updateSolo(data);

            loading.hide();
            loadViz(data);
        }
    );
});<|endoftext|>


<commit_before>const fs = require('fs');
const cp = require('child_process');
const im = require('imagemagick');
const commandLineArgs = require('command-line-args');

const fullWidth = 1920;
const fullHeight = 1080;
const audioDir = './output/';
const outDir = 'clips';

const optionDefinitions = [
  { name: 'background', alias: 'b', type: String },
  { name: 'linecode', alias: 'c', type: String },
  { name: 'image', alias: 'i', type: String },
];
const options = commandLineArgs(optionDefinitions);

if (
      !options.hasOwnProperty('linecode')
   || !options.hasOwnProperty('image')
   || options.image == ''
   ) {
  // Can't do anything useful without input
  return;
}

var background = options.hasOwnProperty('background') ? options.background : 'lightgray';
var imageFile = options.image;
var imageBaseName = imageFile.split('/')[-1];
var lineCode = options.linecode;
var codeParts = lineCode.split('-');
var lineNumber = codeParts[0];
var lineIndex = codeParts[1];
var paddedCode = ('00000' + lineNumber).slice(-5) + '-' + lineIndex;
var sfxFileName = '';
var sfxFileBase = 'speech' + lineCode;
var outFileName = outDir + '/video' + paddedCode + '.mp4';
var audioFiles = fs.readdirSync(audioDir);

for (var i=0; i<audioFiles.length; i++) {
  if (audioFiles[i].startsWith(sfxFileBase)) {
    sfxFileName = audioFiles[i];
  }
}

var proc = cp.spawnSync('/usr/bin/soxi', [ '-D', audioDir + sfxFileName ]);
var time = parseFloat(proc.stdout.toString().trim(), 10);
var frameRate = 1 / time;

var width = 0;
var height = 0;

im.identify(imageFile, function (err, features) {
  if (err) throw err;
  var dir = 'Center';
  width = features.width;
  height = features.height;
  var xoff = Math.trunc((fullWidth - width) / 2);
  var yoff = Math.trunc((fullHeight - height) / 2);
  var geo = '+' + xoff + '+' + yoff;
  dir = 'North';

  im.convert([
      imageFile,
      '-resize', fullWidth + 'x' + fullHeight,
      '-gravity', dir,
      '-background', background,
      '-extent', fullWidth + 'x' + fullHeight,
      'resized_' + imageBaseName
    ], function (err, output) {
    if (err) {
      console.log(err);
    }
    cp.spawnSync('/usr/bin/ffmpeg', [
      '-framerate', frameRate,
      '-i', 'resized_' + imageBaseName,
      '-safe', '0',
      '-strict', '-2',
      '-c:v', 'libx264',
      '-b:a', '4.5M',
      '-b:v', '4.5M',
      '-minrate', '4.5M',
      '-maxrate', '4.5M',
      '-bufsize', '4.5M',
      '-r', '30',
      '-pix_fmt', 'yuv420p',
      outFileName
    ]);
    fs.unlink('resized_' + imageBaseName);
  });
});
<commit_msg>Remove unused variables<commit_after>const fs = require('fs');
const cp = require('child_process');
const im = require('imagemagick');
const commandLineArgs = require('command-line-args');

const fullWidth = 1920;
const fullHeight = 1080;
const audioDir = './output/';
const outDir = 'clips';

const optionDefinitions = [
  { name: 'background', alias: 'b', type: String },
  { name: 'linecode', alias: 'c', type: String },
  { name: 'image', alias: 'i', type: String },
];
const options = commandLineArgs(optionDefinitions);

if (
      !options.hasOwnProperty('linecode')
   || !options.hasOwnProperty('image')
   || options.image == ''
   ) {
  // Can't do anything useful without input
  return;
}

var background = options.hasOwnProperty('background') ? options.background : 'lightgray';
var imageFile = options.image;
var imageBaseName = imageFile.split('/')[-1];
var lineCode = options.linecode;
var codeParts = lineCode.split('-');
var lineNumber = codeParts[0];
var lineIndex = codeParts[1];
var paddedCode = ('00000' + lineNumber).slice(-5) + '-' + lineIndex;
var sfxFileName = '';
var sfxFileBase = 'speech' + lineCode;
var outFileName = outDir + '/video' + paddedCode + '.mp4';
var audioFiles = fs.readdirSync(audioDir);

for (var i=0; i<audioFiles.length; i++) {
  if (audioFiles[i].startsWith(sfxFileBase)) {
    sfxFileName = audioFiles[i];
  }
}

var proc = cp.spawnSync('/usr/bin/soxi', [ '-D', audioDir + sfxFileName ]);
var time = parseFloat(proc.stdout.toString().trim(), 10);
var frameRate = 1 / time;

im.identify(imageFile, function (err) {
  if (err) throw err;
  var dir = 'Center';
  dir = 'North';

  im.convert([
      imageFile,
      '-resize', fullWidth + 'x' + fullHeight,
      '-gravity', dir,
      '-background', background,
      '-extent', fullWidth + 'x' + fullHeight,
      'resized_' + imageBaseName
    ], function (err) {
    if (err) {
      console.log(err);
    }
    cp.spawnSync('/usr/bin/ffmpeg', [
      '-framerate', frameRate,
      '-i', 'resized_' + imageBaseName,
      '-safe', '0',
      '-strict', '-2',
      '-c:v', 'libx264',
      '-b:a', '4.5M',
      '-b:v', '4.5M',
      '-minrate', '4.5M',
      '-maxrate', '4.5M',
      '-bufsize', '4.5M',
      '-r', '30',
      '-pix_fmt', 'yuv420p',
      outFileName
    ]);
    fs.unlink('resized_' + imageBaseName);
  });
});
<|endoftext|>


<commit_before>/** @babel */
/** @jsx etch.dom */

import {CompositeDisposable, Disposable} from 'atom'
import etch from 'etch'

import HunkView from './hunk-view'
import FilePatchSelection from './file-patch-selection'

const EMPTY_SET = new Set()

export default class FilePatchView {
  constructor (props) {
    this.props = props
    this.selection = new FilePatchSelection(this.props.hunks)

    this.mouseSelectionInProgress = false
    this.mousedownOnLine = this.mousedownOnLine.bind(this)
    this.mousemoveOnLine = this.mousemoveOnLine.bind(this)
    this.mouseup = this.mouseup.bind(this)
    window.addEventListener('mouseup', this.mouseup)
    this.disposables = new CompositeDisposable()
    this.disposables.add(new Disposable(() => window.removeEventListener('mouseup', this.mouseup)))

    etch.initialize(this)
    this.disposables.add(atom.commands.add(this.element, {
      'git:toggle-patch-selection-mode': this.togglePatchSelectionMode.bind(this),
      'core:confirm': () => this.stageSelectedLines(),
      'core:move-up': () => this.selectPrevious(),
      'core:move-down': () => this.selectNext(),
      'core:move-to-top': () => this.selectFirst(),
      'core:move-to-bottom': () => this.selectLast(),
      'core:select-up': () => this.selectToPrevious(),
      'core:select-down': () => this.selectToNext(),
      'core:select-to-top': () => this.selectToFirst(),
      'core:select-to-bottom': () => this.selectToLast(),
      'core:select-all': () => this.selectAll()
    }))
  }

  update (props) {
    this.props = props
    this.selection.updateHunks(this.props.hunks)
    return etch.update(this)
  }

  destroy () {
    this.disposables.dispose()
    return etch.destroy(this)
  }

  render () {
    const selectedHunks = this.selection.getSelectedHunks()
    const selectedLines = this.selection.getSelectedLines()
    const stageButtonLabelPrefix = this.props.stagingStatus === 'unstaged' ? 'Stage' : 'Unstage'
    return (

        {this.props.hunks.map((hunk) => {
          const isSelected = selectedHunks.has(hunk)
          const stageButtonLabel =
            stageButtonLabelPrefix +
              ((this.selection.getMode() === 'hunk' || !isSelected) ? ' Hunk' : ' Selection')

          return (
            <HunkView
              hunk={hunk}
              isSelected={selectedHunks.has(hunk)}
              stageButtonLabel={stageButtonLabel}
              selectedLines={selectedLines}
              mousedownOnHeader={() => this.mousedownOnHeader(hunk)}
              mousedownOnLine={this.mousedownOnLine}
              mousemoveOnLine={this.mousemoveOnLine}
              didClickStageButton={() => this.didClickStageButtonForHunk(hunk)}
              registerView={this.props.registerHunkView} />
          )
        })}

    )
  }

  mousedownOnHeader (hunk) {
    this.selection.selectHunk(hunk)
    this.mouseSelectionInProgress = true
    return etch.update(this)
  }

  mousedownOnLine (event, hunk, line) {
    if (event.ctrlKey || event.metaKey) {
      this.selection.addOrSubtractLineSelection(line)
    } else if (event.shiftKey) {
      if (this.selection.getMode() === 'hunk') {
        this.selection.selectHunk(hunk, true)
      } else {
        this.selection.selectLine(line, true)
      }
    } else {
      if (event.detail === 1) {
        this.selection.selectLine(line, false)
      } else {
        this.selection.selectHunk(hunk, false)
      }
    }
    this.mouseSelectionInProgress = true
    return etch.update(this)
  }

  mousemoveOnLine (event, hunk, line) {
    if (this.mouseSelectionInProgress) {
      if (this.selection.getMode() === 'hunk') {
        this.selection.selectHunk(hunk, true)
      } else {
        this.selection.selectLine(line, true)
      }
      return etch.update(this)
    }
  }

  mouseup (event, hunk, line) {
    this.mouseSelectionInProgress = false
    this.selection.coalesce()
  }

  togglePatchSelectionMode () {
    this.selection.toggleMode()
    return etch.update(this)
  }

  selectNext () {
    this.selection.selectNext()
    return etch.update(this)
  }

  selectToNext () {
    this.selection.selectNext(true)
    this.selection.coalesce()
    return etch.update(this)
  }

  selectPrevious () {
    this.selection.selectPrevious()
    return etch.update(this)
  }

  selectToPrevious () {
    this.selection.selectPrevious(true)
    this.selection.coalesce()
    return etch.update(this)
  }

  selectFirst () {
    this.selection.selectFirst()
    return etch.update(this)
  }

  selectToFirst () {
    this.selection.selectFirst(true)
    return etch.update(this)
  }

  selectLast () {
    this.selection.selectLast()
    return etch.update(this)
  }

  selectToLast () {
    this.selection.selectLast(true)
    return etch.update(this)
  }

  selectAll () {
    this.selection.selectAll()
    return etch.update(this)
  }

  didClickStageButtonForHunk (hunk) {
    if (this.selection.getMode() === 'line' && this.selection.getSelectedHunks().has(hunk)) {
      return this.stageSelectedLines()
    } else {
      return this.stageHunk(hunk)
    }
  }

  stageSelectedLines () {
    const selectedLines = this.selection.getSelectedLines()
    if (this.props.stagingStatus === 'unstaged') {
      return this.props.stageLines(selectedLines)
    } else if (this.props.stagingStatus === 'staged') {
      return this.props.unstageLines(selectedLines)
    } else {
      throw new Error(`Unknown stagingStatus: ${this.props.stagingStatus}`)
    }
  }

  stageHunk (hunk) {
    if (this.props.stagingStatus === 'unstaged') {
      return this.props.stageHunk(hunk)
    } else if (this.props.stagingStatus === 'staged') {
      return this.props.unstageHunk(hunk)
    } else {
      throw new Error(`Unknown stagingStatus: ${this.props.stagingStatus}`)
    }
  }
}
<commit_msg>Remove unused method parameters<commit_after>/** @babel */
/** @jsx etch.dom */

import {CompositeDisposable, Disposable} from 'atom'
import etch from 'etch'

import HunkView from './hunk-view'
import FilePatchSelection from './file-patch-selection'

const EMPTY_SET = new Set()

export default class FilePatchView {
  constructor (props) {
    this.props = props
    this.selection = new FilePatchSelection(this.props.hunks)

    this.mouseSelectionInProgress = false
    this.mousedownOnLine = this.mousedownOnLine.bind(this)
    this.mousemoveOnLine = this.mousemoveOnLine.bind(this)
    this.mouseup = this.mouseup.bind(this)
    window.addEventListener('mouseup', this.mouseup)
    this.disposables = new CompositeDisposable()
    this.disposables.add(new Disposable(() => window.removeEventListener('mouseup', this.mouseup)))

    etch.initialize(this)
    this.disposables.add(atom.commands.add(this.element, {
      'git:toggle-patch-selection-mode': this.togglePatchSelectionMode.bind(this),
      'core:confirm': () => this.stageSelectedLines(),
      'core:move-up': () => this.selectPrevious(),
      'core:move-down': () => this.selectNext(),
      'core:move-to-top': () => this.selectFirst(),
      'core:move-to-bottom': () => this.selectLast(),
      'core:select-up': () => this.selectToPrevious(),
      'core:select-down': () => this.selectToNext(),
      'core:select-to-top': () => this.selectToFirst(),
      'core:select-to-bottom': () => this.selectToLast(),
      'core:select-all': () => this.selectAll()
    }))
  }

  update (props) {
    this.props = props
    this.selection.updateHunks(this.props.hunks)
    return etch.update(this)
  }

  destroy () {
    this.disposables.dispose()
    return etch.destroy(this)
  }

  render () {
    const selectedHunks = this.selection.getSelectedHunks()
    const selectedLines = this.selection.getSelectedLines()
    const stageButtonLabelPrefix = this.props.stagingStatus === 'unstaged' ? 'Stage' : 'Unstage'
    return (

        {this.props.hunks.map((hunk) => {
          const isSelected = selectedHunks.has(hunk)
          const stageButtonLabel =
            stageButtonLabelPrefix +
              ((this.selection.getMode() === 'hunk' || !isSelected) ? ' Hunk' : ' Selection')

          return (
            <HunkView
              hunk={hunk}
              isSelected={selectedHunks.has(hunk)}
              stageButtonLabel={stageButtonLabel}
              selectedLines={selectedLines}
              mousedownOnHeader={() => this.mousedownOnHeader(hunk)}
              mousedownOnLine={this.mousedownOnLine}
              mousemoveOnLine={this.mousemoveOnLine}
              didClickStageButton={() => this.didClickStageButtonForHunk(hunk)}
              registerView={this.props.registerHunkView} />
          )
        })}

    )
  }

  mousedownOnHeader (hunk) {
    this.selection.selectHunk(hunk)
    this.mouseSelectionInProgress = true
    return etch.update(this)
  }

  mousedownOnLine (event, hunk, line) {
    if (event.ctrlKey || event.metaKey) {
      this.selection.addOrSubtractLineSelection(line)
    } else if (event.shiftKey) {
      if (this.selection.getMode() === 'hunk') {
        this.selection.selectHunk(hunk, true)
      } else {
        this.selection.selectLine(line, true)
      }
    } else {
      if (event.detail === 1) {
        this.selection.selectLine(line, false)
      } else {
        this.selection.selectHunk(hunk, false)
      }
    }
    this.mouseSelectionInProgress = true
    return etch.update(this)
  }

  mousemoveOnLine (event, hunk, line) {
    if (this.mouseSelectionInProgress) {
      if (this.selection.getMode() === 'hunk') {
        this.selection.selectHunk(hunk, true)
      } else {
        this.selection.selectLine(line, true)
      }
      return etch.update(this)
    }
  }

  mouseup () {
    this.mouseSelectionInProgress = false
    this.selection.coalesce()
  }

  togglePatchSelectionMode () {
    this.selection.toggleMode()
    return etch.update(this)
  }

  selectNext () {
    this.selection.selectNext()
    return etch.update(this)
  }

  selectToNext () {
    this.selection.selectNext(true)
    this.selection.coalesce()
    return etch.update(this)
  }

  selectPrevious () {
    this.selection.selectPrevious()
    return etch.update(this)
  }

  selectToPrevious () {
    this.selection.selectPrevious(true)
    this.selection.coalesce()
    return etch.update(this)
  }

  selectFirst () {
    this.selection.selectFirst()
    return etch.update(this)
  }

  selectToFirst () {
    this.selection.selectFirst(true)
    return etch.update(this)
  }

  selectLast () {
    this.selection.selectLast()
    return etch.update(this)
  }

  selectToLast () {
    this.selection.selectLast(true)
    return etch.update(this)
  }

  selectAll () {
    this.selection.selectAll()
    return etch.update(this)
  }

  didClickStageButtonForHunk (hunk) {
    if (this.selection.getMode() === 'line' && this.selection.getSelectedHunks().has(hunk)) {
      return this.stageSelectedLines()
    } else {
      return this.stageHunk(hunk)
    }
  }

  stageSelectedLines () {
    const selectedLines = this.selection.getSelectedLines()
    if (this.props.stagingStatus === 'unstaged') {
      return this.props.stageLines(selectedLines)
    } else if (this.props.stagingStatus === 'staged') {
      return this.props.unstageLines(selectedLines)
    } else {
      throw new Error(`Unknown stagingStatus: ${this.props.stagingStatus}`)
    }
  }

  stageHunk (hunk) {
    if (this.props.stagingStatus === 'unstaged') {
      return this.props.stageHunk(hunk)
    } else if (this.props.stagingStatus === 'staged') {
      return this.props.unstageHunk(hunk)
    } else {
      throw new Error(`Unknown stagingStatus: ${this.props.stagingStatus}`)
    }
  }
}
<|endoftext|>


<commit_before>describe('SkillService', function() {
  var skillService;
  var email_skill_0 = 'skill_0@example.com';
  var email_skill_1 = 'skill_1@example.com';
  var email_skill_2 = 'skill_2@example.com';
  var email_skill_uy = 'skill_uy@example.com';

  beforeAll(function() {
    skillService = new SkillService();
    skillService.putSkill(email_skill_1, "UX", true);
    skillService.putSkill(email_skill_2, "UY", true);
    skillService.putSkill(email_skill_2, "UZ", true);
    skillService.putSkill(email_skill_uy, "UY", true);
  })

  beforeEach(function() {

  });

  describe('I should be able to search for Users with specific skills', function() {
    //it('for a skill with no user', function() {
    //  users = skillService.getUsersBySkill('NO_SUCH_SKILLYADAYADYADYADYADYADYADYADYAD');
    //  expect(users.length).toBe(0);
    //});

    it('for a skill with one user', function() {
      users = skillService.getUsersBySkill('UX');
      expect(users.indexOf(email_skill_1)).not.toEqual(-1);
    });

    //it('for a skill with two users', function() {
    //  users = skillService.getUserBySkill('UY');
    //  expect(users.indexOf(email_skill_2)).not.toEqual(-1);
    //  expect(users.indexOf(email_skill_uy)).not.toEqual(-1);
    //});
    //
    //it('it does not return a user that I know does not have the skill', function() {
    //  users = skillService.getUserBySkill('UX');
    //  expect(users.find(email_skill_0)).toBe(false);
    //});

  })

  describe('I should be able to read the skills for a specific user', function() {

    it('for a user with no skills getSkills() should return an empty array', function () {
      expect(skillService.getSkills(email_skill_0)).toEqual([]);
    });

    it('for a user with one skill getSkills() should return one skill', function () {
      skills = skillService.getSkills(email_skill_1);
      expect(skills.length).toEqual(1);
      expect(skills[0].skill).toEqual("UX");
    })
  });

  it("hasSkill() should return false if a matching skill is not present in the collection", function() {
    var booleanValue = skillService.hasSkill("someone@somesite.net", "Bikeshedding");
    expect(booleanValue).toBe(false);
  });

  it("hasSkill() should return true if a matching skill is present in the collection", function() {
    var skillDoc = skillService.createSkillDoc("dude@gap.co", "Gradle", true);
    var id = Skills.insert(skillDoc);
    expect(id).not.toBeFalsy();
    var has = skillService.hasSkill("dude@gap.co", "Gradle");
    expect(has).toBe(true);
  });

  it("putSkill() should put another skill document in the skills collection", function () {
    var selector = {email: "user@ducking-nemesis.org", key: "literate programming"};
    skillService.putSkill(selector.email, selector.key, false);
    var docFromColl = Skills.findOne(selector);
    expect(docFromColl).not.toBeFalsy();
  });

  it("putSkill should not put duplicate skills in the collection", function() {
    var skill = "DRY code";
    var selector = {email: "somebody@pillar.org", key: skillService.generateKey(skill)};
    skillService.putSkill(selector.email, skill, true);
    skillService.putSkill(selector.email, skill, true);
    var skillsArray =  Skills.find(selector).fetch();
    expect(skillsArray.length).toEqual(1);
  });

  it("putSkill should update display name and isMentorable", function() {
      var email = 'somebody@somesite.gov';
      Skills.remove({email: email});
      skillService.putSkill(email, 'statecraft', false);
      skillService.putSkill(email, 'StateCraft', true);
      var skillsArray = skillService.getSkills(email);
      var skillDoc = skillsArray[0];
      var skillDisplayName = skillDoc.skill;
      expect(skillDisplayName).toEqual('StateCraft');
      var skillIsMentorable = skillDoc.isMentorable;
      expect(skillIsMentorable).toBe(true);
  });

  it("getSkills should return a list sorted by downcased skill name", function () {
    var email = 'somebody@someothersite.io';
    Skills.remove({email: email});
    skillService.putSkill(email, 'erlang', false);
    skillService.putSkill(email, 'Clojure', false);
    skillService.putSkill(email, 'Aspect Oriented Programming', true);
    skillService.putSkill(email, 'Go', true);
    skillService.putSkill(email, 'Behavior Driven Development', false);
    skillService.putSkill(email, 'Haskell', true);
    skillService.putSkill(email, 'data science', true);
    skillService.putSkill(email, 'F#', false);

    var skillsArray = skillService.getSkills(email);

    function expectation(index, expectedSkill) {
      var skillDoc = skillsArray[index];
      var actual = skillDoc.skill;
      expect(actual).toEqual(expectedSkill);
    }

    expectation(0, 'Aspect Oriented Programming');
    expectation(1, 'Behavior Driven Development');
    expectation(2, 'Clojure');
    expectation(3, 'data science');
    expectation(4, 'erlang');
    expectation(5, 'F#');
    expectation(6, 'Go');
    expectation(7, 'Haskell');
  });

  it("removeSkill should remove a skill from the collection", function() {
    var email = 'brogrammer@somesite.org';
    Skills.remove({email: email});
    skillService.putSkill(email, 'Go', true);
    skillService.putSkill(email, 'Haskell', true);
    skillService.removeSkill(email, 'Go');
    var skillsArray = skillService.getSkills(email);
    expect(skillsArray.length).toEqual(1);
    expect(skillsArray[0].skill).toEqual('Haskell');
  })

});
<commit_msg>Integration tests for search by skill in SkillServiceSpec.js<commit_after>describe('SkillService', function() {
  var skillService;
  var email_skill_0 = 'skill_0@example.com';
  var email_skill_1 = 'skill_1@example.com';
  var email_skill_2 = 'skill_2@example.com';
  var email_skill_uy = 'skill_uy@example.com';

  beforeAll(function() {
    skillService = new SkillService();
    skillService.putSkill(email_skill_1, "UX", true);
    skillService.putSkill(email_skill_2, "UY", true);
    skillService.putSkill(email_skill_2, "UZ", true);
    skillService.putSkill(email_skill_uy, "UY", true);
  });

  beforeEach(function() {

  });

  describe('I should be able to search for Users with specific skills', function() {
    it('for a skill with no user', function() {
      users = skillService.getUsersBySkill('NO_SUCH_SKILLYADAYADYADYADYADYADYADYADYAD');
      expect(users.length).toBe(0);
    });

    it('for a skill with one user', function() {
      users = skillService.getUsersBySkill('UX');
      expect(users.indexOf(email_skill_1)).not.toEqual(-1);
    });

    it('for a skill with two users', function() {
      users = skillService.getUsersBySkill('UY');
      expect(users.indexOf(email_skill_2)).not.toEqual(-1);
      expect(users.indexOf(email_skill_uy)).not.toEqual(-1);
    });

    it('it does not return a user that I know does not have the skill', function() {
      users = skillService.getUsersBySkill('UX');
      expect(users.indexOf(email_skill_0)).toEqual(-1);
    });

  });

  describe('I should be able to read the skills for a specific user', function() {

    it('for a user with no skills getSkills() should return an empty array', function () {
      expect(skillService.getSkills(email_skill_0)).toEqual([]);
    });

    it('for a user with one skill getSkills() should return one skill', function () {
      skills = skillService.getSkills(email_skill_1);
      expect(skills.length).toEqual(1);
      expect(skills[0].skill).toEqual("UX");
    })
  });

  it("hasSkill() should return false if a matching skill is not present in the collection", function() {
    var booleanValue = skillService.hasSkill("someone@somesite.net", "Bikeshedding");
    expect(booleanValue).toBe(false);
  });

  it("hasSkill() should return true if a matching skill is present in the collection", function() {
    var skillDoc = skillService.createSkillDoc("dude@gap.co", "Gradle", true);
    var id = Skills.insert(skillDoc);
    expect(id).not.toBeFalsy();
    var has = skillService.hasSkill("dude@gap.co", "Gradle");
    expect(has).toBe(true);
  });

  it("putSkill() should put another skill document in the skills collection", function () {
    var selector = {email: "user@ducking-nemesis.org", key: "literate programming"};
    skillService.putSkill(selector.email, selector.key, false);
    var docFromColl = Skills.findOne(selector);
    expect(docFromColl).not.toBeFalsy();
  });

  it("putSkill should not put duplicate skills in the collection", function() {
    var skill = "DRY code";
    var selector = {email: "somebody@pillar.org", key: skillService.generateKey(skill)};
    skillService.putSkill(selector.email, skill, true);
    skillService.putSkill(selector.email, skill, true);
    var skillsArray =  Skills.find(selector).fetch();
    expect(skillsArray.length).toEqual(1);
  });

  it("putSkill should update display name and isMentorable", function() {
      var email = 'somebody@somesite.gov';
      Skills.remove({email: email});
      skillService.putSkill(email, 'statecraft', false);
      skillService.putSkill(email, 'StateCraft', true);
      var skillsArray = skillService.getSkills(email);
      var skillDoc = skillsArray[0];
      var skillDisplayName = skillDoc.skill;
      expect(skillDisplayName).toEqual('StateCraft');
      var skillIsMentorable = skillDoc.isMentorable;
      expect(skillIsMentorable).toBe(true);
  });

  it("getSkills should return a list sorted by downcased skill name", function () {
    var email = 'somebody@someothersite.io';
    Skills.remove({email: email});
    skillService.putSkill(email, 'erlang', false);
    skillService.putSkill(email, 'Clojure', false);
    skillService.putSkill(email, 'Aspect Oriented Programming', true);
    skillService.putSkill(email, 'Go', true);
    skillService.putSkill(email, 'Behavior Driven Development', false);
    skillService.putSkill(email, 'Haskell', true);
    skillService.putSkill(email, 'data science', true);
    skillService.putSkill(email, 'F#', false);

    var skillsArray = skillService.getSkills(email);

    function expectation(index, expectedSkill) {
      var skillDoc = skillsArray[index];
      var actual = skillDoc.skill;
      expect(actual).toEqual(expectedSkill);
    }

    expectation(0, 'Aspect Oriented Programming');
    expectation(1, 'Behavior Driven Development');
    expectation(2, 'Clojure');
    expectation(3, 'data science');
    expectation(4, 'erlang');
    expectation(5, 'F#');
    expectation(6, 'Go');
    expectation(7, 'Haskell');
  });

  it("removeSkill should remove a skill from the collection", function() {
    var email = 'brogrammer@somesite.org';
    Skills.remove({email: email});
    skillService.putSkill(email, 'Go', true);
    skillService.putSkill(email, 'Haskell', true);
    skillService.removeSkill(email, 'Go');
    var skillsArray = skillService.getSkills(email);
    expect(skillsArray.length).toEqual(1);
    expect(skillsArray[0].skill).toEqual('Haskell');
  })

});
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Tue Jun 02 2015 11:17:18 GMT+0200 (Paris, Madrid (heure d’été))

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: './test',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['qunit'],

    // list of files / patterns to load in the browser
    files: [
      '../dist/mp4box.all.js',
      'qunit-helper.js',
      'qunit-media-data.js',
      'qunit-box-data.js',
      'qunit-tests.js',
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome', 'ChromeCanary', 'Firefox', 'IE'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    //browserDisconnectTimeout : 10000, // default 2000
    //browserDisconnectTolerance : 1, // default 0
    //browserNoActivityTimeout : 60000, //default 10000
  });
};
<commit_msg>simplify karma for now<commit_after>// Karma configuration
// Generated on Tue Jun 02 2015 11:17:18 GMT+0200 (Paris, Madrid (heure d’été))

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: './test',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['qunit'],

    // list of files / patterns to load in the browser
    files: [
      '../dist/mp4box.all.js',
      'qunit-helper.js',
      'qunit-media-data.js',
      'qunit-box-data.js',
      'qunit-tests.js',
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    //browserDisconnectTimeout : 10000, // default 2000
    //browserDisconnectTolerance : 1, // default 0
    //browserNoActivityTimeout : 60000, //default 10000
  });
};
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import Highlight from 'react-highlight'

import pkg from 'package.json'
import {
  Container,
  Divider,
  Grid,
  Header,
  Icon,
  Label,
  List,
  Message,
  Segment,
} from 'src'
import Logo from '../Components/Logo/Logo'

const AccordionJSX = `const panels = [{
  title: 'What is a dog?',
  content: '...',
  }, {
  title: 'What kinds are there?',
  content: '...',
}]

<Accordion panels={panels} />`
const AccordionHTML = `

    What is a dog?

...

    What kinds are there?

...

`

const ButtonJSX = `<Button size='small' color='green'>
  <Icon name='download' />
  Download
</Button>`
const ButtonHTML = `<button class="ui small green button">

  Download
</button>`
const LabelJSX = ""
const LabelHTML = `

`
const RatingJSX = '<Rating rating={1} maxRating={5} />'
const RatingHTML = `

`

const MessageIconJSX = `<Message
  success
  icon='thumbs up'
  header='Nice job!'
  content='Your profile is complete.'
/>`
const MessageIconHTML = `

      Nice job!

    Your profile is complete.

`

const MessageSubComponentsJSX = `<Message icon>
  <Icon name='circle notched' loading />
  <Message.Content>
    <Message.Header>
      Just one second
    </Message.Header>
    We're fetching that content for you.
  </Message.Content>
</Message>`
const MessageSubComponentsHTML = `

      Just one second

    We're fetching that content for you.

`
const HeaderAugmentationJSX = `
  Learn More
`
const HeaderAugmentationHTML = `

  Learn More

`
const MenuItemLinkAugmentationJSX = `import { Link } from 'react-router'

<Menu>
  <MenuItem as={Link} to='/home'>
    Home
  </MenuItem>
</Menu>`
const MenuItemLinkAugmentationHTML = `

    Learn More

`

const Comparison = ({ jsx, html }) => (
  <Segment className='code-example'>
    <Grid columns='equal' centered textAlign='left'>
      <Grid.Column mobile='16' tablet='16' computer='8' largeScreen='7'>
        JSX
        <Highlight className='language-javascript'>
          {jsx}
        </Highlight>
      </Grid.Column>
      <Grid.Column only='large screen' textAlign='center'>
        <Divider vertical>
          <Icon name='right arrow circle' />
        </Divider>
      </Grid.Column>
      <Grid.Column mobile='16' tablet='16' computer='8' largeScreen='7'>
        Rendered HTML
        <Highlight className='language-html'>
          {html}
        </Highlight>
      </Grid.Column>
    </Grid>
  </Segment>
)

Comparison.propTypes = {
  /** An element type to render as (string or function). */
  as: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.func,
  ]),

  jsx: PropTypes.string,
  html: PropTypes.string,
}

const Introduction = () => (
  <Container id='introduction-page'>
    <Segment className='center aligned basic'>
      <Logo centered size='small' />

        Semantic-UI-React

          {pkg.description}

    </Segment>

    <Segment className='basic padded'>
      Install
      <Message>

$ npm install {pkg.name}

      </Message>
      <List>
        <List.Item icon='check mark'>jQuery Free</List.Item>
        <List.Item icon='check mark'>Declarative API</List.Item>
        <List.Item icon='check mark'>Augmentation</List.Item>
        <List.Item icon='check mark'>Shorthand Props</List.Item>
        <List.Item icon='check mark'>Sub Components</List.Item>
        <List.Item icon='check mark'>Auto Controlled State</List.Item>
      </List>
    </Segment>

    {/* ----------------------------------------
     *  jQuery Free
     * -------------------------------------- */}
    <Segment className='basic padded'>
      jQuery Free

        jQuery is a DOM manipulation library. It reads from and writes to the DOM.
        React uses a virtual DOM (a JavaScript representation of the real DOM).
        React only writes patch updates to the DOM, but never reads from it.

        It is not feasible to keep real DOM manipulations in sync with React's virtual DOM. Because of this, all
        jQuery functionality has been re-implemented in React.

    </Segment>

    {/* ----------------------------------------
     *  Declarative API
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Declarative API

        Declarative APIs provide for robust features and prop validation.

      <Comparison jsx={RatingJSX} html={RatingHTML} />
      <Comparison jsx={ButtonJSX} html={ButtonHTML} />
    </Segment>

    {/* ----------------------------------------
     *  Augmentation
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Augmentation

        Control the rendered HTML tag, or render one component as another component.
        Extra props are passed to the component you are rending as.

        Augmentation is powerful. You can compose component features and props without adding extra nested components.
        This is essential for working with MenuLinks and react-router.

      <Comparison jsx={HeaderAugmentationJSX} html={HeaderAugmentationHTML} />
      <Comparison jsx={MenuItemLinkAugmentationJSX} html={MenuItemLinkAugmentationHTML} />
    </Segment>

    {/* ----------------------------------------
     *  Shorthand Props
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Shorthand Props

        Shorthand props generate markup for you, making many use cases a breeze.
        All object props are spread on the child components.

      Child Object Arrays

        Components with repeating children accept arrays of plain objects.

           Facebook is fond of this

        over using context to handle parent-child coupling and so are we.

      <Comparison jsx={AccordionJSX} html={AccordionHTML} />

      {'icon={...}'}

        The icon prop is standard for many components.
        It can accept an Icon name, an Icon props object, or an {'<Icon />'} instance.

      <Comparison jsx={MessageIconJSX} html={MessageIconHTML} />

      {'image={...}'}

        The image prop is standard for many components.
        It can accept an image src, an Image props object, or an {'<Image />'} instance.

      <Comparison jsx={LabelJSX} html={LabelHTML} />
    </Segment>

    {/* ----------------------------------------
     *  Sub Components
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Sub Components

        Sub components give you complete access to the markup.
        This is essential for flexibility in customizing components.

      <Comparison jsx={MessageSubComponentsJSX} html={MessageSubComponentsHTML} />
    </Segment>

    {/* ----------------------------------------
     *  Auto Controlled State
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Auto Controlled State

        React has the concept of

           controlled and uncontrolled

        components.

        Our stateful components self manage their state out of the box, without wiring. Dropdowns open on click without
        wiring onClick to the open prop. The value is also stored internally, without
        wiring onChange to value.

        If you add a value prop or an open prop, the Dropdown delegates control for that
        one prop to your value. The other props remain auto controlled. Mix and match any number of controlled and
        uncontrolled props. Add and remove control at any time by adding or removing props. Everything just works.

        Take a look at our

           AutoControlledComponent

        to see how this was done.
        See the docs try it out live.

      <Divider hidden section />
      <Divider hidden section />
      <Divider hidden section />
    </Segment>
  </Container>
)

export default Introduction
<commit_msg>fix(Docs): Comparison width fix (#438)<commit_after>import React, { PropTypes } from 'react'
import Highlight from 'react-highlight'

import pkg from 'package.json'
import {
  Container,
  Divider,
  Grid,
  Header,
  Icon,
  Label,
  List,
  Message,
  Segment,
} from 'src'
import Logo from '../Components/Logo/Logo'

const AccordionJSX = `const panels = [{
  title: 'What is a dog?',
  content: '...',
  }, {
  title: 'What kinds are there?',
  content: '...',
}]

<Accordion panels={panels} />`
const AccordionHTML = `

    What is a dog?

...

    What kinds are there?

...

`

const ButtonJSX = `<Button size='small' color='green'>
  <Icon name='download' />
  Download
</Button>`
const ButtonHTML = `<button class="ui small green button">

  Download
</button>`
const LabelJSX = ""
const LabelHTML = `

`
const RatingJSX = '<Rating rating={1} maxRating={5} />'
const RatingHTML = `

`

const MessageIconJSX = `<Message
  success
  icon='thumbs up'
  header='Nice job!'
  content='Your profile is complete.'
/>`
const MessageIconHTML = `

      Nice job!

    Your profile is complete.

`

const MessageSubComponentsJSX = `<Message icon>
  <Icon name='circle notched' loading />
  <Message.Content>
    <Message.Header>
      Just one second
    </Message.Header>
    We're fetching that content for you.
  </Message.Content>
</Message>`
const MessageSubComponentsHTML = `

      Just one second

    We're fetching that content for you.

`
const HeaderAugmentationJSX = `
  Learn More
`
const HeaderAugmentationHTML = `

  Learn More

`
const MenuItemLinkAugmentationJSX = `import { Link } from 'react-router'

<Menu>
  <MenuItem as={Link} to='/home'>
    Home
  </MenuItem>
</Menu>`
const MenuItemLinkAugmentationHTML = `

    Learn More

`

const Comparison = ({ jsx, html }) => (
  <Segment className='code-example'>
    <Grid columns='equal' centered textAlign='left'>
      <Grid.Column computer='8' largeScreen='7' widescreen='7' width='16'>
        JSX
        <Highlight className='language-javascript'>
          {jsx}
        </Highlight>
      </Grid.Column>
      <Grid.Column largeScreen='2' only='large screen' textAlign='center'>
        <Divider vertical>
          <Icon name='right arrow circle' />
        </Divider>
      </Grid.Column>
      <Grid.Column computer='8' largeScreen='7' widescreen='7' width='16'>
        Rendered HTML
        <Highlight className='language-html'>
          {html}
        </Highlight>
      </Grid.Column>
    </Grid>
  </Segment>
)

Comparison.propTypes = {
  /** An element type to render as (string or function). */
  as: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.func,
  ]),

  jsx: PropTypes.string,
  html: PropTypes.string,
}

const Introduction = () => (
  <Container id='introduction-page'>
    <Segment className='center aligned basic'>
      <Logo centered size='small' />

        Semantic-UI-React

          {pkg.description}

    </Segment>

    <Segment className='basic padded'>
      Install
      <Message>

$ npm install {pkg.name}

      </Message>
      <List>
        <List.Item icon='check mark'>jQuery Free</List.Item>
        <List.Item icon='check mark'>Declarative API</List.Item>
        <List.Item icon='check mark'>Augmentation</List.Item>
        <List.Item icon='check mark'>Shorthand Props</List.Item>
        <List.Item icon='check mark'>Sub Components</List.Item>
        <List.Item icon='check mark'>Auto Controlled State</List.Item>
      </List>
    </Segment>

    {/* ----------------------------------------
     *  jQuery Free
     * -------------------------------------- */}
    <Segment className='basic padded'>
      jQuery Free

        jQuery is a DOM manipulation library. It reads from and writes to the DOM.
        React uses a virtual DOM (a JavaScript representation of the real DOM).
        React only writes patch updates to the DOM, but never reads from it.

        It is not feasible to keep real DOM manipulations in sync with React's virtual DOM. Because of this, all
        jQuery functionality has been re-implemented in React.

    </Segment>

    {/* ----------------------------------------
     *  Declarative API
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Declarative API

        Declarative APIs provide for robust features and prop validation.

      <Comparison jsx={RatingJSX} html={RatingHTML} />
      <Comparison jsx={ButtonJSX} html={ButtonHTML} />
    </Segment>

    {/* ----------------------------------------
     *  Augmentation
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Augmentation

        Control the rendered HTML tag, or render one component as another component.
        Extra props are passed to the component you are rending as.

        Augmentation is powerful. You can compose component features and props without adding extra nested components.
        This is essential for working with MenuLinks and react-router.

      <Comparison jsx={HeaderAugmentationJSX} html={HeaderAugmentationHTML} />
      <Comparison jsx={MenuItemLinkAugmentationJSX} html={MenuItemLinkAugmentationHTML} />
    </Segment>

    {/* ----------------------------------------
     *  Shorthand Props
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Shorthand Props

        Shorthand props generate markup for you, making many use cases a breeze.
        All object props are spread on the child components.

      Child Object Arrays

        Components with repeating children accept arrays of plain objects.

           Facebook is fond of this

        over using context to handle parent-child coupling and so are we.

      <Comparison jsx={AccordionJSX} html={AccordionHTML} />

      {'icon={...}'}

        The icon prop is standard for many components.
        It can accept an Icon name, an Icon props object, or an {'<Icon />'} instance.

      <Comparison jsx={MessageIconJSX} html={MessageIconHTML} />

      {'image={...}'}

        The image prop is standard for many components.
        It can accept an image src, an Image props object, or an {'<Image />'} instance.

      <Comparison jsx={LabelJSX} html={LabelHTML} />
    </Segment>

    {/* ----------------------------------------
     *  Sub Components
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Sub Components

        Sub components give you complete access to the markup.
        This is essential for flexibility in customizing components.

      <Comparison jsx={MessageSubComponentsJSX} html={MessageSubComponentsHTML} />
    </Segment>

    {/* ----------------------------------------
     *  Auto Controlled State
     * -------------------------------------- */}
    <Segment className='basic padded'>
      Auto Controlled State

        React has the concept of

           controlled and uncontrolled

        components.

        Our stateful components self manage their state out of the box, without wiring. Dropdowns open on click without
        wiring onClick to the open prop. The value is also stored internally, without
        wiring onChange to value.

        If you add a value prop or an open prop, the Dropdown delegates control for that
        one prop to your value. The other props remain auto controlled. Mix and match any number of controlled and
        uncontrolled props. Add and remove control at any time by adding or removing props. Everything just works.

        Take a look at our

           AutoControlledComponent

        to see how this was done.
        See the docs try it out live.

      <Divider hidden section />
      <Divider hidden section />
      <Divider hidden section />
    </Segment>
  </Container>
)

export default Introduction
<|endoftext|>


<commit_before>require([
    "esri/Map",
    "esri/views/MapView",
    "esri/layers/FeatureLayer",
    "esri/widgets/Search",
    "esri/widgets/Legend",
    "esri/widgets/BasemapToggle",
    "esri/layers/GraphicsLayer",
    "esri/geometry/geometryEngine",
    "esri/Graphic",
    "esri/symbols/SimpleFillSymbol",
    "esri/symbols/SimpleMarkerSymbol",
    "dojo/on",
    "dojo/dom",
    "dojo/dom-construct",
    "dojo/domReady!"
], function(Map, MapView, FeatureLayer, Search, Legend, BasemapToggle, GraphicsLayer, geometryEngine, Graphic, SimpleFillSymbol, SimpleMarkerSymbol, on, dom, domconstruct) {
    var subsaharanT0 = "https://129.2.6.223:6443/arcgis/rest/services/GEOG498K2016/HAO_NTLData/MapServer/3"
    var radcalT0Layer = new FeatureLayer({
        url: subsaharanT0,
        popupTemplate: {
            title: "Radiance Calibrated NTL Urban Extent in 1996",
            content: [{
                type: "text",
                text: "{ExtentName:checkExtentName} has an area of {gAreaKM:NumberFormat} kilometers. " +
                    "This urban extent was " + "{Status} which means that it {Status:checkStatusType}" +
                    "There are {CtyCntT0} cities in this {ExtTypeT0} type urban extent."
            }, {
                type: "media",
                mediaInfos: [{
                    title: "RC Values 1996-2010",
                    type: "bar-chart",
                    caption: "",
                    value: {
                        fields: ["rc1996", "rc1999", "rc2000", "rc2002", "rc2004", "rc2005", "rc2010"],
                        normalizeField: null,
                        tooltipField: ["rc1996", "rc1999", "rc2000", "rc2002", "rc2004", "rc2005", "rc2010"]
                    }
                }]
            }]
        },

        outFields: ["*"],
        visible: true
    });

    var subsaharanT1 = "https://129.2.6.223:6443/arcgis/rest/services/GEOG498K2016/HAO_NTLData/MapServer/2"
    var radcalT1Layer = new FeatureLayer({
        url: subsaharanT1,
        popupTemplate: {
            title: "Radiance Calibrated NTL Urban Extent in 2010",
            content: [{
                type: "text",
                text: "{ExtentName:checkExtentName} has an area of {gAreaKM:NumberFormat} KM, with a net area change of {areaChg:NumberFormat} KM. " +
                    "This urban extent was " + "{Status} which means that it {Status:checkStatusType}" +
                    "There are {CtyCntT0} cities in this {ExtTypeT0} type urban extent." +
                    "\n The net change in NTL brightness DN is {ntlChange:NumberFormat}"
            }, {
                type: "media",
                mediaInfos: [{
                    title: "RC Values 1996-2010",
                    type: "bar-chart",
                    caption: "",
                    value: {
                        fields: ["rc1996", "rc1999", "rc2000", "rc2002", "rc2004", "rc2005", "rc2010"],
                        normalizeField: null,
                        tooltipField: ["rc1996", "rc1999", "rc2000", "rc2002", "rc2004", "rc2005", "rc2010"]
                    }
                }]
            }]
        },

        outFields: ["*"],
        visible: true
    });

    /*var subsaharanNTLFP = "https://129.2.6.223:6443/arcgis/rest/services/GEOG498K2016/HAO_NTLData/MapServer/1"
    var NTLFPLayer = new FeatureLayer({
        url: subsaharanNTLFP,
        outFields: ["*"],
        visible: true
    });*/

    //GraphicsLayer for displaying results
    var resultsLayer = new GraphicsLayer();

    var map = new Map({
        basemap: "dark-gray-vector",
        layers: [radcalT0Layer, radcalT1Layer, resultsLayer]
    });

    var view = new MapView({
        container: "viewDiv", // Reference to the scene div with id viewDiv
        map: map, //Reference to the map object created before the scene
        zoom: 7, // Sets the zoom level based on level of detail (LOD)
        center: [8.0, 6.0]
    });

    checkExtentName = function(value, key, data) {
        //Check if Extent has a defined name or is -1
        if (data.ExtentName != "-1") {
            return data.ExtentName;
        } else {
            return "This Urban Extent"
        }
    }

    checkStatusType = function(value, key, data) {
        //check Status and return appropriate context explanation
        switch (data.Status) {
            case "FOUND":
                context = "intersects cities in both 1996 and 2010.";
                break;
            case "MISSED":
                context = "does not intersect any cities.";
                break;
            case "APPEAR":
                context = "intersects extent only in 2010.";
        }
        return context;
    }

    function anyRadioChecked(radio) {
        for (var n = 0; n < radio.length; n++) {
            if (radio[n].checked) {
                return true;
            }
        }
        return false;
    }

    function getRadioSelected(radio) {
        for (var n = 0; n < radio.length; n++) {
            if (radio[n].checked) {
                return radio[n].value;
            }
        }
    }

    /**
     * runQuery()
     *
     * DESC:
     *  Runs down the query parameters on the left panel and builds a
     *  queriable string from the options specified by the user.
     *  Returns a queried feature layer from the parsed query string.
     *
     * RETURN VALUE:
     *  A feature layer of the queried results.
     */
    // last query run
    var lastQuery = "";

    var savedQueries = [];

    function runQuery() {
        //var l = document.getElementById("layerSelect");
        var layerSelected = l.options[l.selectedIndex].value;
        var query;
        var whereLength = 0;
        var qlayer;
        qlayer = radcalT1Layer;
        query = qlayer.createQuery();
        var whereText = "";

        //var ext = document.getElementById("extent");
        //var extentSelected = ext.options[ext.selectedIndex].value;
        //create condition for no specified extent (all extents)

        var ntlOp = document.getElementsByName("ntlOperator");
        var ntlVal = document.getElementById("chgVal").value;
        if (anyRadioChecked(ntlOp) && ntlVal != "") {
            whereLength++;
            if (whereLength > 1) {
                whereText += " AND ";
            }
            whereText += " ntlChgCorr " + getRadioSelected(ntlOp) + " " + ntlVal;
        }

        var arOp = document.getElementsByName("areaOperator");
        var arVal = document.getElementById("areaVal").value;
        if (anyRadioChecked(arOp) && arVal != "") {
            whereLength++;
            if (whereLength > 1) {
                whereText += " AND ";
            }
            whereText += " gAreaKM " + getRadioSelected(arOp) + " " + arVal;
        }

        var stat = document.getElementsByName("status");
        if (anyRadioChecked(stat)) {
            whereLength++;
            if (whereLength > 1) {
                whereText += " AND ";
            }
            whereText += " Status = \'" + getRadioSelected(stat) + "\'";
        }
        alert(whereText);
        query.where = whereText;
        lastQuery = whereText;

        return qlayer.queryFeatures(query);
    }

    /**
     * dispQuery()
     *
     * DESC:
     *  Takes in a featurelayer as a param (expected to be called
     *  with some query result being passed in).
     *
     *  All layers are removed from the map, and the passed in
     *  feature layer is displayed instead.
     *
     * RETURN VALUE:
     *  None
     */
    function dispQuery(results) {
        resultsLayer.removeAll();
        var features = results.features.map(function(graphic) {
            graphic.symbol = new SimpleFillSymbol({
                style: "solid",
                color: "purple"
            });
            return graphic;
        });
        var sum = features.length;
        console.log(sum);
        dom.byId("popDiv").innerHTML = "
Urban Extents found: " + sum + "
";
        resultsLayer.addMany(features);
    }

    function saveQuery() {
        var qName = dom.byId("qNameText").value;
        if (qName == "") {
            alert("You must name your query");
        }
        if (lastQuery != "") {
            var namedQuery = {
                name: qName,
                query: lastQuery
            };
            savedQueries.push(namedQuery);
            renderQuerySelection();
        }
    }

    function renderQuerySelection() {
        var savedSelect = document.getElementById("savedQueries");
        var qName = savedQueries[savedQueries.length - 1].name;
        var option = document.createElement("option");
        option.text = qName;
        savedSelect.add(option);
    }

    function updateSelectedQueryText() {
        var qText = document.getElementById("savedQueryText");
        var savedSelectOptions = document.getElementById("savedQueries").options;
        var selected = -1;
        for (var i = 0; i < savedSelectOptions.length; i++) {
            if (savedSelectOptions[i].selected) {
                selected = i;
                break;
            }
        }
        if (selected == -1) {
            qText.innerHTML = "";
        } else {
            qText.innerHTML = savedQueries[selected].query;
        }
        return selected;
    }

    function rerunQuery(selected) {
        var queryWhere = savedQueries[selected].query;
        //finish this, save which layer is queried
    }

    var layer1Check = dom.byId("layer1");
    var layer2Check = dom.byId("layer2");
    var queryButton = dom.byId("queryBtn");
    var qSaveButton = dom.byId("saveQuery");
    var rerunButton = dom.byId("rerunQuery");
    var savedQuerySelect = dom.byId("savedQueries");
    // var layer3Check = dom.byId("layer3");

    on(layer1Check, "change", function() {
        radcalT0Layer.visible = layer1Check.checked;
    })

    on(layer2Check, "change", function() {
        radcalT1Layer.visible = layer2Check.checked;
    })

    on(queryButton, "click", function() {
        runQuery().then(dispQuery);
    });

    on(qSaveButton, "click", function() {
        saveQuery();
    });

    on(rerunButton, "click", function() {
        var selected = updateSelectedQueryText();
        if (selected != -1) {
            rerunQuery(selected);
        }
    })

    on(savedQuerySelect, "change", function() {
        updateSelectedQueryText();
    });
    /*
    on(layer3Check, "change", function(){
        NTLFPLayer.visible = layer3Check.checked;
    })
    */

    /*
    //Code to select feature on click and populate PopDiv with some info about the feature
    view.on("click", function(evt) {
      var screenPoint = evt.screenPoint;
      window.alert("clicked");

      view.hitTest(screenPoint)
        .then(getGraphics);
    });

    function getGraphics(response) {
      var graphic = response.results[0].graphic;
      var attributes = graphic.attributes;
      var extentName = checkExtentName(attributes.ExtentName);
      var areaChange = attributes.areaChg;
      var area = attribute.gAreaKM;
      var statuscontext = checkStatusType(attributes.Status);
      var _status = attributes.Status;
      var ntlchange = attribute.ntlChange;
      var cityCount = attributes.CtyCntT0;
      var extentType = attributes.ExtTypeT0;

      dom.byId("popupDiv").innerHTML = "" + extentName + " has an area of " + area  + "KM, with a net area change of " +
      areaChange + " KM. " +
      "This urban extent was " + _status + " which means that it " + statuscontext +

      "There are " + cityCount + " cities in this " + extentType + " type urban extent." +
      "\n The net change in NTL brightness DN is " + ntlchange + "";
    }*/

    // Defining and adding search widget
    var searchWidget = new Search({
        view: view
    });
    searchWidget.startup();

    view.ui.add(searchWidget, {
        position: "top-right",
        index: 0
    });

    var legend = new Legend({
        view: view,
        layerInfos: [{
            layer: radcalT1Layer,
            title: "Area Change 1996-2010 in KM"
        }]
    });

    var basemapToggle = new BasemapToggle({
      view: view,  // The view that provides access to the map's "streets" basemap
      nextBasemap: "hybrid"  // Allows for toggling to the "hybrid" basemap
    });
    basemapToggle.startup();

    // Adds an instance of Legend widget to the
    // bottom right of the view.
    view.ui.add(legend, "bottom-right");

});

function isInt(value) {
    if (isNaN(value)) {
        return false;
    }
    var x = parseFloat(value);
    return (x | 0) === x;
}
<commit_msg>Fixed query problem with Status, added basemap toggle<commit_after>require([
    "esri/Map",
    "esri/views/MapView",
    "esri/layers/FeatureLayer",
    "esri/widgets/Search",
    "esri/widgets/Legend",
    "esri/widgets/BasemapToggle",
    "esri/layers/GraphicsLayer",
    "esri/geometry/geometryEngine",
    "esri/Graphic",
    "esri/symbols/SimpleFillSymbol",
    "esri/symbols/SimpleMarkerSymbol",
    "dojo/on",
    "dojo/dom",
    "dojo/dom-construct",
    "dojo/domReady!"
], function(Map, MapView, FeatureLayer, Search, Legend, BasemapToggle, GraphicsLayer, geometryEngine, Graphic, SimpleFillSymbol, SimpleMarkerSymbol, on, dom, domconstruct) {
    var subsaharanT0 = "https://129.2.6.223:6443/arcgis/rest/services/GEOG498K2016/HAO_NTLData/MapServer/3"
    var radcalT0Layer = new FeatureLayer({
        url: subsaharanT0,
        popupTemplate: {
            title: "Radiance Calibrated NTL Urban Extent in 1996",
            content: [{
                type: "text",
                text: "{ExtentName:checkExtentName} has an area of {gAreaKM:NumberFormat} kilometers. " +
                    "This urban extent was " + "{Status} which means that it {Status:checkStatusType}" +
                    "There are {CtyCntT0} cities in this {ExtTypeT0} type urban extent."
            }, {
                type: "media",
                mediaInfos: [{
                    title: "RC Values 1996-2010",
                    type: "bar-chart",
                    caption: "",
                    value: {
                        fields: ["rc1996", "rc1999", "rc2000", "rc2002", "rc2004", "rc2005", "rc2010"],
                        normalizeField: null,
                        tooltipField: ["rc1996", "rc1999", "rc2000", "rc2002", "rc2004", "rc2005", "rc2010"]
                    }
                }]
            }]
        },

        outFields: ["*"],
        visible: true
    });

    var subsaharanT1 = "https://129.2.6.223:6443/arcgis/rest/services/GEOG498K2016/HAO_NTLData/MapServer/2"
    var radcalT1Layer = new FeatureLayer({
        url: subsaharanT1,
        popupTemplate: {
            title: "Radiance Calibrated NTL Urban Extent in 2010",
            content: [{
                type: "text",
                text: "{ExtentName:checkExtentName} has an area of {gAreaKM:NumberFormat} KM, with a net area change of {areaChg:NumberFormat} KM. " +
                    "This urban extent was " + "{Status} which means that it {Status:checkStatusType}" +
                    "There are {CtyCntT0} cities in this {ExtTypeT0} type urban extent." +
                    "\n The net change in NTL brightness DN is {ntlChange:NumberFormat}"
            }, {
                type: "media",
                mediaInfos: [{
                    title: "RC Values 1996-2010",
                    type: "bar-chart",
                    caption: "",
                    value: {
                        fields: ["rc1996", "rc1999", "rc2000", "rc2002", "rc2004", "rc2005", "rc2010"],
                        normalizeField: null,
                        tooltipField: ["rc1996", "rc1999", "rc2000", "rc2002", "rc2004", "rc2005", "rc2010"]
                    }
                }]
            }]
        },

        outFields: ["*"],
        visible: true
    });

    /*var subsaharanNTLFP = "https://129.2.6.223:6443/arcgis/rest/services/GEOG498K2016/HAO_NTLData/MapServer/1"
    var NTLFPLayer = new FeatureLayer({
        url: subsaharanNTLFP,
        outFields: ["*"],
        visible: true
    });*/

    //GraphicsLayer for displaying results
    var resultsLayer = new GraphicsLayer();

    var map = new Map({
        basemap: "dark-gray-vector",
        layers: [radcalT0Layer, radcalT1Layer, resultsLayer]
    });

    var view = new MapView({
        container: "viewDiv", // Reference to the scene div with id viewDiv
        map: map, //Reference to the map object created before the scene
        zoom: 7, // Sets the zoom level based on level of detail (LOD)
        center: [8.0, 6.0]
    });

    checkExtentName = function(value, key, data) {
        //Check if Extent has a defined name or is -1
        if (data.ExtentName != "-1") {
            return data.ExtentName;
        } else {
            return "This Urban Extent"
        }
    }

    checkStatusType = function(value, key, data) {
        //check Status and return appropriate context explanation
        switch (data.Status) {
            case "FOUND":
                context = "intersects cities in both 1996 and 2010.";
                break;
            case "MISSED":
                context = "does not intersect any cities.";
                break;
            case "APPEAR":
                context = "intersects extent only in 2010.";
        }
        return context;
    }

    function anyRadioChecked(radio) {
        for (var n = 0; n < radio.length; n++) {
            if (radio[n].checked) {
                return true;
            }
        }
        return false;
    }

    function getRadioSelected(radio) {
        for (var n = 0; n < radio.length; n++) {
            if (radio[n].checked) {
                return radio[n].value;
            }
        }
    }

    /**
     * runQuery()
     *
     * DESC:
     *  Runs down the query parameters on the left panel and builds a
     *  queriable string from the options specified by the user.
     *  Returns a queried feature layer from the parsed query string.
     *
     * RETURN VALUE:
     *  A feature layer of the queried results.
     */
    // last query run
    var lastQuery = "";

    var savedQueries = [];

    function runQuery() {
        //var l = document.getElementById("layerSelect");
        //var layerSelected = l.options[l.selectedIndex].value;
        var query;
        var whereLength = 0;
        var qlayer;
        qlayer = radcalT1Layer;
        query = qlayer.createQuery();
        var whereText = "";

        //var ext = document.getElementById("extent");
        //var extentSelected = ext.options[ext.selectedIndex].value;
        //create condition for no specified extent (all extents)

        var ntlOp = document.getElementsByName("ntlOperator");
        var ntlVal = document.getElementById("chgVal").value;
        if (anyRadioChecked(ntlOp) && ntlVal != "") {
            whereLength++;
            if (whereLength > 1) {
                whereText += " AND ";
            }
            whereText += " ntlChgCorr " + getRadioSelected(ntlOp) + " " + ntlVal;
        }

        var arOp = document.getElementsByName("areaOperator");
        var arVal = document.getElementById("areaVal").value;
        if (anyRadioChecked(arOp) && arVal != "") {
            whereLength++;
            if (whereLength > 1) {
                whereText += " AND ";
            }
            whereText += " gAreaKM " + getRadioSelected(arOp) + " " + arVal;
        }

        var stat = document.getElementsByName("status");
        if (anyRadioChecked(stat)) {
            whereLength++;
            if (whereLength > 1) {
                whereText += " AND ";
            }
            whereText += " Status = \'" + getRadioSelected(stat) + "\'";
        }
        alert(whereText);
        query.where = whereText;
        lastQuery = whereText;

        return qlayer.queryFeatures(query);
    }

    /**
     * dispQuery()
     *
     * DESC:
     *  Takes in a featurelayer as a param (expected to be called
     *  with some query result being passed in).
     *
     *  All layers are removed from the map, and the passed in
     *  feature layer is displayed instead.
     *
     * RETURN VALUE:
     *  None
     */
    function dispQuery(results) {
        resultsLayer.removeAll();
        var features = results.features.map(function(graphic) {
            graphic.symbol = new SimpleFillSymbol({
                style: "solid",
                color: "purple"
            });
            return graphic;
        });
        var sum = features.length;
        console.log(sum);
        dom.byId("popDiv").innerHTML = "
Urban Extents found: " + sum + "
";
        resultsLayer.addMany(features);
    }

    function saveQuery() {
        var qName = dom.byId("qNameText").value;
        if (qName == "") {
            alert("You must name your query");
        }
        if (lastQuery != "") {
            var namedQuery = {
                name: qName,
                query: lastQuery
            };
            savedQueries.push(namedQuery);
            renderQuerySelection();
        }
    }

    function renderQuerySelection() {
        var savedSelect = document.getElementById("savedQueries");
        var qName = savedQueries[savedQueries.length - 1].name;
        var option = document.createElement("option");
        option.text = qName;
        savedSelect.add(option);
    }

    function updateSelectedQueryText() {
        var qText = document.getElementById("savedQueryText");
        var savedSelectOptions = document.getElementById("savedQueries").options;
        var selected = -1;
        for (var i = 0; i < savedSelectOptions.length; i++) {
            if (savedSelectOptions[i].selected) {
                selected = i;
                break;
            }
        }
        if (selected == -1) {
            qText.innerHTML = "";
        } else {
            qText.innerHTML = savedQueries[selected].query;
        }
        return selected;
    }

    function rerunQuery(selected) {
        var queryWhere = savedQueries[selected].query;
        //finish this, save which layer is queried
    }

    var layer1Check = dom.byId("layer1");
    var layer2Check = dom.byId("layer2");
    var queryButton = dom.byId("queryBtn");
    var qSaveButton = dom.byId("saveQuery");
    var rerunButton = dom.byId("rerunQuery");
    var savedQuerySelect = dom.byId("savedQueries");
    // var layer3Check = dom.byId("layer3");

    on(layer1Check, "change", function() {
        radcalT0Layer.visible = layer1Check.checked;
    })

    on(layer2Check, "change", function() {
        radcalT1Layer.visible = layer2Check.checked;
    })

    on(queryButton, "click", function() {
        runQuery().then(dispQuery);
    });

    on(qSaveButton, "click", function() {
        saveQuery();
    });

    on(rerunButton, "click", function() {
        var selected = updateSelectedQueryText();
        if (selected != -1) {
            rerunQuery(selected);
        }
    })

    on(savedQuerySelect, "change", function() {
        updateSelectedQueryText();
    });
    /*
    on(layer3Check, "change", function(){
        NTLFPLayer.visible = layer3Check.checked;
    })
    */

    /*
    //Code to select feature on click and populate PopDiv with some info about the feature
    view.on("click", function(evt) {
      var screenPoint = evt.screenPoint;
      window.alert("clicked");

      view.hitTest(screenPoint)
        .then(getGraphics);
    });

    function getGraphics(response) {
      var graphic = response.results[0].graphic;
      var attributes = graphic.attributes;
      var extentName = checkExtentName(attributes.ExtentName);
      var areaChange = attributes.areaChg;
      var area = attribute.gAreaKM;
      var statuscontext = checkStatusType(attributes.Status);
      var _status = attributes.Status;
      var ntlchange = attribute.ntlChange;
      var cityCount = attributes.CtyCntT0;
      var extentType = attributes.ExtTypeT0;

      dom.byId("popupDiv").innerHTML = "" + extentName + " has an area of " + area  + "KM, with a net area change of " +
      areaChange + " KM. " +
      "This urban extent was " + _status + " which means that it " + statuscontext +

      "There are " + cityCount + " cities in this " + extentType + " type urban extent." +
      "\n The net change in NTL brightness DN is " + ntlchange + "";
    }*/

    // Defining and adding search widget
    var searchWidget = new Search({
        view: view
    });
    searchWidget.startup();

    view.ui.add(searchWidget, {
        position: "top-right",
        index: 0
    });

    var legend = new Legend({
        view: view,
        layerInfos: [{
            layer: radcalT1Layer,
            title: "Area Change 1996-2010 in KM"
        }]
    });

    var basemapToggle = new BasemapToggle({
      view: view,  // The view that provides access to the map's "streets" basemap
      nextBasemap: "hybrid"  // Allows for toggling to the "hybrid" basemap
    });
    basemapToggle.startup();
    view.ui.add(basemapToggle, "bottom-left");

    // Adds an instance of Legend widget to the
    // bottom right of the view.
    view.ui.add(legend, "bottom-right");

});

function isInt(value) {
    if (isNaN(value)) {
        return false;
    }
    var x = parseFloat(value);
    return (x | 0) === x;
}
<|endoftext|>