<commit_before>$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    jqXHR.setRequestHeader('X-CSRF-Token', $('meta[name="token"]').attr('content'));
});

var app = app || {};

toastr.options.closeButton = true;
toastr.options.progressBar = true;
toastr.options.preventDuplicates = true;
toastr.options.closeMethod = 'fadeOut';
toastr.options.closeDuration = 300;
toastr.options.closeEasing = 'swing';
toastr.options.positionClass = 'toast-bottom-right';
toastr.options.timeOut = 5000;
toastr.options.extendedTimeOut = 7000;

(function ($) {

    // Don't need to try and connect to the web socket when not logged in
    if (window.location.href.match(/login|password/) != null) {
        return;
    }

    Lang.setLocale($('meta[name="locale"]').attr('content'));

    var FINISHED     = 0;
    var PENDING      = 1;
    var DEPLOYING    = 2;
    var FAILED       = 3;
    var NOT_DEPLOYED = 4;

    var DEPLOYMENT_COMPLETED = 0;
    var DEPLOYMENT_PENDING   = 1;
    var DEPLOYMENT_DEPLOYING = 2;
    var DEPLOYMENT_FAILED    = 3;
    var DEPLOYMENT_ERRORS    = 4;
    var DEPLOYMENT_CANCELLED = 5;

    app.project_id = app.project_id || null;

    app.listener = io.connect($('meta[name="socket_url"]').attr('content'), {
        query: 'jwt=' + $('meta[name="jwt"]').attr('content')
    });

    app.connection_error = false;

    app.listener.on('connect_error', function(error) {
        if (!app.connection_error) {
            $('#socket_offline').show();
        }

        app.connection_error = true;
    });

    app.listener.on('connect', function() {
        $('#socket_offline').hide();
        app.connection_error = false;
    });

    app.listener.on('reconnect', function() {
        $('#socket_offline').hide();
        app.connection_error = false;
    });

    // Navbar deployment status
    // FIXME: Convert these menus to backbone
    // FIXME: Convert the project and deployments to backbone
    // TODO: Update the timeline
    app.listener.on('deployment:REBELinBLUE\\Deployer\\Events\\ModelChanged', function (data) {
        updateNavBar(data);

        //var project = $('#project_' + data.model.project_id);

        if ($('#timeline').length > 0) {
            updateTimeline();
        }

        var deployment  = $('#deployment_' + data.model.id);

        if (deployment.length > 0) {

            $('td:nth-child(4)', deployment).text(data.model.committer);

            if (data.model.commit_url) {
                $('td:nth-child(5)', deployment).html('' + data.model.short_commit + '');
            } else {
                $('td:nth-child(5)', deployment).text(data.model.short_commit);
            }

            var icon_class = 'clock-o';
            var label_class = 'info';
            var label = Lang.get('deployments.pending');
            var done = false;
            var success = false;

            data.model.status = parseInt(data.model.status);
            var status = $('td:nth-child(7) span.label', deployment);

            if (data.model.status === DEPLOYMENT_COMPLETED) {
                icon_class = 'check';
                label_class = 'success';
                label = Lang.get('deployments.completed');
                done = true;
                success = true;
            } else if (data.model.status === DEPLOYMENT_DEPLOYING) {
                icon_class = 'spinner fa-pulse';
                label_class = 'warning';
                label = Lang.get('deployments.running');
            } else if (data.model.status === DEPLOYMENT_FAILED) {
                icon_class = 'warning';
                label_class = 'danger';
                label = Lang.get('deployments.failed');
                done = true;
            } else if (data.model.status === DEPLOYMENT_ERRORS) {
                icon_class = 'warning';
                label_class = 'success';
                label = Lang.get('deployments.completed_with_errors');
                done = true;
                success = true;
            } else if (data.model.status === DEPLOYMENT_CANCELLED) {
                icon_class = 'warning';
                label_class = 'danger';
                label = Lang.get('deployments.cancelled');
                done = true;
            }

            if (done) {
                $('button#deploy_project:disabled').removeAttr('disabled');
                $('td:nth-child(8) a.btn-cancel', deployment).remove();

                if (success) {
                    $('button.btn-rollback').removeClass('hide');
                }
            }

            status.attr('class', 'label label-' + label_class)
            $('i', status).attr('class', 'fa fa-' + icon_class);
            $('span', status).text(label);
        } else if ($('#timeline').length === 0) { // Don't show on dashboard
            // FIXME: Also don't show if viewing the deployment, or the project the deployment is for

            var toast_title = Lang.get('dashboard.deployment_number', {
                'id': data.model.id
            });

            if (data.model.status === DEPLOYMENT_COMPLETED) {
                toastr.success(toast_title + ' - ' + Lang.get('deployments.completed'), data.model.project_name);
            } else if (data.model.status === DEPLOYMENT_FAILED) {
                toastr.error(toast_title + ' - ' + Lang.get('deployments.failed'), data.model.project_name);
            } else if (data.model.status === DEPLOYMENT_ERRORS) {
                toastr.warning(toast_title + ' - ' + Lang.get('deployments.completed_with_errors'), data.model.project_name);
            } // FIXME: Add cancelled
        }
    });

    app.listener.on('group:REBELinBLUE\\Deployer\\Events\\ModelChanged', function (data) {
        $('#sidebar_group_' + data.model.id).html(data.model.name);
    });

    app.listener.on('project:REBELinBLUE\\Deployer\\Events\\ModelChanged', function (data) {
        $('#sidebar_project_' + data.model.id).html(data.model.name);

        var project = $('#project_' + data.model.id);

        if (project.length > 0) {

            var icon_class = 'question-circle';
            var label_class = 'primary';
            var label = Lang.get('projects.not_deployed');

            data.model.status = parseInt(data.model.status);
            var status = $('td:nth-child(3) span.label', project);

            if (data.model.status === FINISHED) {
                icon_class = 'check';
                label_class = 'success';
                label = Lang.get('projects.finished');
            } else if (data.model.status === DEPLOYING) {
                icon_class = 'spinner fa-pulse';
                label_class = 'warning';
                label = Lang.get('projects.deploying');
            } else if (data.model.status === FAILED) {
                icon_class = 'warning';
                label_class = 'danger';
                label = Lang.get('projects.failed');
            } else if (data.model.status === PENDING) {
                icon_class = 'clock-o';
                label_class = 'info';
                label = Lang.get('projects.pending');
            }

            $('td:first a', project).text(data.model.name);
            $('td:nth-child(2)', project).text(moment(data.model.last_run).format('Do MMMM YYYY h:mm:ss A'));
            status.attr('class', 'label label-' + label_class)
            $('i', status).attr('class', 'fa fa-' + icon_class);
            $('span', status).text(label);
        }
    });

    app.listener.on('project:REBELinBLUE\\Deployer\\Events\\ModelTrashed', function (data) {
        $('#sidebar_project_' + data.model.id).parent('li').remove();

        if (parseInt(data.model.id) === parseInt(app.project_id)) {
            window.location.href = '/';
        }
    });

    // FIXME: This is cheating
    function updateTimeline() {
        $.ajax({
            type: 'GET',
            url: '/timeline'
        }).success(function (response) {
            $('#timeline').html(response);
        });
    }

    function updateNavBar(data) {
        data.model.time = moment(data.model.started_at).format('h:mm:ss A');
        data.model.url = '/deployment/' + data.model.id;

        $('#deployment_info_' + data.model.id).remove();
        $('#pending_menu, #deploying_menu').show();

        var template = _.template($('#deployment-list-template').html());
        var html = template(data.model);

        if (data.model.status === DEPLOYMENT_PENDING) {
            $('#pending_menu ul.menu').append(html);
        }
        else if (data.model.status === DEPLOYMENT_DEPLOYING) {
            $('#deploying_menu ul.menu').append(html);
        }

        var pending = $('#pending_menu ul.menu li').length;
        var deploying = $('#deploying_menu ul.menu li').length;

        var pending_label = Lang.choice('dashboard.pending', pending, {
            'count': pending
        });

        if (pending === 0) {
            $('#pending_menu').hide();
        }

        var deploying_label = Lang.choice('dashboard.running', deploying, {
            'count': deploying
        });

        if (deploying === 0) {
            $('#deploying_menu').hide();
        }

        $('#deploying_menu span.label-warning').html(deploying);
        $('#deploying_menu .header').text(deploying_label);

        $('#pending_menu span.label-info').html(pending);
        $('#pending_menu .header').text(pending_label);
    }

    $(document).ready(function () {
        if ($('#pending_menu ul.menu li').length > 0) {
            $('#pending_menu').show();
        }

        if ($('#deploying_menu ul.menu li').length > 0) {
            $('#deploying_menu').show();
        }
    });

})(jQuery);
<commit_msg>More cleanup<commit_after>$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    jqXHR.setRequestHeader('X-CSRF-Token', $('meta[name="token"]').attr('content'));
});

var app = app || {};

toastr.options.closeButton = true;
toastr.options.progressBar = true;
toastr.options.preventDuplicates = true;
toastr.options.closeMethod = 'fadeOut';
toastr.options.closeDuration = 300;
toastr.options.closeEasing = 'swing';
toastr.options.positionClass = 'toast-bottom-right';
toastr.options.timeOut = 5000;
toastr.options.extendedTimeOut = 7000;

