<commit_before>// VISUALIZATION
// ------------------------------------------

var stageWidth = 1600;
var stageHeight = 12000;
var stageSvg = null;

function visualizationInit() {
    var margin = {top: 20, right: 500, bottom: 0, left: 20};

    stageSvg = d3.select("body").append("svg")
        .attr("width", stageWidth + margin.left + margin.right)
        .attr("height", stageHeight + margin.top + margin.bottom)
        .style("margin-left", margin.left + "px")
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
}

var visualize = function visualize(interval, data) {

    var intervalSeconds = interval * 60 * 1000;

    function truncate(str, maxLength, suffix) {
        if (str.length > maxLength) {
            str = str.substring(0, maxLength + 1);
            str = str.substring(0, Math.min(str.length, str.lastIndexOf(" ")));
            str = str + suffix;
        }
        return str;
    }

    data = data['aggregations']['timeframes']['buckets'];
    var timeframesCount = data.length;
    var clusterList = [];
    data.forEach(function (timeframeData) {
        timeframeData['timeframe_start'] = new Date(timeframeData['key']);
        timeframeData['timeframe_end'] = new Date((timeframeData['key'] + intervalSeconds));
        timeframeData['behaviors']['value']['clusters'].forEach(function (cluster) {
            var timeframe = [
                timeframeData['timeframe_start'],
                timeframeData['timeframe_end'],
                cluster['size'],
                timeframeData['behaviors']['value']['clusters_users_count']
            ];
            var percentValue = Math.round((timeframe[2]/timeframe[3])*10000)/100;
            if(percentValue > 1) {
                var representant = cluster['representants'][0];
                if (clusterList.hasOwnProperty(representant.pathHash)) {
                    clusterList[representant.pathHash].timeframes.push(timeframe)
                } else {
                    clusterList[representant.pathHash] = {
                        "timeframes": [
                            timeframe
                        ],
                        "path": representant['path'],
                        "name": representant['path'].join(', ')
                    }
                }
            }
        });
    });
    // fill clusters between timeframes
    data.forEach(function (timeframeData) {
        timeframeData['timeframe_start'] = new Date(timeframeData['key']);
        timeframeData['timeframe_end'] = new Date((timeframeData['key'] + intervalSeconds));
        timeframeData['behaviors']['value']['clusters'].forEach(function (timeFrameCluster) {
            var timeframe = [
                timeframeData['timeframe_start'],
                timeframeData['timeframe_end'],
                timeFrameCluster['size'],
                timeframeData['behaviors']['value']['clusters_users_count']
            ];
            var percentValue = Math.round((timeframe[2]/timeframe[3])*10000)/100;
            if(percentValue > 1) {
                var representant = timeFrameCluster['representants'][0];
                var path = representant['path'];
                var name = path.join(', ');
                for (var key in clusterList) {
                    cluster = clusterList[key];
                    console.log("checking '" + cluster.name + "'("+cluster.path.length+") against '" + name + "'("+path.length+"): result -> " + cluster.name.indexOf(name));
                    if(path.length > cluster.path.length && cluster.name.indexOf(name) !== -1) {
                        console.log("boosting '" + cluster.name + "' with '" + name + "'");
                        clusterList[representant.pathHash].timeframes.push(timeframe);
                    }
                }
            }
        });
    });
    clusterList = clusterList.sort(function(a, b) {
        console.log("sorting");
        var aSum = a.timeframes.reduce( function(prev, next){
           return prev + next[2];
        }, 0);
        var bSum = b.timeframes.reduce( function(prev, next){
           return prev + next[2];
        }, 0);
        console.log(a.name + ": " + aSum);
        console.log(b.name + ": " + bSum);
        return parseFloat(aSum) - parseFloat(bSum);
    });
    data = [];
    for (var key in clusterList) {
        if (!clusterList.hasOwnProperty(key)) continue;
        data.push(clusterList[key]);
    }
    clusterList = null;

    var xMin = d3.min(data, function (cluster) {
        return d3.min(cluster['timeframes'], function (timeframe) {
            return timeframe[0];
        });
    });
    var xMax = d3.max(data, function (cluster) {
        return d3.max(cluster['timeframes'], function (timeframe) {
            return timeframe[0];
        });
    });
    console.log(xMin);
    console.log(xMax);

    var xScale = d3.time.scale()
        .domain([xMin, xMax])
        .range([0, stageWidth]);

    var timeFormat = d3.time.format("%m/%d %H:%M");
    xAxis = d3.svg.axis()
        .scale(xScale)
        .orient("top")
        .ticks(timeframesCount)
        .tickPadding(5)
        .tickFormat(timeFormat);

    stageSvg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + 0 + ")")
        .call(xAxis);

    var c = d3.scale.category20c();

    for (var j = 0; j < data.length; j++) {
        var g = stageSvg.append("g").attr("class", "journal");

        var circles = g.selectAll("circle")
            .data(data[j]['timeframes'])
            .enter()
            .append("circle");

        var text = g.selectAll("text")
            .data(data[j]['timeframes'])
            .enter()
            .append("text");

        var rScale = d3.scale.linear()
            .domain([0, d3.max(data[j]['timeframes'], function (d) {
                return d[3];
            })])
            .range([6, 14]);

        circles
            .attr("cx", function (d, i) {
                return xScale(d[0]);
            })
            .attr("cy", j * 30 + 20)
            .attr("r", function (d) {
                return rScale(d[2]);
            })
            .style("fill", function (d) {
                return c(j);
            });

        text
            .attr("y", j * 30 + 25)
            .attr("x", function (d, i) {
                return xScale(d[0]) - 5;
            })
            .attr("class", "value")
            .text(function (d) {
                return (Math.round((d[2]/d[3])*10000)/100)+"%";
            })
            .style("fill", function (d) {
                return c(j);
            })
            .style("display", "none");

        g.append("text")
            .attr("y", j * 30 + 25)
            .attr("x", stageWidth + 50)
            .attr("class", "label")
            .text(truncate(data[j]['name'], 60, "..."))
            .style("fill", function (d) {
                return c(j);
            })
            .on("mouseover", mouseover)
            .on("mouseout", mouseout);
    }
    ;

    function mouseover(p) {
        var g = d3.select(this).node().parentNode;
        d3.select(g).selectAll("circle").style("display", "none");
        d3.select(g).selectAll("text.value").style("display", "block");
    }

    function mouseout(p) {
        var g = d3.select(this).node().parentNode;
        d3.select(g).selectAll("circle").style("display", "block");
        d3.select(g).selectAll("text.value").style("display", "none");
    }
};<commit_msg>adjustemnts<commit_after>// VISUALIZATION
// ------------------------------------------

var stageWidth = 1600;
var stageHeight = 12000;
var stageSvg = null;

function visualizationInit() {
    var margin = {top: 20, right: 500, bottom: 0, left: 20};

    stageSvg = d3.select("body").append("svg")
        .attr("width", stageWidth + margin.left + margin.right)
        .attr("height", stageHeight + margin.top + margin.bottom)
        .style("margin-left", margin.left + "px")
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
}

var visualize = function visualize(interval, data) {

    var intervalSeconds = interval * 60 * 1000;

    function truncate(str, maxLength, suffix) {
        if (str.length > maxLength) {
            str = str.substring(0, maxLength + 1);
            str = str.substring(0, Math.min(str.length, str.lastIndexOf(" ")));
            str = str + suffix;
        }
        return str;
    }

    data = data['aggregations']['timeframes']['buckets'];
    var timeframesCount = data.length;
    var clusterList = [];
    data.forEach(function (timeframeData) {
        timeframeData['timeframe_start'] = new Date(timeframeData['key']);
        timeframeData['timeframe_end'] = new Date((timeframeData['key'] + intervalSeconds));
        timeframeData['behaviors']['value']['clusters'].forEach(function (cluster) {
            var timeframe = [
                timeframeData['timeframe_start'],
                timeframeData['timeframe_end'],
                cluster['size'],
                timeframeData['behaviors']['value']['clusters_users_count']
            ];
            var percentValue = Math.round((timeframe[2]/timeframe[3])*10000)/100;
            if(percentValue > 1) {
                var representant = cluster['representants'][0];
                if (clusterList.hasOwnProperty(representant.pathHash)) {
                    clusterList[representant.pathHash].timeframes.push(timeframe)
                } else {
                    clusterList[representant.pathHash] = {
                        "timeframes": [
                            timeframe
                        ],
                        "path": representant['path'],
                        "name": representant['path'].join(', ')
                    }
                }
            }
        });
    });
    // fill clusters between timeframes
    data.forEach(function (timeframeData) {
        timeframeData['timeframe_start'] = new Date(timeframeData['key']);
        timeframeData['timeframe_end'] = new Date((timeframeData['key'] + intervalSeconds));
        timeframeData['behaviors']['value']['clusters'].forEach(function (timeFrameCluster) {
            var timeframe = [
                timeframeData['timeframe_start'],
                timeframeData['timeframe_end'],
                timeFrameCluster['size'],
                timeframeData['behaviors']['value']['clusters_users_count']
            ];
            var percentValue = Math.round((timeframe[2]/timeframe[3])*10000)/100;
            if(percentValue > 1) {
                var representant = timeFrameCluster['representants'][0];
                var path = representant['path'];
                var name = path.join(', ');
                for (var key in clusterList) {
                    cluster = clusterList[key];
                    console.log("checking '" + cluster.name + "'("+cluster.path.length+") against '" + name + "'("+path.length+"): result -> " + cluster.name.indexOf(name));
                    if(cluster.path.length > path.length && cluster.name.indexOf(name) !== -1) {
                        console.log("boosting '" + cluster.name + "' with '" + name + "'");
                        clusterList[representant.pathHash].timeframes.push(timeframe);
                    }
                }
            }
        });
    });
    clusterList = clusterList.sort(function(a, b) {
        console.log("sorting");
        var aSum = a.timeframes.reduce( function(prev, next){
           return prev + next[2];
        }, 0);
        var bSum = b.timeframes.reduce( function(prev, next){
           return prev + next[2];
        }, 0);
        console.log(a.name + ": " + aSum);
        console.log(b.name + ": " + bSum);
        return parseFloat(aSum) - parseFloat(bSum);
    });
    data = [];
    for (var key in clusterList) {
        if (!clusterList.hasOwnProperty(key)) continue;
        data.push(clusterList[key]);
    }
    clusterList = null;

    var xMin = d3.min(data, function (cluster) {
        return d3.min(cluster['timeframes'], function (timeframe) {
            return timeframe[0];
        });
    });
    var xMax = d3.max(data, function (cluster) {
        return d3.max(cluster['timeframes'], function (timeframe) {
            return timeframe[0];
        });
    });
    console.log(xMin);
    console.log(xMax);

    var xScale = d3.time.scale()
        .domain([xMin, xMax])
        .range([0, stageWidth]);

    var timeFormat = d3.time.format("%m/%d %H:%M");
    xAxis = d3.svg.axis()
        .scale(xScale)
        .orient("top")
        .ticks(timeframesCount)
        .tickPadding(5)
        .tickFormat(timeFormat);

    stageSvg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + 0 + ")")
        .call(xAxis);

    var c = d3.scale.category20c();

    for (var j = 0; j < data.length; j++) {
        var g = stageSvg.append("g").attr("class", "journal");

        var circles = g.selectAll("circle")
            .data(data[j]['timeframes'])
            .enter()
            .append("circle");

        var text = g.selectAll("text")
            .data(data[j]['timeframes'])
            .enter()
            .append("text");

        var rScale = d3.scale.linear()
            .domain([0, d3.max(data[j]['timeframes'], function (d) {
                return d[3];
            })])
            .range([6, 14]);

        circles
            .attr("cx", function (d, i) {
                return xScale(d[0]);
            })
            .attr("cy", j * 30 + 20)
            .attr("r", function (d) {
                return rScale(d[2]);
            })
            .style("fill", function (d) {
                return c(j);
            });

        text
            .attr("y", j * 30 + 25)
            .attr("x", function (d, i) {
                return xScale(d[0]) - 5;
            })
            .attr("class", "value")
            .text(function (d) {
                return (Math.round((d[2]/d[3])*10000)/100)+"%";
            })
            .style("fill", function (d) {
                return c(j);
            })
            .style("display", "none");

        g.append("text")
            .attr("y", j * 30 + 25)
            .attr("x", stageWidth + 50)
            .attr("class", "label")
            .text(truncate(data[j]['name'], 60, "..."))
            .style("fill", function (d) {
                return c(j);
            })
            .on("mouseover", mouseover)
            .on("mouseout", mouseout);
    }
    ;

    function mouseover(p) {
        var g = d3.select(this).node().parentNode;
        d3.select(g).selectAll("circle").style("display", "none");
        d3.select(g).selectAll("text.value").style("display", "block");
    }

    function mouseout(p) {
        var g = d3.select(this).node().parentNode;
        d3.select(g).selectAll("circle").style("display", "block");
        d3.select(g).selectAll("text.value").style("display", "none");
    }
};<|endoftext|>


