<commit_before>/** @jsx React.DOM */
define([
    'underscore', 'jquery', 'react', '../util/util', '../ControlCommon'
], function (_, $, React, u, controlCommon) {
    'use strict';

    /**
     * Creates a multi-select control.
     * isFlat controls whether the selectors are interpreted as containing optgroups.
     * If isFlat is true selectors will be a two level array of arrays.  The top level will be pairs of (name, children). Children, the second level, will be pairs of (id, name).
     * If isFlat is false selectors will  simply be an array of (id, name).
     * Each level can also have an active property that will be assumed to be true if undefined.
     * Empty optgroups will be elided.
     */
    return React.createClass({

        fieldClass: 'formFieldMultiselect',

        getDefaultProps: function () {
            return {
                disabled: false,
                readonly: false,
                isValid: [true, ''],
                isFlat: true,
                selectors: [],
                selections: [], // this is the value prop that pairs with onChange.
                size: 3,
                onChange: function (selections) { console.log(selections); }
            };
        },

        getInitialState: function () {
            // Here, we cull out all the inactive panels.
            var selectors = this.props.selectors;
            u.test(_.isArray(selectors), 'array required for selectors');
            // implements the behavior that the absence of an active property makes it automatically active.
            function isActive(selector) {
                return _.isUndefined(selector.active) || !! selector.active;
            }
            u.test(_.isArray(selectors), 'array required for selectors');
            if (this.props.isFlat) {
                selectors = _.filter(selectors, function (selector) {
                    return isActive(selector);
                });
            } else {
                selectors = _.filter(selectors, function (group) {
                    return isActive(group);
                });
                selectors = _.map(selectors, function (group) {
                    // this clone will copy the primitive valued properties and leave the arrays as references.
                    // this is fine since we'll be replacing those arrays with filtered versions.
                    var g = _.clone(group);
                    g.children = _.filter(group.children, function (child) { return isActive(child); });
                    return g;
                });
                selectors = _.filter(selectors, function (g) { return 0 < g.children.length; });
            }
            return ({
                selectors: selectors,
                selections: this.props.selections,
                isValid: this.props.isValid
            });
        },

        /* jshint ignore:start */
        render: function () {
            var selectors = this.state.selectors;
            var selections = this.props.selections;
            function option(selector) {
                return (<option value={selector.id}>{selector.name}</option>);
            }
            if (this.props.isFlat) {
                selectors = _.map(selectors, function (selector) {
                    return option(selector); // (<option value={selector.id}>{selector.name}</option>);
                });
            } else {
                selectors = _.map(selectors, function (group) {
                    var options = _.map(group.children, function(child) {
                        return option(child); // (<option value={child.id}>{child.name}</option>);
                    });
                    return (<optgroup label={group.name}>{options}</optgroup>);
                });
            }

            return(
                        <select id={this.props.id} ref="multiselector" value={selections} multiple="multiple">{selectors}</select>
            );
        },
        /* jshint ignore:end */

        componentDidMount: function (rootNode) {
            var self = this;
            $(rootNode).on('change', function (event) {
                void event;
                var selections = _.map(_.filter(self.refs['multiselector'].getDOMNode().options, function (opt) {
                    return opt.selected;
                }), function (opt) {
                    return opt.value;
                });
                self.props.onChange(selections);
                return true;
            });
        }
    });
});
<commit_msg>Remove console.log from MultiSelect<commit_after>/** @jsx React.DOM */
define([
    'underscore', 'jquery', 'react', '../util/util', '../ControlCommon'
], function (_, $, React, u, controlCommon) {
    'use strict';

    /**
     * Creates a multi-select control.
     * isFlat controls whether the selectors are interpreted as containing optgroups.
     * If isFlat is true selectors will be a two level array of arrays.  The top level will be pairs of (name, children). Children, the second level, will be pairs of (id, name).
     * If isFlat is false selectors will  simply be an array of (id, name).
     * Each level can also have an active property that will be assumed to be true if undefined.
     * Empty optgroups will be elided.
     */
    return React.createClass({

        fieldClass: 'formFieldMultiselect',

        getDefaultProps: function () {
            return {
                disabled: false,
                readonly: false,
                isValid: [true, ''],
                isFlat: true,
                selectors: [],
                selections: [], // this is the value prop that pairs with onChange.
                size: 3,
                onChange: function () {}
            };
        },

        getInitialState: function () {
            // Here, we cull out all the inactive panels.
            var selectors = this.props.selectors;
            u.test(_.isArray(selectors), 'array required for selectors');
            // implements the behavior that the absence of an active property makes it automatically active.
            function isActive(selector) {
                return _.isUndefined(selector.active) || !! selector.active;
            }
            u.test(_.isArray(selectors), 'array required for selectors');
            if (this.props.isFlat) {
                selectors = _.filter(selectors, function (selector) {
                    return isActive(selector);
                });
            } else {
                selectors = _.filter(selectors, function (group) {
                    return isActive(group);
                });
                selectors = _.map(selectors, function (group) {
                    // this clone will copy the primitive valued properties and leave the arrays as references.
                    // this is fine since we'll be replacing those arrays with filtered versions.
                    var g = _.clone(group);
                    g.children = _.filter(group.children, function (child) { return isActive(child); });
                    return g;
                });
                selectors = _.filter(selectors, function (g) { return 0 < g.children.length; });
            }
            return ({
                selectors: selectors,
                selections: this.props.selections,
                isValid: this.props.isValid
            });
        },

        /* jshint ignore:start */
        render: function () {
            var selectors = this.state.selectors;
            var selections = this.props.selections;
            function option(selector) {
                return (<option value={selector.id}>{selector.name}</option>);
            }
            if (this.props.isFlat) {
                selectors = _.map(selectors, function (selector) {
                    return option(selector); // (<option value={selector.id}>{selector.name}</option>);
                });
            } else {
                selectors = _.map(selectors, function (group) {
                    var options = _.map(group.children, function(child) {
                        return option(child); // (<option value={child.id}>{child.name}</option>);
                    });
                    return (<optgroup label={group.name}>{options}</optgroup>);
                });
            }

            return(
                        <select id={this.props.id} ref="multiselector" value={selections} multiple="multiple">{selectors}</select>
            );
        },
        /* jshint ignore:end */

        componentDidMount: function (rootNode) {
            var self = this;
            $(rootNode).on('change', function (event) {
                void event;
                var selections = _.map(_.filter(self.refs['multiselector'].getDOMNode().options, function (opt) {
                    return opt.selected;
                }), function (opt) {
                    return opt.value;
                });
                self.props.onChange(selections);
                return true;
            });
        }
    });
});
<|endoftext|>


