<commit_before>var send  = require(CONFIG.root + "/core/send.js").send,
    mongo = require(CONFIG.root + "/db/mongo").db;

var url = require("url"),
    qs  = require("querystring");

exports.getBranches = function(link) {

    mongo("sag", "branch", function(err, db) {

        if (err) {
            send.internalservererror(link, err);
            return;
        }

        // all users
        if (link.path.length == 0) {

            var branchFilter = {};
            var sessionData = link.session.data || {};

            if (sessionData.branch) {

                var splits = sessionData.branch.split(",");

                if (splits.length > 1) {
                    branchFilter = { "short" : splits[0] };
                } else {
                    branchFilter = { "short" : sessionData.branch };
                }
            }

            db.find(branchFilter).toArray(function(err, docs) {

                if (err) {
                    send.internalservererror(link, err);
                    return;
                }

                send.ok(link.res, docs);
            });
        }
    });
};

exports.getOrders = function(link) {

    mongo("sag", "orders_new", function(err, db) {

        if (err) {
            send.internalservererror(link, err);
            return;
        }

        var urlObj = url.parse(link.req.url);
        var queryObj = qs.parse(urlObj.query);

        var archiveFilter = {
            "$elemMatch": {
                "archived": { $exists: 0 }
            }
        };

        // if this user has a branch in his session, always use it as filter
        var sessionData = link.session.data || {};
        var userBranch = "";

        if (sessionData.branch) {
            userBranch = sessionData.branch.toString();
        }

        // branch filtering
        var branch = userBranch || (queryObj.branch !== "0" ? queryObj.branch : "");
        if (branch) {

            // DD Marketing need to see all D* + Lauper order items
            var splits = branch.split(",");

            if (splits.length > 1) {
                archiveFilter["$elemMatch"].branch = { "$in": splits };
            } else {
                archiveFilter["$elemMatch"].branch = branch;
            }
        }

        // archive filtering
        var archive = queryObj.archive;
        if (archive === "1") {
            archiveFilter = {
                "$not": archiveFilter
            };
        }

        // search filtering
        var search = (queryObj.search || "").toLowerCase().trim();
        var searchWords = search === "" ? [] : search.split(" ");

        // paging
        var skip = queryObj.skip || 0;
        var limit = queryObj.limit || 0;

        var isExport = queryObj["export"] ? true : false;

        var mongoQuery = {
            "items": archiveFilter
        }

        console.log(JSON.stringify(mongoQuery));

        db.find(mongoQuery, { sort: { date: -1 } }).toArray(function(err, docs) {

            if (err) {
                send.internalservererror(link, err);
                return;
            }

            // all the orders contain item that match the filters (branch and archive)
            // we have to filter out now all the items that should not be visible by some branches

            var orders = [];

            for (var i in docs) {

                var order = docs[i];

                // make the date a displayable one;
                order.date = order.date.substr(6, 2) + "/" + order.date.substr(4, 2) + "/" + order.date.substr(0, 4);

                // filter only the mathing orders
                if (searchWords.length) {

                    var meta = order.meta || [],
                        metaLength = meta.length;
                    var found = false;

                    for (var k = 0; k < metaLength && !found; k++) {
                        for (var l = 0; l < searchWords.length && !found; l++) {
                            if (meta[k].indexOf(searchWords[l]) != -1) {
                                found = true;
                            }
                        }
                    }

                    if (!found) {
                        continue;
                    }
                }

                var items = [];

                // this will help us eliminate in archive view all the orders
                // that don't have at least one item matching to the users branch
                var hasBranch = false;

                for (var j in order.items) {

                    var item  = order.items[j];

                    if (!branch || (branch && branch.indexOf(item.branch) > -1)) {
                        hasBranch = true;
                    }

                    if (!userBranch || (branch && branch.indexOf(item.branch) > -1)) {
                        item.readonly = false;
                        items.push(item);
                    } else {
                        item.readonly = true;
                        if (branch !== "LAUPER") {
                            items.push(item);
                        }
                    }
                }

                // empty this order if there are no items for this branch
                if (!hasBranch) {
                    items = [];
                }

                // overwrite the initial items after filtering
                order.items = items;

                if (items.length) {
                    orders.push(order);
                }
            }

            if (!isExport) {
                var length = orders.length;
                orders = orders.splice(skip, limit || length);
                orders.unshift(length);
                send.ok(link.res, orders);
            }
            else {
                link.res.headers["content-type"] = "text/csv";
                link.res.headers["content-disposition"] = "attachment; filename=export.csv";
                var csv = generateExport(orders, link.session.loc);
                send.ok(link.res, csv);
            }
        });
    });
};

function generateExport(orders, lang) {
    var NEW_LINE = "\r\n";
    var SEPARATOR = ";";

    var result = "";

    switch (lang) {
        case "fr":
            result += "Région;Succursale;Zone de visite;Numéro de client;Entreprise;Numéro de commande;Date de commande;Numéro d'article;Désignation;Quantité;Net;Prime;Monnaie;";
        case "it":
            result += "Regione;Filiale;Zona visita;Numero cliente;Ditta;No. ordine;Dati per l'ordinazione;Numero articolo;Descrizione;Quantità;Netto;Premio;Valuta;";
            break;
        default:
            result += "Region;Filiale;Besuchsgebiet;Kundennummer;Firma;Bestellnummer;Bestelldatum;Art. Nr.;Bezeichnung;Menge;Netto;Prämie;Währung;";
    }

    result += NEW_LINE;

    for (var i = 0; i < orders.length; i++) {
        var order = orders[i];

        for (var j = 0; j < order.items.length; j++) {
            var item = order.items[j];

            var line = "";

            line += (order.customer.region || "") + SEPARATOR;
            line += (order.customer.branch || "") + SEPARATOR;
            line += (order.customer.vis_region || "") + SEPARATOR;
            line += (order.customer.cnr || "") + SEPARATOR;
            line += (order.adress.company || "") + SEPARATOR;
            line += (order._c || "") + SEPARATOR;
            line += (order.date || "") + SEPARATOR;

            line += (item.nr || "") + SEPARATOR;
            line += (item.caption || "") + SEPARATOR;
            line += (item.number || "") + SEPARATOR;
            line += (item.netto || "") + SEPARATOR;

            line += ("dd" || "") + SEPARATOR;
            line += (order.currency || "") + SEPARATOR;

            result += line + NEW_LINE;
        }
    }

    return result;
}

function dateToInt(date) {

    var day = "0" + date.getDate();
    var month = "0" + (date.getMonth() + 1);
    var year = date.getFullYear();

    return parseInt(year + month.substr(-2) + day.substr(-2));
}

<commit_msg>Fied bug in branch bestellung display<commit_after>var send  = require(CONFIG.root + "/core/send.js").send,
    mongo = require(CONFIG.root + "/db/mongo").db;

var url = require("url"),
    qs  = require("querystring");

exports.getBranches = function(link) {

    mongo("sag", "branch", function(err, db) {

        if (err) {
            send.internalservererror(link, err);
            return;
        }

        // all users
        if (link.path.length == 0) {

            var branchFilter = {};
            var sessionData = link.session.data || {};

            if (sessionData.branch) {

                var splits = sessionData.branch.split(",");

                if (splits.length > 1) {
                    branchFilter = { "short" : splits[0] };
                } else {
                    branchFilter = { "short" : sessionData.branch };
                }
            }

            db.find(branchFilter).toArray(function(err, docs) {

                if (err) {
                    send.internalservererror(link, err);
                    return;
                }

                send.ok(link.res, docs);
            });
        }
    });
};

exports.getOrders = function(link) {

    mongo("sag", "orders_new", function(err, db) {

        if (err) {
            send.internalservererror(link, err);
            return;
        }

        var urlObj = url.parse(link.req.url);
        var queryObj = qs.parse(urlObj.query);

        var archiveFilter = {
            "$elemMatch": {
                "archived": { $exists: 0 }
            }
        };

        // if this user has a branch in his session, always use it as filter
        var sessionData = link.session.data || {};
        var userBranch = "";

        if (sessionData.branch) {
            userBranch = sessionData.branch.toString();
        }

        // branch filtering
        var branch = userBranch || (queryObj.branch !== "0" ? queryObj.branch : "");
        if (branch) {

            // DD Marketing need to see all D* + Lauper order items
            var splits = branch.split(",");

            if (splits.length > 1) {
                archiveFilter["$elemMatch"].branch = { "$in": splits };
            } else {
                archiveFilter["$elemMatch"].branch = branch;
            }
        }

        // archive filtering
        var archive = queryObj.archive;
        if (archive === "1") {
            archiveFilter = {
                "$not": archiveFilter
            };
        }

        // search filtering
        var search = (queryObj.search || "").toLowerCase().trim();
        var searchWords = search === "" ? [] : search.split(" ");

        // paging
        var skip = queryObj.skip || 0;
        var limit = queryObj.limit || 0;

        var isExport = queryObj["export"] ? true : false;

        var mongoQuery = {
            "items": archiveFilter
        }

        console.log(JSON.stringify(mongoQuery));

        db.find(mongoQuery, { sort: { date: -1 } }).toArray(function(err, docs) {

            if (err) {
                send.internalservererror(link, err);
                return;
            }

            // all the orders contain item that match the filters (branch and archive)
            // we have to filter out now all the items that should not be visible by some branches

            var orders = [];

            for (var i in docs) {

                var order = docs[i];

                // make the date a displayable one;
                order.date = order.date.substr(6, 2) + "/" + order.date.substr(4, 2) + "/" + order.date.substr(0, 4);

                // filter only the mathing orders
                if (searchWords.length) {

                    var meta = order.meta || [],
                        metaLength = meta.length;
                    var found = false;

                    for (var k = 0; k < metaLength && !found; k++) {
                        for (var l = 0; l < searchWords.length && !found; l++) {
                            if (meta[k].indexOf(searchWords[l]) != -1) {
                                found = true;
                            }
                        }
                    }

                    if (!found) {
                        continue;
                    }
                }

                var items = [];

                // this will help us eliminate in archive view all the orders
                // that don't have at least one item matching to the users branch
                var hasBranch = false;

                for (var j in order.items) {

                    var item  = order.items[j];

                    if (!branch || (branch && branch.indexOf(item.branch) > -1)) {
                        hasBranch = true;
                    }

                    if (!userBranch && branch) {

                        var splits = branch.split(",");

                        for (var i in splits) {

                            if (splits[i] == item.branch) {
                                item.readonly = false;
                                items.push(item);
                                break;
                            }
                        }
                    } else {
                        item.readonly = true;
                        if (branch !== "LAUPER") {
                            items.push(item);
                        }
                    }
                }

                // empty this order if there are no items for this branch
                if (!hasBranch) {
                    items = [];
                }

                // overwrite the initial items after filtering
                order.items = items;

                if (items.length) {
                    orders.push(order);
                }
            }

            if (!isExport) {
                var length = orders.length;
                orders = orders.splice(skip, limit || length);
                orders.unshift(length);
                send.ok(link.res, orders);
            }
            else {
                link.res.headers["content-type"] = "text/csv";
                link.res.headers["content-disposition"] = "attachment; filename=export.csv";
                var csv = generateExport(orders, link.session.loc);
                send.ok(link.res, csv);
            }
        });
    });
};