<commit_before>
var toggle = document.getElementById('toggle');
var body = document.getElementsByTagName('body')[0];

toggle.addEventListener('click', function () {

	if (body.classList.contains('open')) {
		body.classList.remove('open');
	} else {
		body.classList.add('open');
	}
});<commit_msg>Condition on Javascript toggle<commit_after>if (document.getElementById('toggle')) {
	var toggle = document.getElementById('toggle');
	var body = document.getElementsByTagName('body')[0];

	toggle.addEventListener('click', function () {

		if (body.classList.contains('open')) {
			body.classList.remove('open');
		} else {
			body.classList.add('open');
		}
	});
}<|endoftext|>


<commit_before>/**
 * Js-coding-standards
 *
 * @author      Robert Rossmann <rr.rossmann@me.com>
 * @copyright   2016 STRV
 * @license     http://choosealicense.com/licenses/bsd-3-clause  BSD-3-Clause License
 */

'use strict'

module.exports = {

  extends: '../shared/recommended.js',

  parserOptions: {
    ecmaVersion: 2015,
  },

  env: {
    node: true,
  },

  rules: {
    // Enforce `require()` on the top-level module scope
    // It's arguably harder to identify dependencies when they are deeply nested inside of functions
    // and other statements. Since require() does a synchronous load, it can cause performance
    // problems when used in other locations.
    'global-require': 'warn',

    // Disallow use of the deprecated Buffer() constructor
    // In Node.js, the behavior of the Buffer constructor is different depending on the type of its
    // argument. Passing an argument from user input to Buffer() without validating its type can
    // lead to security vulnerabilities such as remote memory disclosure and denial of service.
    'no-buffer-constructor': 2,

    // Disallow new require
    // This rule aims to eliminate use of the `new require` expression.
    'no-new-require': 'error',

    // Disallow string concatenation when using _dirname and _filename
    // This rule aims to prevent string concatenation of directory paths in Node.js to make sure
    // developers use a platform-independent way of creating paths (we feel you, Windows).
    'no-path-concat': 'error',

    // Disallow process.env
    // This rule is aimed at discouraging use of process.env to avoid global dependencies throughout
    // the project's codebase.
    //
    // Note: Env vars are a great way of managing configuration options. This rule can be safely
    // turned off for a particular file/folder where project configuration is gathered and stored in
    // custom configuration objects which you then use throughout your app, but the use of
    // process.env outside of preparing configuration data should be discouraged.
    'no-process-env': 'warn',

    // Disallow `process.exit()`
    // It's better to throw an error and allow the application to handle it appropriately. Unhandled
    // errors always exit the process, but contrary to `process.exit()` they also print a stack
    // trace.
    'no-process-exit': 'error',

    // Disallow Synchronous Methods
    // This rule is aimed at preventing synchronous methods from being called in Node.js. It looks
    // specifically for the method suffix "Sync" (as is the convention with Node.js operations).
    'no-sync': ['warn', {
      allowAtRootLevel: true,
    }],
  },
}
<commit_msg>fix(rule): re-enable es6 env<commit_after>/**
 * Js-coding-standards
 *
 * @author      Robert Rossmann <rr.rossmann@me.com>
 * @copyright   2016 STRV
 * @license     http://choosealicense.com/licenses/bsd-3-clause  BSD-3-Clause License
 */

'use strict'

module.exports = {

  extends: '../shared/recommended.js',

  parserOptions: {
    ecmaVersion: 2015,
  },

  env: {
    es6: true,
    node: true,
  },

  rules: {
    // Enforce `require()` on the top-level module scope
    // It's arguably harder to identify dependencies when they are deeply nested inside of functions
    // and other statements. Since require() does a synchronous load, it can cause performance
    // problems when used in other locations.
    'global-require': 'warn',

    // Disallow use of the deprecated Buffer() constructor
    // In Node.js, the behavior of the Buffer constructor is different depending on the type of its
    // argument. Passing an argument from user input to Buffer() without validating its type can
    // lead to security vulnerabilities such as remote memory disclosure and denial of service.
    'no-buffer-constructor': 2,

    // Disallow new require
    // This rule aims to eliminate use of the `new require` expression.
    'no-new-require': 'error',

    // Disallow string concatenation when using _dirname and _filename
    // This rule aims to prevent string concatenation of directory paths in Node.js to make sure
    // developers use a platform-independent way of creating paths (we feel you, Windows).
    'no-path-concat': 'error',

    // Disallow process.env
    // This rule is aimed at discouraging use of process.env to avoid global dependencies throughout
    // the project's codebase.
    //
    // Note: Env vars are a great way of managing configuration options. This rule can be safely
    // turned off for a particular file/folder where project configuration is gathered and stored in
    // custom configuration objects which you then use throughout your app, but the use of
    // process.env outside of preparing configuration data should be discouraged.
    'no-process-env': 'warn',

    // Disallow `process.exit()`
    // It's better to throw an error and allow the application to handle it appropriately. Unhandled
    // errors always exit the process, but contrary to `process.exit()` they also print a stack
    // trace.
    'no-process-exit': 'error',

    // Disallow Synchronous Methods
    // This rule is aimed at preventing synchronous methods from being called in Node.js. It looks
    // specifically for the method suffix "Sync" (as is the convention with Node.js operations).
    'no-sync': ['warn', {
      allowAtRootLevel: true,
    }],
  },
}
<|endoftext|>


<commit_before>var logger = require('raptor-logging').logger(module);
var transport = require('raptor-modules/transport');
var parallel = require('raptor-async/parallel');
var nodePath = require('path');
var extend = require('raptor-util/extend');
var markoCompiler = require('marko/compiler');
var extend = require('raptor-util/extend');

var types = {
    'marko': function(callback) {
        var value = this.value;

        if (Array.isArray(value)) {
            value = value.join('\n');
        }

        var dirname = nodePath.dirname(this.dictionaryInfo.absolutePath);
        var templatePath = nodePath.join(dirname, this.key + '.marko');
        var _this = this;

        var moduleName = this.dictionaryModuleName + '/' + this.key + '.marko';

        markoCompiler.compile(value, templatePath, function(err, code) {
            if (err) {
                return callback(err);
            }

            _this.beforeCode.push(transport.defineCode.sync(moduleName, code));

            var out = '';
            out += 'function(data) {\n';
            out += '        return require("marko").load(module.id + ' + JSON.stringify('/' + _this.key + '.marko') + ').renderSync(data);\n';
            out += '    }';
            callback(null, out);
        });
    }
};

function writeDictionary(dictionary, info, localeContext, callback) {

    var code = [];

    function createCompileTask(compiler, compilerContext, theLast, index, length) {
        return function(callback) {
            compiler.call(compilerContext, function(err, compiledCode) {
                if (err) {
                    return callback(err);
                }
                code.push('    ' + JSON.stringify(compilerContext.key) + ': ' + compiledCode);
                callback();
            });
        };
    }

    var work = [];

    var keys = Object.keys(dictionary);
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        var last = (i === keys.length - 1);

        if (dictionary.hasOwnProperty(key)) {
            var value = dictionary[key];
            var compiler = null;

            var pos = key.indexOf(':');
            if (pos !== -1) {
                var type = key.substring(0, pos).trim().toLowerCase();
                compiler = types[type];
                if (compiler) {
                    key = key.substring(pos + 1).trim();
                }
            }

            if (compiler) {

                var compilerContext = {
                    value: value,
                    key: key,
                    dictionaryInfo: info,
                    beforeCode: localeContext.beforeCode,
                    afterCode: localeContext.afterCode,
                    attributes: localeContext.attributes,
                    locale: localeContext.locale,
                    dictionaryModuleName: localeContext.localeModuleName + '/' + info.name
                };

                work.push(createCompileTask(compiler, compilerContext, last, i, keys.length));
            } else {
                code.push('    ' + JSON.stringify(key) + ': ' + JSON.stringify(value));
            }
        }
    }

    parallel(work, function(err) {
        callback(err, code.join(',\n'));
    });
}