<commit_before>(function(scope) {
  if(console && console.time)
    console.time("ElaiJS Start in");

  if(scope.define && scope.define.amd)
    return scope.require(["elaiJS/elaiJSMain"]);

  var baseURL;
  var waitModules = [];
  var modules = {};
  var listeners = {};
  var config;

  function initialize() {
    baseURL = getBaseURL();
    loadMain();
  }

  function loadMain() {
    var mainModuleName = getElaiJSAttribute("main");
    if(mainModuleName)
      scope.require([mainModuleName]);
  }

  function getBaseURL() {
    var baseURL = getElaiJSAttribute("baseUrl");
    if(baseURL)
      return baseURL;

    var appModuleName = getElaiJSAttribute("app") || getElaiJSAttribute("appDebug");
    if(!appModuleName)
      return ".";

    var index = appModuleName.lastIndexOf("/");
    return appModuleName.substring(0, index);
  }

  function getElaiJSAttribute(name) {
    var urlFile;
    var scriptElement = document.getElementsByClassName("elaiJS");
    if(scriptElement && scriptElement.length > 0)
      urlFile = scriptElement[0].getAttribute("data-" + name);

    if(urlFile === "")
      return undefined;

    return urlFile;
	}

  function loadScript(moduleName) {
    var node = createNode(moduleName);
    document.getElementsByTagName("head")[0].appendChild(node);
  }

  function getScriptURL(moduleName) {
    if( config && config.require && config.require.paths &&
        config.require.paths[moduleName]) {
      moduleName = config.require.paths[moduleName];
    }

    if(moduleName.indexOf(".js") >= 0)
      return moduleName;

    var url = baseURL + "/" + moduleName + ".js";
    if(config && config.require && config.require.urlArgs)
      url += "?" + config.require.urlArgs;

    return url;
  }

  function createNode(moduleName) {
    var node = document.createElement('script');
    node.type = 'text/javascript';
    node.charset = 'utf-8';
    node.async = true;

    node.id = "requireElaiJS_module_" + moduleName;
    node.classList.add("requireElaiJS_module");
    node.setAttribute('data-moduleName', moduleName);
    node.addEventListener('load', onScriptLoad, false);
    node.addEventListener('error', onScriptError, false);
    node.src = getScriptURL(moduleName);

    return node;
  }

  function onScriptLoad() {
    var moduleName = this.getAttribute("data-moduleName");
    var moduleDef = waitModules.shift();
    if(moduleDef)
      scope.define(moduleName, moduleDef.deps, moduleDef.callback);
    else
      addModule(moduleName, null);
  }

  function onScriptError(error) {
    var moduleName = this.getAttribute("data-moduleName");
    callErrorListener(error, moduleName);

    throw new Error("Error: Script error during loading module '" + moduleName + "'");
  }

  function internalDefine(name, deps, callback) {
    if(typeof callback === "object") {
      addModule(name, callback);
      return;
    }

    scope.require(deps, function() {
      var module = callback.apply(scope, arguments);
      var index = checkExportsIndex(deps);
      module = (index === undefined) ? module : arguments[index];

      addModule(name, module);
    });
  }

  function checkExportsIndex(deps) {
    for(var i in deps)
      if(deps[i] === "exports")
        return i;
  }

  function addWaitModule(deps, callback) {
    waitModules.push({deps: deps, callback: callback});
  }

  function addModule(name, module) {
    if(modules[name]) {
      callListener(name, module);
      return;
    }

    modules[name] = module;
    callListener(name, module);
    callShimInit(name);
  }

  function getModule(name, callback, errCallback) {
    if(modules[name] !== undefined) {
      if(callback)
        callback(modules[name], name);
      return modules[name];
    }

    if(!callback)
      throw new Error("Module '" + name + "' has not been loaded.");

    if(name === "exports")
      return (callback) ? callback({}, name) : undefined;

    var newListener = addListener(name, callback, errCallback);
    if(newListener)
      loadScript(name);
  }

  function addListener(name, callback, errCallback) {
    var newListener = true;
    if(!listeners[name])
      listeners[name] = [];
    else
      newListener = false;

    listeners[name].push({callback: callback, errCallback: errCallback});
    return newListener;
  }

  function callListener(moduleName, module) {
    if(!listeners[moduleName])
      return;

    for(var i in listeners[moduleName])
      listeners[moduleName][i].callback(module, moduleName);

    delete listeners[moduleName];
  }

  function callErrorListener(error, moduleName) {
    if(!listeners[moduleName])
      return;

    for(var i in listeners[moduleName]) {
      if(listeners[moduleName][i].errCallback)
        listeners[moduleName][i].errCallback(error, moduleName);
    }

    delete listeners[moduleName];
  }

  function callShimInit(moduleName) {
    if( !config
        || !config.require
        || !config.require.shim
        || !config.require.shim[moduleName]
        || !config.require.shim[moduleName].init)
      return;

    config.require.shim[moduleName].init();
  }

  function getModules(modulesName, callback, errCallback) {
    var modulesDep = {};
    var count = modulesName.length;
    var getModuleCallback = function getModuleCallback(module, name) {
      --count;
      modulesDep[name] = module;

      if(count === 0) {
        var deps = sortModules(modulesName, modulesDep);
        if(callback)
          callback.apply(scope, deps);
      }
    };

    for(var i in modulesName)
      getModule(modulesName[i], getModuleCallback, errCallback);

    if(modulesName.length === 0)
      callback();
  }

  function sortModules(modulesName, modulesObj) {
    var modulesDeps = [];

    for(var i in modulesName)
      modulesDeps.push(modulesObj[modulesName[i]]);

    return modulesDeps;
  }

  function getIndirectDeps(modulesName) {
    if(!config || !config.require || !config.require.shim)
      return [];

    var shim = config.require.shim;
    var deps = [];
    for(var i in modulesName) {
      var moduleLoadDef = shim[modulesName[i]];
      if(moduleLoadDef && moduleLoadDef.deps) {
        deps = deps.concat(moduleLoadDef.deps);
      }
    }

    if(deps.length > 0)
      return getIndirectDeps(deps).concat(deps);
    return [];
  }

  /************************************************************
   ********************* Scope functions **********************
  *************************************************************/
  scope.require = function require(deps, callback, errCallback) {
    if(typeof deps === 'string')
      return getModule(deps);

    var indirectDeps = getIndirectDeps(deps);
    getModules(indirectDeps, function() {
      getModules(deps, callback, errCallback);
    }, errCallback);
  };

  scope.define = function define(name, deps, callback) {
    if(typeof name === "string" && !callback) {
      callback = deps;
      deps = [];
    }

    if(!callback) {
      if(!deps) {
        deps = name;
        name = [];
      }

      addWaitModule(name, deps);
      return;
    }

    internalDefine(name, deps, callback);
  };

  scope.requireElaiJS = {};
  scope.requireElaiJS.setConfig = function(newConfig) {
    config = newConfig;
  };

  scope.requireElaiJS.undef = function(name) {
    delete modules[name];
    var node = document.getElementById("requireElaiJS_module_" + name);
    if(node && node.parentNode)
      node.parentNode.removeChild(node);
  };

  scope.requireElaiJS.undefAll = function(excepts) {
    for(var key in modules) {
      var except = false;
      for(var i in excepts) {
        if(key === excepts[i]) {
          except = true;
          break;
        }
      }

      if(!except)
        scope.requireElaiJS.undef(key);
    }
  };

  scope.define.amd = {jQuery: true};

  initialize();
}(this));<commit_msg>Little refactoring<commit_after>(function(scope) {
  if(console && console.time)
    console.time("ElaiJS Start in");

  if(scope.define && scope.define.amd)
    return scope.require(["elaiJS/elaiJSMain"]);

  var baseURL;
  var waitModules = [];
  var modules = {};
  var listeners = {};
  var config;

  function initialize() {
    baseURL = getBaseURL();
    loadMain();
  }

  function loadMain() {
    var mainModuleName = getElaiJSAttribute("main");
    if(mainModuleName)
      scope.require([mainModuleName]);
  }

  function getBaseURL() {
    var baseURL = getElaiJSAttribute("baseUrl");
    if(baseURL)
      return baseURL;

    var appModuleName = getElaiJSAttribute("app");
    if(!appModuleName)
      return ".";

    var index = appModuleName.lastIndexOf("/");
    return appModuleName.substring(0, index);
  }

  function getElaiJSAttribute(name) {
    var urlFile;
    var scriptElement = document.getElementsByClassName("elaiJS");
    if(scriptElement && scriptElement.length > 0)
      urlFile = scriptElement[0].getAttribute("data-" + name);

    if(urlFile === "")
      return undefined;

    return urlFile;
	}

  function loadScript(moduleName) {
    var node = createNode(moduleName);
    document.getElementsByTagName("head")[0].appendChild(node);
  }

  function getScriptURL(moduleName) {
    if( config && config.require && config.require.paths &&
        config.require.paths[moduleName]) {
      moduleName = config.require.paths[moduleName];
    }

    if(moduleName.indexOf(".js") >= 0)
      return moduleName;

    var url = baseURL + "/" + moduleName + ".js";
    if(config && config.require && config.require.urlArgs)
      url += "?" + config.require.urlArgs;

    return url;
  }

  function createNode(moduleName) {
    var node = document.createElement('script');
    node.type = 'text/javascript';
    node.charset = 'utf-8';
    node.async = true;

    node.id = "requireElaiJS_module_" + moduleName;
    node.classList.add("requireElaiJS_module");
    node.setAttribute('data-moduleName', moduleName);
    node.addEventListener('load', onScriptLoad, false);
    node.addEventListener('error', onScriptError, false);
    node.src = getScriptURL(moduleName);

    return node;
  }

  function onScriptLoad() {
    var moduleName = this.getAttribute("data-moduleName");
    var moduleDef = waitModules.shift();
    if(moduleDef)
      scope.define(moduleName, moduleDef.deps, moduleDef.callback);
    else
      addModule(moduleName, null);
  }

  function onScriptError(error) {
    var moduleName = this.getAttribute("data-moduleName");
    callErrorListener(error, moduleName);

    throw new Error("Error: Script error during loading module '" + moduleName + "'");
  }

  function internalDefine(name, deps, callback) {
    if(typeof callback === "object")
      return addModule(name, callback);

    scope.require(deps, function() {
      var module = callback.apply(scope, arguments);
      var index = checkExportsIndex(deps);
      module = (index === undefined) ? module : arguments[index];

      addModule(name, module);
    });
  }

  function checkExportsIndex(deps) {
    for(var i in deps)
      if(deps[i] === "exports")
        return i;
  }

  function addWaitModule(deps, callback) {
    waitModules.push({deps: deps, callback: callback});
  }

  function addModule(name, module) {
    if(modules[name])
      return callListener(name, module);

    modules[name] = module;
    callListener(name, module);
    callShimInit(name);
  }

  function getModule(name, callback, errCallback) {
    if(modules[name] !== undefined) {
      if(callback)
        callback(modules[name], name);
      return modules[name];
    }

    if(!callback)
      throw new Error("Module '" + name + "' has not been loaded.");

    if(name === "exports")
      return (callback) ? callback({}, name) : undefined;

    var newListener = addListener(name, callback, errCallback);
    if(newListener)
      loadScript(name);
  }

  function addListener(name, callback, errCallback) {
    var newListener = true;
    if(!listeners[name])
      listeners[name] = [];
    else
      newListener = false;

    listeners[name].push({callback: callback, errCallback: errCallback});
    return newListener;
  }

  function callListener(moduleName, module) {
    if(!listeners[moduleName])
      return;

    for(var i in listeners[moduleName])
      listeners[moduleName][i].callback(module, moduleName);

    delete listeners[moduleName];
  }

  function callErrorListener(error, moduleName) {
    if(!listeners[moduleName])
      return;

    for(var i in listeners[moduleName]) {
      if(listeners[moduleName][i].errCallback)
        listeners[moduleName][i].errCallback(error, moduleName);
    }

    delete listeners[moduleName];
  }

  function callShimInit(moduleName) {
    if( !config
        || !config.require
        || !config.require.shim
        || !config.require.shim[moduleName]
        || !config.require.shim[moduleName].init)
      return;

    config.require.shim[moduleName].init();
  }

  function getModules(modulesName, callback, errCallback) {
    var modulesDep = {};
    var count = modulesName.length;
    var getModuleCallback = function getModuleCallback(module, name) {
      --count;
      modulesDep[name] = module;

      if(count === 0) {
        var deps = sortModules(modulesName, modulesDep);
        if(callback)
          callback.apply(scope, deps);
      }
    };

    for(var i in modulesName)
      getModule(modulesName[i], getModuleCallback, errCallback);

    if(modulesName.length === 0)
      callback();
  }

  function sortModules(modulesName, modulesObj) {
    var modulesDeps = [];

    for(var i in modulesName)
      modulesDeps.push(modulesObj[modulesName[i]]);

    return modulesDeps;
  }

  function getIndirectDeps(modulesName) {
    if(!config || !config.require || !config.require.shim)
      return [];

    var shim = config.require.shim;
    var deps = [];
    for(var i in modulesName) {
      var moduleLoadDef = shim[modulesName[i]];
      if(moduleLoadDef && moduleLoadDef.deps) {
        deps = deps.concat(moduleLoadDef.deps);
      }
    }

    if(deps.length > 0)
      return getIndirectDeps(deps).concat(deps);
    return [];
  }

  /************************************************************
   ********************* Scope functions **********************
  *************************************************************/
  scope.require = function require(deps, callback, errCallback) {
    if(typeof deps === 'string')
      return getModule(deps);

    var indirectDeps = getIndirectDeps(deps);
    getModules(indirectDeps, function() {
      getModules(deps, callback, errCallback);
    }, errCallback);
  };

  scope.define = function define(name, deps, callback) {
    if(typeof name === "string" && !callback) {
      callback = deps;
      deps = [];
    }

    if(!callback) {
      if(!deps) {
        deps = name;
        name = [];
      }

      addWaitModule(name, deps);
      return;
    }

    internalDefine(name, deps, callback);
  };

  scope.requireElaiJS = {};
  scope.requireElaiJS.setConfig = function(newConfig) {
    config = newConfig;
  };

  scope.requireElaiJS.undef = function(name) {
    delete modules[name];
    var node = document.getElementById("requireElaiJS_module_" + name);
    if(node && node.parentNode)
      node.parentNode.removeChild(node);
  };

  scope.requireElaiJS.undefAll = function(excepts) {
    for(var key in modules) {
      var except = false;
      for(var i in excepts) {
        if(key === excepts[i]) {
          except = true;
          break;
        }
      }

      if(!except)
        scope.requireElaiJS.undef(key);
    }
  };

  scope.define.amd = {jQuery: true};

  initialize();
}(this));<|endoftext|>