(function ($) {

    // Don't need to try and connect to the web socket when not logged in
    if (window.location.href.match(/login|password/) != null) {
        return;
    }

    Lang.setLocale($('meta[name="locale"]').attr('content'));

    var FINISHED     = 0;
    var PENDING      = 1;
    var DEPLOYING    = 2;
    var FAILED       = 3;
    var NOT_DEPLOYED = 4;

    var DEPLOYMENT_COMPLETED = 0;
    var DEPLOYMENT_PENDING   = 1;
    var DEPLOYMENT_DEPLOYING = 2;
    var DEPLOYMENT_FAILED    = 3;
    var DEPLOYMENT_ERRORS    = 4;
    var DEPLOYMENT_CANCELLED = 5;

    app.project_id = app.project_id || null;

    app.listener = io.connect($('meta[name="socket_url"]').attr('content'), {
        query: 'jwt=' + $('meta[name="jwt"]').attr('content')
    });

    app.connection_error = false;

    app.listener.on('connect_error', function(error) {
        if (!app.connection_error) {
            $('#socket_offline').show();
        }

        app.connection_error = true;
    });

    app.listener.on('connect', function() {
        $('#socket_offline').hide();
        app.connection_error = false;
    });

    app.listener.on('reconnect', function() {
        $('#socket_offline').hide();
        app.connection_error = false;
    });

    // Navbar deployment status
    // FIXME: Convert these menus to backbone
    // FIXME: Convert the project and deployments to backbone
    // TODO: Update the timeline
    app.listener.on('deployment:REBELinBLUE\\Deployer\\Events\\ModelChanged', function (data) {
        updateNavBar(data);

        //var project = $('#project_' + data.model.project_id);

        if ($('#timeline').length > 0) {
            updateTimeline();
        }

        var deployment  = $('#deployment_' + data.model.id);

        if (deployment.length > 0) {

            $('td:nth-child(4)', deployment).text(data.model.committer);

            if (data.model.commit_url) {
                $('td:nth-child(5)', deployment).html('' + data.model.short_commit + '');
            } else {
                $('td:nth-child(5)', deployment).text(data.model.short_commit);
            }

            var icon_class = 'clock-o';
            var label_class = 'info';
            var label = Lang.get('deployments.pending');
            var done = false;
            var success = false;

            data.model.status = parseInt(data.model.status);
            var status = $('td:nth-child(7) span.label', deployment);

            if (data.model.status === DEPLOYMENT_COMPLETED) {
                icon_class = 'check';
                label_class = 'success';
                label = Lang.get('deployments.completed');
                done = true;
                success = true;
            } else if (data.model.status === DEPLOYMENT_DEPLOYING) {
                icon_class = 'spinner fa-pulse';
                label_class = 'warning';
                label = Lang.get('deployments.running');
            } else if (data.model.status === DEPLOYMENT_FAILED) {
                icon_class = 'warning';
                label_class = 'danger';
                label = Lang.get('deployments.failed');
                done = true;
            } else if (data.model.status === DEPLOYMENT_ERRORS) {
                icon_class = 'warning';
                label_class = 'success';
                label = Lang.get('deployments.completed_with_errors');
                done = true;
                success = true;
            } else if (data.model.status === DEPLOYMENT_CANCELLED) {
                icon_class = 'warning';
                label_class = 'danger';
                label = Lang.get('deployments.cancelled');
                done = true;
            }

            if (done) {
                $('button#deploy_project:disabled').removeAttr('disabled');
                $('td:nth-child(8) a.btn-cancel', deployment).remove();

                if (success) {
                    $('button.btn-rollback').removeClass('hide');
                }
            }

            status.attr('class', 'label label-' + label_class);
            $('i', status).attr('class', 'fa fa-' + icon_class);
            $('span', status).text(label);
        } else if ($('#timeline').length === 0) { // Don't show on dashboard
            // FIXME: Also don't show if viewing the deployment, or the project the deployment is for

            var toast_title = Lang.get('dashboard.deployment_number', {
                'id': data.model.id
            });

            if (data.model.status === DEPLOYMENT_COMPLETED) {
                toastr.success(toast_title + ' - ' + Lang.get('deployments.completed'), data.model.project_name);
            } else if (data.model.status === DEPLOYMENT_FAILED) {
                toastr.error(toast_title + ' - ' + Lang.get('deployments.failed'), data.model.project_name);
            } else if (data.model.status === DEPLOYMENT_ERRORS) {
                toastr.warning(toast_title + ' - ' + Lang.get('deployments.completed_with_errors'), data.model.project_name);
            } // FIXME: Add cancelled
        }
    });

    app.listener.on('group:REBELinBLUE\\Deployer\\Events\\ModelChanged', function (data) {
        $('#sidebar_group_' + data.model.id).html(data.model.name);
    });

    app.listener.on('project:REBELinBLUE\\Deployer\\Events\\ModelChanged', function (data) {
        $('#sidebar_project_' + data.model.id).html(data.model.name);

        var project = $('#project_' + data.model.id);

        if (project.length > 0) {

            var icon_class = 'question-circle';
            var label_class = 'primary';
            var label = Lang.get('projects.not_deployed');

            data.model.status = parseInt(data.model.status);
            var status = $('td:nth-child(3) span.label', project);

            if (data.model.status === FINISHED) {
                icon_class = 'check';
                label_class = 'success';
                label = Lang.get('projects.finished');
            } else if (data.model.status === DEPLOYING) {
                icon_class = 'spinner fa-pulse';
                label_class = 'warning';
                label = Lang.get('projects.deploying');
            } else if (data.model.status === FAILED) {
                icon_class = 'warning';
                label_class = 'danger';
                label = Lang.get('projects.failed');
            } else if (data.model.status === PENDING) {
                icon_class = 'clock-o';
                label_class = 'info';
                label = Lang.get('projects.pending');
            }

            $('td:first a', project).text(data.model.name);
            $('td:nth-child(2)', project).text(moment(data.model.last_run).format('Do MMMM YYYY h:mm:ss A'));
            status.attr('class', 'label label-' + label_class);
            $('i', status).attr('class', 'fa fa-' + icon_class);
            $('span', status).text(label);
        }
    });

    app.listener.on('project:REBELinBLUE\\Deployer\\Events\\ModelTrashed', function (data) {
        $('#sidebar_project_' + data.model.id).parent('li').remove();

        if (parseInt(data.model.id) === parseInt(app.project_id)) {
            window.location.href = '/';
        }
    });

    // FIXME: This is cheating
    function updateTimeline() {
        $.ajax({
            type: 'GET',
            url: '/timeline'
        }).success(function (response) {
            $('#timeline').html(response);
        });
    }

    function updateNavBar(data) {
        data.model.time = moment(data.model.started_at).format('h:mm:ss A');
        data.model.url = '/deployment/' + data.model.id;

        $('#deployment_info_' + data.model.id).remove();
        $('#pending_menu, #deploying_menu').show();

        var template = _.template($('#deployment-list-template').html());
        var html = template(data.model);

        if (data.model.status === DEPLOYMENT_PENDING) {
            $('#pending_menu ul.menu').append(html);
        }
        else if (data.model.status === DEPLOYMENT_DEPLOYING) {
            $('#deploying_menu ul.menu').append(html);
        }

        var pending = $('#pending_menu ul.menu li').length;
        var deploying = $('#deploying_menu ul.menu li').length;

        var pending_label = Lang.choice('dashboard.pending', pending, {
            'count': pending
        });

        if (pending === 0) {
            $('#pending_menu').hide();
        }

        var deploying_label = Lang.choice('dashboard.running', deploying, {
            'count': deploying
        });

        if (deploying === 0) {
            $('#deploying_menu').hide();
        }

        $('#deploying_menu span.label-warning').html(deploying);
        $('#deploying_menu .header').text(deploying_label);

        $('#pending_menu span.label-info').html(pending);
        $('#pending_menu .header').text(pending_label);
    }

    $(document).ready(function () {
        if ($('#pending_menu ul.menu li').length > 0) {
            $('#pending_menu').show();
        }

        if ($('#deploying_menu ul.menu li').length > 0) {
            $('#deploying_menu').show();
        }
    });

})(jQuery);
<|endoftext|>


<commit_before>/**
 * @author  John Resig <jeresig@gmail.com>
 * @author  Originally by Marcus Spiegel <marcus.spiegel@gmail.com>
 * @link    https://github.com/jeresig/i18n-node
 * @license http://opensource.org/licenses/MIT
 *
 * @version 0.4.7
 */

// dependencies
var vsprintf = require("sprintf").vsprintf,
		fs = require("fs"),
		path = require("path");

function dotNotation (obj, is, value) {
	if (typeof is === 'string') {
		return dotNotation(obj, is.split('.'), value);
	} else if (is.length === 1 && value !== undefined) {
		return obj[is[0]] = value;
	} else if (is.length === 0) {
		return obj;
	} else {
		if (obj.hasOwnProperty(is[0])) {
			return dotNotation(obj[is[0]], is.slice(1), value);
		} else {
			return obj[is.join('.')] = is.join('.');
		}
	}
}

var i18n = module.exports = function (opt) {
	var self = this;

	// Put into dev or production mode
	this.devMode = process.env.NODE_ENV !== "production";

	// Copy over options
	for (var prop in opt) {
		this[prop] = opt[prop];
	}

	// you may register helpers in global scope, up to you
	if (typeof this.register === "object") {
		i18n.resMethods.forEach(function (method) {
			self.register[method] = self[method].bind(self);
		});
	}

	// implicitly read all locales
	// if it's an array of locale names, read in the data
	if (opt.locales && opt.locales.forEach) {
		this.locales = {};

		opt.locales.forEach(function (locale) {
			self.readFile(locale);
		});

		this.defaultLocale = opt.locales[0];
	}

	// Set the locale to the default locale
	this.setLocale(this.defaultLocale);

	// Check the defaultLocale
	if (!this.locales[this.defaultLocale]) {
		console.error("Not a valid default locale.");
	}

	if (this.request) {
		if (this.subdomain) {
			this.setLocaleFromSubdomain(this.request);
		}

		if (this.query !== false) {
			this.setLocaleFromQuery(this.request);
		}

		this.prefLocale = this.preferredLocale();

		if (this.prefLocale !== false && this.prefLocale !== this.locale) {
			this.setLocale(this.prefLocale);
		}
	}
};

i18n.version = "0.4.7";

i18n.localeCache = {};
i18n.resMethods = ["__", "__n", "getLocale", "isPreferredLocale"];

i18n.expressBind = function (app, opt) {
	if (!app) {
		return;
	}

	app.use(function (req, res, next) {
		opt.request = req;
		req.i18n = new i18n(opt);

		// Express 3
		if (res.locals) {
			i18n.registerMethods(res.locals, req)
		}

		next();
	});

	// Express 2
	if (app.dynamicHelpers) {
		app.dynamicHelpers(i18n.registerMethods({}));
	}
};

i18n.registerMethods = function (helpers, req) {
	i18n.resMethods.forEach(function (method) {
		if (req) {
			helpers[method] = req.i18n[method].bind(req.i18n);
		} else {
			helpers[method] = function (req) {
				return req.i18n[method].bind(req.i18n);
			};
		}

	});

	return helpers;
};