function createReadDictionaryTask(info, dependency, localeContext, out) {
    return function(callback) {
        var work = new Array(dependency.locales.length + 1);

        work[0] = function(callback) {
            dependency.i18nContext.readRawDictionary(info.absolutePath, callback);
        };

        dependency.locales.forEach(function(locale, index) {
            work[index + 1] = function(callback) {

                var path = nodePath.join(info.localizedDir, locale, info.relativePath);
                dependency.i18nContext.readRawDictionary(path, callback);
            };
        });

        parallel(work, function(err, result) {
            if (err) {
                return callback(err);
            }

            var merged = (result.length) ? extend({}, result[0]) : {};
            for (var i = 1; i < result.length; i++) {
                var raw = result[i];
                if (raw) {
                    extend(merged, raw);
                }
            }

            writeDictionary(merged, info, localeContext, function(err, dictionaryCode) {
                if (err) {
                    return callback(err);
                }

                var code = '\nmodule.exports = {\n';

                code += dictionaryCode;

                code += '\n}';

                var moduleName = localeContext.localeModuleName + '/' + info.name;

                callback(null, transport.defineCode.sync(moduleName, code) + '\n');
            });

        });
    };
}

module.exports = {
    properties: {
        locale: 'string',
        i18nContext: 'object'
    },

    init: function() {

        this.defaultBundleName = 'raptor-i18n-' + this.locale;

        var locales = this.locales = new Array(2);

        if (this.locale.charAt(2) === '_') {
            locales[0] = this.locale.substring(0, 2);
            locales[1] = this.locale.substring(3);
        } else if (this.locale.length > 0) {
            locales[0] = this.locale;
            locales.length = 1;
        } else {
            locales.length = 0;
        }
    },

    read: function(optimizerContext, callback) {
        var self = this;
        var out = optimizerContext.deferredStream(function() {
            var i18nContext = self.i18nContext;
            var localeContext = {
                beforeCode: [],
                afterCode: [],
                attributes: {},
                locale: self.locale,
                localeModuleName: '/i18n/' + (self.locale || '_')
            };

            var work = [];
            var names = i18nContext.getDictionaryNames();

            for (var i = 0; i < names.length; i++) {
                var info = i18nContext.getDictionaryInfoByName(names[i]);
                work.push(createReadDictionaryTask(info, self, localeContext, out));
            }

            logger.info('Compiling dictionaries for locale "' + self.locale + '"...');

            parallel(work, function(err, results) {
                if (err) {
                    logger.error('Error reading dictionaries for locale "' + self.locale + '"', err);
                } else {
                    out.push('(function(){\n');

                    var i;

                    for (i = 0; i < localeContext.beforeCode.length; i++) {
                        out.push(localeContext.beforeCode[i]);
                        out.push('\n');
                    }

                    for (i = 0; i < results.length; i++) {
                        out.push(results[i]);
                    }

                    for (i = 0; i < localeContext.afterCode.length; i++) {
                        out.push(localeContext.afterCode[i]);
                        out.push('\n');
                    }

                    out.push('})();\n');
                }

                logger.info('Done compiling dictionaries for locale "' + self.locale + '"');

                out.push(null);
            });
        }, {
            encoding: 'utf8'
        });

        return out;
    },

    calculateKey: function() {
        return this.defaultBundleName;
    },

    toString: function() {
        return this.defaultBundleName;
    }
};<commit_msg>raptor-templates --> marko<commit_after>var logger = require('raptor-logging').logger(module);
var transport = require('raptor-modules/transport');
var parallel = require('raptor-async/parallel');
var nodePath = require('path');
var extend = require('raptor-util/extend');
var markoCompiler = require('marko/compiler');
var extend = require('raptor-util/extend');

var types = {
    'marko': function(callback) {
        var value = this.value;

        if (Array.isArray(value)) {
            value = value.join('\n');
        }

        var dirname = nodePath.dirname(this.dictionaryInfo.absolutePath);
        var templatePath = nodePath.join(dirname, this.key + '.marko');
        var _this = this;

        var moduleName = this.dictionaryModuleName + '/' + this.key + '.marko';

        markoCompiler.compile(value, templatePath, function(err, code) {
            if (err) {
                return callback(err);
            }

            _this.beforeCode.push(transport.defineCode.sync(moduleName, code));

            var out = '';
            out += 'function(data) {\n';
            out += '        return require("marko").load(module.id + ' + JSON.stringify('/' + _this.key + '.marko') + ').renderSync(data);\n';
            out += '    }';
            callback(null, out);
        });
    }
};

function writeDictionary(dictionary, info, localeContext, callback) {

    var code = [];

    function createCompileTask(compiler, compilerContext, theLast, index, length) {
        return function(callback) {
            compiler.call(compilerContext, function(err, compiledCode) {
                if (err) {
                    return callback(err);
                }
                code.push('    ' + JSON.stringify(compilerContext.key) + ': ' + compiledCode);
                callback();
            });
        };
    }

    var work = [];

    var keys = Object.keys(dictionary);
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        var last = (i === keys.length - 1);

        if (dictionary.hasOwnProperty(key)) {
            var value = dictionary[key];
            var compiler = null;

            var pos = key.indexOf(':');
            if (pos !== -1) {
                var type = key.substring(0, pos).trim().toLowerCase();
                compiler = types[type];
                if (compiler) {
                    key = key.substring(pos + 1).trim();
                }
            }

            if (compiler) {

                var compilerContext = {
                    value: value,
                    key: key,
                    dictionaryInfo: info,
                    beforeCode: localeContext.beforeCode,
                    afterCode: localeContext.afterCode,
                    attributes: localeContext.attributes,
                    locale: localeContext.locale,
                    dictionaryModuleName: localeContext.localeModuleName + '/' + info.name
                };

                work.push(createCompileTask(compiler, compilerContext, last, i, keys.length));
            } else {
                code.push('    ' + JSON.stringify(key) + ': ' + JSON.stringify(value));
            }
        }
    }

    parallel(work, function(err) {
        callback(err, code.join(',\n'));
    });
}

function createReadDictionaryTask(info, dependency, localeContext, out) {
    return function(callback) {
        var work = new Array(dependency.locales.length + 1);

        work[0] = function(callback) {
            dependency.i18nContext.readRawDictionary(info.absolutePath, callback);
        };

        dependency.locales.forEach(function(locale, index) {
            work[index + 1] = function(callback) {

                var path = nodePath.join(info.localizedDir, locale, info.relativePath);
                dependency.i18nContext.readRawDictionary(path, callback);
            };
        });

        parallel(work, function(err, result) {
            if (err) {
                return callback(err);
            }

            var merged = (result.length) ? extend({}, result[0]) : {};
            for (var i = 1; i < result.length; i++) {
                var raw = result[i];
                if (raw) {
                    extend(merged, raw);
                }
            }

            writeDictionary(merged, info, localeContext, function(err, dictionaryCode) {
                if (err) {
                    return callback(err);
                }

                var code = '\nmodule.exports = {\n';

                code += dictionaryCode;

                code += '\n}';

                var moduleName = localeContext.localeModuleName + '/' + info.name;

                callback(null, transport.defineCode.sync(moduleName, code) + '\n');
            });

        });
    };
}

module.exports = {
    properties: {
        locale: 'string',
        i18nContext: 'object'
    },

    init: function() {

        this.defaultBundleName = 'raptor-i18n-' + this.locale;

        var locales = this.locales = new Array(2);

        if (this.locale.charAt(2) === '_') {
            locales[0] = this.locale.substring(0, 2);
            locales[1] = this.locale.substring(3);
        } else if (this.locale.length > 0) {
            locales[0] = this.locale;
            locales.length = 1;
        } else {
            locales.length = 0;
        }
    },

    read: function(optimizerContext, callback) {
        var self = this;
        var out = optimizerContext.deferredStream(function() {
            var i18nContext = self.i18nContext;
            var localeContext = {
                beforeCode: [],
                afterCode: [],
                attributes: {},
                locale: self.locale,
                localeModuleName: '/i18n/' + (self.locale || '_')
            };

            var work = [];
            var names = i18nContext.getDictionaryNames();

            for (var i = 0; i < names.length; i++) {
                var info = i18nContext.getDictionaryInfoByName(names[i]);
                work.push(createReadDictionaryTask(info, self, localeContext, out));
            }

            logger.info('Compiling dictionaries for locale "' + self.locale + '"...');

            parallel(work, function(err, results) {
                if (err) {
                    logger.error('Error reading dictionaries for locale "' + self.locale + '"', err);
                } else {
                    out.push('(function(){\n');

                    var i;

                    for (i = 0; i < localeContext.beforeCode.length; i++) {
                        out.push(localeContext.beforeCode[i]);
                        out.push('\n');
                    }

                    for (i = 0; i < results.length; i++) {
                        out.push(results[i]);
                    }

                    for (i = 0; i < localeContext.afterCode.length; i++) {
                        out.push(localeContext.afterCode[i]);
                        out.push('\n');
                    }

                    out.push('})();\n');
                }

                logger.info('Done compiling dictionaries for locale "' + self.locale + '"');

                out.push(null);
            });
        }, {
            encoding: 'utf8'
        });

        return out;
    },

    calculateKey: function() {
        return this.defaultBundleName;
    },

    toString: function() {
        return this.defaultBundleName;
    }
};
<|endoftext|>


<commit_before>"use strict";

var Text = require("../text");

var Heading = function(node) {
  Text.call(this, node);
};

Heading.type = {
  "parent": "content",
  "properties": {
    "content": "string",
    "level": "number"
  }
};

Heading.properties = {
  mergeableWith: ["paragraph", "heading"],
  preventEmpty: false,
  splitInto: 'paragraph',
  allowedAnnotations: ["emphasis", "strong", "idea", "question", "error"]
};

Heading.Prototype = function() {

};

Heading.Prototype.prototype = Text.prototype;
Heading.prototype = new Heading.Prototype();

module.exports = Heading;<commit_msg>Add getter for `level`.<commit_after>"use strict";

var Text = require("../text");

var Heading = function(node) {
  Text.call(this, node);
};

Heading.type = {
  "parent": "content",
  "properties": {
    "content": "string",
    "level": "number"
  }
};

Heading.properties = {
  mergeableWith: ["paragraph", "heading"],
  preventEmpty: false,
  splitInto: 'paragraph',
  allowedAnnotations: ["emphasis", "strong", "idea", "question", "error"]
};

Heading.Prototype = function() {

};

Heading.Prototype.prototype = Text.prototype;
Heading.prototype = new Heading.Prototype();

Object.defineProperties(Heading.prototype, {
  level: {
    get: function () {
      return this.properties.level;
    }
  }
});

module.exports = Heading;
<|endoftext|>