<commit_before>Applications = new Mongo.Collection('applications');

// Attach behaviour with the default options
Applications.attachBehaviour('timestampable');

// SCHEMA
Applications.attachSchema(new SimpleSchema({
  name: {
    type: String,
    unique: true,
    label: 'Application Name'
  },

  status: {
    type: String,
    allowedValues: STATUS_ALLOWED_VALUES,
    defaultValue: STATUS_ALLOWED_VALUES[1], // PROGRESS.
    autoform: {
      type: 'hidden',
      firstOption: false
    }
  },

  monit: { type: Object, optional: true, autoform: { type: 'hidden' } },
  'monit.memory': { type: Number },
  'monit.cpu': { type: Number },

  // ENVIRONMENT VARIABLES
  env: { type: Object },
  'env.ROOT_URL': { type: String, regEx: SimpleSchema.RegEx.Url },
  'env.MONGO_URL': { type: String, optional: true },
  'env.MAIL_URL': { type: String, optional: true },
  'env.PORT': { type: Number, optional: true },
  'env.DISABLE_WEBSOCKETS': { type: Number, optional: true},
  'env.MONGO_OPLOG_URL': { type: String, optional: true },

  bundleId: {
    type: String,
    label: 'Bundle',
    autoform: {
      afFieldInput: {
        type: "cfs-file",
        collection: "bundles"
      }
    }
  }
}));

Applications.helpers({
  logs() {
    return Logs.find({ applicationId: this._id }, {
      sort: {
        createdAt: -1
      }
    });
  },

  bundle() {
    return Bundles.findOne(this.bundleId);
  },

  absoluteUrl() {
    if (isLocal()) {
      return `http://localhost:${this.env.PORT}`
    }
    return this.env.ROOT_URL;
  },

  isOnline() {
    return _.isEqual(this.status, STATUS_ALLOWED_VALUES[2]);
  },

  isStop() {
    return _.isEqual(this.status, STATUS_ALLOWED_VALUES[0]);
  },

  isProgress() {
    return _.isEqual(this.status, STATUS_ALLOWED_VALUES[1]);
  }
});

isServer(() => {
  Applications.helpers({
    dir() {
      return `${process.env.BUNDLE_DIR}/${this._id}`;
    },

    setStatus(index) {
      return Applications.update(this._id, {
        $set: {
          status: STATUS_ALLOWED_VALUES[index]
        }
      });
    },

    options(PORT) {
      return {
        name: this._id,
        script: 'main.js',
        cwd: this.dir(),
        env: _.extend(this.env, {
          PORT: this.env.PORT || PORT,
        })
      }
    }
  });

  Applications.before.insert((userId, doc) => {
    doc.env.MONGO_URL = `mongodb://localhost:27017/${doc._id}`;
  });

  Applications.before.update((userId, doc, fieldNames, modifier, options) => {
    if (_.has(modifier.$set, 'status')) {

      // IF STOPPED THEN
      if (_.isEqual(modifier.$set.status, 'STOPPED')) {
        pm2.connect((connect_err) => {
          pm2.stop(doc._id, (delete_err) => {

            // DISCONNECT
            pm2.disconnect();
          });
        });
      }
    }
  });

  Applications.after.remove((userId, doc) => {
    const dir = `${process.env.BUNDLE_DIR}/${doc._id}`;

    // CONNECT AND DELETE
    pm2.connect((connect_err) => {
      pm2.delete(doc._id, (delete_err) => {

        shell.cd(`${process.env.BUNDLE_DIR}`);

        // REMOVE APPLICATON DIR AND BUNDLE FILE
        shell.rm('-rf', [ doc._id, doc.bundleId ]);

        // DISCONNECT
        pm2.disconnect();
      });
    });

    // Applications all logs removed.
    Logs.remove({
      applicationId: doc._id
    });
  });
});
<commit_msg>after remove application const dir removed.<commit_after>Applications = new Mongo.Collection('applications');

// Attach behaviour with the default options
Applications.attachBehaviour('timestampable');

// SCHEMA
Applications.attachSchema(new SimpleSchema({
  name: {
    type: String,
    unique: true,
    label: 'Application Name'
  },

  status: {
    type: String,
    allowedValues: STATUS_ALLOWED_VALUES,
    defaultValue: STATUS_ALLOWED_VALUES[1], // PROGRESS.
    autoform: {
      type: 'hidden',
      firstOption: false
    }
  },

  monit: { type: Object, optional: true, autoform: { type: 'hidden' } },
  'monit.memory': { type: Number },
  'monit.cpu': { type: Number },

  // ENVIRONMENT VARIABLES
  env: { type: Object },
  'env.ROOT_URL': { type: String, regEx: SimpleSchema.RegEx.Url },
  'env.MONGO_URL': { type: String, optional: true },
  'env.MAIL_URL': { type: String, optional: true },
  'env.PORT': { type: Number, optional: true },
  'env.DISABLE_WEBSOCKETS': { type: Number, optional: true},
  'env.MONGO_OPLOG_URL': { type: String, optional: true },

  bundleId: {
    type: String,
    label: 'Bundle',
    autoform: {
      afFieldInput: {
        type: "cfs-file",
        collection: "bundles"
      }
    }
  }
}));

Applications.helpers({
  logs() {
    return Logs.find({ applicationId: this._id }, {
      sort: {
        createdAt: -1
      }
    });
  },

  bundle() {
    return Bundles.findOne(this.bundleId);
  },

  absoluteUrl() {
    if (isLocal()) {
      return `http://localhost:${this.env.PORT}`
    }
    return this.env.ROOT_URL;
  },

  isOnline() {
    return _.isEqual(this.status, STATUS_ALLOWED_VALUES[2]);
  },

  isStop() {
    return _.isEqual(this.status, STATUS_ALLOWED_VALUES[0]);
  },

  isProgress() {
    return _.isEqual(this.status, STATUS_ALLOWED_VALUES[1]);
  }
});

isServer(() => {
  Applications.helpers({
    dir() {
      return `${process.env.BUNDLE_DIR}/${this._id}`;
    },

    setStatus(index) {
      return Applications.update(this._id, {
        $set: {
          status: STATUS_ALLOWED_VALUES[index]
        }
      });
    },

    options(PORT) {
      return {
        name: this._id,
        script: 'main.js',
        cwd: this.dir(),
        env: _.extend(this.env, {
          PORT: this.env.PORT || PORT,
        })
      }
    }
  });

  Applications.before.insert((userId, doc) => {
    doc.env.MONGO_URL = `mongodb://localhost:27017/${doc._id}`;
  });

  Applications.before.update((userId, doc, fieldNames, modifier, options) => {
    if (_.has(modifier.$set, 'status')) {

      // IF STOPPED THEN
      if (_.isEqual(modifier.$set.status, 'STOPPED')) {
        pm2.connect((connect_err) => {
          pm2.stop(doc._id, (delete_err) => {

            // DISCONNECT
            pm2.disconnect();
          });
        });
      }
    }
  });

  Applications.after.remove((userId, doc) => {

    // CONNECT AND DELETE
    pm2.connect((connect_err) => {
      pm2.delete(doc._id, (delete_err) => {

        shell.cd(`${process.env.BUNDLE_DIR}`);

        // REMOVE APPLICATON DIR AND BUNDLE FILE
        shell.rm('-rf', [ doc._id, doc.bundleId ]);

        // DISCONNECT
        pm2.disconnect();
      });
    });

    // Applications all logs removed.
    Logs.remove({
      applicationId: doc._id
    });
  });
});
<|endoftext|>


<commit_before>var fs = require('fs');
var Schema = require('protobuf').Schema;

module.exports = {
	"base_gcmessages": new Schema(fs.readFileSync(__dirname + '/generated/base_gcmessages.desc')),
	"tf_gcmessages": new Schema(fs.readFileSync(__dirname + '/generated/tf_gcmessages.desc'))
};<commit_msg>Parse gcsdk_gcmessages.desc<commit_after>var fs = require('fs');
var Schema = require('protobuf').Schema;

module.exports = {
	"base_gcmessages": new Schema(fs.readFileSync(__dirname + '/generated/base_gcmessages.desc')),
	"gcsdk_gcmessages": new Schema(fs.readFileSync(__dirname + '/generated/gcsdk_gcmessages.desc')),
	"tf_gcmessages": new Schema(fs.readFileSync(__dirname + '/generated/tf_gcmessages.desc'))
};<|endoftext|>


<commit_before>import { A } from '@ember/array';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import {
  assertionInjector,
  assertionCleanup
} from '../../assertions';
import ArrayPathLayerComponent from 'ember-leaflet/components/array-path-layer';
import locations from '../../helpers/locations';

let arrayPath;

moduleForComponent('array-path-layer', 'Integration | Component | array path layer', {
  integration: true,
  beforeEach() {
    assertionInjector();

    this.register('component:custom-array-path-layer', ArrayPathLayerComponent.extend({
      init() {
        this._super(...arguments);
        arrayPath = this;
      },
      createLayer() {
        return this.L.polyline(...this.get('requiredOptions'), this.get('options'));
      }
    }));

    this.set('center', locations.nyc);
    this.set('zoom', 13);
  },
  afterEach() {
    assertionCleanup();
  }
});

test('replace locations updates array path layer', function(assert) {
  this.set('locations', [locations.chicago, locations.nyc, locations.sf]);

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);

  this.set('locations', [locations.paris, locations.london, locations.newdelhi]);

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.paris);
  assert.locationsEqual(layerLatLngs[1], locations.london);
  assert.locationsEqual(layerLatLngs[2], locations.newdelhi);
});

test('adding to locations updates array path layer', function(assert) {
  this.set('locations', A([locations.chicago, locations.nyc, locations.sf]));

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);

  this.get('locations').pushObject(locations.paris);

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);
  assert.locationsEqual(layerLatLngs[3], locations.paris);
});

test('removing from locations updates array path layer', function(assert) {
  this.set('locations', A([locations.chicago, locations.nyc, locations.sf]));

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);

  this.get('locations').popObject();

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.equal(layerLatLngs.length, 2);
});