i18n.prototype = {
	defaultLocale: "en",
	extension: ".js",
	directory: "./locales",
	cookieName: "lang",
	indent: "\t",

	__: function () {
		var msg = this.translate(this.locale, arguments[0]);

		if (arguments.length > 1) {
			msg = vsprintf(msg, Array.prototype.slice.call(arguments, 1));
		}

		return msg;
	},

	__n: function (pathOrSingular, countOrPlural, additionalOrCount) {
		var msg;
		if (typeof countOrPlural === 'number') {
			var path = pathOrSingular;
			var count = countOrPlural;
			msg = this.translate(this.locale, path);

			msg = vsprintf(parseInt(count, 10) > 1 ? msg.other : msg.one, Array.prototype.slice.call(arguments, 1));
		} else {
			var singular = pathOrSingular;
			var plural = countOrPlural;
			var count = additionalOrCount;
			msg = this.translate(this.locale, singular, plural);

			msg = vsprintf(parseInt(count, 10) > 1 ? msg.other : msg.one, [count]);

			if (arguments.length > 3) {
				msg = vsprintf(msg, Array.prototype.slice.call(arguments, 3));
			}
		}

		return msg;
	},

	setLocale: function (locale) {

		if (!locale) return;

		if (!this.locales[locale]) {
			if (this.devMode) {
				console.warn("Locale (" + locale + ") not found.");
			}

			locale = this.defaultLocale;
		}

		return (this.locale = locale);
	},

	getLocale: function () {
		return this.locale;
	},

	isPreferredLocale: function () {
		return !this.prefLocale ||
				this.prefLocale === this.getLocale();
	},

	setLocaleFromSessionVar: function (req) {
		req = req || this.request;

		var locale = req.session.locale;

		if (this.locales[locale]) {
			if (this.devMode) {
				console.log("Overriding locale from query: " + locale);
			}
			this.setLocale(locale);
		}

	},

	setLocaleFromQuery: function (req) {
		req = req || this.request;

		if (!req || !req.query || !req.query.lang) {
			return;
		}

		var locale = (req.query.lang+'').toLowerCase();

		if (this.locales[locale]) {
			if (this.devMode) {
				console.log("Overriding locale from query: " + locale);
			}

			this.setLocale(locale);
		}
	},

	setLocaleFromSubdomain: function (req) {
		req = req || this.request;

		if (!req || !req.headers || !req.headers.host) {
			return;
		}

		if (/^([^.]+)/.test(req.headers.host) && this.locales[RegExp.$1]) {
			if (this.devMode) {
				console.log("Overriding locale from host: " + RegExp.$1);
			}

			this.setLocale(RegExp.$1);
		}
	},

	setLocaleFromCookie: function (req) {
		req = req || this.request;

		if (!req || !req.cookies || !this.cookieName || !req.cookies[this.cookieName]) {
			return;
		}

		var locale = req.cookies[this.cookieName].toLowerCase();

		if (this.locales[locale]) {
			if (this.devMode) {
				console.log("Overriding locale from cookie: " + locale);
			}

			this.setLocale(locale);
		}
	},

	preferredLocale: function (req) {
		req = req || this.request;

		if (!req || !req.headers) {
			return;
		}

		var accept = req.headers["accept-language"] || "",
				regExp = /(^|,\s*)([a-z0-9-]+)/gi,
				self = this,
				prefLocale;

		while (!prefLocale && (match = regExp.exec(accept))) {
			var locale = match[2].toLowerCase();
			var parts = locale.split("-");

			if (self.locales[locale]) {
				prefLocale = locale;
			} else if (parts.length > 1 && self.locales[parts[0]]) {
              	prefLocale = parts[0];
            }
		}

		return prefLocale || this.defaultLocale;
	},

	// read locale file, translate a msg and write to fs if new
	translate: function (locale, singular, plural) {
		if (!locale || !this.locales[locale]) {
			if (this.devMode) {
				console.warn("WARN: No locale found. Using the default (" +
						this.defaultLocale + ") as current locale");
			}

			locale = this.defaultLocale;

			this.initLocale(locale, {});
		}

		if (!this.locales[locale][singular]) {
			if (this.devMode) {
				this.writeFile(locale);
			}
		}

		return dotNotation(this.locales[locale], singular, plural ? { one: singular, other: plural } : undefined);
	},

	// try reading a file
	readFile: function (locale) {
		var file = this.locateFile(locale);

		if (!this.devMode && i18n.localeCache[file]) {
			this.initLocale(locale, i18n.localeCache[file]);
			return;
		}

		try {
			var localeFile = fs.readFileSync(file);
			var base;

			// reading base file if 'base' provided
			if (typeof this.base === "function") {
				var baseFilename;

				try {
					baseFilename = this.base(locale);
				} catch (e) {
					console.error('base function threw exception for locale %s', locale, e);
				}

				if (typeof baseFilename === "string") {
					try {
						base = JSON.parse(fs.readFileSync(this.locateFile(baseFilename)));
					} catch (e) {
						console.error('unable to read or parse base file %s for locale %s', baseFilename, locale, e);
					}
				}
			}

			try {
				// parsing file content
				var content = JSON.parse(localeFile);

				if (base) {
					// writing content to the base and swapping
					for (var prop in content) {
						base[prop] = content[prop];
					}
					content = base;
				}

				// putting content to locales[locale]
				this.initLocale(locale, content);
			} catch (e) {
				console.error('unable to parse locales from file (maybe ' + file +
						' is empty or invalid json?): ', e);
			}

		} catch (e) {
			// unable to read, so intialize that file
			// locales[locale] are already set in memory, so no extra read required
			// or locales[locale] are empty, which initializes an empty locale.json file
			if (!fs.existsSync(file)) {
				this.writeFile(locale);
			}
		}
	},

	// try writing a file in a created directory
	writeFile: function (locale) {
		// don't write new locale information to disk if we're not in dev mode
		if (!this.devMode) {
			// Initialize the locale if didn't exist already
			this.initLocale(locale, {});
			return;
		}

		// creating directory if necessary
		try {
			fs.lstatSync(this.directory);

		} catch (e) {
			if (this.devMode) {
				console.log('creating locales dir in: ' + this.directory);
			}

			fs.mkdirSync(this.directory, 0755);
		}

		// Initialize the locale if didn't exist already
		this.initLocale(locale, {});

		// writing to tmp and rename on success
		try {
			var target = this.locateFile(locale),
					tmp = target + ".tmp";

			fs.writeFileSync(tmp, JSON.stringify(
				this.locales[locale], null, this.indent), "utf8");

			if (fs.statSync(tmp).isFile()) {
				fs.renameSync(tmp, target);

			} else {
				console.error('unable to write locales to file (either ' + tmp +
						' or ' + target + ' are not writeable?): ');
			}

		} catch (e) {
			console.error('unexpected error writing files (either ' + tmp +
					' or ' + target + ' are not writeable?): ', e);
		}
	},

	// basic normalization of filepath
	locateFile: function (locale) {
		return path.normalize(this.directory + '/' + locale + this.extension);
	},

	initLocale: function (locale, data) {
		if (!this.locales[locale]) {
			this.locales[locale] = data;

			// Only cache the files when we're not in dev mode
			if (!this.devMode) {
				var file = this.locateFile(locale);
				if (!i18n.localeCache[file]) {
					i18n.localeCache[file] = data;
				}
			}
		}
	}
};
<commit_msg>New option to cover setLocaleFromSessionVar<commit_after>/**
 * @author  John Resig <jeresig@gmail.com>
 * @author  Originally by Marcus Spiegel <marcus.spiegel@gmail.com>
 * @link    https://github.com/jeresig/i18n-node
 * @license http://opensource.org/licenses/MIT
 *
 * @version 0.4.7
 */

// dependencies
var vsprintf = require("sprintf").vsprintf,
		fs = require("fs"),
		path = require("path");

function dotNotation (obj, is, value) {
	if (typeof is === 'string') {
		return dotNotation(obj, is.split('.'), value);
	} else if (is.length === 1 && value !== undefined) {
		return obj[is[0]] = value;
	} else if (is.length === 0) {
		return obj;
	} else {
		if (obj.hasOwnProperty(is[0])) {
			return dotNotation(obj[is[0]], is.slice(1), value);
		} else {
			return obj[is.join('.')] = is.join('.');
		}
	}
}

var i18n = module.exports = function (opt) {
	var self = this;

	// Put into dev or production mode
	this.devMode = process.env.NODE_ENV !== "production";

	// Copy over options
	for (var prop in opt) {
		this[prop] = opt[prop];
	}

	// you may register helpers in global scope, up to you
	if (typeof this.register === "object") {
		i18n.resMethods.forEach(function (method) {
			self.register[method] = self[method].bind(self);
		});
	}

	// implicitly read all locales
	// if it's an array of locale names, read in the data
	if (opt.locales && opt.locales.forEach) {
		this.locales = {};

		opt.locales.forEach(function (locale) {
			self.readFile(locale);
		});

		this.defaultLocale = opt.locales[0];
	}

	// Set the locale to the default locale
	this.setLocale(this.defaultLocale);

	// Check the defaultLocale
	if (!this.locales[this.defaultLocale]) {
		console.error("Not a valid default locale.");
	}

	if (this.request) {
		if (this.subdomain) {
			this.setLocaleFromSubdomain(this.request);
		}

		if (this.query !== false) {
			this.setLocaleFromQuery(this.request);
		}

		if (this.session !== false) {
			this.setLocaleFromSessionVar(this.request);
		}

		this.prefLocale = this.preferredLocale();

		if (this.prefLocale !== false && this.prefLocale !== this.locale) {
			this.setLocale(this.prefLocale);
		}
	}
};

i18n.version = "0.4.7";

i18n.localeCache = {};
i18n.resMethods = ["__", "__n", "getLocale", "isPreferredLocale"];

i18n.expressBind = function (app, opt) {
	if (!app) {
		return;
	}

	app.use(function (req, res, next) {
		opt.request = req;
		req.i18n = new i18n(opt);

		// Express 3
		if (res.locals) {
			i18n.registerMethods(res.locals, req)
		}

		next();
	});

	// Express 2
	if (app.dynamicHelpers) {
		app.dynamicHelpers(i18n.registerMethods({}));
	}
};