<commit_before>angular.module('categorycontrol', [])
.directive('add', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                e.preventDefault();
            });
        }
    }
})
.directive('renameCtgy', function(Category) {
    return {
        restrict: 'A'
      , scope: {
          catid: "@catid"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                var that = $(this);

                var input = $('<input type="text" name="ctgy_nm"/>').val(
                    that.parents('div').siblings('div').children('.ctgy-name').html()
                );

                if(that.text() == "Update") {
                    var ctgy_nm_val = $('input[name="ctgy_nm"]').val()

                    that.text("Rename")
                        .parents('div')
                        .siblings('div')
                        .children('.ctgy-name')
                        .html( ctgy_nm_val ).end().end().end();

                    Category.modify({ctgy_id: scope.catid, ctgy_nm: ctgy_nm_val});

                } else {
                    that.text("Update")
                        .parents('div')
                        .siblings('div')
                        .children('.ctgy-name')
                        .html( input ).end().end().end()
                }
                e.preventDefault();
            });
        }
    }

})
<commit_msg>I love you<commit_after>angular.module('categorycontrol', [])
.directive('add', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                e.preventDefault();
            });
        }
    }
})
.directive('renameCtgy', function(Category) {
    return {
        restrict: 'A'
      , scope: {
          catid: "@catid"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                var that = $(this);

                var input = $('<input type="text" name="ctgy_nm"/>').val(
                    that.parents('div').siblings('div').children('.ctgy-name').html()
                );

                if(that.text() == "Update") {
                    var ctgy_nm_val = $('input[name="ctgy_nm"]').val()

                    if(ctgy_nm_val == 'undefined' || ctgy_nm_val == null || ctgy_nm_val == "")  {
                        alert("Cannot be blank!");
                    } else {
                        that.text("Rename")
                            .parents('div')
                            .siblings('div')
                            .children('.ctgy-name')
                            .html( ctgy_nm_val ).end().end().end();

                        Category.modify({ctgy_id: scope.catid, ctgy_nm: ctgy_nm_val});
                    }
                } else {
                    that.text("Update")
                        .parents('div')
                        .siblings('div')
                        .children('.ctgy-name')
                        .html( input ).end().end().end()
                }
                e.preventDefault();
            });
        }
    }

})
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Kagilum SAS.
 *
 * This file is part of iceScrum.
 *
 * iceScrum is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License.
 *
 * iceScrum is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with iceScrum.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *
 * Vincent Barrier (vbarrier@kagilum.com)
 * Nicolas Noullet (nnoullet@kagilum.com)
 *
 */
controllers.controller('teamCtrl', ['$scope', '$filter', 'Session', 'TeamService', 'UserService', function($scope, $filter, Session, TeamService, UserService) {

    $scope.team = {};
    $scope.searchTeam = function(val, create){
        return TeamService.search(val, create);
    };

    $scope.warning = { on: false };

    $scope.selectTeam = function($item, $model, $label){
        $scope.team = $model;
        $scope.team.selected = true;
        //Add current user to the team
        if (!$scope.team.id){
            $scope.team.class = 'team';
            var current = angular.copy(Session.user);
            $scope.team.members = [];
            $scope.team.members.push(current);
            $scope.team.scrumMasters = [];
            $scope.team.scrumMasters.push(current);
        }
        if ($model.members && $model.scrumMasters){
            $scope.team.members = $model.members.map(function(member){
                member.scrumMaster = _.find($model.scrumMasters, { id: member.id }) ? true : false;
                return member;
            });
        }
        if ($scope.project) {
            var filteredStakeHolders = _.filter($scope.project.stakeHolders, function(u) {
                return !_.find($scope.team.members, { email: u.email });
            });
            var filteredProductOwners = _.filter($scope.project.productOwners, function(u) {
                var member = _.find($scope.team.members, { email: u.email });
                return member ? member.scrumMaster : true;
            });
            if (filteredProductOwners.length != $scope.project.productOwners.length || filteredStakeHolders.length != $scope.project.stakeHolders.length) {
                $scope.warning.on = true;
            }
            $scope.project.stakeHolders = filteredStakeHolders;
            $scope.project.productOwners = filteredProductOwners;
            $scope.team.members = $scope.team.members.map(function(member) {
                member.productOwner = _.find($scope.project.productOwners, { id: member.id }) ? true : false;
                return member;
            });
            $scope.project.team = $scope.team;
        }
        if (!_.isEmpty($model.invitedMembers)) {
            $scope.team.members = $scope.team.members.concat($model.invitedMembers);
        }
        if (!_.isEmpty($model.invitedScrumMasters)) {
            $scope.team.members = $scope.team.members.concat(_.map($model.invitedScrumMasters, function(member) { return _.merge(member, { scrumMaster: true })}));
        }
    };

    if ($scope.teamPromise) {
        $scope.teamPromise.then(function(team) {
            $scope.selectTeam(null, team);
        });
    }

    $scope.unSelectTeam = function() {
        $scope.warning.on = false;
        $scope.project.team = {};
        if ($scope.team.selected) {
            $scope.team = {};
            $scope.member = {};
        }
    };

    $scope.member = {};
    $scope.searchMembers = function(val){
        return UserService.search(val).then(function(users) {
            return _.chain(users)
                .filter(function(member){
                    var found = false;
                    if ($scope.project){
                        found = _.find($scope.project.stakeHolders, { email: member.email });
                    }
                    if (!found){
                        found = _.find($scope.team.members, { email: member.email });
                    }
                    return !found;
                })
                .map(function(member){
                    member.name = $filter('userFullName')(member);
                    return member;
                })
                .value();
        });
    };

    $scope.addTeamMember = function(member){
        var po = _.find($scope.project.productOwners, { email: member.email });
        if (po) {
            member.scrumMaster = true;
            member.productOwner = true;
            $scope.team.scrumMasters.push(member);
        }
        $scope.team.members.push(member);
        $scope.member = {};
    };

    $scope.removeTeamMember = function(member) {
        _.remove($scope.team.members, { email: member.email });
        _.remove($scope.team.scrumMasters, { email: member.email });
    };

    $scope.scrumMasterChanged = function(member) {
        if (member.scrumMaster) {
            $scope.team.scrumMasters.push(member);
        } else {
            _.remove($scope.team.scrumMasters, { email: member.email }); // equality on email because invited members have no id
        }
    };
}]);

controllers.controller('manageTeamsModalCtrl', ['$scope', '$filter', 'TeamService', 'UserService', function($scope, $filter, TeamService, UserService) {
    // Functions
    $scope.selectTeam = function(team) {
        $scope.team = angular.copy(team);
        if (team.members && team.scrumMasters){
            $scope.team.members = team.members.map(function(member){
                member.scrumMaster = _.find(team.scrumMasters, { id: member.id }) ? true : false;
                return member;
            });
            if (!_.isEmpty(team.invitedMembers)) {
                $scope.team.members = $scope.team.members.concat(team.invitedMembers);
            }
            if (!_.isEmpty(team.invitedScrumMasters)) {
                $scope.team.members = $scope.team.members.concat(_.map(team.invitedScrumMasters, function(member) { return _.merge(member, { scrumMaster: true })}));
            }
        }
        $scope.ownerCandidates = angular.copy($scope.team.members);
        var owner = team.owner;
        if (!_.find($scope.ownerCandidates, {id: owner.id})) {
            $scope.ownerCandidates.push(owner);
        }
    };
    $scope.save = function(team) {
        TeamService.save(team)
            .then(function(team) {
                $scope.newTeam = {};
                $scope.team = team;
                $scope.teams.push(team);
                $scope.resetFormValidation($scope.formHolder.newTeamForm);
                $scope.notifySuccess('todo.is.ui.team.saved');
            });
    };
    $scope.update = function(team) {
        TeamService.update(team)
            .then(function(returnedTeam) {
                $scope.resetFormValidation($scope.formHolder.updateTeamForm);
                angular.extend(_.find($scope.teams, { id: team.id }), returnedTeam);
                $scope.notifySuccess('todo.is.ui.team.updated');
            });
    };
    $scope.delete = function(team) {
        // TODO cancellable delete
        TeamService.delete(team)
            .then(function() {
                $scope.notifySuccess('todo.is.ui.deleted');
                $scope.team = {};
            });
    };
    $scope.cancel = function() {
        $scope.team = {};
        $scope.resetFormValidation($scope.formHolder.updateTeamForm);
    };
    $scope.teamSelected = function() {
        return !_.isEmpty($scope.team);
    };
    $scope.authorizedTeam = function(action, team) {
        return TeamService.authorizedTeam(action, team);
    };
    $scope.searchTeams = function() {
        var offset = $scope.teamsPerPage * ($scope.currentPage - 1);
        TeamService.listByUser($scope.teamSearch, offset).then(function(teamsAndTotal) {
            $scope.totalTeams = teamsAndTotal.total;
            $scope.teams = teamsAndTotal.teams;
        });
    };
    // Init
    $scope.totalTeams = 0;
    $scope.currentPage = 1;
    $scope.teamsPerPage = 9; // Constant
    $scope.teamSearch = '';
    $scope.teams = [];
    $scope.formHolder = {};
    $scope.team = {};
    $scope.newTeam = {};
    $scope.searchTeams();

    // Member management TODO remove duplication with controller above
    $scope.teamMembersEditable = function(team) {
        return true;
    };
    $scope.member = {};
    $scope.searchMembers = function(val){
        return UserService.search(val).then(function(users) {
            return _.chain(users)
                .filter(function(member){
                    var found = false;
                    if (!found){
                        found = _.find($scope.team.members, { email: member.email });
                    }
                    return !found;
                })
                .map(function(member){
                    member.name = $filter('userFullName')(member);
                    return member;
                })
                .value();
        });
    };
    $scope.addTeamMember = function(member){
        $scope.team.members.push(member);
        $scope.member = {};
    };
    $scope.removeTeamMember = function(member) {
        _.remove($scope.team.members, { email: member.email });
        _.remove($scope.team.scrumMasters, { email: member.email });
    };
    $scope.scrumMasterChanged = function(member) {
        if (member.scrumMaster) {
            $scope.team.scrumMasters.push(member);
        } else {
            _.remove($scope.team.scrumMasters, { email: member.email }); // equality on email because invited members have no id
        }
    };
}]);<commit_msg>Clean team controller<commit_after>/*
 * Copyright (c) 2014 Kagilum SAS.
 *
 * This file is part of iceScrum.
 *
 * iceScrum is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License.
 *
 * iceScrum is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with iceScrum.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *
 * Vincent Barrier (vbarrier@kagilum.com)
 * Nicolas Noullet (nnoullet@kagilum.com)
 *
 */