test('replace item in content moves polyline', function(assert) {
  this.set('locations', A([locations.chicago, locations.nyc, locations.sf]));

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);

  this.get('locations').replace(1, 1, locations.paris);

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.paris);
  assert.locationsEqual(layerLatLngs[2], locations.sf);
  assert.equal(layerLatLngs.length, 3);
});

test('supports array of arrays as well', function(assert) {
  this.set('locations', [[-43.123, 71.123], [-43.123, 71.123], [-43.123, 71.123]]);

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.ok(layerLatLngs[0].equals([-43.123, 71.123]));
  assert.ok(layerLatLngs[1].equals([-43.123, 71.123]));
  assert.ok(layerLatLngs[2].equals([-43.123, 71.123]));

  this.set('locations', [[45.528531, -122.681682], [45.530970, -122.661968], [45.522752, -122.657979]]);

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.ok(layerLatLngs[0].equals([45.528531, -122.681682]));
  assert.ok(layerLatLngs[1].equals([45.530970, -122.661968]));
  assert.ok(layerLatLngs[2].equals([45.522752, -122.657979]));
});
<commit_msg>correctly use replace<commit_after>import { A } from '@ember/array';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import {
  assertionInjector,
  assertionCleanup
} from '../../assertions';
import ArrayPathLayerComponent from 'ember-leaflet/components/array-path-layer';
import locations from '../../helpers/locations';

let arrayPath;

moduleForComponent('array-path-layer', 'Integration | Component | array path layer', {
  integration: true,
  beforeEach() {
    assertionInjector();

    this.register('component:custom-array-path-layer', ArrayPathLayerComponent.extend({
      init() {
        this._super(...arguments);
        arrayPath = this;
      },
      createLayer() {
        return this.L.polyline(...this.get('requiredOptions'), this.get('options'));
      }
    }));

    this.set('center', locations.nyc);
    this.set('zoom', 13);
  },
  afterEach() {
    assertionCleanup();
  }
});

test('replace locations updates array path layer', function(assert) {
  this.set('locations', [locations.chicago, locations.nyc, locations.sf]);

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);

  this.set('locations', [locations.paris, locations.london, locations.newdelhi]);

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.paris);
  assert.locationsEqual(layerLatLngs[1], locations.london);
  assert.locationsEqual(layerLatLngs[2], locations.newdelhi);
});

test('adding to locations updates array path layer', function(assert) {
  this.set('locations', A([locations.chicago, locations.nyc, locations.sf]));

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);

  this.get('locations').pushObject(locations.paris);

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);
  assert.locationsEqual(layerLatLngs[3], locations.paris);
});

test('removing from locations updates array path layer', function(assert) {
  this.set('locations', A([locations.chicago, locations.nyc, locations.sf]));

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);

  this.get('locations').popObject();

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.equal(layerLatLngs.length, 2);
});

test('replace item in content moves polyline', function(assert) {
  this.set('locations', A([locations.chicago, locations.nyc, locations.sf]));

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.nyc);
  assert.locationsEqual(layerLatLngs[2], locations.sf);

  this.get('locations').replace(1, 1, [locations.paris]);

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.locationsEqual(layerLatLngs[0], locations.chicago);
  assert.locationsEqual(layerLatLngs[1], locations.paris);
  assert.locationsEqual(layerLatLngs[2], locations.sf);
  assert.equal(layerLatLngs.length, 3);
});

test('supports array of arrays as well', function(assert) {
  this.set('locations', [[-43.123, 71.123], [-43.123, 71.123], [-43.123, 71.123]]);

  this.render(hbs`
    {{#leaflet-map zoom=zoom center=center}}
      {{custom-array-path-layer locations=locations}}
    {{/leaflet-map}}
  `);
  let layerLatLngs = arrayPath._layer.getLatLngs();
  assert.ok(layerLatLngs[0].equals([-43.123, 71.123]));
  assert.ok(layerLatLngs[1].equals([-43.123, 71.123]));
  assert.ok(layerLatLngs[2].equals([-43.123, 71.123]));

  this.set('locations', [[45.528531, -122.681682], [45.530970, -122.661968], [45.522752, -122.657979]]);

  layerLatLngs = arrayPath._layer.getLatLngs();
  assert.ok(layerLatLngs[0].equals([45.528531, -122.681682]));
  assert.ok(layerLatLngs[1].equals([45.530970, -122.661968]));
  assert.ok(layerLatLngs[2].equals([45.522752, -122.657979]));
});
<|endoftext|>


<commit_before>module.exports = {
  mainJS  : false, // 添加公共main.js
  devHost : '0.0.0.0',
  devPort : '1000',
  viewType: 'html', // pug,jade,html...
  cssType : 'css', // sass,scss,less,pcss,css...
  cdnPath : '/', // 资源指向位置,可寄放CDN
  version : '1.0.0' // 输出资源带版本号
};<commit_msg>修改端口为3000 输出文件优化为相对路劲<commit_after>module.exports = {
  mainJS  : false, // 添加公共main.js
  devHost : '0.0.0.0',
  devPort : '3000',
  viewType: 'html', // pug,jade,html...
  cssType : 'css', // sass,scss,less,pcss,css...
  cdnPath : './', // 资源指向位置,可寄放CDN
  version : '1.0.0' // 输出资源带版本号
};<|endoftext|>


<commit_before>var redisClient   = require('../redis_client/redisClient').getClient()
var configuration = require('../config/configuration.json')
var utility       = require('../../public/utility')

module.exports = {
  addIPAddressToSafeIPAddress: function(accountHashID, networkModel, callback) {
    var ipListTable = configuration.TableMSNetworkPrivacyIPList + accountHashID
    var score = utility.getUnixTimeStamp()
    var multi = redisClient.multi()
    multi.zadd(ipListTable, 'NX', score, networkModel.ipAddress)
    var ipAddressTable = configuration.TableMANetworkPrivacyIPDetails + networkModel.ipAddress
    multi.hmset(ipAddressTable,
      configuration.ConstantNPMMacAddress, networkModel.macAddress,
      configuration.ConstantNPMCountry, networkModel.country,
      configuration.ConstantNPMAgent, networkModel.agent,
      configuration.ConstantNPMISP, networkModel.isp
    )
    multi.exec(function (err, replies) {
      if (err)
        callback(err, null)
      callback(null, configuration.message.safeIPAddressAddition)
    })
  },

  checkUserNetworkChangeByCountry: function(accountHashID, countryType, callback) {
    var modelTable = configuration.TableMAAccountModel + accountHashID
    redisClient.hget(modelTable, configuration.ConstantAMRegistrationCountry, function(err, replies) {
      if (err)
        callback(err, null)
      if (replies === countryType)
        callback(null, configuration.message.country.notChanged)
      else
      {
        // do appropriate tasks
        callback(null, configuration.message.country.changed)
      }
    })
  },

  checkUserNetworkChangeByIPAddress: function(accountHashID, ipAddress, callback) {
    var ipListTable = configuration.TableMSNetworkPrivacyIPList + accountHashID
    redisClient.zscore(ipListTable, ipAddress, function(err, replies) {
      if (err)
        callback(err, null)
      if (replies !== 'null')
        callback(configuration.message.ipAddress.notChanged)
      else
      {
        // do appropriate tasks
        callback(configuration.message.ipAddress.changed)
      }
    })
  },

  checkUserNetworkChangeByMacAddress: function(accountHashID, macAddress, callback) {
    var modelTable = configuration.TableMAAccountModel + accountHashID
    redisClient.hget(modelTable, configuration.ConstantAMRegistrationMacAddress, function(err, replies) {
      if (err)
        callback(err, null)
      if (replies === macAddress)
        callback(null, configuration.message.madAddress.notChanged)
      else
      {
        // do appropriate tasks
        callback(null, configuration.message.madAddress.changed)
      }
    })
  }
}
<commit_msg>Modify And Add Starter Function<commit_after>var redisClient   = require('../redis_client/redisClient').getClient()
var configuration = require('../config/configuration.json')
var utility       = require('../../public/utility')

module.exports = {

  startNetworkChecking: function (accountHashID, networkModel, callback) {
    checkUserNetworkChangeByCountry(accountHashID, networkModel.country, function(err, replies) {
      if (err)
        callback(err, null)
      if (!replies)
        callback(new Error(configuration.message.country.Changed), null)

      checkUserNetworkChangeByIPAddress(accountHashID, networkModel.ipAddress, function(err, replies) {
        if (err)
          callback(err, null)
        if (!replies)
          callback(new Error(configuration.message.ipAddress.changed), null)

        checkUserNetworkChangeByMacAddress(accountHashID, networkModel.macAddress, function(err, replies) {
          if (err)
            callback(err, null)
          if (!replies)
            callback(new Error(configuration.message.macAddress.Changed), null)
        })
      })
    })
    //do apropriate task
    callback(null, 'networkModel not changed message')
  }
}

addIPAddressToSafeIPAddress: function(accountHashID, networkModel, callback) {
  var ipListTable = configuration.TableMSNetworkPrivacyIPList + accountHashID
  var score = utility.getUnixTimeStamp()
  var multi = redisClient.multi()
  multi.zadd(ipListTable, 'NX', score, networkModel.ipAddress)
  var ipAddressTable = configuration.TableMANetworkPrivacyIPDetails + networkModel.ipAddress
  multi.hmset(ipAddressTable,
    configuration.ConstantNPMMacAddress, networkModel.macAddress,
    configuration.ConstantNPMCountry, networkModel.country,
    configuration.ConstantNPMAgent, networkModel.agent,
    configuration.ConstantNPMISP, networkModel.isp
  )
  multi.exec(function (err, replies) {
    if (err)
      callback(err, null)
    callback(null, configuration.message.safeIPAddressAddition)
  })
},

checkUserNetworkChangeByCountry: function(accountHashID, countryType, callback) {
  var modelTable = configuration.TableMAAccountModel + accountHashID
  redisClient.hget(modelTable, configuration.ConstantAMRegistrationCountry, function(err, replies) {
    if (err)
      callback(err, null)
    if (replies !== countryType)
      callback(new Error('country changed message'), null)
    callback(null, true)
  })
},

checkUserNetworkChangeByIPAddress: function(accountHashID, ipAddress, callback) {
  var ipListTable = configuration.TableMSNetworkPrivacyIPList + accountHashID
  redisClient.zscore(ipListTable, ipAddress, function(err, replies) {
    if (err)
      callback(err, null)
    if (replies !== ipAddress)
      callback(new Error('ipAddress changed message'), null)
    callback(null, true)
  })
},