i18n.registerMethods = function (helpers, req) {
	i18n.resMethods.forEach(function (method) {
		if (req) {
			helpers[method] = req.i18n[method].bind(req.i18n);
		} else {
			helpers[method] = function (req) {
				return req.i18n[method].bind(req.i18n);
			};
		}

	});

	return helpers;
};

i18n.prototype = {
	defaultLocale: "en",
	extension: ".js",
	directory: "./locales",
	cookieName: "lang",
	indent: "\t",

	__: function () {
		var msg = this.translate(this.locale, arguments[0]);

		if (arguments.length > 1) {
			msg = vsprintf(msg, Array.prototype.slice.call(arguments, 1));
		}

		return msg;
	},

	__n: function (pathOrSingular, countOrPlural, additionalOrCount) {
		var msg;
		if (typeof countOrPlural === 'number') {
			var path = pathOrSingular;
			var count = countOrPlural;
			msg = this.translate(this.locale, path);

			msg = vsprintf(parseInt(count, 10) > 1 ? msg.other : msg.one, Array.prototype.slice.call(arguments, 1));
		} else {
			var singular = pathOrSingular;
			var plural = countOrPlural;
			var count = additionalOrCount;
			msg = this.translate(this.locale, singular, plural);

			msg = vsprintf(parseInt(count, 10) > 1 ? msg.other : msg.one, [count]);

			if (arguments.length > 3) {
				msg = vsprintf(msg, Array.prototype.slice.call(arguments, 3));
			}
		}

		return msg;
	},

	setLocale: function (locale) {

		if (!locale) return;

		if (!this.locales[locale]) {
			if (this.devMode) {
				console.warn("Locale (" + locale + ") not found.");
			}

			locale = this.defaultLocale;
		}

		return (this.locale = locale);
	},

	getLocale: function () {
		return this.locale;
	},

	isPreferredLocale: function () {
		return !this.prefLocale ||
				this.prefLocale === this.getLocale();
	},

	setLocaleFromSessionVar: function (req) {
		req = req || this.request;

		var locale = req.session.locale;

		if (this.locales[locale]) {
			if (this.devMode) {
				console.log("Overriding locale from query: " + locale);
			}
			this.setLocale(locale);
		}

	},

	setLocaleFromQuery: function (req) {
		req = req || this.request;

		if (!req || !req.query || !req.query.lang) {
			return;
		}

		var locale = (req.query.lang+'').toLowerCase();

		if (this.locales[locale]) {
			if (this.devMode) {
				console.log("Overriding locale from query: " + locale);
			}

			this.setLocale(locale);
		}
	},

	setLocaleFromSubdomain: function (req) {
		req = req || this.request;

		if (!req || !req.headers || !req.headers.host) {
			return;
		}

		if (/^([^.]+)/.test(req.headers.host) && this.locales[RegExp.$1]) {
			if (this.devMode) {
				console.log("Overriding locale from host: " + RegExp.$1);
			}

			this.setLocale(RegExp.$1);
		}
	},

	setLocaleFromCookie: function (req) {
		req = req || this.request;

		if (!req || !req.cookies || !this.cookieName || !req.cookies[this.cookieName]) {
			return;
		}

		var locale = req.cookies[this.cookieName].toLowerCase();

		if (this.locales[locale]) {
			if (this.devMode) {
				console.log("Overriding locale from cookie: " + locale);
			}

			this.setLocale(locale);
		}
	},

	preferredLocale: function (req) {
		req = req || this.request;

		if (!req || !req.headers) {
			return;
		}

		var accept = req.headers["accept-language"] || "",
				regExp = /(^|,\s*)([a-z0-9-]+)/gi,
				self = this,
				prefLocale;

		while (!prefLocale && (match = regExp.exec(accept))) {
			var locale = match[2].toLowerCase();
			var parts = locale.split("-");

			if (self.locales[locale]) {
				prefLocale = locale;
			} else if (parts.length > 1 && self.locales[parts[0]]) {
              	prefLocale = parts[0];
            }
		}

		return prefLocale || this.defaultLocale;
	},

	// read locale file, translate a msg and write to fs if new
	translate: function (locale, singular, plural) {
		if (!locale || !this.locales[locale]) {
			if (this.devMode) {
				console.warn("WARN: No locale found. Using the default (" +
						this.defaultLocale + ") as current locale");
			}

			locale = this.defaultLocale;

			this.initLocale(locale, {});
		}

		if (!this.locales[locale][singular]) {
			if (this.devMode) {
				this.writeFile(locale);
			}
		}

		return dotNotation(this.locales[locale], singular, plural ? { one: singular, other: plural } : undefined);
	},

	// try reading a file
	readFile: function (locale) {
		var file = this.locateFile(locale);

		if (!this.devMode && i18n.localeCache[file]) {
			this.initLocale(locale, i18n.localeCache[file]);
			return;
		}

		try {
			var localeFile = fs.readFileSync(file);
			var base;

			// reading base file if 'base' provided
			if (typeof this.base === "function") {
				var baseFilename;

				try {
					baseFilename = this.base(locale);
				} catch (e) {
					console.error('base function threw exception for locale %s', locale, e);
				}

				if (typeof baseFilename === "string") {
					try {
						base = JSON.parse(fs.readFileSync(this.locateFile(baseFilename)));
					} catch (e) {
						console.error('unable to read or parse base file %s for locale %s', baseFilename, locale, e);
					}
				}
			}

			try {
				// parsing file content
				var content = JSON.parse(localeFile);

				if (base) {
					// writing content to the base and swapping
					for (var prop in content) {
						base[prop] = content[prop];
					}
					content = base;
				}

				// putting content to locales[locale]
				this.initLocale(locale, content);
			} catch (e) {
				console.error('unable to parse locales from file (maybe ' + file +
						' is empty or invalid json?): ', e);
			}

		} catch (e) {
			// unable to read, so intialize that file
			// locales[locale] are already set in memory, so no extra read required
			// or locales[locale] are empty, which initializes an empty locale.json file
			if (!fs.existsSync(file)) {
				this.writeFile(locale);
			}
		}
	},

	// try writing a file in a created directory
	writeFile: function (locale) {
		// don't write new locale information to disk if we're not in dev mode
		if (!this.devMode) {
			// Initialize the locale if didn't exist already
			this.initLocale(locale, {});
			return;
		}

		// creating directory if necessary
		try {
			fs.lstatSync(this.directory);

		} catch (e) {
			if (this.devMode) {
				console.log('creating locales dir in: ' + this.directory);
			}

			fs.mkdirSync(this.directory, 0755);
		}

		// Initialize the locale if didn't exist already
		this.initLocale(locale, {});

		// writing to tmp and rename on success
		try {
			var target = this.locateFile(locale),
					tmp = target + ".tmp";

			fs.writeFileSync(tmp, JSON.stringify(
				this.locales[locale], null, this.indent), "utf8");

			if (fs.statSync(tmp).isFile()) {
				fs.renameSync(tmp, target);

			} else {
				console.error('unable to write locales to file (either ' + tmp +
						' or ' + target + ' are not writeable?): ');
			}

		} catch (e) {
			console.error('unexpected error writing files (either ' + tmp +
					' or ' + target + ' are not writeable?): ', e);
		}
	},

	// basic normalization of filepath
	locateFile: function (locale) {
		return path.normalize(this.directory + '/' + locale + this.extension);
	},

	initLocale: function (locale, data) {
		if (!this.locales[locale]) {
			this.locales[locale] = data;

			// Only cache the files when we're not in dev mode
			if (!this.devMode) {
				var file = this.locateFile(locale);
				if (!i18n.localeCache[file]) {
					i18n.localeCache[file] = data;
				}
			}
		}
	}
};
<|endoftext|>


<commit_before>/**
 * @class ModelController
 * @classdesc
 * Openbiz Model Controller class for operate a defined data model,
 * It ships with all ready to use CRUD methods.
 *
 * @constructs openbiz.controllers.ModelController
 * @returns {openbiz.controllers.ModelController}
 * @author Jixian Wang <jixian@openbiz.me>
 * @version 4.0.0
 * @copyright {@link http://www.openbiz.me|Openbiz LLC}
 * @license {@link http://opensource.org/licenses/BSD-3-Clause|BSD License}
 */