controllers.controller('teamCtrl', ['$scope', '$filter', 'Session', 'TeamService', 'UserService', function($scope, $filter, Session, TeamService, UserService) {
    // Functions
    $scope.searchTeam = function(val, create) {
        return TeamService.search(val, create);
    };
    $scope.selectTeam = function($item, $model) {
        $scope.team = $model;
        $scope.team.selected = true;
        //Add current user to the team
        if (!$scope.team.id) {
            $scope.team.class = 'team';
            var current = angular.copy(Session.user);
            $scope.team.members = [];
            $scope.team.members.push(current);
            $scope.team.scrumMasters = [];
            $scope.team.scrumMasters.push(current);
        }
        if ($model.members && $model.scrumMasters) {
            $scope.team.members = $model.members.map(function(member) {
                member.scrumMaster = _.find($model.scrumMasters, {id: member.id}) ? true : false;
                return member;
            });
        }
        if ($scope.project) {
            var filteredStakeHolders = _.filter($scope.project.stakeHolders, function(u) {
                return !_.find($scope.team.members, {email: u.email});
            });
            var filteredProductOwners = _.filter($scope.project.productOwners, function(u) {
                var member = _.find($scope.team.members, {email: u.email});
                return member ? member.scrumMaster : true;
            });
            if (filteredProductOwners.length != $scope.project.productOwners.length || filteredStakeHolders.length != $scope.project.stakeHolders.length) {
                $scope.warning.on = true;
            }
            $scope.project.stakeHolders = filteredStakeHolders;
            $scope.project.productOwners = filteredProductOwners;
            $scope.team.members = $scope.team.members.map(function(member) {
                member.productOwner = _.find($scope.project.productOwners, {id: member.id}) ? true : false;
                return member;
            });
            $scope.project.team = $scope.team;
        }
        if (!_.isEmpty($model.invitedMembers)) {
            $scope.team.members = $scope.team.members.concat($model.invitedMembers);
        }
        if (!_.isEmpty($model.invitedScrumMasters)) {
            $scope.team.members = $scope.team.members.concat(_.map($model.invitedScrumMasters, function(member) {
                return _.merge(member, {scrumMaster: true})
            }));
        }
    };
    $scope.unSelectTeam = function() {
        $scope.warning.on = false;
        $scope.project.team = {};
        if ($scope.team.selected) {
            $scope.team = {};
            $scope.member = {};
        }
    };
    $scope.searchMembers = function(val) {
        return UserService.search(val).then(function(users) {
            return _.chain(users)
                .filter(function(member) {
                    var found = false;
                    if ($scope.project) {
                        found = _.find($scope.project.stakeHolders, {email: member.email});
                    }
                    if (!found) {
                        found = _.find($scope.team.members, {email: member.email});
                    }
                    return !found;
                })
                .map(function(member) {
                    member.name = $filter('userFullName')(member);
                    return member;
                })
                .value();
        });
    };
    $scope.addTeamMember = function(member) {
        var po = _.find($scope.project.productOwners, {email: member.email});
        if (po) {
            member.scrumMaster = true;
            member.productOwner = true;
            $scope.team.scrumMasters.push(member);
        }
        $scope.team.members.push(member);
        $scope.member = {};
    };
    $scope.removeTeamMember = function(member) {
        _.remove($scope.team.members, {email: member.email});
        _.remove($scope.team.scrumMasters, {email: member.email});
    };
    $scope.scrumMasterChanged = function(member) {
        if (member.scrumMaster) {
            $scope.team.scrumMasters.push(member);
        } else {
            _.remove($scope.team.scrumMasters, {email: member.email}); // equality on email because invited members have no id
        }
    };
    // Init
    $scope.team = {};
    $scope.member = {};
    $scope.warning = {on: false};
    if ($scope.teamPromise) {
        $scope.teamPromise.then(function(team) {
            $scope.selectTeam(null, team);
        });
    }
}]);

controllers.controller('manageTeamsModalCtrl', ['$scope', '$filter', 'TeamService', 'UserService', function($scope, $filter, TeamService, UserService) {
    // Functions
    $scope.selectTeam = function(team) {
        $scope.team = angular.copy(team);
        if (team.members && team.scrumMasters) {
            $scope.team.members = team.members.map(function(member) {
                member.scrumMaster = _.find(team.scrumMasters, {id: member.id}) ? true : false;
                return member;
            });
            if (!_.isEmpty(team.invitedMembers)) {
                $scope.team.members = $scope.team.members.concat(team.invitedMembers);
            }
            if (!_.isEmpty(team.invitedScrumMasters)) {
                $scope.team.members = $scope.team.members.concat(_.map(team.invitedScrumMasters, function(member) {
                    return _.merge(member, {scrumMaster: true})
                }));
            }
        }
        $scope.ownerCandidates = angular.copy($scope.team.members);
        var owner = team.owner;
        if (!_.find($scope.ownerCandidates, {id: owner.id})) {
            $scope.ownerCandidates.push(owner);
        }
    };
    $scope.save = function(team) {
        TeamService.save(team)
            .then(function(team) {
                $scope.newTeam = {};
                $scope.team = team;
                $scope.teams.push(team);
                $scope.resetFormValidation($scope.formHolder.newTeamForm);
                $scope.notifySuccess('todo.is.ui.team.saved');
            });
    };
    $scope.update = function(team) {
        TeamService.update(team)
            .then(function(returnedTeam) {
                $scope.resetFormValidation($scope.formHolder.updateTeamForm);
                angular.extend(_.find($scope.teams, {id: team.id}), returnedTeam);
                $scope.notifySuccess('todo.is.ui.team.updated');
            });
    };
    $scope.delete = function(team) {
        // TODO cancellable delete
        TeamService.delete(team)
            .then(function() {
                $scope.notifySuccess('todo.is.ui.deleted');
                $scope.team = {};
            });
    };
    $scope.cancel = function() {
        $scope.team = {};
        $scope.resetFormValidation($scope.formHolder.updateTeamForm);
    };
    $scope.teamSelected = function() {
        return !_.isEmpty($scope.team);
    };
    $scope.authorizedTeam = function(action, team) {
        return TeamService.authorizedTeam(action, team);
    };
    $scope.searchTeams = function() {
        var offset = $scope.teamsPerPage * ($scope.currentPage - 1);
        TeamService.listByUser($scope.teamSearch, offset).then(function(teamsAndTotal) {
            $scope.totalTeams = teamsAndTotal.total;
            $scope.teams = teamsAndTotal.teams;
        });
    };
    // Init
    $scope.totalTeams = 0;
    $scope.currentPage = 1;
    $scope.teamsPerPage = 9; // Constant
    $scope.teamSearch = '';
    $scope.teams = [];
    $scope.formHolder = {};
    $scope.team = {};
    $scope.newTeam = {};
    $scope.searchTeams();

    // Member management TODO remove duplication with controller above
    $scope.teamMembersEditable = function() {
        return true;
    };
    $scope.member = {};
    $scope.searchMembers = function(val) {
        return UserService.search(val).then(function(users) {
            return _.chain(users)
                .filter(function(member) {
                    var found = false;
                    if (!found) {
                        found = _.find($scope.team.members, {email: member.email});
                    }
                    return !found;
                })
                .map(function(member) {
                    member.name = $filter('userFullName')(member);
                    return member;
                })
                .value();
        });
    };
    $scope.addTeamMember = function(member) {
        $scope.team.members.push(member);
        $scope.member = {};
    };
    $scope.removeTeamMember = function(member) {
        _.remove($scope.team.members, {email: member.email});
        _.remove($scope.team.scrumMasters, {email: member.email});
    };
    $scope.scrumMasterChanged = function(member) {
        if (member.scrumMaster) {
            $scope.team.scrumMasters.push(member);
        } else {
            _.remove($scope.team.scrumMasters, {email: member.email}); // equality on email because invited members have no id
        }
    };
}]);<|endoftext|>