checkUserNetworkChangeByMacAddress: function(accountHashID, macAddress, callback) {
  var modelTable = configuration.TableMAAccountModel + accountHashID
  redisClient.hget(modelTable, configuration.ConstantAMRegistrationMacAddress, function(err, replies) {
    if (err)
      callback(err, null)
    if (replies !== macAddress)
      callback(new Error('macAddress changed message'), null)
    callback(null, true)
  })
}
}
<|endoftext|>


<commit_before>// PROJECTS
var updateProjects = function(projects) {
  // Render projects template
	var projects_template = $('#projects-template').html();
	Mustache.parse(projects_template);
	var rendered = Mustache.render(projects_template, projects);
	$('#projects-data').html(rendered);
  $("#projectsList").tablesorter( {sortList: [[0,0]]} );
}
var setupProjectsForm = function(projects) {
  updateProjects(projects);
};
var projects_template;
var projectData;
var setupProjects = function() {
	$.getJSON("/api/activities/", function(data) {
      projectData = data;
      setupProjectsForm(data);
	});
  $("#selectCountry").val("all").change();
};
setupProjects()
$(document).on("change", "#selectCountry", function(e) {
  if (e.currentTarget.value == "all") {
    var data = {}
  }
  else {
    var data = {
      'country_code': e.currentTarget.value
    }
  }
  $.post("/api/activities/", data, function(resultdata) {
    setupProjectsForm(resultdata);
  });
});<commit_msg>Resort table<commit_after>// PROJECTS
var updateProjects = function(projects) {
  // Render projects template
	var projects_template = $('#projects-template').html();
	Mustache.parse(projects_template);
	var rendered = Mustache.render(projects_template, projects);
	$('#projects-data').html(rendered);
  $("#projectsList").tablesorter( {sortList: [[3,1],[1,0],[0,0]]} );
}
var setupProjectsForm = function(projects) {
  updateProjects(projects);
};
var projects_template;
var projectData;
var setupProjects = function() {
	$.getJSON("/api/activities/", function(data) {
      projectData = data;
      setupProjectsForm(data);
	});
  $("#selectCountry").val("all").change();
};
setupProjects()
$(document).on("change", "#selectCountry", function(e) {
  if (e.currentTarget.value == "all") {
    var data = {}
  }
  else {
    var data = {
      'country_code': e.currentTarget.value
    }
  }
  $.post("/api/activities/", data, function(resultdata) {
    setupProjectsForm(resultdata);
  });
});<|endoftext|>