'use strict';
var _ = require('underscore');
module.exports = function(app, name){
	var controller = require("../objects/Controller").extend({
		_model:null,
		//default data get method
		//trigger method for data collection get
		//The fetched record is at req.record
		beforeGetItem: function(req, res, next){next();},
		afterGetItem: function(req, res){},

		//trigger method for data collection fetch
		//The fetched records is at req.recordCollection
		beforeGetCollection: function(req, res, next){next();},
		beforeQueryCollection: function(req,query){return query;},
		afterGetCollection: function(req, res,next){next();},

		//trigger method for data create
		//The created record is at req.record
		beforeCreate: function(req, res, next){next();},
		afterCreate: function(req, res){},

		//trigger method for data update
		//The old record is at req.record
		//The new record is at req.recordNew
		beforeUpdate: function(req, res, next){next();},
		afterUpdate: function(req, res){},

		//trigger method for data delete
		//The old record is at req.record
		beforeDelete: function(req, res, next){next();},
		afterDelete: function(req, res){},

		ensureExists:function(req,res,next){
			app.getModel.call(app,getSelf()._model).findById(req.params.id,function(err,record){
				if(err){
					res.json(500,{error:err});
				}else if(record){
					req.record = record;
					next();
				}else{
					res.send(404);
				}
			});
		},
		create:function(req,res){
			getSelf().beforeCreate(req, res, function(){
				var input = req.body;
				var _metadata = {ownership:{},creator:{id:{},timestamp:new Date()}};
				_metadata.ownership.ownerId = req.user.id;
				_metadata.creator.id = req.user.id;
				if(req.user.account.id != null)
					_metadata.ownership.accountId = req.user.account.id;
				input["_metadata"] = _metadata;
				app.getModel.call(app,getSelf()._model).create(input,function(err,record){
					if(err){
						res.json(500,{error:err});
					}
					else{
						req.newRecord = record;
						getSelf().afterCreate(req, res);
						res.json(201,record);
					}
				});
			});
		},
		getItem:function(req,res){
			getSelf().beforeGetItem(req,res,function(){
				res.json(200,req.record);
				getSelf().afterGetItem();
			});
		},
		getCollection: function(req, res){
			getSelf().beforeGetCollection(req, res, function(){
				var model = app.getModel.call(app,getSelf()._model);
				var queryConditions = {};
				if(req.query.query){
					queryConditions['$or'] = [];
					for(var field in model.schema.paths){
						if(model.schema.paths[field].instance!='ObjectID'){
							var fieldCond = {};
							// fieldCond[field]={ $regex: req.query.query, $options: 'i' } ;
							if(field.indexOf('__')==0) continue;
							if(field.indexOf('_metadata')==0)continue;
							if(field.indexOf('_approval')==0)continue;
							var fieldObj = model.schema.paths[field];
							if(typeof fieldObj.options=='undefined') fieldObj.options = {type:null};
							switch(fieldObj.options.type){
								case "Date":
								case "Number":
									//fieldCond[field] = req.query.query;
									break;
								default:
									if(!(fieldObj.options.type instanceof Array)){
										fieldCond[field] = new RegExp(req.query.query,"i");
										queryConditions['$or'].push ( fieldCond );
									}
									break;
							}

						}
					}
				}
				queryConditions["_metadata.ownership.accountId"] = req.user.account.id;
				var pageSize = req.query.per_page?req.query.per_page:0;
				var page = req.query.page?req.query.page-1:0;

				var mainQuery = model.find(queryConditions);
				mainQuery = getSelf().beforeQueryCollection(req,mainQuery);

				var async = require('async');
				async.series({
					count:function(cb){
							var query = _.clone(mainQuery);
							query.count(function(err,count){
							cb(err,count);
						});
					},items:function(cb){
						var sort = req.query.sort_by;
						var order = req.query.order;

						var query = _.clone(mainQuery);

						query.skip(parseInt(page * pageSize)).limit(pageSize);
						if(sort && order){
							query = query.sort({sort:order});
						}else{
							query = query.sort({_id:"desc"});
						}
						query = getSelf().beforeQueryCollection(req,query);
						query.exec(function(err,collection){
							req.recordCollection = collection;
							cb(err,collection);
						});
					}
				},function(err,results){
					if(err){
						res.json(500,{error:err});
					}
					else{
						getSelf().afterGetCollection(req, res,function(){
							var dataArrayInfo = {
								total_entries : parseInt(results.count),
								total_pages: Math.ceil(results.count/pageSize),
								page: parseInt(page+1),
								per_page :parseInt(pageSize)
							}
							res.json(200,[dataArrayInfo,req.recordCollection]);
						});
					}
				});
			});
		},
		delete:function(req,res){
			if(typeof req.record._metadata.state.deletable != "undefined"){
				if(req.record._metadata.state.deletable == false){
					res.json(403,error:{
						code:403,
							message: "This record is not deletable"
					});
					return;
				}
			}
			getSelf().beforeDelete(req, res, function(){
				req.record.remove(function(err){
					if(err){
						res.json(500,{error:err});
					}
					else{
						getSelf().afterDelete(req, res);
						res.send(204);
					}
				});
			});
		},
		update:function(req,res){
			getSelf().beforeUpdate(req, res, function(){
				getSelf().processChangeLog(req,"UPDATE");
				for(var i in req.body){
					if( i!="_id" && i != "_metadata")
					{
						req.record[i] = req.body[i];
					}
				}
				req.record.save(function(err){
					if(err){
						res.json(500,{error:err});
					}
					else{
						req.recordNew = req.record;
						getSelf().afterUpdate(req, res);
						res.send(204);
					}
				})
			});
		},
		processChangeLog:function(req,action){
			var updateLog = {
				id:req.user.id,
				original:{},
				current:{},
				action:action
			};
			for(var i in req.body){
				if(_.isDate(req.record[i])){
					req.body[i] = new Date(req.body[i]);
				}

				if( !_.isArray(req.body[i]) &&
					i!="_metadata" ){
					if( req.record[i]==null|| !_.isEqual(req.record[i].toString(), req.body[i].toString()) ){
						updateLog.original[i] = req.record[i];
						updateLog.current[i] = req.body[i];
					}

				}
			}
			if(!_.isEmpty(updateLog.original)){
				req.record._metadata.updates.push(updateLog);
			}
		}
	});

	var getSelf = function(){
		return app.getController(name);
	}

	return controller;
};
<commit_msg>add deletable logic<commit_after>/**
 * @class ModelController
 * @classdesc
 * Openbiz Model Controller class for operate a defined data model,
 * It ships with all ready to use CRUD methods.
 *
 * @constructs openbiz.controllers.ModelController
 * @returns {openbiz.controllers.ModelController}
 * @author Jixian Wang <jixian@openbiz.me>
 * @version 4.0.0
 * @copyright {@link http://www.openbiz.me|Openbiz LLC}
 * @license {@link http://opensource.org/licenses/BSD-3-Clause|BSD License}
 */
'use strict';
var _ = require('underscore');
module.exports = function(app, name){
	var controller = require("../objects/Controller").extend({
		_model:null,
		//default data get method
		//trigger method for data collection get
		//The fetched record is at req.record
		beforeGetItem: function(req, res, next){next();},
		afterGetItem: function(req, res){},

		//trigger method for data collection fetch
		//The fetched records is at req.recordCollection
		beforeGetCollection: function(req, res, next){next();},
		beforeQueryCollection: function(req,query){return query;},
		afterGetCollection: function(req, res,next){next();},

		//trigger method for data create
		//The created record is at req.record
		beforeCreate: function(req, res, next){next();},
		afterCreate: function(req, res){},

		//trigger method for data update
		//The old record is at req.record
		//The new record is at req.recordNew
		beforeUpdate: function(req, res, next){next();},
		afterUpdate: function(req, res){},

		//trigger method for data delete
		//The old record is at req.record
		beforeDelete: function(req, res, next){next();},
		afterDelete: function(req, res){},

		ensureExists:function(req,res,next){
			app.getModel.call(app,getSelf()._model).findById(req.params.id,function(err,record){
				if(err){
					res.json(500,{error:err});
				}else if(record){
					req.record = record;
					next();
				}else{
					res.send(404);
				}
			});
		},
		create:function(req,res){
			getSelf().beforeCreate(req, res, function(){
				var input = req.body;
				var _metadata = {ownership:{},creator:{id:{},timestamp:new Date()}};
				_metadata.ownership.ownerId = req.user.id;
				_metadata.creator.id = req.user.id;
				if(req.user.account.id != null)
					_metadata.ownership.accountId = req.user.account.id;
				input["_metadata"] = _metadata;
				app.getModel.call(app,getSelf()._model).create(input,function(err,record){
					if(err){
						res.json(500,{error:err});
					}
					else{
						req.newRecord = record;
						getSelf().afterCreate(req, res);
						res.json(201,record);
					}
				});
			});
		},
		getItem:function(req,res){
			getSelf().beforeGetItem(req,res,function(){
				res.json(200,req.record);
				getSelf().afterGetItem();
			});
		},
		getCollection: function(req, res){
			getSelf().beforeGetCollection(req, res, function(){
				var model = app.getModel.call(app,getSelf()._model);
				var queryConditions = {};
				if(req.query.query){
					queryConditions['$or'] = [];
					for(var field in model.schema.paths){
						if(model.schema.paths[field].instance!='ObjectID'){
							var fieldCond = {};
							// fieldCond[field]={ $regex: req.query.query, $options: 'i' } ;
							if(field.indexOf('__')==0) continue;
							if(field.indexOf('_metadata')==0)continue;
							if(field.indexOf('_approval')==0)continue;
							var fieldObj = model.schema.paths[field];
							if(typeof fieldObj.options=='undefined') fieldObj.options = {type:null};
							switch(fieldObj.options.type){
								case "Date":
								case "Number":
									//fieldCond[field] = req.query.query;
									break;
								default:
									if(!(fieldObj.options.type instanceof Array)){
										fieldCond[field] = new RegExp(req.query.query,"i");
										queryConditions['$or'].push ( fieldCond );
									}
									break;
							}

						}
					}
				}
				queryConditions["_metadata.ownership.accountId"] = req.user.account.id;
				var pageSize = req.query.per_page?req.query.per_page:0;
				var page = req.query.page?req.query.page-1:0;

				var mainQuery = model.find(queryConditions);
				mainQuery = getSelf().beforeQueryCollection(req,mainQuery);

				var async = require('async');
				async.series({
					count:function(cb){
							var query = _.clone(mainQuery);
							query.count(function(err,count){
							cb(err,count);
						});
					},items:function(cb){
						var sort = req.query.sort_by;
						var order = req.query.order;

						var query = _.clone(mainQuery);

						query.skip(parseInt(page * pageSize)).limit(pageSize);
						if(sort && order){
							query = query.sort({sort:order});
						}else{
							query = query.sort({_id:"desc"});
						}
						query = getSelf().beforeQueryCollection(req,query);
						query.exec(function(err,collection){
							req.recordCollection = collection;
							cb(err,collection);
						});
					}
				},function(err,results){
					if(err){
						res.json(500,{error:err});
					}
					else{
						getSelf().afterGetCollection(req, res,function(){
							var dataArrayInfo = {
								total_entries : parseInt(results.count),
								total_pages: Math.ceil(results.count/pageSize),
								page: parseInt(page+1),
								per_page :parseInt(pageSize)
							}
							res.json(200,[dataArrayInfo,req.recordCollection]);
						});
					}
				});
			});
		},
		delete:function(req,res){
			if(typeof req.record._metadata.state.deletable != "undefined"){
				if(req.record._metadata.state.deletable == false){
					res.json(403,{error:{
						code:403,
							message: "This record is not deletable"
					}});
					return;
				}
			}
			getSelf().beforeDelete(req, res, function(){
				req.record.remove(function(err){
					if(err){
						res.json(500,{error:err});
					}
					else{
						getSelf().afterDelete(req, res);
						res.send(204);
					}
				});
			});
		},
		update:function(req,res){
			getSelf().beforeUpdate(req, res, function(){
				getSelf().processChangeLog(req,"UPDATE");
				for(var i in req.body){
					if( i!="_id" && i != "_metadata")
					{
						req.record[i] = req.body[i];
					}
				}
				req.record.save(function(err){
					if(err){
						res.json(500,{error:err});
					}
					else{
						req.recordNew = req.record;
						getSelf().afterUpdate(req, res);
						res.send(204);
					}
				})
			});
		},
		processChangeLog:function(req,action){
			var updateLog = {
				id:req.user.id,
				original:{},
				current:{},
				action:action
			};
			for(var i in req.body){
				if(_.isDate(req.record[i])){
					req.body[i] = new Date(req.body[i]);
				}

				if( !_.isArray(req.body[i]) &&
					i!="_metadata" ){
					if( req.record[i]==null|| !_.isEqual(req.record[i].toString(), req.body[i].toString()) ){
						updateLog.original[i] = req.record[i];
						updateLog.current[i] = req.body[i];
					}

				}
			}
			if(!_.isEmpty(updateLog.original)){
				req.record._metadata.updates.push(updateLog);
			}
		}
	});

	var getSelf = function(){
		return app.getController(name);
	}

	return controller;
};
<|endoftext|>