<commit_before>Ext.define('devilry.extjshelpers.studentsmanager.StudentsGrid', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.studentsmanager_studentsgrid',
    cls: 'widget-studentsmanager_studentsgrid',
    sortableColumns: false,

    config: {
        assignmentid: undefined
    },

    mixins: {
        canPerformActionsOnSelected: 'devilry.extjshelpers.GridPeformActionOnSelected'
    },

    infoColTpl: Ext.create('Ext.XTemplate',
        '
',
        '
',
        '        <tpl if="is_open">',
        '           Open',
        '        </tpl>',
        '        <tpl if="!is_open">',
        '           Closed',
        '       </tpl>',
        '
',
        '
',
        '        <tpl if="latest_deadline_id === null">',
        '           No deadlines',
        '        </tpl>',
        '
',
        '
'
    ),

    candidatesCol: Ext.create('Ext.XTemplate',
        '
',
        '    <tpl for="candidates__identifier">',
        '
{.}
',
        '    </tpl>',
        '
'
    ),

    examinersCol: Ext.create('Ext.XTemplate',
        '
',
        '    <tpl for="examiners__username">',
        '
{.}
',
        '    </tpl>',
        '
'
    ),

    deliveriesColTpl: Ext.create('Ext.XTemplate',
        '',
        '    <tpl if="number_of_deliveries > 0">',
        '       {number_of_deliveries}',
        '    </tpl>',
        '    <tpl if="number_of_deliveries == 0">',
        '       0
',
        '   </tpl>',
        ''
    ),

    pointsColTpl: Ext.create('Ext.XTemplate',
        '',
        '    <tpl if="feedback">',
        '       {feedback__points}',
        '    </tpl>',
        '    <tpl if="!feedback">',
        '       ∅',
        '   </tpl>',
        ''
    ),

    gradeColTpl: Ext.create('Ext.XTemplate',
        '
',
        '   <tpl if="feedback">',
        '
',
        '           <tpl if="feedback__is_passing_grade">Passed</tpl>',
        '           <tpl if="!feedback__is_passing_grade">Failed</tpl>',
        '           : {feedback__grade}',
        '
',
        '
',
        '            <tpl if="feedback__delivery__delivery_type == 0">Electronic</tpl>',
        '            <tpl if="feedback__delivery__delivery_type == 1">Non-electronic</tpl>',
        '            <tpl if="feedback__delivery__delivery_type == 2">From previous period</tpl>',
        '            <tpl if="feedback__delivery__delivery_type > 2">Unknown delivery type</tpl>',
        '
',
        '   </tpl>',
        '    <tpl if="!feedback">',
        '
',
        '           No feedback',
        '
',
        '    </tpl>',
        '
'
    ),

    constructor: function(config) {
        this.callParent([config]);
        this.initConfig(config);
    },

    initComponent: function() {
        this.store.pageSize = 30;
        this.store.proxy.extraParams.filters = Ext.JSON.encode([{
            field: 'parentnode',
            comp: 'exact',
            value: this.assignmentid
        }]);

        this.selModel = Ext.create('Ext.selection.CheckboxModel', {
            checkOnly: true
        });

        Ext.apply(this, {
            dockedItems: [{
                xtype: 'pagingtoolbar',
                store: this.store,
                dock: 'bottom',
                displayInfo: true
            }],

            //listeners: {
                //scope: this,
                //itemclick: function(grid, record) {
                    //if(grid.getSelectionModel().isSelected(record)) {
                        //grid.getSelectionModel().deselect(record);
                    //} else {
                        //grid.getSelectionModel().select(record, true);
                    //}
                //}
            //},

            columns: [{
                text: '', dataIndex: 'id', width: 100,
                renderer: this.formatInfoCol
            }, {
                text: 'Students', dataIndex: 'id', flex: 4,
                renderer: this.formatCandidatesCol
            }, {
                text: 'Deliveries', dataIndex: 'id', flex: 2,
                renderer: this.formatDeliveriesCol
            }, {
                text: 'Latest feedback',
                columns: [{
                    text: 'Points',
                    dataIndex: 'feedback__points',
                    renderer: this.formatPointsCol,
                    width: 70
                }, {
                    text: 'Grade',
                    dataIndex: 'feedback__grade',
                    width: 150,
                    renderer: this.formatGradeCol
                }]
            }, {
                text: 'Examiners', dataIndex: 'id', flex: 4,
                renderer: this.formatExaminersCol
            }, {
                text: 'Group name', dataIndex: 'name', flex: 3
            }]
        });
        this.callParent(arguments);
        this.store.load();
    },

    formatInfoCol: function(value, p, record) {
        return this.infoColTpl.apply(record.data);
    },

    formatCandidatesCol: function(value, p, record) {
        return this.candidatesCol.apply(record.data);
    },

    formatExaminersCol: function(value, p, record) {
        return this.examinersCol.apply(record.data);
    },

    formatDeliveriesCol: function(value, p, record) {
        return this.deliveriesColTpl.apply(record.data);
    },

    formatPointsCol: function(value, p, record) {
        return this.pointsColTpl.apply(record.data);
    },

    formatGradeCol: function(value, p, record) {
        return this.gradeColTpl.apply(record.data);
    }
});
<commit_msg>apps.extjshelpers: Column header styling.<commit_after>Ext.define('devilry.extjshelpers.studentsmanager.StudentsGrid', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.studentsmanager_studentsgrid',
    cls: 'widget-studentsmanager_studentsgrid',
    sortableColumns: false,

    config: {
        assignmentid: undefined
    },

    mixins: {
        canPerformActionsOnSelected: 'devilry.extjshelpers.GridPeformActionOnSelected'
    },

    infoColTpl: Ext.create('Ext.XTemplate',
        '
',
        '
',
        '        <tpl if="is_open">',
        '           Open',
        '        </tpl>',
        '        <tpl if="!is_open">',
        '           Closed',
        '       </tpl>',
        '
',
        '
',
        '        <tpl if="latest_deadline_id === null">',
        '           No deadlines',
        '        </tpl>',
        '
',
        '
'
    ),

    candidatesCol: Ext.create('Ext.XTemplate',
        '
',
        '    <tpl for="candidates__identifier">',
        '
{.}
',
        '    </tpl>',
        '
'
    ),

    examinersCol: Ext.create('Ext.XTemplate',
        '
',
        '    <tpl for="examiners__username">',
        '
{.}
',
        '    </tpl>',
        '
'
    ),

    deliveriesColTpl: Ext.create('Ext.XTemplate',
        '',
        '    <tpl if="number_of_deliveries > 0">',
        '       {number_of_deliveries}',
        '    </tpl>',
        '    <tpl if="number_of_deliveries == 0">',
        '       0
',
        '   </tpl>',
        ''
    ),

    pointsColTpl: Ext.create('Ext.XTemplate',
        '',
        '    <tpl if="feedback">',
        '       {feedback__points}',
        '    </tpl>',
        '    <tpl if="!feedback">',
        '       ∅',
        '   </tpl>',
        ''
    ),

    gradeColTpl: Ext.create('Ext.XTemplate',
        '
',
        '   <tpl if="feedback">',
        '
',
        '           <tpl if="feedback__is_passing_grade">Passed</tpl>',
        '           <tpl if="!feedback__is_passing_grade">Failed</tpl>',
        '           : {feedback__grade}',
        '
',
        '
',
        '            <tpl if="feedback__delivery__delivery_type == 0">Electronic</tpl>',
        '            <tpl if="feedback__delivery__delivery_type == 1">Non-electronic</tpl>',
        '            <tpl if="feedback__delivery__delivery_type == 2">From previous period</tpl>',
        '            <tpl if="feedback__delivery__delivery_type > 2">Unknown delivery type</tpl>',
        '
',
        '   </tpl>',
        '    <tpl if="!feedback">',
        '
',
        '           No feedback',
        '
',
        '    </tpl>',
        '
'
    ),

    constructor: function(config) {
        this.callParent([config]);
        this.initConfig(config);
    },

    initComponent: function() {
        this.store.pageSize = 30;
        this.store.proxy.extraParams.filters = Ext.JSON.encode([{
            field: 'parentnode',
            comp: 'exact',
            value: this.assignmentid
        }]);

        this.selModel = Ext.create('Ext.selection.CheckboxModel', {
            checkOnly: true
        });

        Ext.apply(this, {
            dockedItems: [{
                xtype: 'pagingtoolbar',
                store: this.store,
                dock: 'bottom',
                displayInfo: true
            }],

            //listeners: {
                //scope: this,
                //itemclick: function(grid, record) {
                    //if(grid.getSelectionModel().isSelected(record)) {
                        //grid.getSelectionModel().deselect(record);
                    //} else {
                        //grid.getSelectionModel().select(record, true);
                    //}
                //}
            //},

            columns: [{
                text: '', dataIndex: 'id', width: 100,
                menuDisabled: true,
                renderer: this.formatInfoCol
            }, {
                text: 'Students', dataIndex: 'id', flex: 4,
                menuDisabled: true,
                renderer: this.formatCandidatesCol
            }, {
                text: 'Deliveries', dataIndex: 'id', flex: 2,
                menuDisabled: true,
                renderer: this.formatDeliveriesCol
            }, {
                text: 'Latest feedback',
                menuDisabled: true,
                columns: [{
                    text: 'Points',
                    dataIndex: 'feedback__points',
                    renderer: this.formatPointsCol,
                    menuDisabled: true,
                    width: 70
                }, {
                    text: 'Grade',
                    dataIndex: 'feedback__grade',
                    width: 150,
                    menuDisabled: true,
                    renderer: this.formatGradeCol
                }]
            }, {
                text: 'Examiners', dataIndex: 'id', flex: 4,
                menuDisabled: true,
                renderer: this.formatExaminersCol
            }, {
                text: 'Group name', dataIndex: 'name', flex: 3,
                menuDisabled: true
            }]
        });
        this.callParent(arguments);
        this.store.load();
    },

    formatInfoCol: function(value, p, record) {
        return this.infoColTpl.apply(record.data);
    },

    formatCandidatesCol: function(value, p, record) {
        return this.candidatesCol.apply(record.data);
    },

    formatExaminersCol: function(value, p, record) {
        return this.examinersCol.apply(record.data);
    },

    formatDeliveriesCol: function(value, p, record) {
        return this.deliveriesColTpl.apply(record.data);
    },

    formatPointsCol: function(value, p, record) {
        return this.pointsColTpl.apply(record.data);
    },

    formatGradeCol: function(value, p, record) {
        return this.gradeColTpl.apply(record.data);
    }
});
<|endoftext|>


<commit_before>
OEX.BrowserTabsManager = function( parentObj ) {

  OPromise.call( this );

  // Set up 0 mock BrowserTab objects at startup
  this.length = 0;

  this._lastFocusedTab = null;

  this._parent = parentObj;

  // Remove all collection items and replace with browserTabs
  this.replaceTabs = function( browserTabs ) {

    for( var i = 0, l = this.length; i < l; i++ ) {
      delete this[ i ];
    }
    this.length = 0;

    for( var i = 0, l = browserTabs.length; i < l; i++ ) {
      if(this !== OEX.tabs) {
        browserTabs[ i ].properties.index = i;
      }
      browserTabs[ i ].properties.closed = false;
      this[ i ] = browserTabs[ i ];
    }
    this.length = browserTabs.length;
  };

  // Add an array of browserTabs to the current collection
  this.addTabs = function( browserTabs, startPosition ) {
    // Extract current set of tabs in collection
    var allTabs = [];
    for(var i = 0, l = this.length; i < l; i++) {
      allTabs[ i ] = this[ i ];
    }

    // Add new browserTabs to allTabs array
    var spliceArgs = [startPosition || allTabs.length - 1, 0].concat( browserTabs );
    Array.prototype.splice.apply(allTabs, spliceArgs);

    // Rewrite the current tabs collection in order
    for( var i = 0, l = allTabs.length; i < l; i++ ) {
      if(this !== OEX.tabs) {
        // Update all tab indexes to the current tabs collection order
        allTabs[ i ].properties.index = i;
      }
      allTabs[ i ].properties.closed = false;
      this[ i ] = allTabs[ i ];
    }
    this.length = allTabs.length;

  };

  // Remove a browserTab from the current collection
  this.removeTab = function( browserTab ) {

    var oldCollectionLength = this.length;

    // Extract current set of tabs in collection
    var allTabs = [];
    var removeTabIndex = -1;
    for(var i = 0, l = this.length; i < l; i++) {
      allTabs[ i ] = this[ i ];
      if( allTabs[ i ].id == browserTab.id ) {
        removeTabIndex = i;
      }
    }

    // Remove browser tab
    if(removeTabIndex > -1) {
      allTabs.splice(removeTabIndex, 1);
    }

    // Indicate that this tab is now closed
    browserTab.properties.closed = true;
    // Detach _windowParent from removed tab
    browserTab._windowParent = null;

    // Rewrite the current tabs collection
    for( var i = 0, l = allTabs.length; i < l; i++ ) {
      if(this !== OEX.tabs) {
        allTabs[ i ].properties.index = i;
      }
      this[ i ] = allTabs[ i ];
    }
    this.length = allTabs.length;

    // Remove any ghost items, if any
    if(oldCollectionLength > this.length) {
      for(var i = this.length, l = oldCollectionLength; i < l; i++) {
        delete this[ i ];
      }
    }

  };

};