<commit_before>(function() {
  'use strict';
  /* global hash  */
  /* global jQuery  */
  /* global chroma  */
  /* global Kartograph */
  var STROKE_WIDTH = 1.5;
  var RIVER_WIDTH = STROKE_WIDTH * 2;
  var ANIMATION_TIME_MS = 500;

  angular.module('blindMaps.map', [])

  .value('chroma', chroma)

  .value('$', jQuery)

  .value('$K', Kartograph)

  .value('colors', {
    'GOOD': '#0d0',
    'BAD': '#ff0000',
    'NEUTRAL': '#bbb',
    'BRIGHT_GRAY' : '#ddd',
    'WATER_COLOR' : '#73c5ef'
  })

  .value('stateAlternatives', [
    "region",
    "province",
    "region_cz",
    "region_it",
    "bundesland",
    "autonomous_comunity",
  ])

  .factory('colorScale', function(colors, chroma) {
    var scale = chroma.scale([
        colors.BAD,
        '#ff4500',
        '#ffa500',
        '#ffff00',
        colors.GOOD
      ]);
    return scale;
  })

  .factory('getLayerConfig', function($log, colors, colorScale, citySizeRatio, stateAlternatives) {
    return function(config) {
      var layerConfig = {};
      layerConfig.bg = {
        'styles' : {
          'fill' : colors.BRIGHT_GRAY,
          'stroke-width' : STROKE_WIDTH,
          'transform' : ''
        }
      };

      layerConfig.state = {
        'styles' : {
          'fill' : function(d) {
            var state = config.places && config.places[d.code];
            return state ?
              colorScale(state.probability).brighten((1 - state.certainty) * 80).hex() :
              '#fff';
          },
          'stroke-width' : STROKE_WIDTH,
          'transform' : ''
        },
        'click' : function(data) {
          $log.log(data.code);
          if (config.click !== undefined) {
            config.click(data.code);
          }
        }
      };

      angular.forEach(stateAlternatives.concat('island', 'mountains'), function(sa){
        layerConfig[sa] = angular.copy(layerConfig.state);
      });

      layerConfig.river = angular.extend(angular.extend({}, layerConfig.state), {
        'styles' : {
          'stroke-width' : RIVER_WIDTH,
          'stroke' : colors.WATER_COLOR,
          'transform' : ''
        },
        'mouseenter' : function(data, path) {
          var zoomRatio = 4;
          var animAttrs = { 'stroke-width' : zoomRatio * RIVER_WIDTH };
          path.animate(animAttrs, ANIMATION_TIME_MS / 2, '>');
        },
        'mouseleave' : function(data, path) {
          var animAttrs = { 'stroke-width' : RIVER_WIDTH };
          path.animate(animAttrs, ANIMATION_TIME_MS / 2, '>');
        }
      });

      layerConfig.city = angular.extend(angular.extend({},layerConfig.state), {
        'mouseenter' : function(data, path) {
          path.toFront();
          var zoomRatio = 2.5 / citySizeRatio(data.population);
          var animAttrs = {
              'transform' : 's' + zoomRatio,
              'stroke-width' : zoomRatio * STROKE_WIDTH
            };
          path.animate(animAttrs, ANIMATION_TIME_MS / 2, '>');
        },
        'mouseleave' : function(data, path) {
          var animAttrs = {
              'transform' : '',
              'stroke-width' : STROKE_WIDTH
            };
          path.animate(animAttrs, ANIMATION_TIME_MS / 2, '>');
        }
      });

      layerConfig.lakes = angular.copy(layerConfig.city, {});
      layerConfig.lakes.styles.fill = function(d) {
        var state = config.places && config.places[d.name];
        return state ?
          colorScale(state.probability).brighten((1 - state.certainty) * 80).hex() :
          colors.WATER_COLOR;
      };
      return layerConfig;
    };
  })

  .factory('initLayers', function(getLayerConfig, stateAlternatives) {

    function _hideLayer(layer){
      var paths = layer ? layer.getPaths({}) : [];
      angular.forEach(paths, function(path) {
        path.svgPath.hide();
      });
    }

    return function(map, config) {
      var layersConfig = getLayerConfig(config);
      var layersArray = [];
      for (var i in layersConfig) {
        map.addLayer(i, layersConfig[i]);
        var l = map.getLayer(i);
        if (l && l.id != 'bg') {
          layersArray.push(l);
          _hideLayer(l);
        }
      }
      var that = {
        hideLayer : function(layer) {
          _hideLayer(layer);
        },
        showLayer : function(layer) {
          var paths = layer ? layer.getPaths({}) : [];
          angular.forEach(paths, function(path) {
            path.svgPath.show();
          });
        },
        getLayerBySlug: function(slug) {
          var ret;
          angular.forEach(layersArray, function(l) {
            if (l.id == slug) {
              ret = l;
            }
          });
          return ret;
        },
        getAll : function(){
          return layersArray;
        },
        getConfig : function(layer){
          return layersConfig[layer.id];
        },
        getStateAlternative : function() {
          var ret;
          angular.forEach(stateAlternatives.concat(['state']), function(alternative){
            l = that.getLayerBySlug(alternative);
            if (l) {
              ret = l;
            }
          });
          return ret;
        }
      };
      return that;
    };
  })

  .factory('mapFunctions', function($timeout, $, stateAlternatives){
    var bboxCache = {};
    var that = {
      getZoomRatio : function(placePath) {
        if (!bboxCache[placePath.data.code]) {
          bboxCache[placePath.data.code] = placePath.svgPath.getBBox();
        }
        var bbox = bboxCache[placePath.data.code];
        var bboxArea = bbox.width * bbox.height;
        var zoomRatio = Math.max(1.2, 70 / Math.sqrt(bboxArea));
        return zoomRatio;
      },
      initMapZoom : function(paper) {
        var panZoom = paper.panzoom({});
        panZoom.enable();

        $('#zoom-in').click(function(e) {
          panZoom.zoomIn(1);
          e.preventDefault();
        });

        $('#zoom-out').click(function(e) {
          panZoom.zoomOut(1);
          e.preventDefault();
        });
        return panZoom;
      },
      getHighlightAnimationAttributes : function(placePath, layer, origStroke, color, zoomRatio) {
        zoomRatio = zoomRatio || that.getZoomRatio(placePath);
        var animAttrs = {
            transform : 's' + zoomRatio,
            'stroke-width' : Math.min(6, zoomRatio) * origStroke
          };
        if (color) {
          if (layer.id == 'river') {
            animAttrs.stroke = color;
          } else {
            animAttrs.fill = color;
          }
        }
        return animAttrs;
      },
      isStateAlternative : function (id) {
        var ret;
        angular.forEach(stateAlternatives.concat(['state']), function(alternative){
          if (id == alternative) {
            ret = alternative;
          }
        });
        return ret;
      }
    };
    return that;
  })

  .factory('getTooltipGetter', function($filter, colorScale){
    return function(config) {
      return function(d) {
        var state = config.places && config.places[d.code];
        var name = ( state ?
          '
' +
            ' ' +
            state.name +
            '
' :
          '
Zatím neprocvičováno

');
        var description = (state ?
          '
' +
            ' Odhad znalosti: ' +
              '' +
                '' +
                Math.round(100 * state.probability) + '% ' +
              '

' +
            (d.population ? ' Počet obyvatel: ' +
              '' +
                $filter('number')(d.population) +
              '

' : '') +
          '
' :
          '');
        return [
          name + description,
          config.places[d.code] ? config.places[d.code].name : ''
        ];
      };
    };
  })

  .service('citySizeRatio', function(){
    var min_pop_ratios = [
      [5000000, 1.8],
      [1000000, 1.4],
      [500000, 1.2],
      [100000, 1],
      [30000, 0.8],
      [0, 0.6]
    ];

    return function (population) {
      for (var i = 0; i < min_pop_ratios.length; i++) {
        if (population > min_pop_ratios[i][0]) {
          return min_pop_ratios[i][1];
        }
      }
    };
  })

  .service('getMapResizeFunction', function($, citySizeRatio){

    function getNewHeight(mapAspectRatio, isPractise, holderInitHeight) {
      $('#ng-view').removeClass('horizontal');
      var newHeight;
      if (isPractise) {
        var screenAspectRatio = $(window).height() / $(window).width();
        if (screenAspectRatio - mapAspectRatio < -0.2) {
          $('#ng-view').addClass('horizontal');
          newHeight = $(window).height();
        } else {
          var controlsHeight = $(window).width() > 767 ? 290 : 200;
          newHeight = $(window).height() - controlsHeight;
        }
      } else if (holderInitHeight / mapAspectRatio >= $(window).width()) {
        newHeight = Math.max(holderInitHeight / 2, mapAspectRatio * $(window).width());
      } else {
        newHeight = holderInitHeight;
      }
      return newHeight;
    }

    var initCitySizes = {};

    function setCitiesSize(layer, currZoom) {
      currZoom = currZoom || 0;
      var paths = layer.paths;
      angular.forEach(paths, function(path) {
        var initSize = initCitySizes[path.data.code] || path.svgPath.attr("r");
        initCitySizes[path.data.code] = initSize;
        var newRadius = initSize * citySizeRatio(path.data.population) * (1 - (currZoom * 0.08));
        path.svgPath.attr({r: newRadius});
      });
    }

    return function(m, holder, practice) {
      var holderInitHeight = holder.height();
      var panZoom = m.panZoom;
      var map = m.map;
      var mapAspectRatio = map.viewAB.height / map.viewAB.width;

      return function () {
        var newHeight = getNewHeight(mapAspectRatio, practice, holderInitHeight);
        holder.height(newHeight);
        map.resize();
        if (panZoom) {
          panZoom.zoomIn(1);
          panZoom.zoomOut(1);
          panZoom.onZoomChange(function(currZoom) {
            setCitiesSize(l, currZoom);
          });
        }
        if (practice) {
          $("html, body").animate({ scrollTop: ($('.navbar').height() - 8) + "px" });
        }
        var l = map.getLayer("city");
        if(l) {
          setCitiesSize(l);
        }
      };
    };
  })

  .service('singleWindowResizeFn', function($){
    var fn = function(){};
    $(window).resize(function() {
      fn();
    });
    return function(newFn) {
      fn = newFn;
    };
  })

  .factory('mapControler', function($, $K, mapFunctions, initLayers, $filter, getTooltipGetter) {

    $.fn.qtip.defaults.style.classes = 'qtip-dark';

    return function(mapCode, showTooltips, holder, callback) {
      var config = { state : [] };
      var layers;
      var _placesByTypes;

      config.showTooltips = showTooltips;
      config.isPractise = !showTooltips;
      config.places = [];

      var myMap = {
        map :  $K.map(holder),
        panZoom : undefined,
        onClick : function(clickFn) {
          config.click = function(code) {
            if (!myMap.panZoom.isDragging()) {
              clickFn(code);
            }
          };
        },
        highlightStates : function(states, color, zoomRatio) {
          var state = states.pop();
          var layer = this.getLayerContaining(state);
          var placePath = layer ? layer.getPaths({ code : state })[0] : undefined;
          if (placePath) {
            placePath.svgPath.toFront();
            var origStroke = layers.getConfig(layer).styles['stroke-width'];
            var animAttrs = mapFunctions.getHighlightAnimationAttributes(placePath, layer,
                origStroke, color, zoomRatio);
            placePath.svgPath.animate(animAttrs, ANIMATION_TIME_MS / 2, '>', function() {
              placePath.svgPath.animate({
                transform : '',
                'stroke-width' : origStroke
              }, ANIMATION_TIME_MS / 2, '<');
              myMap.highlightStates(states, color);
            });
          } else if (states.length > 0) {
            myMap.highlightStates(states, color);
          }
        },
        highlightState : function(state, color, zoomRatio) {
          myMap.highlightStates([state], color, zoomRatio);
        },
        clearHighlights : function() {
          angular.forEach(layers.getAll(), function(layer) {
            layer.style(layers.getConfig(layer).styles);
            layers.showLayer(layer);
          });
        },
        updatePlaces : function(placesByTypes) {
          if (layers === undefined) {
            _placesByTypes = placesByTypes;
            return;
          }
          angular.forEach(placesByTypes, function(type) {
            var l = layers.getLayerBySlug(type.slug);
            if (type.hidden) {
              layers.hideLayer(l);
            } else {
              layers.showLayer(l);
            }
          });

          var places = $filter('StatesFromPlaces')(placesByTypes);
          config.places = places;
          angular.forEach(layers.getAll(), function(layer) {
            var layerConfig = layers.getConfig(layer);
            layer.style('fill', layerConfig.styles.fill);
            if (config.showTooltips) {
              layer.tooltips(getTooltipGetter(config));
            }

          });
        },
        getLayerContaining : function(placeCode) {
          var ret;
          angular.forEach(layers.getAll(), function(layer) {
            if (layer.getPaths({ code : placeCode }).length >= 1) {
              ret = layer;
            }
          });
          return ret;
        },
        showLayerContaining : function(placeCode) {
          var l = myMap.getLayerContaining(placeCode);
          layers.showLayer(l);
          if (l && l.id == "city") {
            layers.showLayer(layers.getStateAlternative());
          }
        },
        highLightLayer : function(layer) {
          angular.forEach(layers.getAll(), function(l) {
            if (l == layer || (layer && layer.id == 'city' && mapFunctions.isStateAlternative(l.id))) {
              layers.showLayer(l);
            }
            else {
              layers.hideLayer(l);
            }
          });
        },
        hideLayers : function() {
          angular.forEach(layers.getAll(), function(l) {
            layers.hideLayer(l);
          });
        },
        placeToFront : function(placeCode) {
          angular.forEach(layers.getAll(), function(layer) {
            var place = layer.getPaths({ code : placeCode })[0];
            if (place) {
              place.svgPath.toFront();
            }
          });
        }
      };

      myMap.map.loadCSS(hash('static/css/map.css'), function() {
        myMap.map.loadMap(hash('static/map/' + mapCode + '.svg'), function() {
          layers = initLayers(myMap.map, config);
          if (_placesByTypes !== undefined) {
            myMap.updatePlaces(_placesByTypes);
          }
          myMap.panZoom = mapFunctions.initMapZoom(myMap.map.paper);
          callback(myMap);
        });
      });
      return myMap;
    };
  });
}());
<commit_msg>Fix zoom bug<commit_after>(function() {
  'use strict';
  /* global hash  */
  /* global jQuery  */
  /* global chroma  */
  /* global Kartograph */
  var STROKE_WIDTH = 1.5;
  var RIVER_WIDTH = STROKE_WIDTH * 2;
  var ANIMATION_TIME_MS = 500;

  angular.module('blindMaps.map', [])

  .value('chroma', chroma)

  .value('$', jQuery)

  .value('$K', Kartograph)

  .value('colors', {
    'GOOD': '#0d0',
    'BAD': '#ff0000',
    'NEUTRAL': '#bbb',
    'BRIGHT_GRAY' : '#ddd',
    'WATER_COLOR' : '#73c5ef'
  })

  .value('stateAlternatives', [
    "region",
    "province",
    "region_cz",
    "region_it",
    "bundesland",
    "autonomous_comunity",
  ])

  .factory('colorScale', function(colors, chroma) {
    var scale = chroma.scale([
        colors.BAD,
        '#ff4500',
        '#ffa500',
        '#ffff00',
        colors.GOOD
      ]);
    return scale;
  })

  .factory('getLayerConfig', function($log, colors, colorScale, citySizeRatio, stateAlternatives) {
    return function(config) {
      var layerConfig = {};
      layerConfig.bg = {
        'styles' : {
          'fill' : colors.BRIGHT_GRAY,
          'stroke-width' : STROKE_WIDTH,
          'transform' : ''
        }
      };

      layerConfig.state = {
        'styles' : {
          'fill' : function(d) {
            var state = config.places && config.places[d.code];
            return state ?
              colorScale(state.probability).brighten((1 - state.certainty) * 80).hex() :
              '#fff';
          },
          'stroke-width' : STROKE_WIDTH,
          'transform' : ''
        },
        'click' : function(data) {
          $log.log(data.code);
          if (config.click !== undefined) {
            config.click(data.code);
          }
        }
      };

      angular.forEach(stateAlternatives.concat('island', 'mountains'), function(sa){
        layerConfig[sa] = angular.copy(layerConfig.state);
      });

      layerConfig.river = angular.extend(angular.extend({}, layerConfig.state), {
        'styles' : {
          'stroke-width' : RIVER_WIDTH,
          'stroke' : colors.WATER_COLOR,
          'transform' : ''
        },
        'mouseenter' : function(data, path) {
          var zoomRatio = 4;
          var animAttrs = { 'stroke-width' : zoomRatio * RIVER_WIDTH };
          path.animate(animAttrs, ANIMATION_TIME_MS / 2, '>');
        },
        'mouseleave' : function(data, path) {
          var animAttrs = { 'stroke-width' : RIVER_WIDTH };
          path.animate(animAttrs, ANIMATION_TIME_MS / 2, '>');
        }
      });

      layerConfig.city = angular.extend(angular.extend({},layerConfig.state), {
        'mouseenter' : function(data, path) {
          path.toFront();
          var zoomRatio = 2.5 / citySizeRatio(data.population);
          var animAttrs = {
              'transform' : 's' + zoomRatio,
              'stroke-width' : zoomRatio * STROKE_WIDTH
            };
          path.animate(animAttrs, ANIMATION_TIME_MS / 2, '>');
        },
        'mouseleave' : function(data, path) {
          var animAttrs = {
              'transform' : '',
              'stroke-width' : STROKE_WIDTH
            };
          path.animate(animAttrs, ANIMATION_TIME_MS / 2, '>');
        }
      });

      layerConfig.lakes = angular.copy(layerConfig.city, {});
      layerConfig.lakes.styles.fill = function(d) {
        var state = config.places && config.places[d.name];
        return state ?
          colorScale(state.probability).brighten((1 - state.certainty) * 80).hex() :
          colors.WATER_COLOR;
      };
      return layerConfig;
    };
  })

  .factory('initLayers', function(getLayerConfig, stateAlternatives) {

    function _hideLayer(layer){
      var paths = layer ? layer.getPaths({}) : [];
      angular.forEach(paths, function(path) {
        path.svgPath.hide();
      });
    }

    return function(map, config) {
      var layersConfig = getLayerConfig(config);
      var layersArray = [];
      for (var i in layersConfig) {
        map.addLayer(i, layersConfig[i]);
        var l = map.getLayer(i);
        if (l && l.id != 'bg') {
          layersArray.push(l);
          _hideLayer(l);
        }
      }
      var that = {
        hideLayer : function(layer) {
          _hideLayer(layer);
        },
        showLayer : function(layer) {
          var paths = layer ? layer.getPaths({}) : [];
          angular.forEach(paths, function(path) {
            path.svgPath.show();
          });
        },
        getLayerBySlug: function(slug) {
          var ret;
          angular.forEach(layersArray, function(l) {
            if (l.id == slug) {
              ret = l;
            }
          });
          return ret;
        },
        getAll : function(){
          return layersArray;
        },
        getConfig : function(layer){
          return layersConfig[layer.id];
        },
        getStateAlternative : function() {
          var ret;
          angular.forEach(stateAlternatives.concat(['state']), function(alternative){
            l = that.getLayerBySlug(alternative);
            if (l) {
              ret = l;
            }
          });
          return ret;
        }
      };
      return that;
    };
  })

  .factory('mapFunctions', function($timeout, $, stateAlternatives){
    var bboxCache = {};
    var that = {
      getZoomRatio : function(placePath) {
        if (!bboxCache[placePath.data.code]) {
          bboxCache[placePath.data.code] = placePath.svgPath.getBBox();
        }
        var bbox = bboxCache[placePath.data.code];
        var bboxArea = bbox.width * bbox.height;
        var zoomRatio = Math.max(1.2, 70 / Math.sqrt(bboxArea));
        return zoomRatio;
      },
      initMapZoom : function(paper) {
        var panZoom = paper.panzoom({});
        panZoom.enable();

        $('#zoom-in').click(function(e) {
          panZoom.zoomIn(1);
          e.preventDefault();
        });

        $('#zoom-out').click(function(e) {
          panZoom.zoomOut(1);
          e.preventDefault();
        });
        return panZoom;
      },
      getHighlightAnimationAttributes : function(placePath, layer, origStroke, color, zoomRatio) {
        zoomRatio = zoomRatio || that.getZoomRatio(placePath);
        var animAttrs = {
            transform : 's' + zoomRatio,
            'stroke-width' : Math.min(6, zoomRatio) * origStroke
          };
        if (color) {
          if (layer.id == 'river') {
            animAttrs.stroke = color;
          } else {
            animAttrs.fill = color;
          }
        }
        return animAttrs;
      },
      isStateAlternative : function (id) {
        var ret;
        angular.forEach(stateAlternatives.concat(['state']), function(alternative){
          if (id == alternative) {
            ret = alternative;
          }
        });
        return ret;
      }
    };
    return that;
  })

  .factory('getTooltipGetter', function($filter, colorScale){
    return function(config) {
      return function(d) {
        var state = config.places && config.places[d.code];
        var name = ( state ?
          '
' +
            ' ' +
            state.name +
            '
' :
          '
Zatím neprocvičováno

');
        var description = (state ?
          '
' +
            ' Odhad znalosti: ' +
              '' +
                '' +
                Math.round(100 * state.probability) + '% ' +
              '

' +
            (d.population ? ' Počet obyvatel: ' +
              '' +
                $filter('number')(d.population) +
              '

' : '') +
          '
' :
          '');
        return [
          name + description,
          config.places[d.code] ? config.places[d.code].name : ''
        ];
      };
    };
  })

  .service('citySizeRatio', function(){
    var min_pop_ratios = [
      [5000000, 1.8],
      [1000000, 1.4],
      [500000, 1.2],
      [100000, 1],
      [30000, 0.8],
      [0, 0.6]
    ];

    return function (population) {
      for (var i = 0; i < min_pop_ratios.length; i++) {
        if (population > min_pop_ratios[i][0]) {
          return min_pop_ratios[i][1];
        }
      }
    };
  })

  .service('getMapResizeFunction', function($, citySizeRatio){

    function getNewHeight(mapAspectRatio, isPractise, holderInitHeight) {
      $('#ng-view').removeClass('horizontal');
      var newHeight;
      if (isPractise) {
        var screenAspectRatio = $(window).height() / $(window).width();
        if (screenAspectRatio - mapAspectRatio < -0.2) {
          $('#ng-view').addClass('horizontal');
          newHeight = $(window).height();
        } else {
          var controlsHeight = $(window).width() > 767 ? 290 : 200;
          newHeight = $(window).height() - controlsHeight;
        }
      } else if (holderInitHeight / mapAspectRatio >= $(window).width()) {
        newHeight = Math.max(holderInitHeight / 2, mapAspectRatio * $(window).width());
      } else {
        newHeight = holderInitHeight;
      }
      return newHeight;
    }

    var initCitySizes = {};

    function setCitiesSize(layer, currZoom) {
      if (!layer) {
        return;
      }
      currZoom = currZoom || 0;
      var paths = layer.paths;
      angular.forEach(paths, function(path) {
        var initSize = initCitySizes[path.data.code] || path.svgPath.attr("r");
        initCitySizes[path.data.code] = initSize;
        var newRadius = initSize * citySizeRatio(path.data.population) * (1 - (currZoom * 0.08));
        path.svgPath.attr({r: newRadius});
      });
    }

    return function(m, holder, practice) {
      var holderInitHeight = holder.height();
      var panZoom = m.panZoom;
      var map = m.map;
      var mapAspectRatio = map.viewAB.height / map.viewAB.width;

      return function () {
        var newHeight = getNewHeight(mapAspectRatio, practice, holderInitHeight);
        holder.height(newHeight);
        map.resize();
        if (panZoom) {
          panZoom.zoomIn(1);
          panZoom.zoomOut(1);
          panZoom.onZoomChange(function(currZoom) {
            setCitiesSize(map.getLayer("city"), currZoom);
          });
        }
        if (practice) {
          $("html, body").animate({ scrollTop: ($('.navbar').height() - 8) + "px" });
        }
        setCitiesSize(map.getLayer("city"));
      };
    };
  })

  .service('singleWindowResizeFn', function($){
    var fn = function(){};
    $(window).resize(function() {
      fn();
    });
    return function(newFn) {
      fn = newFn;
    };
  })

  .factory('mapControler', function($, $K, mapFunctions, initLayers, $filter, getTooltipGetter) {

    $.fn.qtip.defaults.style.classes = 'qtip-dark';

    return function(mapCode, showTooltips, holder, callback) {
      var config = { state : [] };
      var layers;
      var _placesByTypes;

      config.showTooltips = showTooltips;
      config.isPractise = !showTooltips;
      config.places = [];

      var myMap = {
        map :  $K.map(holder),
        panZoom : undefined,
        onClick : function(clickFn) {
          config.click = function(code) {
            if (!myMap.panZoom.isDragging()) {
              clickFn(code);
            }
          };
        },
        highlightStates : function(states, color, zoomRatio) {
          var state = states.pop();
          var layer = this.getLayerContaining(state);
          var placePath = layer ? layer.getPaths({ code : state })[0] : undefined;
          if (placePath) {
            placePath.svgPath.toFront();
            var origStroke = layers.getConfig(layer).styles['stroke-width'];
            var animAttrs = mapFunctions.getHighlightAnimationAttributes(placePath, layer,
                origStroke, color, zoomRatio);
            placePath.svgPath.animate(animAttrs, ANIMATION_TIME_MS / 2, '>', function() {
              placePath.svgPath.animate({
                transform : '',
                'stroke-width' : origStroke
              }, ANIMATION_TIME_MS / 2, '<');
              myMap.highlightStates(states, color);
            });
          } else if (states.length > 0) {
            myMap.highlightStates(states, color);
          }
        },
        highlightState : function(state, color, zoomRatio) {
          myMap.highlightStates([state], color, zoomRatio);
        },
        clearHighlights : function() {
          angular.forEach(layers.getAll(), function(layer) {
            layer.style(layers.getConfig(layer).styles);
            layers.showLayer(layer);
          });
        },
        updatePlaces : function(placesByTypes) {
          if (layers === undefined) {
            _placesByTypes = placesByTypes;
            return;
          }
          angular.forEach(placesByTypes, function(type) {
            var l = layers.getLayerBySlug(type.slug);
            if (type.hidden) {
              layers.hideLayer(l);
            } else {
              layers.showLayer(l);
            }
          });

          var places = $filter('StatesFromPlaces')(placesByTypes);
          config.places = places;
          angular.forEach(layers.getAll(), function(layer) {
            var layerConfig = layers.getConfig(layer);
            layer.style('fill', layerConfig.styles.fill);
            if (config.showTooltips) {
              layer.tooltips(getTooltipGetter(config));
            }

          });
        },
        getLayerContaining : function(placeCode) {
          var ret;
          angular.forEach(layers.getAll(), function(layer) {
            if (layer.getPaths({ code : placeCode }).length >= 1) {
              ret = layer;
            }
          });
          return ret;
        },
        showLayerContaining : function(placeCode) {
          var l = myMap.getLayerContaining(placeCode);
          layers.showLayer(l);
          if (l && l.id == "city") {
            layers.showLayer(layers.getStateAlternative());
          }
        },
        highLightLayer : function(layer) {
          angular.forEach(layers.getAll(), function(l) {
            if (l == layer || (layer && layer.id == 'city' && mapFunctions.isStateAlternative(l.id))) {
              layers.showLayer(l);
            }
            else {
              layers.hideLayer(l);
            }
          });
        },
        hideLayers : function() {
          angular.forEach(layers.getAll(), function(l) {
            layers.hideLayer(l);
          });
        },
        placeToFront : function(placeCode) {
          angular.forEach(layers.getAll(), function(layer) {
            var place = layer.getPaths({ code : placeCode })[0];
            if (place) {
              place.svgPath.toFront();
            }
          });
        }
      };

      myMap.map.loadCSS(hash('static/css/map.css'), function() {
        myMap.map.loadMap(hash('static/map/' + mapCode + '.svg'), function() {
          layers = initLayers(myMap.map, config);
          if (_placesByTypes !== undefined) {
            myMap.updatePlaces(_placesByTypes);
          }
          myMap.panZoom = mapFunctions.initMapZoom(myMap.map.paper);
          callback(myMap);
        });
      });
      return myMap;
    };
  });
}());
<|endoftext|>


<commit_before>import distance from './distance';
import mass from './mass';
import currency from './currency';
import temperature from './temperature';

const icon = '/Applications/Calculator.app';

// Array of all available converters
const CONVERTERS = [
  distance,
  mass,
  currency,
  temperature,
];

const numberRegexp = /-?\d+(?:(?:\.|,)\d+)?/;
const unitRegexp = /[\wa-я\$€£'"°℃]+/;

const mainRegexpString = [
  // Start of line
  '^',
  // Number that we want to convert
  `(${numberRegexp.source})`,
  // Maybe space before source unit
  '\\s?',
  // Source unit name
  `(${unitRegexp.source})`,
  // Maybe spaces and any of word, like 'to' or 'in'
  '\\s*(?:to|in|at|в)?\\s*',
  // Maybe target unit (we can try to get default target unit by source unit)
  `(${unitRegexp.source})?`,
  // End of line
  '$'
].join('');

// Main regexp to match conversation strings
const REGEXP = new RegExp(mainRegexpString, 'i');

/**
 * Get rates for all units
 * @return {Promise} promise that resolves when all units are ready
 */
function eachConverter(fn) {
  CONVERTERS.forEach(converter => {
    converter.getRates().then(() => fn(converter));
  });
}

/**
 * Convert currency
 * @param  {String} term
 */
const converterPlugin = (term, callback) => {
  const match = term.toLowerCase().match(REGEXP);
  if (match) {
    const amount = parseFloat(match[1].toString().replace(',', '.'));
    eachConverter(converter => {
      const pair = converter.extract(match);
      if (!pair) {
        return;
      }
      const [from, to] = pair;
      const result = converter.convert(amount, from, to).toLocaleString();
      callback({
        icon,
        id: `converter-${from.unit}-${to.unit}`,
        title: `${amount.toLocaleString()}${from.displayName} = ${result}${to.displayName}`,
        term: `${term} = ${result}${to.displayName}`,
        clipboard: result.toString(),
      });
    });
  }
};

export default {
  name: 'Convert',
  fn: converterPlugin,
};
<commit_msg>Allow to do math operations in converter plugin<commit_after>import distance from './distance';
import mass from './mass';
import currency from './currency';
import temperature from './temperature';

const icon = '/Applications/Calculator.app';

// Array of all available converters
const CONVERTERS = [
  distance,
  mass,
  currency,
  temperature,
];

const numberRegexp = /[-+/*\d\s,\.\( )]+/;
const unitRegexp = /[\wa-я\$€£'"°℃]+/;

const mainRegexpString = [
  // Start of line
  '^',
  // Number that we want to convert
  `(${numberRegexp.source})`,
  // Maybe space before source unit
  '\\s?',
  // Source unit name
  `(${unitRegexp.source})`,
  // Maybe spaces and any of word, like 'to' or 'in'
  '\\s*(?:to|in|at|в)?\\s*',
  // Maybe target unit (we can try to get default target unit by source unit)
  `(${unitRegexp.source})?`,
  // End of line
  '$'
].join('');

// Main regexp to match conversation strings
const REGEXP = new RegExp(mainRegexpString, 'i');

/**
 * Get rates for all units
 * @return {Promise} promise that resolves when all units are ready
 */
function eachConverter(fn) {
  CONVERTERS.forEach(converter => {
    converter.getRates().then(() => fn(converter));
  });
}

/**
 * Convert currency
 * @param  {String} term
 */
const converterPlugin = (term, callback) => {
  const match = term.toLowerCase().match(REGEXP);
  console.log(match);
  if (match) {
    let amount;
    try {
      amount = parseFloat(eval(match[1].toString().replace(/,/g, '.')));
    } catch (err) {
      // do nothing when amount parse failed
      return;
    }
    eachConverter(converter => {
      const pair = converter.extract(match);
      if (!pair) {
        return;
      }
      const [from, to] = pair;
      const result = converter.convert(amount, from, to).toLocaleString();
      callback({
        icon,
        id: `converter-${from.unit}-${to.unit}`,
        title: `${amount.toLocaleString()}${from.displayName} = ${result}${to.displayName}`,
        term: `${term} = ${result}${to.displayName}`,
        clipboard: result.toString(),
      });
    });
  }
};

export default {
  name: 'Convert',
  fn: converterPlugin,
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

var util = require('util');
var config = require('./config');
var fs = require('fs');

util.log("velbusweb starting");

process.on('SIGINT', function () {
	util.log('Caught SIGINT, quitting');
	process.exit(0);
});

var velbus = require('./velbus').ctor(config.velbusd.host, config.velbusd.port);
velbus.on('error', function(e) {
	util.log("velbus connection error: " + e.syscall + " -> " + e.code);
});
velbus.on('connect', function() {
	util.log('velbus connection opened');
});
velbus.on('close', function() {
	util.log('velbus connection closed');
});

velbus.on('resync', function(why) {
	util.log('velbus connection: lost sync: ' + why + ', resyncing');
});

var vbm = require('./velbusMessage');
velbus.on('message', function(data) {
	//util.log('velbus connection: message: ' + util.inspect(data) );
	vbm.parse(data);
});

var express = require('express');
var webapp = express.createServer();

webapp.configure(function() {
	webapp.use( express.logger() );
	//webapp.use( express.bodyParser() );
	//webapp.use( express.cookieParser(...) );
	//webapp.use( express.session(...) );
	webapp.use( webapp.router );
	webapp.use( express.static(__dirname + '/public') );
});
webapp.configure('development', function() {
	webapp.use( express.errorHandler({ dumpExceptions: true, showStack: true }) );
});
webapp.configure('production', function() {
	webapp.use(express.errorHandler() );
});

webapp.listen(config.webapp.port);
util.log("webserver listening on " +
	webapp.address().address + ':' + webapp.address().port +
	" in " + webapp.settings.env + " mode");

webapp.get('/js/controls.js', function(req, res, next) {
	// Generate the concatenated JS file of the content
	fs.readdir('public/js/controls', function(err, files) {
		if( err !== null ) { next(err); }
		var body = '';
		for( var f in files ) {
			var fn = files[f];
			// Read all files
			fs.readFile('public/js/controls/' + fn, function(err, data) {
				if( err !== null ) { next(err); }
				// Append content to the body
				body += data + "\n";
				// Remove us from the todo list
				files.splice( files.indexOf(fn), 1 );

				if( files.length == 0 ) {
					// We are the last one to finish, send output
					res.send(body, {'Content-Type': 'application/javascript'} );
				}
			});
		}
	});
});

webapp.get(/\/control\/relay\/([0-9a-fA-F]{2}).([1-4])(?:\/([a-zA-Z ]*))?$/, function(req, res, next) {
	var id = parseInt( req.params[0], 16 );
	var relay = parseInt( req.params[1] );
	var field = req.params[2];

	// Set up listener for the answer
	var timeout;
	var send_answer = function(msg) {
		clearTimeout(timeout);
		if( field != undefined && field != '' ) {
			if( msg.hasOwnProperty(field) ) {
				res.send( msg[field].toString(), {'Content-Type': 'text/plain'} );
			} else {
				res.send("Unknown property", 500);
			}
		} else {
			res.send(msg);
		}
	};
	vbm.once('relay status ' + id + '.' + relay, send_answer);
	timeout = setTimeout(function() {
			vbm.removeListener('relay status ' + id + '.' + relay, send_answer);
			res.send("Timeout", 500);
		}, config.webapp.timeout);

	// Now send the request
	var relaybit = 1 << (relay-1);
	velbus.send_message(3, id, 0, "\xfa" + String.fromCharCode(relaybit) );
});
<commit_msg>Moved relaybit higher up<commit_after>#!/usr/bin/env node

var util = require('util');
var config = require('./config');
var fs = require('fs');

util.log("velbusweb starting");

process.on('SIGINT', function () {
	util.log('Caught SIGINT, quitting');
	process.exit(0);
});

var velbus = require('./velbus').ctor(config.velbusd.host, config.velbusd.port);
velbus.on('error', function(e) {
	util.log("velbus connection error: " + e.syscall + " -> " + e.code);
});
velbus.on('connect', function() {
	util.log('velbus connection opened');
});
velbus.on('close', function() {
	util.log('velbus connection closed');
});

velbus.on('resync', function(why) {
	util.log('velbus connection: lost sync: ' + why + ', resyncing');
});

var vbm = require('./velbusMessage');
velbus.on('message', function(data) {
	//util.log('velbus connection: message: ' + util.inspect(data) );
	vbm.parse(data);
});

var express = require('express');
var webapp = express.createServer();

webapp.configure(function() {
	webapp.use( express.logger() );
	//webapp.use( express.bodyParser() );
	//webapp.use( express.cookieParser(...) );
	//webapp.use( express.session(...) );
	webapp.use( webapp.router );
	webapp.use( express.static(__dirname + '/public') );
});
webapp.configure('development', function() {
	webapp.use( express.errorHandler({ dumpExceptions: true, showStack: true }) );
});
webapp.configure('production', function() {
	webapp.use(express.errorHandler() );
});

webapp.listen(config.webapp.port);
util.log("webserver listening on " +
	webapp.address().address + ':' + webapp.address().port +
	" in " + webapp.settings.env + " mode");

webapp.get('/js/controls.js', function(req, res, next) {
	// Generate the concatenated JS file of the content
	fs.readdir('public/js/controls', function(err, files) {
		if( err !== null ) { next(err); }
		var body = '';
		for( var f in files ) {
			var fn = files[f];
			// Read all files
			fs.readFile('public/js/controls/' + fn, function(err, data) {
				if( err !== null ) { next(err); }
				// Append content to the body
				body += data + "\n";
				// Remove us from the todo list
				files.splice( files.indexOf(fn), 1 );

				if( files.length == 0 ) {
					// We are the last one to finish, send output
					res.send(body, {'Content-Type': 'application/javascript'} );
				}
			});
		}
	});
});

webapp.all(/\/control\/relay\/([0-9a-fA-F]{2}).([1-4])(?:\/([a-zA-Z ]*))?$/, function(req, res, next) {
	var id = parseInt( req.params[0], 16 );
	var relay = parseInt( req.params[1] );
	var field = req.params[2];

	var relaybit = String.fromCharCode( 1 << (relay-1) );

	// Set up listener for the answer
	var timeout;
	var send_answer = function(msg) {
		clearTimeout(timeout);
		if( field != undefined && field != '' ) {
			if( msg.hasOwnProperty(field) ) {
				res.send( msg[field].toString(), {'Content-Type': 'text/plain'} );
			} else {
				res.send("Unknown property", 500);
			}
		} else {
			res.send(msg);
		}
	};
	vbm.once('relay status ' + id + '.' + relay, send_answer);
	timeout = setTimeout(function() {
			vbm.removeListener('relay status ' + id + '.' + relay, send_answer);
			res.send("Timeout", 500);
		}, config.webapp.timeout);

	// Now send the request
	velbus.send_message(3, id, 0, "\xfa" + relaybit );
});
<|endoftext|>