<commit_before>[
{
			"author": "Hiten Soni",
			"name": "Dark Night",
			"url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Dark_Night.png",
			"thumb_url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Dark_Night.png"

		},
              {
			"name": "Moon",
			"author": "Hiten Soni",
			"url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Moon.png",
			"thumb_url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Moon.png"
		},
		{
			"name": "Mountain",
			"author": "Hiten Soni",
			"url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Mountain.png",
			"thumb_url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Mountain.png"
		},
		{
			"name": "Mountain",
			"author": "Hiten Soni",
			"url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Mountain_Trials.png",
			"thumb_url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Mountain_Trials.png"
		},
		{
			"name": "Mountain 2",
			"author": "Hiten Soni",
			"url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Mountain2.png",
			"thumb_url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Mountain2.png"
		},
                {
			"name": "Mountain 3",
			"author": "Hiten Soni",
			"url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Mountain3.png",
			"thumb_url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Mountain3.png"
		},
		{
			"name": "Sea",
			"author": "Hiten Soni",
			"url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Misc/Sea.png",
			"thumb_url": "https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Sea.png"
		}
]
<commit_msg>Update Mountain.js<commit_after>[
   {
      "author":"Hiten Soni",
      "name":"Dark Night",
      "url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Dark_Night.png",
      "small_url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Thumb/Dark_Night.png"
   },
   {
      "author":"Hiten Soni",
      "name":"Dark Night",
      "url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Dark_Night.png",
      "thumb_url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Dark_Night.png"
   },
   {
      "name":"Moon",
      "author":"Hiten Soni",
      "url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Moon.png",
      "thumb_url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Moon.png"
   },
   {
      "name":"Mountain",
      "author":"Hiten Soni",
      "url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Mountain.png",
      "thumb_url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Mountain.png"
   },
   {
      "name":"Mountain",
      "author":"Hiten Soni",
      "url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Mountain_Trials.png",
      "thumb_url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Mountain_Trials.png"
   },
   {
      "name":"Mountain 2",
      "author":"Hiten Soni",
      "url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Mountain2.png",
      "thumb_url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Mountain2.png"
   },
   {
      "name":"Mountain 3",
      "author":"Hiten Soni",
      "url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Mountains/Mountain3.png",
      "thumb_url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Mountain3.png"
   },
   {
      "name":"Sea",
      "author":"Hiten Soni",
      "url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Misc/Sea.png",
      "thumb_url":"https://raw.githubusercontent.com/hiten1985/Backgrounds/master/Walls/Thumbs/Sea.png"
   }
]
<|endoftext|>


<commit_before>'use strict';

// Load modules
var Boom = require('boom');
var Joi = require('joi');
var Road = require('../models/road');
var Sensor = require('../models/sensor');
var Reading = require('../models/reading');

/**
 * GET /roads
 * Get roads
 *
 */
exports.index = {
  handler: function (request, reply) {
    Road.find(function (err, docs) {
      if (err) {
        return reply(Boom.badImplementation(err));
      }

      reply(docs);
    });
  }
};

/**
 * POST /roads
 * Create a new road
 *
 */
exports.create = {
  handler: function (request, reply) {
    var road = new Road();
    road._id = request.payload._id;
    road.name = request.payload.name;
    road.save(function (err, doc) {
      if (err) {
        return reply(Boom.badImplementation(err));
      }

      reply(doc).created('/roads/' + doc.id);
    });
  },
  validate: {
    payload: {
      _id: Joi.string().required(),
      name: Joi.string().default('')
    }
  }
};

/**
 * GET /roads/{id}/mean-time-speed
 * Get mean time speed between two spots (km) of the road
 *
 */
exports.meanTimeSpeed = {
  handler: function (request, reply) {
    var id = request.params.id;
    var fromKm = request.query.fromKm;
    var toKm = request.query.toKm;
    var fromTime = request.query.fromTime;
    var toTime = request.query.toTime;
    Sensor.find({ roadId: id, kilometer: { $gte: fromKm, $lte: toKm } }, { _id: 1 }, function (err, docs) {
      if (err) {
        return reply(Boom.badImplementation(err));
      }

      var sensors = docs.map(function (elem) {
        return elem._id;
      });

      Reading.find({ sensorId: { $in: sensors }, time: { $gte: fromTime, $lte: toTime } }, function (err, docs) {
        var speeds = docs.map(function (elem) {
          return elem.speed;
        });

        var sum = speeds.reduce(function (a, b) {
          return a + b;
        });

        var meanTimeSpeed = sum / speeds.length;
        reply(meanTimeSpeed);
      });
    });
  },
  validate: {
    params: {
      id: Joi.string().required()
    },
    query: {
      fromKm: Joi.number().required(),
      toKm: Joi.number().required(),
      fromTime: Joi.string().required(),
      toTime: Joi.string().required()
    }
  }
};

/**
 * GET /roads/{id}/mean-time-speed-dummy
 * Get mean time speed between two spots (km) of the road
 *
 */
exports.meanTimeSpeedDummy = {
  handler: function (request, reply) {
    var low = 0;
    var high = 110;
    var value = Math.random() * (high - low) + low;
    reply(value);
  },
  validate: {
    params: {
      id: Joi.string().required()
    },
    query: {
      fromKm: Joi.number().required(),
      toKm: Joi.number().required(),
      fromTime: Joi.string().required(),
      toTime: Joi.string().required()
    }
  }
};

/**
 * GET /roads/{id}/volume
 * Get volume between two spots (km) of the road
 *
 */
exports.volume = {
  handler: function (request, reply) {
    var id = request.params.id;
    var fromKm = request.query.fromKm;
    var toKm = request.query.toKm;
    // var fromTime = request.query.fromTime;
    // var toTime = request.query.toTime;
    Sensor.find({ roadId: id, kilometer: { $gte: fromKm, $lte: toKm }}, function (err, docs) {
      if (err) {
        return reply(Boom.badImplementation(err));
      }

      reply(docs);
    });
  },
  validate: {
    params: {
      id: Joi.string().required()
    },
    query: {
      fromKm: Joi.number().required(),
      toKm: Joi.number().required()
      // fromTime: Joi.string().required(),
      // toTime: Joi.string().required()
    }
  }
};

/**
 * GET /roads/{id}/volume-dummy
 * Get mean time speed between two spots (km) of the road
 *
 */
exports.volumeDummy = {
  handler: function (request, reply) {
    var low = 0;
    var high = 500;
    var value = Math.random() * (high - low) + low;
    reply(value);
  },
  validate: {
    params: {
      id: Joi.string().required()
    },
    query: {
      fromKm: Joi.number().required(),
      toKm: Joi.number().required(),
      fromTime: Joi.string().required(),
      toTime: Joi.string().required()
    }
  }
};

<commit_msg>Add volume calculation<commit_after>'use strict';

// Load modules
var Boom = require('boom');
var Joi = require('joi');
var Road = require('../models/road');
var Sensor = require('../models/sensor');
var Reading = require('../models/reading');

/**
 * GET /roads
 * Get roads
 *
 */
exports.index = {
  handler: function (request, reply) {
    Road.find(function (err, docs) {
      if (err) {
        return reply(Boom.badImplementation(err));
      }

      reply(docs);
    });
  }
};

/**
 * POST /roads
 * Create a new road
 *
 */
exports.create = {
  handler: function (request, reply) {
    var road = new Road();
    road._id = request.payload._id;
    road.name = request.payload.name;
    road.save(function (err, doc) {
      if (err) {
        return reply(Boom.badImplementation(err));
      }

      reply(doc).created('/roads/' + doc.id);
    });
  },
  validate: {
    payload: {
      _id: Joi.string().required(),
      name: Joi.string().default('')
    }
  }
};

/**
 * GET /roads/{id}/mean-time-speed
 * Get mean time speed between two spots (km) of the road
 *
 */
exports.meanTimeSpeed = {
  handler: function (request, reply) {
    var id = request.params.id;
    var fromKm = request.query.fromKm;
    var toKm = request.query.toKm;
    var fromTime = request.query.fromTime;
    var toTime = request.query.toTime;
    Sensor.find({ roadId: id, kilometer: { $gte: fromKm, $lte: toKm } }, { _id: 1 }, function (err, docs) {
      if (err) {
        return reply(Boom.badImplementation(err));
      }

      var sensors = docs.map(function (elem) {
        return elem._id;
      });

      Reading.find({ sensorId: { $in: sensors }, time: { $gte: fromTime, $lte: toTime } }, function (err, docs) {
        var speeds = docs.map(function (elem) {
          return elem.speed;
        });

        var sum = speeds.reduce(function (a, b) {
          return a + b;
        });

        var meanTimeSpeed = sum / speeds.length;
        reply(meanTimeSpeed);
      });
    });
  },
  validate: {
    params: {
      id: Joi.string().required()
    },
    query: {
      fromKm: Joi.number().required(),
      toKm: Joi.number().required(),
      fromTime: Joi.string().required(),
      toTime: Joi.string().required()
    }
  }
};

/**
 * GET /roads/{id}/mean-time-speed-dummy
 * Get mean time speed between two spots (km) of the road
 *
 */