OEX.BrowserTabsManager.prototype = Object.create( OPromise.prototype );

OEX.BrowserTabsManager.prototype.create = function( browserTabProperties, before, obj ) {

  browserTabProperties = browserTabProperties || {};

  var shadowBrowserTab = obj || new OEX.BrowserTab();

  // If current object is not resolved, then enqueue this action
  if( !this.resolved || (this._parent && !this._parent.resolved) ) {
    this.enqueue( 'create', browserTabProperties, before, shadowBrowserTab );
    return shadowBrowserTab;
  }

  // Parameter mappings
  browserTabProperties.pinned = browserTabProperties.locked || false;
  browserTabProperties.active = browserTabProperties.focused || false;

  // Not allowed in Chromium API
  delete browserTabProperties.focused;

  // TODO handle private tab insertion differently in Chromium
  //browserTabProperties.incognito = browserTabProperties.private || false;

  // Set parent window to create the tab in

  if(this._parent && this._parent.closed === true ) {
    throw {
        name:        "Invalid State Error",
        message:     "Parent window is in the closed state and therefore is invalid"
    };
    return;
  }
  // no windowId will default to adding the tab to the current window
  browserTabProperties.windowId = this._parent ? this._parent.properties.id : null;

  // Set insert position for the new tab from 'before' attribute, if any
  if( before && before instanceof OEX.BrowserTab ) {

    if( before.closed === true ) {
      throw {
          name:        "Invalid State Error",
          message:     "'before' attribute is in the closed state and therefore is invalid"
      };
      return;
    }

    if(before._windowParent && before._windowParent.closed === true ) {
      throw {
          name:        "Invalid State Error",
          message:     "Parent window of 'before' attribute is in the closed state and therefore is invalid"
      };
      return;
    }
    browserTabProperties.windowId = before._windowParent ?
                                      before._windowParent.properties.id : browserTabProperties.windowId;
    browserTabProperties.index = before.position;

  }

  chrome.tabs.create(
    browserTabProperties,
    function( _tab ) {

      // Update BrowserTab properties
      for(var i in _tab) {
        shadowBrowserTab.properties[i] = _tab[i];
      }

      // Set up the shadowBrowserTab's parent BrowserWindow relationship
      var noParentWindow = true;

      if(_tab.windowId) {
        var _windows = opera.extension.windows;
        for(var i = 0, l = _windows.length; i < l; i++ ) {
          if( _windows[ i ].properties.id === _tab.windowId ) {
            noParentWindow = false;
            shadowBrowserTab._windowParent = _windows[ i ];
            break;
          }
        }
      }

      // Add to the default window if there is no other parent to use
      if( noParentWindow ) {
        shadowBrowserTab._windowParent = OEX.windows.getLastFocused();
      }

      // Add this object to the current tabs collection
      this.addTabs([ shadowBrowserTab ], shadowBrowserTab.properties.index);

      // Add this object to the root tab manager (if this is not the root tab manager)
      if(this !== OEX.tabs) {
        OEX.tabs.addTabs([ shadowBrowserTab ]);
      }

      // Resolve new tab, if it hasn't been resolved already
      shadowBrowserTab.resolve( _tab );

      // Dispatch oncreate event to all attached event listeners
      this.fireEvent( new OEvent('create', {
          "tab": shadowBrowserTab,
          "prevWindow": shadowBrowserTab._windowParent,
          "prevTabGroup": null,
          "prevPosition": -1
      }) );

      this.dequeue();

  }.bind(this));

  return shadowBrowserTab;

};

OEX.BrowserTabsManager.prototype.getAll = function() {

  var allTabs = [];

  for(var i = 0, l = this.length; i < l; i++) {
    allTabs[ i ] = this[ i ];
  }

  return allTabs;

};

OEX.BrowserTabsManager.prototype.getSelected = function() {

  return this._lastFocusedTab || this[ 0 ];

};
// Alias of .getSelected()
OEX.BrowserTabsManager.prototype.getFocused = OEX.BrowserTabsManager.prototype.getSelected;

OEX.BrowserTabsManager.prototype.close = function( browserTab ) {

  if( !browserTab ) {
    return;
  }

  // If current object is not resolved, then enqueue this action
  if( !this.resolved || (this._parent && !this._parent.resolved) || !browserTab.resolved ) {
    this.enqueue( 'close', browserTab );
    return;
  }

  chrome.tabs.remove(browserTab.properties.id, function() {
    browserTab.dequeue();

    this.dequeue();
  }.bind(this));

};
<commit_msg>Fix minor bug in BrowserTabsManager.js<commit_after>
OEX.BrowserTabsManager = function( parentObj ) {

  OPromise.call( this );

  // Set up 0 mock BrowserTab objects at startup
  this.length = 0;

  this._lastFocusedTab = null;

  this._parent = parentObj;

  // Remove all collection items and replace with browserTabs
  this.replaceTabs = function( browserTabs ) {

    for( var i = 0, l = this.length; i < l; i++ ) {
      delete this[ i ];
    }
    this.length = 0;

    for( var i = 0, l = browserTabs.length; i < l; i++ ) {
      if(this !== OEX.tabs) {
        browserTabs[ i ].properties.index = i;
      }
      browserTabs[ i ].properties.closed = false;
      this[ i ] = browserTabs[ i ];
    }
    this.length = browserTabs.length;
  };

  // Add an array of browserTabs to the current collection
  this.addTabs = function( browserTabs, startPosition ) {
    // Extract current set of tabs in collection
    var allTabs = [];
    for(var i = 0, l = this.length; i < l; i++) {
      allTabs[ i ] = this[ i ];
    }

    // Add new browserTabs to allTabs array
    var spliceArgs = [startPosition || allTabs.length - 1, 0].concat( browserTabs );
    Array.prototype.splice.apply(allTabs, spliceArgs);

    // Rewrite the current tabs collection in order
    for( var i = 0, l = allTabs.length; i < l; i++ ) {
      if(this !== OEX.tabs) {
        // Update all tab indexes to the current tabs collection order
        allTabs[ i ].properties.index = i;
      }
      allTabs[ i ].properties.closed = false;
      this[ i ] = allTabs[ i ];
    }
    this.length = allTabs.length;

  };

  // Remove a browserTab from the current collection
  this.removeTab = function( browserTab ) {

    var oldCollectionLength = this.length;

    // Extract current set of tabs in collection
    var allTabs = [];
    var removeTabIndex = -1;
    for(var i = 0, l = this.length; i < l; i++) {
      allTabs[ i ] = this[ i ];
      if( allTabs[ i ].id == browserTab.id ) {
        removeTabIndex = i;
      }
    }

    // Remove browser tab
    if(removeTabIndex > -1) {
      allTabs.splice(removeTabIndex, 1);
    }

    // Indicate that this tab is now closed
    browserTab.properties.closed = true;
    // Detach _windowParent from removed tab
    browserTab._windowParent = null;

    // Rewrite the current tabs collection
    for( var i = 0, l = allTabs.length; i < l; i++ ) {
      if(this !== OEX.tabs) {
        allTabs[ i ].properties.index = i;
      }
      this[ i ] = allTabs[ i ];
    }
    this.length = allTabs.length;

    // Remove any ghost items, if any
    if(oldCollectionLength > this.length) {
      for(var i = this.length, l = oldCollectionLength; i < l; i++) {
        delete this[ i ];
      }
    }

  };

};

OEX.BrowserTabsManager.prototype = Object.create( OPromise.prototype );

OEX.BrowserTabsManager.prototype.create = function( browserTabProperties, before, obj ) {

  browserTabProperties = browserTabProperties || {};

  var shadowBrowserTab = obj || new OEX.BrowserTab();

  // If current object is not resolved, then enqueue this action
  if( !this.resolved || (this._parent && !this._parent.resolved) ) {
    this.enqueue( 'create', browserTabProperties, before, shadowBrowserTab );
    return shadowBrowserTab;
  }

  // Parameter mappings
  browserTabProperties.pinned = browserTabProperties.locked || false;
  browserTabProperties.active = browserTabProperties.focused || false;

  // Not allowed in Chromium API
  delete browserTabProperties.focused;

  // TODO handle private tab insertion differently in Chromium
  //browserTabProperties.incognito = browserTabProperties.private || false;

  // Set parent window to create the tab in

  if(this._parent && this._parent.closed === true ) {
    throw {
        name:        "Invalid State Error",
        message:     "Parent window is in the closed state and therefore is invalid"
    };
    return;
  }
  // no windowId will default to adding the tab to the current window
  browserTabProperties.windowId = this._parent ? this._parent.properties.id : undefined;

  // Set insert position for the new tab from 'before' attribute, if any
  if( before && before instanceof OEX.BrowserTab ) {

    if( before.closed === true ) {
      throw {
          name:        "Invalid State Error",
          message:     "'before' attribute is in the closed state and therefore is invalid"
      };
      return;
    }

    if(before._windowParent && before._windowParent.closed === true ) {
      throw {
          name:        "Invalid State Error",
          message:     "Parent window of 'before' attribute is in the closed state and therefore is invalid"
      };
      return;
    }
    browserTabProperties.windowId = before._windowParent ?
                                      before._windowParent.properties.id : browserTabProperties.windowId;
    browserTabProperties.index = before.position;

  }

  chrome.tabs.create(
    browserTabProperties,
    function( _tab ) {

      // Update BrowserTab properties
      for(var i in _tab) {
        shadowBrowserTab.properties[i] = _tab[i];
      }

      // Set up the shadowBrowserTab's parent BrowserWindow relationship
      var noParentWindow = true;

      if(_tab.windowId) {
        var _windows = opera.extension.windows;
        for(var i = 0, l = _windows.length; i < l; i++ ) {
          if( _windows[ i ].properties.id === _tab.windowId ) {
            noParentWindow = false;
            shadowBrowserTab._windowParent = _windows[ i ];
            break;
          }
        }
      }

      // Add to the default window if there is no other parent to use
      if( noParentWindow ) {
        shadowBrowserTab._windowParent = OEX.windows.getLastFocused();
      }

      // Add this object to the current tabs collection
      this.addTabs([ shadowBrowserTab ], shadowBrowserTab.properties.index);

      // Add this object to the root tab manager (if this is not the root tab manager)
      if(this !== OEX.tabs) {
        OEX.tabs.addTabs([ shadowBrowserTab ]);
      }

      // Resolve new tab, if it hasn't been resolved already
      shadowBrowserTab.resolve( _tab );

      // Dispatch oncreate event to all attached event listeners
      this.fireEvent( new OEvent('create', {
          "tab": shadowBrowserTab,
          "prevWindow": shadowBrowserTab._windowParent,
          "prevTabGroup": null,
          "prevPosition": -1
      }) );

      this.dequeue();

  }.bind(this));

  return shadowBrowserTab;

};