function generateExport(orders, lang) {
    var NEW_LINE = "\r\n";
    var SEPARATOR = ";";

    var result = "";

    switch (lang) {
        case "fr":
            result += "Région;Succursale;Zone de visite;Numéro de client;Entreprise;Numéro de commande;Date de commande;Numéro d'article;Désignation;Quantité;Net;Prime;Monnaie;";
        case "it":
            result += "Regione;Filiale;Zona visita;Numero cliente;Ditta;No. ordine;Dati per l'ordinazione;Numero articolo;Descrizione;Quantità;Netto;Premio;Valuta;";
            break;
        default:
            result += "Region;Filiale;Besuchsgebiet;Kundennummer;Firma;Bestellnummer;Bestelldatum;Art. Nr.;Bezeichnung;Menge;Netto;Prämie;Währung;";
    }

    result += NEW_LINE;

    for (var i = 0; i < orders.length; i++) {
        var order = orders[i];

        for (var j = 0; j < order.items.length; j++) {
            var item = order.items[j];

            var line = "";

            line += (order.customer.region || "") + SEPARATOR;
            line += (order.customer.branch || "") + SEPARATOR;
            line += (order.customer.vis_region || "") + SEPARATOR;
            line += (order.customer.cnr || "") + SEPARATOR;
            line += (order.adress.company || "") + SEPARATOR;
            line += (order._c || "") + SEPARATOR;
            line += (order.date || "") + SEPARATOR;

            line += (item.nr || "") + SEPARATOR;
            line += (item.caption || "") + SEPARATOR;
            line += (item.number || "") + SEPARATOR;
            line += (item.netto || "") + SEPARATOR;

            line += ("dd" || "") + SEPARATOR;
            line += (order.currency || "") + SEPARATOR;

            result += line + NEW_LINE;
        }
    }

    return result;
}

function dateToInt(date) {

    var day = "0" + date.getDate();
    var month = "0" + (date.getMonth() + 1);
    var year = date.getFullYear();

    return parseInt(year + month.substr(-2) + day.substr(-2));
}

<|endoftext|>


<commit_before>var fs = require('fs'),
	settings = require('./settings.json'),
	walk = require('walk'),
	taglib = require('taglib'),
	path = require('path'),
	mongoose = require('mongoose'),
	scanTimeout = null,
	progressTimeout = null,
	scanInProgess = false,
	t = 1000;

function merge(filepath, mtime, tag, audioProperties){
	var Track = mongoose.model('track');
	var track = {
			path: filepath,
			genre: tag.genre,
			album: tag.album,
			name: tag.title,
			duration: audioProperties.length,
			year: tag.year,
			bitrate: audioProperties.bitrate,
			frequency: audioProperties.sampleRate,
			trackno: tag.track,
			last_updated: mtime
		};
	Track.update({ path: filepath }, track, {upsert: true}, function(err, a, b){
		console.log('updated');
		clearProgressTimeout();
	});
}

function cleanold(files){
	var Track = mongoose.model('track'),
		filesToDelete = [];
	Object.keys(files).forEach(function(element) {
		filesToDelete.push(element);
	});
	Track.remove({path: {$in: filesToDelete}}).exec();
	clearProgressTimeout();
}

function clearProgressTimeout(){
	clearTimeout(progressTimeout);
	progressTimeout = setTimeout(function(){
		scanInProgess = false;
	}, t);
}

exports.scan = function(){
	var Track = mongoose.model('track');
	if (!scanInProgess){
		scanInProgess = true;
		Track.find(
			{},
			"path last_updated",
			function(err, docs) {
				var files = {};
				for (var i in docs) {
					if (docs.hasOwnProperty(i)) {
						files[docs[i].path] = docs[i].last_updated;
					}
				}
				walker = walk.walk(settings.scanner.path);
				walker.on("file", function(root, fileStats, next) {
					var filepath = path.join(root, fileStats.name);
					delete files[filepath];
					if (!files[filepath] || fileStats.mtime > files[filepath]){
						taglib.read(filepath, function(err, tag, audioProperties){
							merge(filepath, fileStats.mtime, tag, audioProperties);
							next();
						});
					}else{
						next();
					}
				});

				walker.on("end", function () {
					console.log('cleanold', files);
					cleanold(files);
				});
			}
		);
	}
};

exports.watch = function(){
	fs.watch(settings.scanner.path, function(event, filename){
		console.log("File " + filename + "; event " + event);
		clearTimeout(scanTimeout);
		scanTimeout = setTimeout(exports.scan, t);
	});
};<commit_msg>Adding comments<commit_after>var fs = require('fs'),
	settings = require('./settings.json'),
	walk = require('walk'),
	taglib = require('taglib'),
	path = require('path'),
	mongoose = require('mongoose'),
	scanTimeout = null,
	progressTimeout = null,
	scanInProgess = false,
	t = 10000;

/**
 * Add or update track to database
 * @param filepath
 * @param mtime
 * @param tag
 * @param audioProperties
 */
function merge(filepath, mtime, tag, audioProperties){
	var Track = mongoose.model('track');
	var track = {
			path: filepath,
			genre: tag.genre,
			album: tag.album,
			name: tag.title,
			duration: audioProperties.length,
			year: tag.year,
			bitrate: audioProperties.bitrate,
			frequency: audioProperties.sampleRate,
			trackno: tag.track,
			last_updated: mtime
		};
	Track.update({ path: filepath }, track, {upsert: true}, function(err, a, b){
		console.log('updated');
		clearProgressTimeout();
	});
}

/**
 * Delete files that are not on the filesystem anymore
 * @param files
 */
function cleanold(files){
	var Track = mongoose.model('track'),
		filesToDelete = [];
	Object.keys(files).forEach(function(element) {
		filesToDelete.push(element);
	});
	Track.remove({path: {$in: filesToDelete}}).exec();
	clearProgressTimeout();
}

/**
 * Update the scanInProgess boolean
 */
function clearProgressTimeout(){
	clearTimeout(progressTimeout);
	progressTimeout = setTimeout(function(){
		scanInProgess = false;
	}, t);
}

/**
 * Walk through folder defined in settings.json in order
 * to retrieve music files
 */
exports.scan = function(){
	var Track = mongoose.model('track');
	if (!scanInProgess){
		scanInProgess = true;
		Track.find(
			{},
			"path last_updated",
			function(err, docs) {
				var files = {};
				for (var i in docs) {
					if (docs.hasOwnProperty(i)) {
						files[docs[i].path] = docs[i].last_updated;
					}
				}
				walker = walk.walk(settings.scanner.path);
				walker.on("file", function(root, fileStats, next) {
					var filepath = path.join(root, fileStats.name);
					delete files[filepath];
					if (!files[filepath] || fileStats.mtime > files[filepath]){
						taglib.read(filepath, function(err, tag, audioProperties){
							merge(filepath, fileStats.mtime, tag, audioProperties);
							next();
						});
					}else{
						next();
					}
				});

				walker.on("end", function () {
					console.log('cleanold', files);
					cleanold(files);
				});
			}
		);
	}
};

/**
 * Watch folder defined in settings.json and then call scan()
 * if an event is triggered
 */
exports.watch = function(){
	fs.watch(settings.scanner.path, function(event, filename){
		console.log("File " + filename + "; event " + event);
		clearTimeout(scanTimeout);
		scanTimeout = setTimeout(exports.scan, t);
	});
};<|endoftext|>


<commit_before>/*
*     (C) Copyright 2008 Telefonica Investigacion y Desarrollo
*     S.A.Unipersonal (Telefonica I+D)
*
*     This file is part of Morfeo EzWeb Platform.
*
*     Morfeo EzWeb Platform 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, or
*     (at your option) any later version.
*
*     Morfeo EzWeb Platform 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 Affero General Public License for more details.
*
*     You should have received a copy of the GNU Affero General Public License
*     along with Morfeo EzWeb Platform.  If not, see <http://www.gnu.org/licenses/>.
*
*     Info about members and contributors of the MORFEO project
*     is available at
*
*     http://morfeo-project.org
 */

// This class represents the parameter that a filter can have
function Param (name_, label_, type_, index_, required_, defaultValue_){
  this._name = name_;
  this._label = label_;
  this._type = type_;
  this._index = index_;
  this._required = required_;
  this._defaultValue = defaultValue_;
}

Param.prototype.Param = function (name_, label_, type_, index_, required_, defaultValue_){
  this._name = name_;
  this._label = label_;
  this._type = type_;
  this._index = index_;
  this._required = required_;
  this._defaultValue = defaultValue_;
}

Param.prototype.getName = function() {
  return this._name;
}

Param.prototype.getType = function() {
  return this._type;
}

Param.prototype.getLabel = function() {
  return this._label;
}

Param.prototype.getIndex = function() {
  return this._index;
}

Param.prototype.getRequired = function() {
  return this._required;
}

Param.prototype.getDefaultValue = function() {
  return this._defaultValue;
}

Param.prototype.createHtmlLabel = function() {
  var labelLayer = document.createElement("div");
  Element.extend(labelLayer);
  labelLayer.addClassName('paramName');
  var img = document.createElement("img");
  img.setAttribute("src", _currentTheme.getIconURL('wiring-filter_param'));
  labelLayer.appendChild(img);
  var labelElement = document.createElement("label");
  labelElement.innerHTML = this._label + ':';
  labelLayer.appendChild(labelElement);

  return labelLayer;
}

Param.prototype.createHtmlValue = function(wiringGUI, channel, valueElement){
	var context = {wiringGUI:wiringGUI, channel:channel, filter:channel.getFilter(), param:this, valueElement:valueElement};

	var paramValueLayer = document.createElement("div");
	Element.extend(paramValueLayer);
	var paramInput = document.createElement("input");
	Element.extend(paramInput);
	paramInput.addClassName("paramValueInput");
	paramInput.setAttribute ("value", channel.getFilterParams()[this._index]['value']);
	Event.observe(paramInput, 'click',function(e){Event.stop(e);});

	var checkResult = function(e) {
		var msg;

		// Sets the param value
		this.channel.setFilterParam(this.param._index, target.value);

		// Sets the channel value
		this.valueElement.update(channel.getValue());

		// Shows a message (only with error)
		if (this.channel.getFilter().getlastExecError() != null) {
			LayoutManagerFactory.getInstance().showMessageMenu(this.channel.getFilter().getlastExecError(), Constants.Logging.WARN_MSG);
			this.valueElement.nodeValue = gettext('undefined');
		}
	};

  // Sets the input
  Event.observe(paramInput, 'change', checkResult.bind(context));
  paramValueLayer.appendChild(paramInput);
  return paramValueLayer;
}

// This class represents the filter of the a channel
function Filter (id_, name_, label_, nature_, code_, category_, params_, helpText_) {
  this._id = id_;
  this._name = name_;
  this._label = label_;
  this._nature = nature_;
  this._params = new Array();
  this._lastExecError = null;
  this._category = category_;
  this._helpText = helpText_;

  // Sets the filter parameters
  this.processParams (params_);

  // Sets the filter code
  try{
  	 eval ('this._code = ' + code_);

  	 if ((typeof this._code) != 'function')
  		this._code = null;

  }catch(e){
  	this._code = null;

	var msg = interpolate(gettext("Error loading code of the filter '%(filterName)s'."), {filterName: this._label}, true);
	LogManagerFactory.getInstance().log(msg, Constants.ERROR_MSG);
  }
}

Filter.prototype.getNature = function() {
  return this._nature;
}

Filter.prototype.getId = function() {
  return this._id;
}

Filter.prototype.getName = function() {
  return this._name;
}

Filter.prototype.getLabel = function() {
  return this._label;
}

Filter.prototype.getParams = function() {
  return this._params;
}

Filter.prototype.getlastExecError = function() {
  return this._lastExecError;
}

Filter.prototype.setParam = function(param_) {
  this._params[param_.getIndex()] = param_;
}

Filter.prototype.hasParams = function() {
  return this._params.length != 0;
}

Filter.prototype.getCategory = function() {
  return this._category;
}

Filter.prototype.getHelpText = function() {
  return this._helpText;
}

Filter.prototype.processParams = function(params_) {
  this._params = new Array();
  if (params_ != null && params_ != ''){
  	var fParam, paramObject;
  	var jsonParams = params_.evalJSON();
  	for (var i = 0; i < jsonParams.length; i++) {
		fParam = jsonParams[i];
		if (fParam.type == 'jpath'){
			paramObject = new JPathParam (fParam.name, fParam.label, fParam.index, fParam.required, fParam.defaultValue);
		} else {
			paramObject = new Param(fParam.name, fParam.label, fParam.type, fParam.index, fParam.required, fParam.defaultValue);
		}
		this.setParam(paramObject);
  	}
  }
}