exports.meanTimeSpeedDummy = {
  handler: function (request, reply) {
    var low = 0;
    var high = 110;
    var value = Math.random() * (high - low) + low;
    reply(value);
  },
  validate: {
    params: {
      id: Joi.string().required()
    },
    query: {
      fromKm: Joi.number().required(),
      toKm: Joi.number().required(),
      fromTime: Joi.string().required(),
      toTime: Joi.string().required()
    }
  }
};

/**
 * GET /roads/{id}/volume
 * Get volume in one spot (km) of the road
 *
 */
exports.volume = {
  handler: function (request, reply) {
    var id = request.params.id;
    var km = request.query.km;
    var fromTime = request.query.fromTime;
    var toTime = request.query.toTime;
    Sensor.findOne({ roadId: id, kilometer: km }, { _id: 1 }, function (err, doc) {
      if (err) {
        return reply(Boom.badImplementation(err));
      }

      if (!doc) {
        return reply(Boom.notFound());
      }

      Reading.find({ sensorId: doc.id, time: { $gte: fromTime, $lte: toTime } }, function (err, docs) {
        reply(docs.length);
      });
    });
  },
  validate: {
    params: {
      id: Joi.string().required()
    },
    query: {
      km: Joi.number().required(),
      fromTime: Joi.string().required(),
      toTime: Joi.string().required()
    }
  }
};

/**
 * GET /roads/{id}/volume-dummy
 * Get mean time speed between two spots (km) of the road
 *
 */
exports.volumeDummy = {
  handler: function (request, reply) {
    var low = 0;
    var high = 500;
    var value = Math.random() * (high - low) + low;
    reply(value);
  },
  validate: {
    params: {
      id: Joi.string().required()
    },
    query: {
      fromKm: Joi.number().required(),
      toKm: Joi.number().required(),
      fromTime: Joi.string().required(),
      toTime: Joi.string().required()
    }
  }
};

<|endoftext|>


<commit_before>var debug = require('debug')('keystone:core:openDatabaseConnection');

module.exports = function openDatabaseConnection (callback) {

	var keystone = this;
	var mongoConnectionOpen = false;

	// support replica sets for mongoose
	if (keystone.get('mongo replica set')) {

		if (keystone.get('logger')) {
			console.log('\nWarning: using the `mongo replica set` option has been deprecated and will be removed in' +
				' a future version.\nInstead set the `mongo` connection string with your host details, e.g.' +
				' mongodb://username:password@host:port,host:port,host:port/database and set any replica set options' +
				' in `mongo options`.\n\nRefer to https://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html' +
				' for more details on the connection settings.');
		}

		debug('setting up mongo replica set');
		var replicaData = keystone.get('mongo replica set');
		var replica = '';

		var credentials = (replicaData.username && replicaData.password) ? replicaData.username + ':' + replicaData.password + '@' : '';

		replicaData.db.servers.forEach(function (server) {
			replica += 'mongodb://' + credentials + server.host + ':' + server.port + '/' + replicaData.db.name + ',';
		});

		var options = {
			auth: { authSource: replicaData.authSource },
			replset: {
				rs_name: replicaData.db.replicaSetOptions.rs_name,
				readPreference: replicaData.db.replicaSetOptions.readPreference,
			},
		};

		debug('connecting to replicate set');
		keystone.mongoose.connect(replica, options);

	} else {
		debug('connecting to mongo');
		keystone.mongoose.connect(keystone.get('mongo'), keystone.get('mongo options'));
	}

	keystone.mongoose.connection.on('error', function (err) {

		if (keystone.get('logger')) {
			console.log('------------------------------------------------');
			console.log('Mongo Error:\n');
			console.log(err);
		}

		if (mongoConnectionOpen) {
			if (err.name === 'ValidationError') return;
			throw err;
		} else {
			throw new Error('KeystoneJS (' + keystone.get('name') + ') failed to start - Check that you are running `mongod` in a separate process.');
		}

	}).on('open', function () {

		debug('mongo connection open');
		mongoConnectionOpen = true;

		var connected = function () {
			if (keystone.get('auto update')) {
				debug('applying auto update');
				keystone.applyUpdates(callback);
			} else {
				callback();
			}
		};

		if (keystone.sessionStorePromise) {
			keystone.sessionStorePromise.then(connected);
		} else {
			connected();
		}

	});

	return this;
};
<commit_msg>clean up eslint errors<commit_after>var debug = require('debug')('keystone:core:openDatabaseConnection');

module.exports = function openDatabaseConnection (callback) {

	var keystone = this;
	var mongoConnectionOpen = false;

	// support replica sets for mongoose
	if (keystone.get('mongo replica set')) {

		if (keystone.get('logger')) {
			console.log('\nWarning: using the `mongo replica set` option has been deprecated and will be removed in'
				+ ' a future version.\nInstead set the `mongo` connection string with your host details, e.g.'
				+ ' mongodb://username:password@host:port,host:port,host:port/database and set any replica set options'
				+ ' in `mongo options`.\n\nRefer to https://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html'
				+ ' for more details on the connection settings.');
		}

		debug('setting up mongo replica set');
		var replicaData = keystone.get('mongo replica set');
		var replica = '';

		var credentials = (replicaData.username && replicaData.password) ? replicaData.username + ':' + replicaData.password + '@' : '';

		replicaData.db.servers.forEach(function (server) {
			replica += 'mongodb://' + credentials + server.host + ':' + server.port + '/' + replicaData.db.name + ',';
		});

		var options = {
			auth: { authSource: replicaData.authSource },
			replset: {
				rs_name: replicaData.db.replicaSetOptions.rs_name,
				readPreference: replicaData.db.replicaSetOptions.readPreference,
			},
		};

		debug('connecting to replicate set');
		keystone.mongoose.connect(replica, options);

	} else {
		debug('connecting to mongo');
		keystone.mongoose.connect(keystone.get('mongo'), keystone.get('mongo options'));
	}

	keystone.mongoose.connection.on('error', function (err) {

		if (keystone.get('logger')) {
			console.log('------------------------------------------------');
			console.log('Mongo Error:\n');
			console.log(err);
		}

		if (mongoConnectionOpen) {
			if (err.name === 'ValidationError') return;
			throw err;
		} else {
			throw new Error('KeystoneJS (' + keystone.get('name') + ') failed to start - Check that you are running `mongod` in a separate process.');
		}

	}).on('open', function () {

		debug('mongo connection open');
		mongoConnectionOpen = true;

		var connected = function () {
			if (keystone.get('auto update')) {
				debug('applying auto update');
				keystone.applyUpdates(callback);
			} else {
				callback();
			}
		};

		if (keystone.sessionStorePromise) {
			keystone.sessionStorePromise.then(connected);
		} else {
			connected();
		}

	});

	return this;
};
<|endoftext|>


<commit_before>// create the module and name it multimetro
var multimetro = angular.module('multimetro', ['ngRoute', 'ngProgress']);

// configure our routes
multimetro.config(function($routeProvider) {
    $routeProvider

        // route for the home page
        .when('/', {
            templateUrl : 'pages/home.html',
            controller  : 'mainController'
        })

        // route for the about page
        .when('/about', {
            templateUrl : 'pages/about.html',
            controller  : 'aboutController'
        })

        // route for the contact page
        .when('/contact', {
            templateUrl : 'pages/contact.html',
            controller  : 'contactController'
        });
});
// create the controller and inject Angular's $scope
multimetro.controller('mainController', function($scope, ngProgress) {
    // create a title to display in our view
    $scope.appName = 'Multimetro';
    ngProgress.start(2);
    ngProgress.complete()
});

multimetro.controller('aboutController', function($scope, ngProgress) {
    ngProgress.start(2);
    ngProgress.complete()
});

multimetro.controller('contactController', function($scope, ngProgress) {
    ngProgress.start(2);
    ngProgress.complete()
});
<commit_msg>improved search<commit_after>// create the module and name it multimetro
var multimetro = angular.module('multimetro', ['ngRoute', 'ngProgress', 'lbServices']);

// configure our routes
multimetro.config(function($routeProvider) {
    $routeProvider

        // route for the home page
        .when('/', {
            templateUrl : 'pages/home.html',
            controller  : 'mainController'
        })

        // route for the about page
        .when('/about', {
            templateUrl : 'pages/about.html',
            controller  : 'aboutController'
        })

        // route for the contact page
        .when('/contact', {
            templateUrl : 'pages/contact.html',
            controller  : 'contactController'
        });
});
// create the controller and inject Angular's $scope
multimetro.controller('mainController', ['$scope', 'ngProgresste', 'Multas', function($scope, ngProgress, Multas) {
    // create a title to display in our view
    $scope.appName = 'Multimetro';
    $scope.multas = [];

    function getMultas() {
      Todo
        .find()
        .$promise
        .then(function(results) {
          $scope.multas = results;
        });
    }
    getTodos();

    ngProgress.start(2);
    ngProgress.complete();
}]);

multimetro.controller('aboutController', function($scope, ngProgress) {
    ngProgress.start(2);
    ngProgress.complete();
});

multimetro.controller('contactController', function($scope, ngProgress) {
    ngProgress.start(2);
    ngProgress.complete();
});
<|endoftext|>


<commit_before>/**
 * Create a WaveSurfer instance.
 */
var wavesurfer = Object.create(WaveSurfer);

/**
 * Init & load.
 */
document.addEventListener('DOMContentLoaded', function () {
    // Init wavesurfer
    wavesurfer.init({
        container: '#waveform',
        height: 100,
        scrollParent: true,
        normalize: true,
        minimap: true,
        backend: 'AudioElement'
    });

    wavesurfer.util.ajax({
        responseType: 'json',
        url: 'rashomon.json'
    }).on('success', function (data) {
        wavesurfer.load(
            'http://www.archive.org/download/mshortworks_001_1202_librivox/msw001_03_rashomon_akutagawa_mt_64kb.mp3',
            data
        );
    });

    /* Regions */
    wavesurfer.enableDragSelection({
        color: randomColor(0.1)
    });

    wavesurfer.on('ready', localStorage.regions ? loadSegments : selectSegments);
    wavesurfer.on('region-click', function (region, e) {
        e.stopPropagation();
        // Play on click, loop on shift click
        e.shiftKey ? region.playLoop() : region.play();
    });
    wavesurfer.on('region-dblclick', editAnnotation);
    wavesurfer.on('region-updated', saveSegments);
    wavesurfer.on('region-removed', saveSegments);

    wavesurfer.on('region-play', function (region) {
        region.once('out', function () {
            wavesurfer.play(region.start);
            wavesurfer.pause();
        });
    });

    /* Minimap plugin */
    wavesurfer.initMinimap({
        height: 30,
        waveColor: '#ddd',
        progressColor: '#999',
        cursorColor: '#999'
    });

    /* Toggle play/pause buttons. */
    var playButton = document.querySelector('#play');
    var pauseButton = document.querySelector('#pause');
    wavesurfer.on('play', function () {
        playButton.style.display = 'none';
        pauseButton.style.display = '';
    });
    wavesurfer.on('pause', function () {
        playButton.style.display = '';
        pauseButton.style.display = 'none';
    });
});