OEX.BrowserTabsManager.prototype.getAll = function() {

  var allTabs = [];

  for(var i = 0, l = this.length; i < l; i++) {
    allTabs[ i ] = this[ i ];
  }

  return allTabs;

};

OEX.BrowserTabsManager.prototype.getSelected = function() {

  return this._lastFocusedTab || this[ 0 ];

};
// Alias of .getSelected()
OEX.BrowserTabsManager.prototype.getFocused = OEX.BrowserTabsManager.prototype.getSelected;

OEX.BrowserTabsManager.prototype.close = function( browserTab ) {

  if( !browserTab ) {
    return;
  }

  // If current object is not resolved, then enqueue this action
  if( !this.resolved || (this._parent && !this._parent.resolved) || !browserTab.resolved ) {
    this.enqueue( 'close', browserTab );
    return;
  }

  chrome.tabs.remove(browserTab.properties.id, function() {
    browserTab.dequeue();

    this.dequeue();
  }.bind(this));

};
<|endoftext|>


<commit_before>/**
 * Animable.js
 *
 * https://github.com/JWhile/Animable.js
 *
 * version 1.2.0
 */

var anime,stopAnime;

(function(){ // namespace

// class Animation
function Animation(id, from, to, time, update)
{
    this.id = id; // :int

    this.from = from; // :float
    this.diff = to - from; // :float

    this.start = Date.now(); // :long
    this.time = time; // :int

    this.update = update; // :function
}
// function next(long now):boolean
Animation.prototype.next = function(now)
{
    var n = (now - this.start) / this.time;

    if(n >= 1)
    {
        this.update(this.diff + this.from);

        return true;
    }

    this.update(n * this.diff + this.from);

    return false;
};

var lastAnimId = 0; // :int
var animations = []; // :Array<Animation>
var loop = false; // :boolean

// function next():void
var next = function()
{
    loop = (animations.length > 0);

    if(loop)
    {
        newFrame(next);

        var now = Date.now();

        for(var i = 0; i < animations.length; ++i)
        {
            if(animations[i].next(now))
            {
                animations.splice(i, 1);

                --i;
            }
        }
    }
};

// function anime(function update, float from, float to, int time):int
anime = function(update, from, to, time)
{
    animations.push(new Animation(++lastAnimId, from, to, time, update));

    if(!loop)
    {
        newFrame(next);
    }

    return lastAnimId;
};

// function stopAnime(int id):void
stopAnime = function(id)
{
    for(var i = 0; i < animations.length; ++i)
    {
        if(animations[i].id === id)
        {
            animations.splice(i, 1);

            --i;
        }
    }
};

if(typeof Builder === 'function')
{
    // function anime(String property, int to, int time, function callback = null):@Chainable
    Builder.prototype.anime = function(property, to, time, callback)
    {
        this.stopAnime(''+ property);

        var self = this;

        var style = Builder.getStyle(this.node, property);
        var unit = (style.match(/em$|px$|%$/i) || [''])[0];

        this._animations[property] = anime(function(value)
        {
            if(value === to)
            {
                delete self._animations[property];

                if(callback != null)
                {
                    callback();
                }
            }

            self.node.style[property] = value + unit;

        }, parseInt(style), to, time);

        return this;
    };

    // function stopAnime(String property = null):void
    Builder.prototype.stopAnime = function(property)
    {
        this._animations = this._animations || {}; // Map<String, int>

        if(typeof property === 'string')
        {
            if(this._animations[property])
            {
                stopAnime(this._animations[property]);

                delete this._animations[property];
            }
        }
        else
        {
            for(var key in this._animations)
            {
                if(this._animations.hasOwnProperty(key))
                {
                    stopAnime(this._animations[key]);
                }
            }

            this._animations = {};
        }
    };
}

})();
<commit_msg>Add optionnal param smooth, to change animation acceleration<commit_after>/**
 * Animable.js
 *
 * https://github.com/JWhile/Animable.js
 *
 * version 1.2.0
 */

var anime,stopAnime;

(function(){ // namespace

// class Animation
function Animation(id, from, to, time, update, smooth)
{
    this.id = id; // :int

    this.from = from; // :float
    this.diff = to - from; // :float

    this.start = Date.now(); // :long
    this.time = time; // :int

    this.update = update; // :function

    this.smooth = smooth; // :function
}
// function next(long now):boolean
Animation.prototype.next = function(now)
{
    var currTime = now - this.start;

    if(currTime >= this.time)
    {
        this.update(this.diff + this.from);

        return true;
    }

    this.update(this.smooth(currTime, this.time, this.diff + this.from));

    return false;
};

var lastAnimId = 0; // :int
var animations = []; // :Array<Animation>
var loop = false; // :boolean

// function defaultSmooth(int currTime, int endTime, float endValue):float
var defaultSmooth = function(currTime, endTime, endValue)
{
    return currTime / endTime * endValue;
};

// function next():void
var next = function()
{
    loop = (animations.length > 0);

    if(loop)
    {
        newFrame(next);

        var now = Date.now();

        for(var i = 0; i < animations.length; ++i)
        {
            if(animations[i].next(now))
            {
                animations.splice(i, 1);

                --i;
            }
        }
    }
};

// function anime(function update, float from, float to, int time, function smooth = null):int
anime = function(update, from, to, time, smooth)
{
    animations.push(new Animation(++lastAnimId, from, to, time, update, (typeof smooth === 'function')? smooth : defaultSmooth));

    if(!loop)
    {
        newFrame(next);
    }

    return lastAnimId;
};

// function stopAnime(int id):void
stopAnime = function(id)
{
    for(var i = 0; i < animations.length; ++i)
    {
        if(animations[i].id === id)
        {
            animations.splice(i, 1);

            --i;
        }
    }
};

if(typeof Builder === 'function')
{
    // function anime(String property, int to, int time, function callback = null, function smooth = null):@Chainable
    Builder.prototype.anime = function(property, to, time, callback, smooth)
    {
        this.stopAnime(''+ property);

        var self = this;

        var style = Builder.getStyle(this.node, property);
        var unit = (style.match(/em$|px$|%$/i) || [''])[0];

        this._animations[property] = anime(function(value)
        {
            if(value === to)
            {
                delete self._animations[property];

                if(callback != null)
                {
                    callback();
                }
            }

            self.node.style[property] = value + unit;

        }, parseInt(style), to, time, smooth);

        return this;
    };

    // function stopAnime(String property = null):void
    Builder.prototype.stopAnime = function(property)
    {
        this._animations = this._animations || {}; // Map<String, int>

        if(typeof property === 'string')
        {
            if(this._animations[property])
            {
                stopAnime(this._animations[property]);

                delete this._animations[property];
            }
        }
        else
        {
            for(var key in this._animations)
            {
                if(this._animations.hasOwnProperty(key))
                {
                    stopAnime(this._animations[key]);
                }
            }

            this._animations = {};
        }
    };
}

})();
<|endoftext|>


<commit_before>
const { Store, update } = require('westore')
const Log = require('../models/log')
const Todo = require('../models/todo')

class OtherStore extends Store {
  constructor() {
    super()
    this.data = {
      logsSize: [],
      todoTitle: '',
      todos: [],
      count: 18,

      left: 1,
      done: 1,
      type: 'all'
    }

    this.log = new Log()
    this.todo = new Todo()

    this.todo.subscribe(() => {
      this.data.todos = this.todo.todos
      this.computeCount()
      this.update()
    })

  }

  init() {
    this.data.todos = this.todo.todos
    this.log.loadLogs()
    this.data.logsSize = this.log.logs.length
    this.update()
  }

  addTodo() {
    if (this.data.todoTitle.trim() === '') {
      wx.showToast({
        title: '内容不能为空',
        icon: 'none',
        duration: 2000
      })

      return
    }
    this.todo.addTodo(this.data.todoTitle)
    this.data.todoTitle = ''
    this.update()
  }

  toggle(id) {
    this.todo.toggle(id)
  }

  destroy(id) {
    this.todo.destroy(id)
  }

  computeCount() {
    this.data.left = 0
    this.data.done = 0
    for (let i = 0, len = this.data.todos.length; i < len; i++) {
      this.data.todos[i].done ? this.data.done++ : this.data.left++
    }
  }

  clearDone() {
    this.todo.clearDone()
  }

  filter(type) {
    this.data.type = type
    this.update()
  }
}

module.exports = new OtherStore
<commit_msg>fix: page state error<commit_after>
const { Store, update } = require('westore')
const Log = require('../models/log')
const Todo = require('../models/todo')

class OtherStore extends Store {
  constructor() {
    super()
    this.data = {
      logsSize: [],
      todoTitle: '',
      todos: [],
      count: 18,

      left: 1,
      done: 1,
      type: 'all'
    }

    this.log = new Log()
    this.todo = new Todo()

    this.todo.subscribe(() => {
      this.data.todos = this.todo.todos
      this.computeCount()
      this.update()
    })

  }

  init() {
    this.data.todos = this.todo.todos
    this.log.loadLogs()
    this.data.logsSize = this.log.logs.length

    this.data.type = 'all'
    this.computeCount()
    this.update()
  }

  addTodo() {
    if (this.data.todoTitle.trim() === '') {
      wx.showToast({
        title: '内容不能为空',
        icon: 'none',
        duration: 2000
      })

      return
    }
    this.todo.addTodo(this.data.todoTitle)
    this.data.todoTitle = ''
    this.update()
  }

  toggle(id) {
    this.todo.toggle(id)
  }

  destroy(id) {
    this.todo.destroy(id)
  }

  computeCount() {
    this.data.left = 0
    this.data.done = 0
    for (let i = 0, len = this.data.todos.length; i < len; i++) {
      this.data.todos[i].done ? this.data.done++ : this.data.left++
    }
  }

  clearDone() {
    this.todo.clearDone()
  }

  filter(type) {
    this.data.type = type
    this.update()
  }
}

module.exports = new OtherStore
<|endoftext|>


<commit_before>// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require_tree .
//= require angular-rails-templates
<commit_msg>angular-rails-templates.js doesn't exist anymore<commit_after>// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require_tree .
<|endoftext|>