Filter.prototype.getInitialValues = function() {
	var params = [];

  	for (var i = 0; i < this._params.length; i++) {
  		params.push({'index': this._params[i]._index, 'value': this._params[i]._defaultValue})
  	}

  	return params;
}

Filter.prototype.fillFilterParamValues = function(filterParams, valueElement) {
	var paramLayers = valueElement.childElements();

	for (var i = 0; i < paramLayers.length; i++) {
		var paramInput = paramLayers[i].childElements()[0];

		if(filterParams[i]['value'])
			paramInput.value = filterParams[i]['value'];
		else
			paramInput.value = null;
	}
}

Filter.prototype.run = function(channelValue_, paramValues_, channel) {
	var i, msg, params = {};

	// Begins to run, no errors
	this._lastExecError = null;

//	// Creates the varible for the channel value
//	eval ("var channelValue = '" + channelValue_ + "';");

	try{
		// Creates the variables for other params
		for (i=0; i < this._params.length; ++i){

			var paramValue = paramValues_[i]['value'];

			if(!paramValue){
				if(this._params[i].getRequired()){
					msg = interpolate(gettext("Look out! '%(paramName)s' of '%(filterName)s' is required"),
						{paramName: this._params[i].getLabel(), filterName: this._label}, true);
					this._lastExecError = msg;
					return gettext('undefined');

				}else{
					params [this._params[i].getName()] = null;
					continue;
				}
			}

			// Checks the type of parameter
			switch (this._params[i].getType()){
			case 'N': // Param is Number
				var interger_value = parseInt(paramValue);

				if (isNaN(interger_value)){
					msg = interpolate(gettext("Error loading parameter '%(paramName)s' of the filter '%(filterName)s'. It must be a number"),
						{paramName: this._params[i].getLabel(), filterName: this._label}, true);
					LogManagerFactory.getInstance().log(msg, Constants.ERROR_MSG);
					this._lastExecError = msg;
					return gettext('undefined');
				}
				params[this._params[i].getName()] = paramValue;
				break;
			case 'regexp': // Param is RegExp
				if ((paramValue.indexOf('/') == 0) && (paramValue.lastIndexOf('/') > 0)){
					var current_pattern = paramValue.substring(1, paramValue.lastIndexOf('/'));
					var current_modifiers = paramValue.substring(paramValue.lastIndexOf('/') + 1, paramValue.length);
					params[this._params[i].getName()] = new RegExp(current_pattern, current_modifiers);
				}else {
					params[this._params[i].getName()] = new RegExp (paramValue);
				}
				break;
			case 'jpath': // Param is a JPATH expresion (for JSON)
				var jpath_exp = this._params[i].parse(paramValue);
				params[this._params[i].getName()] = this._params[i].parse(paramValue);
				break;
			default: // Otherwise is String
				params[this._params[i].getName()] = paramValue.replace(/"/g,"'");
				break;
			}

		}
	}catch(e){
		msg = interpolate(gettext("Error loading param '%(paramName)s' of the filter '%(filterName)s': %(error)s."),
			{paramName: this._params[i].getLabel(), filterName: this._label, error: e}, true);
		LogManagerFactory.getInstance().log(msg, Constants.ERROR_MSG);
		this._lastExecError = msg;
		return gettext('undefined');
	}

	try{

		// Executes the filter code
		return this._code(channelValue_, channel, params);

	}catch(err){
		if(err.name == "DONT_PROPAGATE"){
			throw new DontPropagateException(err)
		}
		else{
			var msg = interpolate(gettext("Error executing code of the filter '%(filterName)s'."), {filterName: this._Label}, true);
			LogManagerFactory.getInstance().log(msg, Constants.ERROR_MSG);
			// Saves the message (for wiring interface)
			if (this._params.length == 0){
				this._lastExecError = msg;
			}else{
				this._lastExecError = interpolate(gettext("Error executing code of the filter '%(filterName)s'. Check the parametres."), {filterName: this._label}, true);
			}
			return gettext('undefined');
		}
	}

}<commit_msg>refs #438. Fixed problem on callback function when checking filter params<commit_after>/*
*     (C) Copyright 2008 Telefonica Investigacion y Desarrollo
*     S.A.Unipersonal (Telefonica I+D)
*
*     This file is part of Morfeo EzWeb Platform.
*
*     Morfeo EzWeb Platform 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, or
*     (at your option) any later version.
*
*     Morfeo EzWeb Platform 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 Affero General Public License for more details.
*
*     You should have received a copy of the GNU Affero General Public License
*     along with Morfeo EzWeb Platform.  If not, see <http://www.gnu.org/licenses/>.
*
*     Info about members and contributors of the MORFEO project
*     is available at
*
*     http://morfeo-project.org
 */

// This class represents the parameter that a filter can have
function Param (name_, label_, type_, index_, required_, defaultValue_){
  this._name = name_;
  this._label = label_;
  this._type = type_;
  this._index = index_;
  this._required = required_;
  this._defaultValue = defaultValue_;
}

Param.prototype.Param = function (name_, label_, type_, index_, required_, defaultValue_){
  this._name = name_;
  this._label = label_;
  this._type = type_;
  this._index = index_;
  this._required = required_;
  this._defaultValue = defaultValue_;
}

Param.prototype.getName = function() {
  return this._name;
}

Param.prototype.getType = function() {
  return this._type;
}

Param.prototype.getLabel = function() {
  return this._label;
}

Param.prototype.getIndex = function() {
  return this._index;
}

Param.prototype.getRequired = function() {
  return this._required;
}

Param.prototype.getDefaultValue = function() {
  return this._defaultValue;
}

Param.prototype.createHtmlLabel = function() {
  var labelLayer = document.createElement("div");
  Element.extend(labelLayer);
  labelLayer.addClassName('paramName');
  var img = document.createElement("img");
  img.setAttribute("src", _currentTheme.getIconURL('wiring-filter_param'));
  labelLayer.appendChild(img);
  var labelElement = document.createElement("label");
  labelElement.innerHTML = this._label + ':';
  labelLayer.appendChild(labelElement);

  return labelLayer;
}

Param.prototype.createHtmlValue = function(wiringGUI, channel, valueElement){
	var context = {wiringGUI:wiringGUI, channel:channel, filter:channel.getFilter(), param:this, valueElement:valueElement};

	var paramValueLayer = document.createElement("div");
	Element.extend(paramValueLayer);
	var paramInput = document.createElement("input");
	Element.extend(paramInput);
	paramInput.addClassName("paramValueInput");
	paramInput.setAttribute ("value", channel.getFilterParams()[this._index]['value']);
	Event.observe(paramInput, 'click',function(e){Event.stop(e);});

	var checkResult = function(e) {
		var msg;
		var target = BrowserUtilsFactory.getInstance().getTarget(e);

		// Sets the param value
		this.channel.setFilterParam(this.param._index, target.value);

		// Sets the channel value
		this.valueElement.update(channel.getValue());

		// Shows a message (only with error)
		if (this.channel.getFilter().getlastExecError() != null) {
			LayoutManagerFactory.getInstance().showMessageMenu(this.channel.getFilter().getlastExecError(), Constants.Logging.WARN_MSG);
			this.valueElement.nodeValue = gettext('undefined');
		}
	};

  // Sets the input
  Event.observe(paramInput, 'change', checkResult.bind(context));
  paramValueLayer.appendChild(paramInput);
  return paramValueLayer;
}

// This class represents the filter of the a channel
function Filter (id_, name_, label_, nature_, code_, category_, params_, helpText_) {
  this._id = id_;
  this._name = name_;
  this._label = label_;
  this._nature = nature_;
  this._params = new Array();
  this._lastExecError = null;
  this._category = category_;
  this._helpText = helpText_;

  // Sets the filter parameters
  this.processParams (params_);

  // Sets the filter code
  try{
  	 eval ('this._code = ' + code_);

  	 if ((typeof this._code) != 'function')
  		this._code = null;

  }catch(e){
  	this._code = null;

	var msg = interpolate(gettext("Error loading code of the filter '%(filterName)s'."), {filterName: this._label}, true);
	LogManagerFactory.getInstance().log(msg, Constants.ERROR_MSG);
  }
}

Filter.prototype.getNature = function() {
  return this._nature;
}

Filter.prototype.getId = function() {
  return this._id;
}

Filter.prototype.getName = function() {
  return this._name;
}

Filter.prototype.getLabel = function() {
  return this._label;
}

Filter.prototype.getParams = function() {
  return this._params;
}

Filter.prototype.getlastExecError = function() {
  return this._lastExecError;
}

Filter.prototype.setParam = function(param_) {
  this._params[param_.getIndex()] = param_;
}

Filter.prototype.hasParams = function() {
  return this._params.length != 0;
}

Filter.prototype.getCategory = function() {
  return this._category;
}

Filter.prototype.getHelpText = function() {
  return this._helpText;
}

Filter.prototype.processParams = function(params_) {
  this._params = new Array();
  if (params_ != null && params_ != ''){
  	var fParam, paramObject;
  	var jsonParams = params_.evalJSON();
  	for (var i = 0; i < jsonParams.length; i++) {
		fParam = jsonParams[i];
		if (fParam.type == 'jpath'){
			paramObject = new JPathParam (fParam.name, fParam.label, fParam.index, fParam.required, fParam.defaultValue);
		} else {
			paramObject = new Param(fParam.name, fParam.label, fParam.type, fParam.index, fParam.required, fParam.defaultValue);
		}
		this.setParam(paramObject);
  	}
  }
}

Filter.prototype.getInitialValues = function() {
	var params = [];

  	for (var i = 0; i < this._params.length; i++) {
  		params.push({'index': this._params[i]._index, 'value': this._params[i]._defaultValue})
  	}

  	return params;
}

Filter.prototype.fillFilterParamValues = function(filterParams, valueElement) {
	var paramLayers = valueElement.childElements();

	for (var i = 0; i < paramLayers.length; i++) {
		var paramInput = paramLayers[i].childElements()[0];

		if(filterParams[i]['value'])
			paramInput.value = filterParams[i]['value'];
		else
			paramInput.value = null;
	}
}

Filter.prototype.run = function(channelValue_, paramValues_, channel) {
	var i, msg, params = {};

	// Begins to run, no errors
	this._lastExecError = null;

//	// Creates the varible for the channel value
//	eval ("var channelValue = '" + channelValue_ + "';");

	try{
		// Creates the variables for other params
		for (i=0; i < this._params.length; ++i){

			var paramValue = paramValues_[i]['value'];

			if(!paramValue){
				if(this._params[i].getRequired()){
					msg = interpolate(gettext("Look out! '%(paramName)s' of '%(filterName)s' is required"),
						{paramName: this._params[i].getLabel(), filterName: this._label}, true);
					this._lastExecError = msg;
					return gettext('undefined');

				}else{
					params [this._params[i].getName()] = null;
					continue;
				}
			}

			// Checks the type of parameter
			switch (this._params[i].getType()){
			case 'N': // Param is Number
				var interger_value = parseInt(paramValue);

				if (isNaN(interger_value)){
					msg = interpolate(gettext("Error loading parameter '%(paramName)s' of the filter '%(filterName)s'. It must be a number"),
						{paramName: this._params[i].getLabel(), filterName: this._label}, true);
					LogManagerFactory.getInstance().log(msg, Constants.ERROR_MSG);
					this._lastExecError = msg;
					return gettext('undefined');
				}
				params[this._params[i].getName()] = paramValue;
				break;
			case 'regexp': // Param is RegExp
				if ((paramValue.indexOf('/') == 0) && (paramValue.lastIndexOf('/') > 0)){
					var current_pattern = paramValue.substring(1, paramValue.lastIndexOf('/'));
					var current_modifiers = paramValue.substring(paramValue.lastIndexOf('/') + 1, paramValue.length);
					params[this._params[i].getName()] = new RegExp(current_pattern, current_modifiers);
				}else {
					params[this._params[i].getName()] = new RegExp (paramValue);
				}
				break;
			case 'jpath': // Param is a JPATH expresion (for JSON)
				var jpath_exp = this._params[i].parse(paramValue);
				params[this._params[i].getName()] = this._params[i].parse(paramValue);
				break;
			default: // Otherwise is String
				params[this._params[i].getName()] = paramValue.replace(/"/g,"'");
				break;
			}

		}
	}catch(e){
		msg = interpolate(gettext("Error loading param '%(paramName)s' of the filter '%(filterName)s': %(error)s."),
			{paramName: this._params[i].getLabel(), filterName: this._label, error: e}, true);
		LogManagerFactory.getInstance().log(msg, Constants.ERROR_MSG);
		this._lastExecError = msg;
		return gettext('undefined');
	}

	try{

		// Executes the filter code
		return this._code(channelValue_, channel, params);

	}catch(err){
		if(err.name == "DONT_PROPAGATE"){
			throw new DontPropagateException(err)
		}
		else{
			var msg = interpolate(gettext("Error executing code of the filter '%(filterName)s'."), {filterName: this._Label}, true);
			LogManagerFactory.getInstance().log(msg, Constants.ERROR_MSG);
			// Saves the message (for wiring interface)
			if (this._params.length == 0){
				this._lastExecError = msg;
			}else{
				this._lastExecError = interpolate(gettext("Error executing code of the filter '%(filterName)s'. Check the parametres."), {filterName: this._label}, true);
			}
			return gettext('undefined');
		}
	}

}<|endoftext|>


<commit_before>var Fighters = {
    TheDoctor: 'thedoctor'
};

var FighterEntity = Entity.extend({
    isPlayer: true,
    isFighter: true,

    fighterType: null,

    xMargin: 0,
    yMargin: 0,

    playerNumber: 0,

    isAttacking: false,

    init: function () {
        this._super();

        this.posX = 170;
        this.posY = 100;

        this.xMargin = 0;
        this.yMargin = 0;

        this.playerNumber = 0;
        this.isAttacking = false;
    },

    configureRenderer: function () {
        this.renderer = new FighterRenderer(this);
    },

    projectRect: function (x, y) {
        var r = this._super(x, y);

        r.top += this.yMargin;
        r.height -= this.yMargin;

        r.left += this.xMargin;
        r.width -= this.xMargin * 2;

        r.right = r.left + r.width;
        r.bottom = r.top + r.height;
        return r;
    },

    isLocalPlayer: function () {
        return (Game.stage.player === this);
    },

    prepareSyncMessage: function () {
        return {
            op: Opcode.PLAYER_UPDATE,
            p: this.playerNumber,
            x: this.posX,
            y: this.posY,
            vX: this.velocityX,
            vY: this.velocityY,
            a: this.isAttacking,
            aW: this.attackingWith != null ? this.attackingWith.id : null
        };
    },

    applySyncMessage: function (data) {
        this.posX = data.x;
        this.posY = data.y;
        this.velocityX = data.vX;
        this.velocityY = data.vY;
        this.isAttacking = data.a;

        if (data.aW != null) {
            if (this.attackingWith == null || this.attackingWith.id != data.aW) {
                this.attackingWith = Game.stage.getEntityById(data.aW);
            }
        } else {
            this.attackingWith = null;
        }
    },

    pickUp: function (entity) {
        this.isAttacking = true;
        this.attackingWith = entity;
    },

    update: function () {
        this._super();

        if (this.isAttacking && this.attackingWith != null) {
            this.attackingWith.posX = this.posX;
            this.attackingWith.posY = this.posY - (this.attackingWith.height / 2);

            this.attackingWith.causesCollision = false;
            this.attackingWith.causesTouchDamage = false;
            this.attackingWith.receivesCollision = false;
            this.attackingWith.affectedByGravity = false;
        }
    }
});<commit_msg>[Game] You can now jump on top of other player's blocks to steal 'em away :D<commit_after>var Fighters = {
    TheDoctor: 'thedoctor'
};

var FighterEntity = Entity.extend({
    isPlayer: true,
    isFighter: true,

    fighterType: null,

    xMargin: 0,
    yMargin: 0,

    playerNumber: 0,

    isAttacking: false,

    init: function () {
        this._super();

        this.posX = 170;
        this.posY = 100;

        this.xMargin = 0;
        this.yMargin = 0;

        this.playerNumber = 0;
        this.isAttacking = false;
    },

    configureRenderer: function () {
        this.renderer = new FighterRenderer(this);
    },

    projectRect: function (x, y) {
        var r = this._super(x, y);

        r.top += this.yMargin;
        r.height -= this.yMargin;

        r.left += this.xMargin;
        r.width -= this.xMargin * 2;

        r.right = r.left + r.width;
        r.bottom = r.top + r.height;
        return r;
    },

    isLocalPlayer: function () {
        return (Game.stage.player === this);
    },

    prepareSyncMessage: function () {
        return {
            op: Opcode.PLAYER_UPDATE,
            p: this.playerNumber,
            x: this.posX,
            y: this.posY,
            vX: this.velocityX,
            vY: this.velocityY,
            a: this.isAttacking,
            aW: this.attackingWith != null ? this.attackingWith.id : null
        };
    },

    applySyncMessage: function (data) {
        this.posX = data.x;
        this.posY = data.y;
        this.velocityX = data.vX;
        this.velocityY = data.vY;
        this.isAttacking = data.a;

        if (data.aW != null) {
            if (this.attackingWith == null || this.attackingWith.id != data.aW) {
                this.attackingWith = Game.stage.getEntityById(data.aW);
            }
        } else {
            this.attackingWith = null;
        }
    },

    pickUp: function (entity) {
        this.isAttacking = true;
        this.attackingWith = entity;
    },

    update: function () {
        this._super();

        if (this.isAttacking && this.attackingWith != null) {
            this.attackingWith.posX = this.posX;
            this.attackingWith.posY = this.posY - (this.attackingWith.height / 2);

            this.attackingWith.causesCollision = true;
            this.attackingWith.causesTouchDamage = false;
            this.attackingWith.receivesCollision = false;
            this.attackingWith.affectedByGravity = false;
        }
    }
});<|endoftext|>


<commit_before>/*
	Copyright (C) 2018 Claude SIMON (http://q37.info/contact/).

	This file is part of XDHq.

	XDHq 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, or (at your option) any later version.

	XDHq 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
	Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with XDHq. If not, see <http://www.gnu.org/licenses/>.
*/

"use strict"

var pAddr = "atlastk.org";
var pPort = 53800;
var wAddr = "";
var wPort = "";
var cgi = "xdh";

function getEnv(name, value) {
	let env = process.env[name];

	if (env)
		return env.trim();
	else if (value)
		return value.trim();
	else
		return "";
}

switch (getEnv("ATK") ) {
case 'DEV':
	pAddr = "localhost";
	wPort = "8080";
	console.log( "\tDEV mode !")
	break;
case 'TEST':
	cgi = "xdh_";
	console.log("\tTEST mode !")
	break;
case '':
	break;
default:
	throw "Bad 'ATK' environment variable value : should be 'DEV' or 'TEST' !";
	break;
}

pAddr = getEnv("ATK_PADDR", pAddr);
pPort = parseInt(getEnv("ATK_PPORT", pPort.toString()));
wAddr = getEnv("ATK_WADDR", wAddr);
wPort = getEnv("ATK_WPORT", wPort);

if (wAddr == "")
	wAddr = pAddr;

if (wPort != "")
	wPort = ":" + wPort;

const shared = require('./XDHqSHRD.js');
const net = require('net');

const types = shared.types;
const open = shared.open;

const mainProtocolLabel = "6e010737-31d8-4be3-9195-c5b5b2a9d5d9";
const mainProtocolVersion = "0";

function byteLength(str) {
	// returns the byte length of an utf8 string
	var s = str.length;
	for (var i = str.length - 1; i >= 0; i--) {
		var code = str.charCodeAt(i);
		if (code > 0x7f && code <= 0x7ff) s++;
		else if (code > 0x7ff && code <= 0xffff) s += 2;
		if (code >= 0xDC00 && code <= 0xDFFF) i--; //trail surrogate
	}
	return s;
}

function getSize(query, offset) {
	var byte = query[offset++];
	var size = byte & 0x7f;

	while (byte & 0x80) {
		byte = query[offset++];

		size = (size << 7) + (byte & 0x7f);
	}

	return [size, offset];
}

function getString(query, offset) {
	var size = 0;
	[size, offset] = getSize(query, offset);

	return [query.toString("utf-8", offset, offset + size), offset + size];
}

function getStrings(query, offset) {
	var size = 0;
	var strings = new Array();
	var string = "";

	[size, offset] = getSize(query, offset);

	while (size--) {
		[string, offset] = getString(query, offset);
		strings.push(string);
	}

	return [strings, offset];
}

function convertSize(size) {
	var result = Buffer.alloc(1, size & 0x7f);
	size >>= 7;

	while (size != 0) {
		result = Buffer.concat([Buffer.alloc(1, (size & 0x7f) | 0x80), result]);
		size >>= 7;
	}

	return result;
}

function addString(data, string) {
	return Buffer.concat([data, convertSize(byteLength(string)), Buffer.from(string, 'utf8')]);
}

function addStrings(data, strings) {
	var i = 0;
	data = Buffer.concat([data, convertSize(strings.length)]);

	while (i < strings.length)
		data = addString(data, strings[i++]);

	return data;
}

function handleString(string) {
	var data = new Buffer(0);

	data = addString(data, string);

	return data;
}

function getQuery(socket) {
	var buffer;
	var query = Buffer.alloc(0);

	while (buffer = socket.read())
		query = Buffer.concat([query, buffer]);

	return query;
}

function getId(query) {
	return getString(query, 0)[0];
}

function getAction(query) {
	return getString(query, getSize(query, 0)[0] + 1)[0];
}

function getResponse(query, type) {
	switch (type) {
		case types.UNDEFINED:
			throw "This function should not be called with UNDEFINED type !!!";
			break;
		case types.VOID:
			throw "The VOID type should be handled upstream !!!";
			break;
		case types.STRING:
			return getString(query, 0)[0];
			break;
		case types.STRINGS:
			return getStrings(query, 0)[0];
			break;
		default:
			throw "Unknown response type !!!";
			break;
	}
}

function getToken() {
	return getEnv("ATK_TOKEN");
}

var token = getToken();

if (token !== "" )
	token = "&" + token;

function standBy(socket) {
	socket.write(Buffer.from("StandBy_1\x00"));
}

function isTokenEmpty() {
	return ( token == "" ) || ( token.charAt( 0 ) == '&' );
}

function serve(client, createCallback, callbacks) {

}

function handshake(client, createCallback, callbacks) {
	let offset = 0;
	let query = getQuery(client);

	[token, offset] = getString(query, offset);

	if (isTokenEmpty())
		throw getString(query, offset)[0];	// Display error message.

	if (wPort != ":0") {
		let completeURL = "http://" + wAddr + wPort + "/" + cgi + ".php?_token=" + token;

		console.log(completeURL);
		console.log(new Array(completeURL.length + 1).join('^'))
		console.log("Open above URL in a web browser. Enjoy!");

		open(completeURL);
	}

	client.on('readable', () => serve(client, createCallback, callbacks));
}

function handshake(client, createCallback, callbacks, head) {
	let offset = 0;
	let error = "";
	let notification = "";
	let query = getQuery(client);

	[error, offset] = getString(query, offset);

	if (error != "")
		throw error;

	[notification, offset] = getString(query, offset);

	if (notification != "")
		console.log(notification);

	client.write(handleString(token));

	if (head === undefined)
		head = "";

	client.write(handleString(head));
}

function pseudoServer(createCallback, callbacks, head) {
	var client = new net.Socket();

	client.connect(pPort, pAddr, () => {
		client.write(handleString(demoProtocolLabel));
		client.write(handleString(demoProtocolVersion));

		client.on('readable', () => handshake(client, createCallback, callbacks, head));
	});

	client.on('error', (err) => {
		throw "Unable to connect to '" + pAddr + ":" + pPort + "' !!!";
	});
}

function pseudoServer_(createCallback, callbacks, head) {
	var client = new net.Socket();

	client.connect(pPort, pAddr, () => {
		let relaunch = true;

		client.write(handleString(token));

		if ( isTokenEmpty() ) {
			if (head === undefined)
				head = "";
			client.write(handleString(head));
		}

		client.on('readable', () => {
			if (client._xdhDOM === undefined) {
				let offset = 0;
				let query = getQuery(client);

				if (isTokenEmpty()) {
					[token, offset] = getString(query, offset);

					if (isTokenEmpty())
						throw getString(query, offset)[0];

					if (wPort != ":0") {
						let completeURL = "http://" + wAddr + wPort + "/" + cgi + ".php?_token=" + token;

						console.log(completeURL);
						console.log(new Array(completeURL.length + 1).join('^'))
						console.log("Open above URL in a web browser. Enjoy!");

						open(completeURL);
					}
				} else {
					let returnedToken = "";

					[returnedToken, offset] = getString(query, offset);

					if (returnedToken == "")
						throw getString(query, offset)[0];

					if (returnedToken != token)
						throw "Unmatched token !!!";
				}

				client._xdhDOM = createCallback();
				client._xdhDOM._xdhSocket = client;
				client._xdhDOM._xdhIsDEMO = true;
				client._xdhDOM._xdhType = types.UNDEFINED;
				client.write(addString(addString(Buffer.from(""), mainProtocolLabel), mainProtocolVersion));
			} else if (relaunch) {
				let query = ""
				let offset = 0;
				let errorMessage = "";
				let notification = "";

				pseudoServer(createCallback, callbacks);	// Useless to give 'head', as it will no more be used.

				query = getQuery(client);

				[errorMessage, offset] = getString(query, offset);

				if (errorMessage != "")
					throw (errorMessage);

				[notification, offset] = getString(query, offset);

				if (notification != "")
					console.log(notification);

				getString(query, offset);	// Language.

				client.write(handleString("NJS"));

				relaunch = false;
			} else {
				let query;

				let cont = true;

				query = getQuery(client);

				if (client._xdhDOM._xdhType === types.UNDEFINED) {
					let id, action;

					id = getId(query);
					action = getAction(query);

					callbacks[action](client._xdhDOM, id);

					if (client._xdhDOM._xdhType === types.UNDEFINED) {
						cont = false;
						standBy(client);
					}  else
						cont = client._xdhDOM._xdhType === types.VOID;
				}

				while (cont) {
					if (client._xdhDOM._xdhCallback != undefined) {
						let type = client._xdhDOM._xdhType;
						client._xdhDOM._xdhType = types.UNDEFINED;
						if (type === types.VOID)
							client._xdhDOM._xdhCallback();
						else
							client._xdhDOM._xdhCallback(getResponse(query, type));
						if (client._xdhDOM._xdhType === types.UNDEFINED) {
							cont = false;
							standBy(client);
						} else if (client._xdhDOM._xdhType !== types.VOID)
							cont = false;
					} else {
						if (client._xdhDOM._xdhType !== types.VOID)
							getResponse(query, client._xdhDOM._xdhType);
						client._xdhDOM._xdhType = types.UNDEFINED;
						cont = false;
						standBy(client);
					}
				}
			}
		});
	});
	client.on('error', (err) => {
		throw "Unable to connect to '" + pAddr + ":" + pPort + "' !!!";
	});
}

function launch(createCallback, callbacks, head) {
	if (process.env.EPEIOS_SRC) {
		console.log("DEMO mode !");
	}

	setTimeout(() => pseudoServer(createCallback, callbacks, head), 1000);

}

function add(data, argument) {
	if (typeof (argument) === "string")
		return addString(data, argument);
	else if (typeof (argument) === "object")
		return addStrings(data, argument);
	else
		throw "Unexpected argument type: " + typeof (argument);
}

function call(dom, command, type) {
	var i = 3;
	var data = Buffer.from(command + '\x00');
	var amount = arguments[i++];

	dom._xdhType = type;

	while (amount--)
		data = add(data, arguments[i++]);

	amount = arguments[i++];

	while (amount--)
		data = add(data, arguments[i++]);

	dom._xdhCallback = arguments[i++];

	dom._xdhSocket.write(data);
}

module.exports.launch = launch;
module.exports.call = call;
<commit_msg>29/01/2019 19:47:29<commit_after>/*
	Copyright (C) 2018 Claude SIMON (http://q37.info/contact/).

	This file is part of XDHq.

	XDHq 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, or (at your option) any later version.

	XDHq 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
	Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with XDHq. If not, see <http://www.gnu.org/licenses/>.
*/

"use strict"

var pAddr = "atlastk.org";
var pPort = 53800;
var wAddr = "";
var wPort = "";
var cgi = "xdh";

function getEnv(name, value) {
	let env = process.env[name];

	if (env)
		return env.trim();
	else if (value)
		return value.trim();
	else
		return "";
}

switch (getEnv("ATK") ) {
case 'DEV':
	pAddr = "localhost";
	wPort = "8080";
	console.log( "\tDEV mode !")
	break;
case 'TEST':
	cgi = "xdh_";
	console.log("\tTEST mode !")
	break;
case '':
	break;
default:
	throw "Bad 'ATK' environment variable value : should be 'DEV' or 'TEST' !";
	break;
}

pAddr = getEnv("ATK_PADDR", pAddr);
pPort = parseInt(getEnv("ATK_PPORT", pPort.toString()));
wAddr = getEnv("ATK_WADDR", wAddr);
wPort = getEnv("ATK_WPORT", wPort);

if (wAddr == "")
	wAddr = pAddr;

if (wPort != "")
	wPort = ":" + wPort;

const shared = require('./XDHqSHRD.js');
const net = require('net');

const types = shared.types;
const open = shared.open;

const mainProtocolLabel = "6e010737-31d8-4be3-9195-c5b5b2a9d5d9";
const mainProtocolVersion = "0";

function byteLength(str) {
	// returns the byte length of an utf8 string
	var s = str.length;
	for (var i = str.length - 1; i >= 0; i--) {
		var code = str.charCodeAt(i);
		if (code > 0x7f && code <= 0x7ff) s++;
		else if (code > 0x7ff && code <= 0xffff) s += 2;
		if (code >= 0xDC00 && code <= 0xDFFF) i--; //trail surrogate
	}
	return s;
}

function getSize(query, offset) {
	var byte = query[offset++];
	var size = byte & 0x7f;

	while (byte & 0x80) {
		byte = query[offset++];

		size = (size << 7) + (byte & 0x7f);
	}

	return [size, offset];
}

function getString(query, offset) {
	var size = 0;
	[size, offset] = getSize(query, offset);

	return [query.toString("utf-8", offset, offset + size), offset + size];
}

function getStrings(query, offset) {
	var size = 0;
	var strings = new Array();
	var string = "";

	[size, offset] = getSize(query, offset);

	while (size--) {
		[string, offset] = getString(query, offset);
		strings.push(string);
	}

	return [strings, offset];
}

function convertSize(size) {
	var result = Buffer.alloc(1, size & 0x7f);
	size >>= 7;

	while (size != 0) {
		result = Buffer.concat([Buffer.alloc(1, (size & 0x7f) | 0x80), result]);
		size >>= 7;
	}

	return result;
}

function addString(data, string) {
	return Buffer.concat([data, convertSize(byteLength(string)), Buffer.from(string, 'utf8')]);
}

function addStrings(data, strings) {
	var i = 0;
	data = Buffer.concat([data, convertSize(strings.length)]);

	while (i < strings.length)
		data = addString(data, strings[i++]);

	return data;
}

function handleString(string) {
	var data = new Buffer(0);

	data = addString(data, string);

	return data;
}

function getQuery(socket) {
	var buffer;
	var query = Buffer.alloc(0);

	while (buffer = socket.read())
		query = Buffer.concat([query, buffer]);

	return query;
}

function getId(query) {
	return getString(query, 0)[0];
}

function getAction(query) {
	return getString(query, getSize(query, 0)[0] + 1)[0];
}

function getResponse(query, type) {
	switch (type) {
		case types.UNDEFINED:
			throw "This function should not be called with UNDEFINED type !!!";
			break;
		case types.VOID:
			throw "The VOID type should be handled upstream !!!";
			break;
		case types.STRING:
			return getString(query, 0)[0];
			break;
		case types.STRINGS:
			return getStrings(query, 0)[0];
			break;
		default:
			throw "Unknown response type !!!";
			break;
	}
}

function getToken() {
	return getEnv("ATK_TOKEN");
}

var token = getToken();

if (token !== "" )
	token = "&" + token;

function standBy(socket) {
	socket.write(Buffer.from("StandBy_1\x00"));
}

function isTokenEmpty() {
	return ( token == "" ) || ( token.charAt( 0 ) == '&' );
}

function serve(client, createCallback, callbacks) {

}

function handshake(client, createCallback, callbacks) {
	let offset = 0;
	let query = getQuery(client);

	[token, offset] = getString(query, offset);

	if (isTokenEmpty())
		throw getString(query, offset)[0];	// Displays error message.

	if (wPort != ":0") {
		let completeURL = "http://" + wAddr + wPort + "/" + cgi + ".php?_token=" + token;

		console.log(completeURL);
		console.log(new Array(completeURL.length + 1).join('^'))
		console.log("Open above URL in a web browser. Enjoy!");

		open(completeURL);
	}

	client.on('readable', () => serve(client, createCallback, callbacks));
}

function handshake(client, createCallback, callbacks, head) {
	let offset = 0;
	let error = "";
	let notification = "";
	let query = getQuery(client);

	[error, offset] = getString(query, offset);

	if (error != "")
		throw error;

	[notification, offset] = getString(query, offset);

	if (notification != "")
		console.log(notification);

	client.write(handleString(token));

	if (head === undefined)
		head = "";

	client.write(handleString(head));

	client.on('readable', () => ignition(client, createCallback, callbacks));
}

function pseudoServer(createCallback, callbacks, head) {
	var client = new net.Socket();

	client.connect(pPort, pAddr, () => {
		client.write(handleString(demoProtocolLabel));
		client.write(handleString(demoProtocolVersion));

		client.on('readable', () => handshake(client, createCallback, callbacks, head));
	});

	client.on('error', (err) => {
		throw "Unable to connect to '" + pAddr + ":" + pPort + "' !!!";
	});
}

function pseudoServer_(createCallback, callbacks, head) {
	var client = new net.Socket();

	client.connect(pPort, pAddr, () => {
		let relaunch = true;

		client.write(handleString(token));

		if ( isTokenEmpty() ) {
			if (head === undefined)
				head = "";
			client.write(handleString(head));
		}

		client.on('readable', () => {
			if (client._xdhDOM === undefined) {
				let offset = 0;
				let query = getQuery(client);

				if (isTokenEmpty()) {
					[token, offset] = getString(query, offset);

					if (isTokenEmpty())
						throw getString(query, offset)[0];

					if (wPort != ":0") {
						let completeURL = "http://" + wAddr + wPort + "/" + cgi + ".php?_token=" + token;

						console.log(completeURL);
						console.log(new Array(completeURL.length + 1).join('^'))
						console.log("Open above URL in a web browser. Enjoy!");

						open(completeURL);
					}
				} else {
					let returnedToken = "";

					[returnedToken, offset] = getString(query, offset);

					if (returnedToken == "")
						throw getString(query, offset)[0];

					if (returnedToken != token)
						throw "Unmatched token !!!";
				}

				client._xdhDOM = createCallback();
				client._xdhDOM._xdhSocket = client;
				client._xdhDOM._xdhIsDEMO = true;
				client._xdhDOM._xdhType = types.UNDEFINED;
				client.write(addString(addString(Buffer.from(""), mainProtocolLabel), mainProtocolVersion));
			} else if (relaunch) {
				let query = ""
				let offset = 0;
				let errorMessage = "";
				let notification = "";

				pseudoServer(createCallback, callbacks);	// Useless to give 'head', as it will no more be used.

				query = getQuery(client);

				[errorMessage, offset] = getString(query, offset);

				if (errorMessage != "")
					throw (errorMessage);

				[notification, offset] = getString(query, offset);

				if (notification != "")
					console.log(notification);

				getString(query, offset);	// Language.

				client.write(handleString("NJS"));

				relaunch = false;
			} else {
				let query;

				let cont = true;

				query = getQuery(client);

				if (client._xdhDOM._xdhType === types.UNDEFINED) {
					let id, action;

					id = getId(query);
					action = getAction(query);

					callbacks[action](client._xdhDOM, id);

					if (client._xdhDOM._xdhType === types.UNDEFINED) {
						cont = false;
						standBy(client);
					}  else
						cont = client._xdhDOM._xdhType === types.VOID;
				}

				while (cont) {
					if (client._xdhDOM._xdhCallback != undefined) {
						let type = client._xdhDOM._xdhType;
						client._xdhDOM._xdhType = types.UNDEFINED;
						if (type === types.VOID)
							client._xdhDOM._xdhCallback();
						else
							client._xdhDOM._xdhCallback(getResponse(query, type));
						if (client._xdhDOM._xdhType === types.UNDEFINED) {
							cont = false;
							standBy(client);
						} else if (client._xdhDOM._xdhType !== types.VOID)
							cont = false;
					} else {
						if (client._xdhDOM._xdhType !== types.VOID)
							getResponse(query, client._xdhDOM._xdhType);
						client._xdhDOM._xdhType = types.UNDEFINED;
						cont = false;
						standBy(client);
					}
				}
			}
		});
	});
	client.on('error', (err) => {
		throw "Unable to connect to '" + pAddr + ":" + pPort + "' !!!";
	});
}

function launch(createCallback, callbacks, head) {
	if (process.env.EPEIOS_SRC) {
		console.log("DEMO mode !");
	}

	setTimeout(() => pseudoServer(createCallback, callbacks, head), 1000);

}

function add(data, argument) {
	if (typeof (argument) === "string")
		return addString(data, argument);
	else if (typeof (argument) === "object")
		return addStrings(data, argument);
	else
		throw "Unexpected argument type: " + typeof (argument);
}

function call(dom, command, type) {
	var i = 3;
	var data = Buffer.from(command + '\x00');
	var amount = arguments[i++];

	dom._xdhType = type;

	while (amount--)
		data = add(data, arguments[i++]);

	amount = arguments[i++];

	while (amount--)
		data = add(data, arguments[i++]);

	dom._xdhCallback = arguments[i++];

	dom._xdhSocket.write(data);
}

module.exports.launch = launch;
module.exports.call = call;
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var Grid = function(h, w) {
  return {
    _mines: [],

    width: w,
    height: h,

    addMine: function(r,c) {
      this._mines.push(r + ',' + c);
    },

    isMine: function(r,c) {
      return this._mines.indexOf(r + ',' + c) !== -1;
    }
  };
};

var createGridFromString = function(str) {
  var lines = str.split('\n');
  var hw = lines[0].split(' ');
  var height = hw[0] | 0;
  var width = hw[1] | 0;

  var grid = new Grid(hw[0]|0,hw[1]|0);

  for (var i=0;i<height;++i) {
    var row = lines[i+1];
    for (var j=0;j<width;++j) {
      var isMine = row[j] === '*';
      if (isMine) {
        grid.addMine(j,i);
      }
    }
  }

  return grid;
};

describe('minefield', function() {
  var sampleGrid = '3 4\n*...\n..*.\n....';

  describe('grid', function() {
    it('should be able to create a grid', function() {
      var grid = new Grid(5,6);

      assert.equal(grid.width, 6);
      assert.equal(grid.height,5);
    });

    it('should be able to create a grid of size from a string', function() {
      var grid = createGridFromString(sampleGrid);

      assert.equal(grid.width,4);
      assert.equal(grid.height,3);
    });

    it('reads in the correct values', function() {
      var grid = createGridFromString(sampleGrid);

      assert(grid.isMine(0,0));
      assert(grid.isMine(2,1));
      assert(!grid.isMine(0,1));
    });

    it('knows the surrounding number of mines', function() {
      var grid = createGridFromString(sampleGrid);

      assert.equal(0, grid.surroundingMines(0,2));
    });
  });
});
<commit_msg>simplest passing test<commit_after>"use strict";

var assert = require('assert');

var Grid = function(h, w) {
  return {
    _mines: [],

    width: w,
    height: h,

    addMine: function(r,c) {
      this._mines.push(r + ',' + c);
    },

    isMine: function(r,c) {
      return this._mines.indexOf(r + ',' + c) !== -1;
    },

    surroundingMines: function(r,c) {
      return 0;
    }
  };
};

var createGridFromString = function(str) {
  var lines = str.split('\n');
  var hw = lines[0].split(' ');
  var height = hw[0] | 0;
  var width = hw[1] | 0;

  var grid = new Grid(hw[0]|0,hw[1]|0);

  for (var i=0;i<height;++i) {
    var row = lines[i+1];
    for (var j=0;j<width;++j) {
      var isMine = row[j] === '*';
      if (isMine) {
        grid.addMine(j,i);
      }
    }
  }

  return grid;
};

describe('minefield', function() {
  var sampleGrid = '3 4\n*...\n..*.\n....';

  describe('grid', function() {
    it('should be able to create a grid', function() {
      var grid = new Grid(5,6);

      assert.equal(grid.width, 6);
      assert.equal(grid.height,5);
    });

    it('should be able to create a grid of size from a string', function() {
      var grid = createGridFromString(sampleGrid);

      assert.equal(grid.width,4);
      assert.equal(grid.height,3);
    });

    it('reads in the correct values', function() {
      var grid = createGridFromString(sampleGrid);

      assert(grid.isMine(0,0));
      assert(grid.isMine(2,1));
      assert(!grid.isMine(0,1));
    });

    it('knows the surrounding number of mines', function() {
      var grid = createGridFromString(sampleGrid);

      assert.equal(0, grid.surroundingMines(0,2));
    });
  });
});
<|endoftext|>


<commit_before>/*!
 * template.js v0.5.0 (https://github.com/yanhaijing/template.js)
 * API https://github.com/yanhaijing/template.js/blob/master/doc/api.md
 * Copyright 2015 yanhaijing. All Rights Reserved
 * Licensed under MIT (https://github.com/yanhaijing/template.js/blob/master/MIT-LICENSE.txt)
 */
;(function(root, factory) {
    var template = factory(root);
    if (typeof define === 'function' && define.amd) {
        // AMD
        define('template', function() {
            return template;
        });
    } else if (typeof exports === 'object') {
        // Node.js
        module.exports = template;
    } else {
        // Browser globals
        var _template = root.template;

        template.noConflict = function() {
            if (root.template === template) {
                root.template = _template;
            }

            return template;
        };
        root.template = template;
    }
}(this, function(root) {
    'use strict';
    var o = {
        sTag: '<%',//开始标签
        eTag: '%>',//结束标签
        compress: false,//是否压缩html
        escape: true, //默认输出是否进行HTML转义
        error: function (e) {}//错误回调
    };
    var toString = {}.toString;

    function getType(x) {
        if(x === null){
            return 'null';
        }

        var t= typeof x;

        if(t !== 'object'){
            return t;
        }

        var c = toString.call(x).slice(8, -1).toLowerCase();
        if(c !== 'object'){
            return c;
        }

        if(x.constructor==Object){
            return c;
        }

        return 'unkonw';
    }

    function isObject(obj) {
        return getType(obj) === 'object';
    }
    function extend() {
        var target = arguments[0] || {};
        var arrs = Array.prototype.slice.call(arguments, 1);
        var len = arrs.length;

        for (var i = 0; i < len; i++) {
            var arr = arrs[i];
            for (var name in arr) {
                target[name] = arr[name];
            }

        }
        return target;
    }
    function encodeHTML(source) {
        return String(source)
            .replace(/&/g,'&')
            .replace(/</g,'<')
            .replace(/>/g,'>')
            .replace(/\\/g,'\')
            .replace(/"/g,'"')
            .replace(/'/g,''');
    };
    function compress(html) {
        return html.replace(/\s+/g, ' ').replace(/<!--[\w\W]*?-->/g, '');
    }
    function handelError(e) {
        var message = 'template.js error\n\n';

        for (var key in e) {
            message += '<' + key + '>\n' + e[key] + '\n\n';
        }
        message += '<message>\n' + e.message + '\n\n';
        console && console.error && console.error(message);

        o.error(e);

        return function () {
            return 'template.js error';
        };
    }
    function parse(tpl, opt) {
        var code = '';
        var sTag = opt.sTag;
        var eTag = opt.eTag;
        var escape = opt.escape;
        function parsehtml(line) {
            // 单双引号转义，换行符替换为空格
            line = line.replace(/('|")/g, '\\$1').replace(/\n/g, ' ');
            return ';__code__ += ("' + line + '")\n';
        }
        function parsejs(line) {
            var html;
            if (line.search(/^=/) !== -1) {
                //默认输出
                html = line.slice(1);
                html = escape ? ('__encodeHTML__(typeof (' + html + ') === "undefined" ? "" : ' + html + ')') : html;
                return ';__code__ += (' + html + ')\n';
            }

            if (line.search(/^:h=/) !== -1) {
                //HTML转义输出
                html = line.slice(3);
                return ';__code__ += (__encodeHTML__(typeof (' + html + ') === "undefined" ? "" : ' + html + '))\n';
            }

            if (line.search(/^:=/) !== -1) {
                //不转义
                html = line.slice(2);
                return ';__code__ += (typeof (' + html + ') === "undefined" ? "" : ' + html + ')\n';
            }

            if (line.search(/^:u=/) !== -1) {
                //URL转义
                html = line.slice(3);
                return ';__code__ += (typeof (' + html + ') === "undefined" ? "" : encodeURI(' + html + '))\n';
            }

            //原生js
            return ';' + line + '\n';
        }

        var tokens = tpl.split(sTag);

        for (var i = 0, len = tokens.length; i < len; i++) {
            var token = tokens[i].split(eTag);

            if (token.length === 1) {
                code += parsehtml(token[0]);
            } else {
                code += parsejs(token[0], true);
                if (token[1]) {
                    code += parsehtml(token[1]);
                }
            }
        }

        return code;
    }
    function compiler(tpl, opt) {
        var mainCode = parse(tpl, opt);

        var headerCode = '\n' +
        '    var html = (function (__data__, __encodeHTML__) {\n' +
        '        var __str__ = "", __code__ = "";\n' +
        '        for(var key in __data__) {\n' +
        '            __str__+=("var " + key + "=__data__[\'" + key + "\'];");\n' +
        '        }\n' +
        '        eval(__str__);\n\n';

        var footerCode = '\n' +
        '        ;return __code__;\n' +
        '    }(__data__, __encodeHTML__));\n' +
        '    return html;\n';

        var code = headerCode + mainCode + footerCode;
        code = code.replace(/[\r]/g, ' '); // ie 7 8 会报错，不知道为什么
        try {
            var Render = new Function('__data__', '__encodeHTML__', code);
            Render.toString = function () {
                return mainCode;
            }
            return Render;
        } catch(e) {
            e.temp = 'function anonymous(__data__, __encodeHTML__) {' + code + '}';
            throw e;
        }
    }
    function compile(tpl, opt) {
        opt = extend({}, o, opt);

        try {
            var Render = compiler(tpl, opt);
        } catch(e) {
            e.name = 'CompileError';
            e.tpl = tpl;
            e.render = e.temp;
            delete e.temp;
            return handelError(e);
        }

        function render(data) {
            try {
                var html = Render(data, encodeHTML);
                html = opt.compress ? compress(html) : html;
                return html;
            } catch(e) {
                e.name = 'RenderError';
                e.tpl = tpl;
                e.render = Render.toString();
                return handelError(e);
            }
        }

        render.toString = function () {
            return Render.toString();
        };
        return render;
    }
    function template(tpl, data) {
        if (typeof tpl !== 'string') {
            return '';
        }

        var fn = compile(tpl);
        if (!isObject(data)) {
            return fn;
        }

        return fn(data);
    }

    template.config = function (option) {
        if (isObject(option)) {
            o = extend(o, option);
        }

        return extend({}, o);
    };

    template.__encodeHTML = encodeHTML;
    template.__compile = compile;
    template.version = '0.5.0';
    return template;
}));
<commit_msg>添加编译出错时的错误输出语句<commit_after>/*!
 * template.js v0.5.0 (https://github.com/yanhaijing/template.js)
 * API https://github.com/yanhaijing/template.js/blob/master/doc/api.md
 * Copyright 2015 yanhaijing. All Rights Reserved
 * Licensed under MIT (https://github.com/yanhaijing/template.js/blob/master/MIT-LICENSE.txt)
 */
;(function(root, factory) {
    var template = factory(root);
    if (typeof define === 'function' && define.amd) {
        // AMD
        define('template', function() {
            return template;
        });
    } else if (typeof exports === 'object') {
        // Node.js
        module.exports = template;
    } else {
        // Browser globals
        var _template = root.template;

        template.noConflict = function() {
            if (root.template === template) {
                root.template = _template;
            }

            return template;
        };
        root.template = template;
    }
}(this, function(root) {
    'use strict';
    var o = {
        sTag: '<%',//开始标签
        eTag: '%>',//结束标签
        compress: false,//是否压缩html
        escape: true, //默认输出是否进行HTML转义
        error: function (e) {}//错误回调
    };
    var toString = {}.toString;

    function getType(x) {
        if(x === null){
            return 'null';
        }

        var t= typeof x;

        if(t !== 'object'){
            return t;
        }

        var c = toString.call(x).slice(8, -1).toLowerCase();
        if(c !== 'object'){
            return c;
        }

        if(x.constructor==Object){
            return c;
        }

        return 'unkonw';
    }

    function isObject(obj) {
        return getType(obj) === 'object';
    }
    function extend() {
        var target = arguments[0] || {};
        var arrs = Array.prototype.slice.call(arguments, 1);
        var len = arrs.length;

        for (var i = 0; i < len; i++) {
            var arr = arrs[i];
            for (var name in arr) {
                target[name] = arr[name];
            }

        }
        return target;
    }
    function encodeHTML(source) {
        return String(source)
            .replace(/&/g,'&')
            .replace(/</g,'<')
            .replace(/>/g,'>')
            .replace(/\\/g,'\')
            .replace(/"/g,'"')
            .replace(/'/g,''');
    };
    function compress(html) {
        return html.replace(/\s+/g, ' ').replace(/<!--[\w\W]*?-->/g, '');
    }
    function handelError(e) {
        var message = 'template.js error\n\n';

        for (var key in e) {
            message += '<' + key + '>\n' + e[key] + '\n\n';
        }
        message += '<message>\n' + e.message + '\n\n';
        console && console.error && console.error(message);

        o.error(e);
        function error() {
            return 'template.js error';
        }
        error.toString = function () {
            return '__str__ = "template.js error"';
        }
        return error;
    }
    function parse(tpl, opt) {
        var code = '';
        var sTag = opt.sTag;
        var eTag = opt.eTag;
        var escape = opt.escape;
        function parsehtml(line) {
            // 单双引号转义，换行符替换为空格
            line = line.replace(/('|")/g, '\\$1').replace(/\n/g, ' ');
            return ';__code__ += ("' + line + '")\n';
        }
        function parsejs(line) {
            var html;
            if (line.search(/^=/) !== -1) {
                //默认输出
                html = line.slice(1);
                html = escape ? ('__encodeHTML__(typeof (' + html + ') === "undefined" ? "" : ' + html + ')') : html;
                return ';__code__ += (' + html + ')\n';
            }

            if (line.search(/^:h=/) !== -1) {
                //HTML转义输出
                html = line.slice(3);
                return ';__code__ += (__encodeHTML__(typeof (' + html + ') === "undefined" ? "" : ' + html + '))\n';
            }

            if (line.search(/^:=/) !== -1) {
                //不转义
                html = line.slice(2);
                return ';__code__ += (typeof (' + html + ') === "undefined" ? "" : ' + html + ')\n';
            }

            if (line.search(/^:u=/) !== -1) {
                //URL转义
                html = line.slice(3);
                return ';__code__ += (typeof (' + html + ') === "undefined" ? "" : encodeURI(' + html + '))\n';
            }

            //原生js
            return ';' + line + '\n';
        }

        var tokens = tpl.split(sTag);

        for (var i = 0, len = tokens.length; i < len; i++) {
            var token = tokens[i].split(eTag);

            if (token.length === 1) {
                code += parsehtml(token[0]);
            } else {
                code += parsejs(token[0], true);
                if (token[1]) {
                    code += parsehtml(token[1]);
                }
            }
        }

        return code;
    }
    function compiler(tpl, opt) {
        var mainCode = parse(tpl, opt);

        var headerCode = '\n' +
        '    var html = (function (__data__, __encodeHTML__) {\n' +
        '        var __str__ = "", __code__ = "";\n' +
        '        for(var key in __data__) {\n' +
        '            __str__+=("var " + key + "=__data__[\'" + key + "\'];");\n' +
        '        }\n' +
        '        eval(__str__);\n\n';

        var footerCode = '\n' +
        '        ;return __code__;\n' +
        '    }(__data__, __encodeHTML__));\n' +
        '    return html;\n';

        var code = headerCode + mainCode + footerCode;
        code = code.replace(/[\r]/g, ' '); // ie 7 8 会报错，不知道为什么
        try {
            var Render = new Function('__data__', '__encodeHTML__', code);
            Render.toString = function () {
                return mainCode;
            }
            return Render;
        } catch(e) {
            e.temp = 'function anonymous(__data__, __encodeHTML__) {' + code + '}';
            throw e;
        }
    }
    function compile(tpl, opt) {
        opt = extend({}, o, opt);

        try {
            var Render = compiler(tpl, opt);
        } catch(e) {
            e.name = 'CompileError';
            e.tpl = tpl;
            e.render = e.temp;
            delete e.temp;
            return handelError(e);
        }

        function render(data) {
            try {
                var html = Render(data, encodeHTML);
                html = opt.compress ? compress(html) : html;
                return html;
            } catch(e) {
                e.name = 'RenderError';
                e.tpl = tpl;
                e.render = Render.toString();
                return handelError(e);
            }
        }

        render.toString = function () {
            return Render.toString();
        };
        return render;
    }
    function template(tpl, data) {
        if (typeof tpl !== 'string') {
            return '';
        }

        var fn = compile(tpl);
        if (!isObject(data)) {
            return fn;
        }

        return fn(data);
    }

    template.config = function (option) {
        if (isObject(option)) {
            o = extend(o, option);
        }

        return extend({}, o);
    };

    template.__encodeHTML = encodeHTML;
    template.__compile = compile;
    template.version = '0.5.0';
    return template;
}));
<|endoftext|>


<commit_before>import $ from 'jquery';
import { addSelectOnFocusBehaviour } from '../lib/utils/common_utils';
import { slugifyWithHyphens } from '../lib/utils/text_utility';

let hasUserDefinedProjectPath = false;

const deriveProjectPathFromUrl = $projectImportUrl => {
  const $currentProjectPath = $projectImportUrl
    .parents('.toggle-import-form')
    .find('#project_path');
  if (hasUserDefinedProjectPath) {
    return;
  }

  let importUrl = $projectImportUrl.val().trim();
  if (importUrl.length === 0) {
    return;
  }

  /*
    \/?: remove trailing slash
    (\.git\/?)?: remove trailing .git (with optional trailing slash)
    (\?.*)?: remove query string
    (#.*)?: remove fragment identifier
  */
  importUrl = importUrl.replace(/\/?(\.git\/?)?(\?.*)?(#.*)?$/, '');

  // extract everything after the last slash
  const pathMatch = /\/([^/]+)$/.exec(importUrl);
  if (pathMatch) {
    $currentProjectPath.val(pathMatch[1]);
  }
};

const onProjectNameChange = ($projectNameInput, $projectPathInput) => {
  const slug = slugifyWithHyphens($projectNameInput.val());
  $projectPathInput.val(slug);
};

const bindEvents = () => {
  const $newProjectForm = $('#new_project');
  const $projectImportUrl = $('#project_import_url');
  const $projectPath = $('.tab-pane.active #project_path');
  const $useTemplateBtn = $('.template-button > input');
  const $projectFieldsForm = $('.project-fields-form');
  const $selectedTemplateText = $('.selected-template');
  const $changeTemplateBtn = $('.change-template');
  const $selectedIcon = $('.selected-icon');
  const $pushNewProjectTipTrigger = $('.push-new-project-tip');
  const $projectTemplateButtons = $('.project-templates-buttons');
  const $projectName = $('.tab-pane.active #project_name');

  if ($newProjectForm.length !== 1) {
    return;
  }

  $('.how_to_import_link').on('click', e => {
    e.preventDefault();
    $(e.currentTarget)
      .next('.modal')
      .show();
  });

  $('.modal-header .close').on('click', () => {
    $('.modal').hide();
  });

  $('.btn_import_gitlab_project').on('click', () => {
    const importHref = $('a.btn_import_gitlab_project').attr('href');
    $('.btn_import_gitlab_project').attr(
      'href',
      `${importHref}?namespace_id=${$(
        '#project_namespace_id',
      ).val()}&name=${$projectName.val()}&path=${$projectPath.val()}`,
    );
  });

  if ($pushNewProjectTipTrigger) {
    $pushNewProjectTipTrigger
      .removeAttr('rel')
      .removeAttr('target')
      .on('click', e => {
        e.preventDefault();
      })
      .popover({
        title: $pushNewProjectTipTrigger.data('title'),
        placement: 'bottom',
        html: true,
        content: $('.push-new-project-tip-template').html(),
      })
      .on('shown.bs.popover', () => {
        $(document).on('click.popover touchstart.popover', event => {
          if ($(event.target).closest('.popover').length === 0) {
            $pushNewProjectTipTrigger.trigger('click');
          }
        });

        const target = $(`#${$pushNewProjectTipTrigger.attr('aria-describedby')}`).find(
          '.js-select-on-focus',
        );
        addSelectOnFocusBehaviour(target);

        target.focus();
      })
      .on('hide.bs.popover', () => {
        $(document).off('click.popover touchstart.popover');
      });
  }

  function chooseTemplate() {
    $projectTemplateButtons.addClass('hidden');
    $projectFieldsForm.addClass('selected');
    $selectedIcon.empty();
    const value = $(this).val();
    const templates = {
      rails: {
        text: 'Ruby on Rails',
        icon: '.template-option .icon-rails',
      },
      express: {
        text: 'NodeJS Express',
        icon: '.template-option .icon-express',
      },
      spring: {
        text: 'Spring',
        icon: '.template-option .icon-spring',
      },
      iosswift: {
        text: 'iOS (Swift)',
        icon: '.template-option svg.icon-gitlab',
      },
      dotnetcore: {
        text: '.NET Core',
        icon: '.template-option .icon-dotnet',
      },
      android: {
        text: 'Android',
        icon: '.template-option svg.icon-android',
      },
      gomicro: {
        text: 'Go Micro',
        icon: '.template-option .icon-gomicro',
      },
      hugo: {
        text: 'Pages/Hugo',
        icon: '.template-option .icon-hugo',
      },
      jekyll: {
        text: 'Pages/Jekyll',
        icon: '.template-option .icon-jekyll',
      },
      plainhtml: {
        text: 'Pages/Plain HTML',
        icon: '.template-option .icon-plainhtml',
      },
      gitbook: {
        text: 'Pages/GitBook',
        icon: '.template-option .icon-gitbook',
      },
      hexo: {
        text: 'Pages/Hexo',
        icon: '.template-option .icon-hexo',
      },
      nfhugo: {
        text: 'Netlify/Hugo',
        icon: '.template-option .icon-netlify',
      },
      nfjekyll: {
        text: 'Netlify/Jekyll',
        icon: '.template-option .icon-netlify',
      },
      nfplainhtml: {
        text: 'Netlify/Plain HTML',
        icon: '.template-option .icon-netlify',
      },
      nfgitbook: {
        text: 'Netlify/GitBook',
        icon: '.template-option .icon-netlify',
      },
      nfhexo: {
        text: 'Netlify/Hexo',
        icon: '.template-option .icon-netlify',
      },
    };

    const selectedTemplate = templates[value];
    $selectedTemplateText.text(selectedTemplate.text);
    $(selectedTemplate.icon)
      .clone()
      .addClass('d-block')
      .appendTo($selectedIcon);

    const $activeTabProjectName = $('.tab-pane.active #project_name');
    const $activeTabProjectPath = $('.tab-pane.active #project_path');
    $activeTabProjectName.focus();
    $activeTabProjectName.keyup(() => {
      onProjectNameChange($activeTabProjectName, $activeTabProjectPath);
      hasUserDefinedProjectPath = $activeTabProjectPath.val().trim().length > 0;
    });
  }

  $useTemplateBtn.on('change', chooseTemplate);

  $changeTemplateBtn.on('click', () => {
    $projectTemplateButtons.removeClass('hidden');
    $projectFieldsForm.removeClass('selected');
    $useTemplateBtn.prop('checked', false);
  });

  $newProjectForm.on('submit', () => {
    $projectPath.val($projectPath.val().trim());
  });

  $projectPath.on('keyup', () => {
    hasUserDefinedProjectPath = $projectPath.val().trim().length > 0;
  });

  $projectImportUrl.keyup(() => deriveProjectPathFromUrl($projectImportUrl));

  $projectName.on('keyup change', () => {
    onProjectNameChange($projectName, $projectPath);
    hasUserDefinedProjectPath = $projectPath.val().trim().length > 0;
  });
};

export default {
  bindEvents,
  deriveProjectPathFromUrl,
  onProjectNameChange,
};
<commit_msg>Backport of "Resolves EE differences for project_new.js"<commit_after>import $ from 'jquery';
import { addSelectOnFocusBehaviour } from '../lib/utils/common_utils';
import { slugifyWithHyphens } from '../lib/utils/text_utility';

let hasUserDefinedProjectPath = false;

const deriveProjectPathFromUrl = $projectImportUrl => {
  const $currentProjectPath = $projectImportUrl
    .parents('.toggle-import-form')
    .find('#project_path');
  if (hasUserDefinedProjectPath) {
    return;
  }

  let importUrl = $projectImportUrl.val().trim();
  if (importUrl.length === 0) {
    return;
  }

  /*
    \/?: remove trailing slash
    (\.git\/?)?: remove trailing .git (with optional trailing slash)
    (\?.*)?: remove query string
    (#.*)?: remove fragment identifier
  */
  importUrl = importUrl.replace(/\/?(\.git\/?)?(\?.*)?(#.*)?$/, '');

  // extract everything after the last slash
  const pathMatch = /\/([^/]+)$/.exec(importUrl);
  if (pathMatch) {
    $currentProjectPath.val(pathMatch[1]);
  }
};

const onProjectNameChange = ($projectNameInput, $projectPathInput) => {
  const slug = slugifyWithHyphens($projectNameInput.val());
  $projectPathInput.val(slug);
};

const bindEvents = () => {
  const $newProjectForm = $('#new_project');
  const $projectImportUrl = $('#project_import_url');
  const $projectPath = $('.tab-pane.active #project_path');
  const $useTemplateBtn = $('.template-button > input');
  const $projectFieldsForm = $('.project-fields-form');
  const $selectedTemplateText = $('.selected-template');
  const $changeTemplateBtn = $('.change-template');
  const $selectedIcon = $('.selected-icon');
  const $pushNewProjectTipTrigger = $('.push-new-project-tip');
  const $projectTemplateButtons = $('.project-templates-buttons');
  const $projectName = $('.tab-pane.active #project_name');

  if ($newProjectForm.length !== 1) {
    return;
  }

  $('.how_to_import_link').on('click', e => {
    e.preventDefault();
    $(e.currentTarget)
      .next('.modal')
      .show();
  });

  $('.modal-header .close').on('click', () => {
    $('.modal').hide();
  });

  $('.btn_import_gitlab_project').on('click', () => {
    const importHref = $('a.btn_import_gitlab_project').attr('href');
    $('.btn_import_gitlab_project').attr(
      'href',
      `${importHref}?namespace_id=${$(
        '#project_namespace_id',
      ).val()}&name=${$projectName.val()}&path=${$projectPath.val()}`,
    );
  });

  if ($pushNewProjectTipTrigger) {
    $pushNewProjectTipTrigger
      .removeAttr('rel')
      .removeAttr('target')
      .on('click', e => {
        e.preventDefault();
      })
      .popover({
        title: $pushNewProjectTipTrigger.data('title'),
        placement: 'bottom',
        html: true,
        content: $('.push-new-project-tip-template').html(),
      })
      .on('shown.bs.popover', () => {
        $(document).on('click.popover touchstart.popover', event => {
          if ($(event.target).closest('.popover').length === 0) {
            $pushNewProjectTipTrigger.trigger('click');
          }
        });

        const target = $(`#${$pushNewProjectTipTrigger.attr('aria-describedby')}`).find(
          '.js-select-on-focus',
        );
        addSelectOnFocusBehaviour(target);

        target.focus();
      })
      .on('hide.bs.popover', () => {
        $(document).off('click.popover touchstart.popover');
      });
  }

  function chooseTemplate() {
    $projectTemplateButtons.addClass('hidden');
    $projectFieldsForm.addClass('selected');
    $selectedIcon.empty();
    const value = $(this).val();
    const templates = {
      rails: {
        text: 'Ruby on Rails',
        icon: '.template-option .icon-rails',
      },
      express: {
        text: 'NodeJS Express',
        icon: '.template-option .icon-express',
      },
      spring: {
        text: 'Spring',
        icon: '.template-option .icon-spring',
      },
      iosswift: {
        text: 'iOS (Swift)',
        icon: '.template-option svg.icon-gitlab',
      },
      dotnetcore: {
        text: '.NET Core',
        icon: '.template-option .icon-dotnet',
      },
      android: {
        text: 'Android',
        icon: '.template-option svg.icon-android',
      },
      gomicro: {
        text: 'Go Micro',
        icon: '.template-option .icon-gomicro',
      },
      hugo: {
        text: 'Pages/Hugo',
        icon: '.template-option .icon-hugo',
      },
      jekyll: {
        text: 'Pages/Jekyll',
        icon: '.template-option .icon-jekyll',
      },
      plainhtml: {
        text: 'Pages/Plain HTML',
        icon: '.template-option .icon-plainhtml',
      },
      gitbook: {
        text: 'Pages/GitBook',
        icon: '.template-option .icon-gitbook',
      },
      hexo: {
        text: 'Pages/Hexo',
        icon: '.template-option .icon-hexo',
      },
      nfhugo: {
        text: 'Netlify/Hugo',
        icon: '.template-option .icon-netlify',
      },
      nfjekyll: {
        text: 'Netlify/Jekyll',
        icon: '.template-option .icon-netlify',
      },
      nfplainhtml: {
        text: 'Netlify/Plain HTML',
        icon: '.template-option .icon-netlify',
      },
      nfgitbook: {
        text: 'Netlify/GitBook',
        icon: '.template-option .icon-netlify',
      },
      nfhexo: {
        text: 'Netlify/Hexo',
        icon: '.template-option .icon-netlify',
      },
    };

    const selectedTemplate = templates[value];
    $selectedTemplateText.text(selectedTemplate.text);
    $(selectedTemplate.icon)
      .clone()
      .addClass('d-block')
      .appendTo($selectedIcon);

    const $activeTabProjectName = $('.tab-pane.active #project_name');
    const $activeTabProjectPath = $('.tab-pane.active #project_path');
    $activeTabProjectName.focus();
    $activeTabProjectName.keyup(() => {
      onProjectNameChange($activeTabProjectName, $activeTabProjectPath);
      hasUserDefinedProjectPath = $activeTabProjectPath.val().trim().length > 0;
    });
  }

  $useTemplateBtn.on('change', chooseTemplate);

  $changeTemplateBtn.on('click', () => {
    $projectTemplateButtons.removeClass('hidden');
    $projectFieldsForm.removeClass('selected');
    $useTemplateBtn.prop('checked', false);
  });

  $newProjectForm.on('submit', () => {
    $projectPath.val($projectPath.val().trim());
  });

  $projectPath.on('keyup', () => {
    hasUserDefinedProjectPath = $projectPath.val().trim().length > 0;
  });

  $projectImportUrl.keyup(() => deriveProjectPathFromUrl($projectImportUrl));

  $('.js-import-git-toggle-button').on('click', () => {
    const $projectMirror = $('#project_mirror');

    $projectMirror.attr('disabled', !$projectMirror.attr('disabled'));
  });

  $projectName.on('keyup change', () => {
    onProjectNameChange($projectName, $projectPath);
    hasUserDefinedProjectPath = $projectPath.val().trim().length > 0;
  });
};

export default {
  bindEvents,
  deriveProjectPathFromUrl,
  onProjectNameChange,
};
<|endoftext|>


<commit_before>developerKingdomModule.
	controller("layoutCtrl", function layoutCtrl($scope, $window){

		$scope.setSize = function(){
			$scope.fullWidth = ($window.innerWidth <= 1410);
		}

		$scope.getSize = function(){
			return ($window.innerWidth <= 1410)
		}

		$scope.fullWidth = false || $scope.getSize();

		var w = angular.element($window);

		w.bind('resize', function () {
			$scope.setSize();
			$scope.$apply();
		});
	});
<commit_msg>Update layout.js<commit_after>developerKingdomModule.
	controller("layoutCtrl", function layoutCtrl($scope, $window){

		$scope.setSize = function(){
			$scope.fullWidth = ($window.innerWidth <= 1410);
		}

		$scope.getSize = function(){
			return ($window.innerWidth <= 1410)
		}

		$scope.fullWidth = $scope.getSize();

		var w = angular.element($window);

		w.bind('resize', function () {
			$scope.setSize();
			$scope.$apply( $scope.fullWidth );
		});
	});
<|endoftext|>


<commit_before>module.exports = {
  entry: './entry.js', // 源文件
  output: {
    filename: 'bundle.js' // 输出文件
  },
  module: {
    loaders: [
      {
        test:/\.css$/,
        loader: "style!css" // 用!去链式调用loader
      }
    ]
  }
};
<commit_msg>增加extensions<commit_after>module.exports = {
  entry: './entry.js', // 源文件
  output: {
    filename: 'bundle.js' // 输出文件
  },
  module: {
    loaders: [
      {
        test:/\.css$/,
        loader: 'style!css' // 用!去链式调用loader
      }
    ]
  }
};
<|endoftext|>