/**
 * Save annotations to localStorage.
 */
function saveSegments() {
    localStorage.regions = JSON.stringify(
        Object.keys(wavesurfer.regions.list).map(function (id) {
            var region = wavesurfer.regions.list[id];
            return {
                start: region.start,
                end: region.end,
                data: region.data
            };
        })
    );
}

/**
 * Load segments from localStorage.
 */
function loadSegments() {
    var regions = JSON.parse(localStorage.regions);
    regions.forEach(function (region) {
        region.color = randomColor(0.1);
        wavesurfer.addRegion(region);
    });
}

/**
 * Create segments separated by silence.
 */
function selectSegments() {
    // Silence params
    var minValue = 0.0025;
    var minSeconds = 0.25;

    var peaks = wavesurfer.backend.peaks;
    var length = peaks.length;
    var duration = wavesurfer.getDuration();
    var coef = duration / length;
    var minLen = (minSeconds / duration) * length;

    var i = 0;
    var start;
    var extend;
    while (i < length) {
        if (peaks[i] < minValue) {
            i += 1;
        } else {
            start = i;
            do {
                while (peaks[i] >= minValue) {
                    i += 1;
                }
                if (i - start < minLen) {
                    i += 1;
                } else {
                    var j = i;
                    while (peaks[j] < minValue) {
                        j += 1;
                    }
                    if (j - i < minLen) {
                        i = j;
                        extend = true;
                    } else {
                        wavesurfer.addRegion({
                            start: Math.round(start * coef * 10) / 10,
                            end: Math.round(i * coef * 10) / 10,
                            color: randomColor(0.1)
                        });
                        i += 1;
                        extend = false;
                    }
                }
            } while (extend)
        }
    }

    wavesurfer.regions && saveSegments();
}

/**
 * Random RGBA color.
 */
function randomColor(alpha) {
    return 'rgba(' + [
        ~~(Math.random() * 255),
        ~~(Math.random() * 255),
        ~~(Math.random() * 255),
        alpha || 1
    ] + ')';

}

/**
 * Edit annotation for a segment.
 */
function editAnnotation (region) {
    var form = document.forms.edit;
    form.style.opacity = 1;
    form.elements.start.value = Math.floor(region.start);
    form.elements.end.value = Math.ceil(region.end);
    form.elements.note.value = region.data.note || '';
    form.onsubmit = function (e) {
        e.preventDefault();
        region.update({
            start: form.elements.start.value,
            end: form.elements.end.value,
            data: {
                note: form.elements.note.value
            }
        });
        form.style.opacity = 0;
    };
    form.onreset = function () {
        form.style.opacity = 0;
        form.dataset.region = null;
    };
    form.dataset.region = region.id;
}

/**
 * Bind controls.
 */
wavesurfer.once('ready', function () {
    var handlers = {
        'play': function () {
            wavesurfer.play();
        },
        'pause': function () {
            wavesurfer.pause();
        },
        'delete-region': function () {
            var form = document.forms.edit;
            var regionId = form.dataset.region;
            if (regionId) {
                wavesurfer.regions.list[regionId].remove();
                form.reset();
            }
        },
        'export': function () {
            window.open('data:application/json;charset=utf-8,' +
                encodeURIComponent(localStorage.regions));
        }
    };

    document.addEventListener('click', function (e) {
        var action = e.target.dataset && e.target.dataset.action;
        if (action && action in handlers) {
            handlers[action](e);
        }
    });
});
<commit_msg>refactor localStorage<commit_after>/**
 * Create a WaveSurfer instance.
 */
var wavesurfer = Object.create(WaveSurfer);

/**
 * Init & load.
 */
document.addEventListener('DOMContentLoaded', function () {
    // Init wavesurfer
    wavesurfer.init({
        container: '#waveform',
        height: 100,
        scrollParent: true,
        normalize: true,
        minimap: true,
        backend: 'AudioElement'
    });

    wavesurfer.util.ajax({
        responseType: 'json',
        url: 'rashomon.json'
    }).on('success', function (data) {
        wavesurfer.load(
            'http://www.archive.org/download/mshortworks_001_1202_librivox/msw001_03_rashomon_akutagawa_mt_64kb.mp3',
            data
        );
    });

    /* Regions */
    wavesurfer.enableDragSelection({
        color: randomColor(0.1)
    });

    wavesurfer.on('ready', function () {
        if (localStorage.regions) {
            loadRegions(JSON.parse(localStorage.regions));
        } else {
            loadRegions(detectRegions());
            saveRegions();
        }
    });
    wavesurfer.on('region-click', function (region, e) {
        e.stopPropagation();
        // Play on click, loop on shift click
        e.shiftKey ? region.playLoop() : region.play();
    });
    wavesurfer.on('region-dblclick', editAnnotation);
    wavesurfer.on('region-updated', saveRegions);
    wavesurfer.on('region-removed', saveRegions);

    wavesurfer.on('region-play', function (region) {
        region.once('out', function () {
            wavesurfer.play(region.start);
            wavesurfer.pause();
        });
    });

    /* Minimap plugin */
    wavesurfer.initMinimap({
        height: 30,
        waveColor: '#ddd',
        progressColor: '#999',
        cursorColor: '#999'
    });

    /* Toggle play/pause buttons. */
    var playButton = document.querySelector('#play');
    var pauseButton = document.querySelector('#pause');
    wavesurfer.on('play', function () {
        playButton.style.display = 'none';
        pauseButton.style.display = '';
    });
    wavesurfer.on('pause', function () {
        playButton.style.display = '';
        pauseButton.style.display = 'none';
    });
});

/**
 * Save annotations to localStorage.
 */
function saveRegions() {
    localStorage.regions = JSON.stringify(
        Object.keys(wavesurfer.regions.list).map(function (id) {
            var region = wavesurfer.regions.list[id];
            return {
                start: region.start,
                end: region.end,
                data: region.data
            };
        })
    );
}

/**
 * Load regions from localStorage.
 */
function loadRegions(regions) {
    regions.forEach(function (region) {
        region.color = randomColor(0.1);
        wavesurfer.addRegion(region);
    });
}

/**
 * Detect regions separated by silence.
 */
function detectRegions() {
    // Silence params
    var minValue = 0.0015;
    var minSeconds = 0.25;

    var peaks = wavesurfer.backend.peaks;
    var length = peaks.length;
    var duration = wavesurfer.getDuration();
    var coef = duration / length;
    var minLen = (minSeconds / duration) * length;

    var regions = [];
    var i = 0;
    var start;
    var extend;
    while (i < length) {
        if (peaks[i] < minValue) {
            i += 1;
        } else {
            start = i;
            do {
                while (peaks[i] >= minValue) {
                    i += 1;
                }
                if (i - start < minLen) {
                    i += 1;
                } else {
                    var j = i;
                    while (peaks[j] < minValue) {
                        j += 1;
                    }
                    if (j - i < minLen) {
                        i = j;
                        extend = true;
                    } else {
                        regions.push({
                            start: Math.round(start * coef * 10) / 10,
                            end: Math.round(i * coef * 10) / 10
                        });
                        i += 1;
                        extend = false;
                    }
                }
            } while (extend)
        }
    }
    return regions;
}

/**
 * Random RGBA color.
 */
function randomColor(alpha) {
    return 'rgba(' + [
        ~~(Math.random() * 255),
        ~~(Math.random() * 255),
        ~~(Math.random() * 255),
        alpha || 1
    ] + ')';

}

/**
 * Edit annotation for a region.
 */
function editAnnotation (region) {
    var form = document.forms.edit;
    form.style.opacity = 1;
    form.elements.start.value = Math.floor(region.start);
    form.elements.end.value = Math.ceil(region.end);
    form.elements.note.value = region.data.note || '';
    form.onsubmit = function (e) {
        e.preventDefault();
        region.update({
            start: form.elements.start.value,
            end: form.elements.end.value,
            data: {
                note: form.elements.note.value
            }
        });
        form.style.opacity = 0;
    };
    form.onreset = function () {
        form.style.opacity = 0;
        form.dataset.region = null;
    };
    form.dataset.region = region.id;
}

/**
 * Bind controls.
 */
wavesurfer.once('ready', function () {
    var handlers = {
        'play': function () {
            wavesurfer.play();
        },
        'pause': function () {
            wavesurfer.pause();
        },
        'delete-region': function () {
            var form = document.forms.edit;
            var regionId = form.dataset.region;
            if (regionId) {
                wavesurfer.regions.list[regionId].remove();
                form.reset();
            }
        },
        'export': function () {
            window.open('data:application/json;charset=utf-8,' +
                encodeURIComponent(localStorage.regions));
        }
    };

    document.addEventListener('click', function (e) {
        var action = e.target.dataset && e.target.dataset.action;
        if (action && action in handlers) {
            handlers[action](e);
        }
    });
});
<|endoftext|>


<commit_before>module.exports = {
  kaliber: {
    // compileWitBabel: ['firebase'],
    templateRenderers: {
      xml: '/xmlRenderer',
      mjml: '/mjml-renderer'
    }
  },
  client: {
    someConfigKey: true
  },
  thisConfigKeyShouldNotAppearInTheClient: true,
}
<commit_msg>renaming<commit_after>module.exports = {
  kaliber: {
    // compileWitBabel: ['gsap'],
    templateRenderers: {
      xml: '/xmlRenderer',
      mjml: '/mjml-renderer'
    }
  },
  client: {
    someConfigKey: true
  },
  thisConfigKeyShouldNotAppearInTheClient: true,
}
<|endoftext|>