<commit_before>// Copyright (c) 2012 Florian H., https://github.com/js-coder/x18n

(function() {
  var Observable;

  Observable = (function() {
    var utils;

    utils = {
      isPlainObject: function(value) {
        return !!value && Object.prototype.toString.call(value) === '[object Object]';
      },
      isArray: function(value) {
        return Object.prototype.toString.call(value) === '[object Array]';
      },
      toArray: function(value) {
        if (utils.isArray(value)) {
          return value;
        } else {
          return [value];
        }
      }
    };

    function Observable() {
      this.__observable = {
        lastIds: {},
        events: {}
      };
    }

    Observable.prototype.on = function(topics, fn, once) {
      var id, ids, topic, _base, _base1, _i, _len, _results;
      if (utils.isPlainObject(topics)) {
        once = fn;
        _results = [];
        for (topic in topics) {
          fn = topics[topic];
          _results.push(this.on(topic, fn, once));
        }
        return _results;
      } else {
        topics = utils.toArray(topics);
        ids = [];
        for (_i = 0, _len = topics.length; _i < _len; _i++) {
          topic = topics[_i];
          (_base = this.__observable.lastIds)[topic] || (_base[topic] = 0);
          id = "" + topic + ";" + (String(++this.__observable.lastIds[topic]));
          if (once) {
            id += ' once';
          }
          ids.push(id);
          (_base1 = this.__observable.events)[topic] || (_base1[topic] = {});
          this.__observable.events[topic][id] = fn;
        }
        if (ids.length === 1) {
          return ids[0];
        } else {
          return ids;
        }
      }
    };

    Observable.prototype.once = function(topics, fn) {
      return this.on(topics, fn, true);
    };

    Observable.prototype.off = function(ids) {
      var id, topic, _i, _len;
      ids = utils.toArray(ids);
      for (_i = 0, _len = ids.length; _i < _len; _i++) {
        id = ids[_i];
        if (typeof id !== 'string') {
          continue;
        }
        topic = id.substr(0, id.lastIndexOf(';')).split(' ')[0];
        if ((this.__observable.events[topic] != null) && (this.__observable.events[topic][id] != null)) {
          delete this.__observable.events[topic][id];
        }
      }
      return this;
    };

    Observable.prototype.trigger = function(topic, args) {
      var fn, id, _ref;
      if (this.__observable.events[topic] == null) {
        return this;
      }
      _ref = this.__observable.events[topic];
      for (id in _ref) {
        fn = _ref[id];
        fn.apply(null, args);
        if (id.lastIndexOf(' once') === id.length - 1) {
          this.off(id);
        }
      }
      return this;
    };

    return Observable;

  })();

  if (typeof define === 'function' && define.amd) {
    define('observable', function() {
      return Observable;
    });
  } else if (typeof exports !== 'undefined') {
    module.exports = Observable;
  } else {
    window.Observable = Observable;
  }

}).call(this);

(function() {
  var base,
    __slice = [].slice,
    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  base = function(Observable) {
    var x18n;
    return x18n = (function() {
      var eventSystem, oldT;

      function x18n() {}

      x18n.dict = {};

      x18n.defaultlocal = 'en';

      x18n.chosenLocal = void 0;

      x18n.availableLocales = [];

      x18n.locales = [];

      x18n.dynamicBindings = true;

      x18n.missingTranslations = {};

      eventSystem = new Observable;

      x18n.__observable = eventSystem.__observable;

      x18n.on = eventSystem.on;

      x18n.once = eventSystem.once;

      x18n.off = eventSystem.off;

      x18n.trigger = eventSystem.trigger;

      x18n.utils = {
        merge: function(one, two) {
          var k, v, _results;
          _results = [];
          for (k in two) {
            v = two[k];
            if (typeof v === 'object' && typeof one[k] === 'object') {
              _results.push(this.merge(one[k], v));
            } else {
              _results.push(one[k] = v);
            }
          }
          return _results;
        },
        filter: function(arr, fn) {
          var v, _i, _len, _results;
          _results = [];
          for (_i = 0, _len = arr.length; _i < _len; _i++) {
            v = arr[_i];
            if (fn(v)) {
              _results.push(v);
            }
          }
          return _results;
        },
        unique: function(arr) {
          var k, ret, v, _i, _len, _results;
          ret = {};
          for (_i = 0, _len = arr.length; _i < _len; _i++) {
            v = arr[_i];
            ret[v] = v;
          }
          _results = [];
          for (k in ret) {
            v = ret[k];
            _results.push(v);
          }
          return _results;
        },
        getByDotNotation: function(obj, key) {
          var keys;
          keys = key.split('.');
          while (!(keys.length === 0 || obj === void 0)) {
            obj = obj[keys[0]];
            keys.shift();
          }
          return obj;
        },
        isPlainObject: function(value) {
          return !!value && Object.prototype.toString.call(value) === '[object Object]';
        }
      };

      x18n.register = function(local, dict) {
        if (!(local in this.dict)) {
          this.dict[local] = {};
          this.availableLocales.push(local);
        }
        this.utils.merge(this.dict[local], dict);
        return this.trigger('dict:change');
      };

      x18n.set = function(local) {
        this.chosenLocal = local;
        return this.sortLocales();
      };

      x18n.setDefault = function(local) {
        this.defaultLocal = local;
        return this.sortLocales();
      };

      x18n.detectLocal = function() {
        return navigator.userLanguage || navigator.language;
      };

      x18n.similiarLocales = function(local) {
        local = String(local).slice(0, 2).toLowerCase();
        return this.utils.filter(this.availableLocales, function(l) {
          if (local === l) {
            return false;
          }
          return l.toLowerCase().indexOf(local) === 0;
        });
      };

      x18n.sortLocales = function() {
        var local, locales, _i, _len, _locales;
        _locales = [this.chosenLocal].concat(__slice.call(this.similiarLocales(this.chosenLocal)), [this.detectLocal()], __slice.call(this.similiarLocales(this.detectLocal)), [this.defaultlocal], [this.similiarLocales(this.defaultlocal)], ['en'], __slice.call(this.similiarLocales('en')));
        locales = [];
        for (_i = 0, _len = _locales.length; _i < _len; _i++) {
          local = _locales[_i];
          if (__indexOf.call(this.availableLocales, local) >= 0) {
            locales.push(local);
          }
        }
        locales.push.apply(locales, this.availableLocales);
        this.locales = this.utils.unique(locales);
        return this.trigger('lang:change');
      };

      x18n.resolveBindings = function(str) {
        str = String(str);
        if (!this.dynamicBindings) {
          return str;
        }
        return str.replace(/\$\{([^}]+)\}/g, function(_, src) {
          return x18n.globalEval(src);
        });
      };

      x18n.interpolate = function() {
        var interpolation, str;
        str = arguments[0], interpolation = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
        if (this.utils.isPlainObject(interpolation[0])) {
          str = str.replace(/%\{([^}]+)\}/g, function(_, key) {
            return interpolation[0][key];
          });
        } else {
          str = str.replace(/%(\d+)/g, function(_, n) {
            return interpolation[Number(n) - 1];
          });
        }
        return this.resolveBindings(str);
      };

      x18n.globalEval = function(src) {
        return (window.execScript || function(src) {
          return eval.call(window, src);
        })(src);
      };

      oldT = window.t;

      x18n.t = function() {
        var interpolation, key, local, tr, _i, _len, _ref;
        key = arguments[0], interpolation = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
        tr = void 0;
        _ref = x18n.locales;
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          local = _ref[_i];
          tr = x18n.utils.getByDotNotation(x18n.dict[local], key);
          if (tr) {
            break;
          } else {
            if (!(local in x18n.missingTranslations)) {
              x18n.missingTranslations[local] = [];
            }
            x18n.missingTranslations[local].push(key);
            x18n.missingTranslations[local] = x18n.utils.unique(x18n.missingTranslations[local]);
            x18n.trigger('missing-translation', [local, key]);
          }
        }
        if (typeof tr === 'string') {
          tr = x18n.interpolate.apply(x18n, [x18n.resolveBindings(tr)].concat(__slice.call(interpolation)));
        } else if (tr !== void 0) {
          tr.plural = function(n) {
            n = x18n.resolveBindings(n);
            if (n in tr) {
              return tr[n];
            } else {
              return x18n.interpolate(tr.n, n);
            }
          };
        }
        return tr;
      };

      x18n.t.noConflict = function() {
        window.t = oldT;
        return x18n.t;
      };

      window.t = x18n.t;

      x18n.on('dict:change', function() {
        return x18n.sortLocales();
      });

      return x18n;

    }).call(this);
  };

  if (typeof define === 'function' && define.amd) {
    define('x18n', ['observable'], function(Observable) {
      return base(Observable);
    });
  } else {
    window.x18n = base(Observable);
  }

}).call(this);

// Copyright (c) 2012 Florian H., https://github.com/js-coder/jQuery.x18n

(function() {
  var $, config, plural, setTranslation,
    __slice = [].slice;

  $ = jQuery;

  $.x18n = {
    config: {
      key: 't',
      interpolation: 'interpolation',
      plural: 'plural'
    }
  };

  config = $.x18n.config;

  setTranslation = function(el, tr) {
    if (el.is(':submit, :reset, input[type=button]')) {
      return el.val(tr);
    } else if (el.is('input')) {
      return el.attr('placeholder', tr);
    } else {
      return el.html(tr);
    }
  };

  plural = function(n) {
    var tr;
    tr = this.x18n.tr.plural(n);
    setTranslation(this, tr);
    return this.attr("data-" + config.plural, n);
  };

  $.fn.t = function() {
    var interpolation, key, tr;
    key = arguments[0], interpolation = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
    tr = x18n.t.apply(x18n, [key].concat(__slice.call(interpolation)));
    this.attr("data-" + config.key, key);
    if ($.isPlainObject(tr)) {
      this.x18n.tr = tr;
      this.plural = plural;
    } else {
      setTranslation(this, tr);
      this.plural = function() {
        return this;
      };
      this.attr("data-" + config.interpolation, JSON.stringify(interpolation));
    }
    return this;
  };

  $.fn.x18n = function() {
    $("[data-" + config.key + "]").each(function() {
      var $this, interpolation, key, n, tr;
      $this = $(this);
      key = $this.attr("data-" + config.key);
      interpolation = JSON.parse($this.attr("data-" + config.interpolation) || '[]');
      n = $this.attr("data-" + config.plural);
      tr = x18n.t.apply(x18n, [key].concat(__slice.call(interpolation)));
      if ($.isPlainObject(tr)) {
        tr = tr.plural(n);
      }
      return setTranslation($this, tr);
    });
    return this;
  };

  x18n.on(['lang:change', 'dict:change'], function() {
    return $('body').x18n();
  });

}).call(this);
<commit_msg>Proper handling <button type="submit"><commit_after>// Copyright (c) 2012 Florian H., https://github.com/js-coder/x18n

(function() {
  var Observable;

  Observable = (function() {
    var utils;

    utils = {
      isPlainObject: function(value) {
        return !!value && Object.prototype.toString.call(value) === '[object Object]';
      },
      isArray: function(value) {
        return Object.prototype.toString.call(value) === '[object Array]';
      },
      toArray: function(value) {
        if (utils.isArray(value)) {
          return value;
        } else {
          return [value];
        }
      }
    };

    function Observable() {
      this.__observable = {
        lastIds: {},
        events: {}
      };
    }

    Observable.prototype.on = function(topics, fn, once) {
      var id, ids, topic, _base, _base1, _i, _len, _results;
      if (utils.isPlainObject(topics)) {
        once = fn;
        _results = [];
        for (topic in topics) {
          fn = topics[topic];
          _results.push(this.on(topic, fn, once));
        }
        return _results;
      } else {
        topics = utils.toArray(topics);
        ids = [];
        for (_i = 0, _len = topics.length; _i < _len; _i++) {
          topic = topics[_i];
          (_base = this.__observable.lastIds)[topic] || (_base[topic] = 0);
          id = "" + topic + ";" + (String(++this.__observable.lastIds[topic]));
          if (once) {
            id += ' once';
          }
          ids.push(id);
          (_base1 = this.__observable.events)[topic] || (_base1[topic] = {});
          this.__observable.events[topic][id] = fn;
        }
        if (ids.length === 1) {
          return ids[0];
        } else {
          return ids;
        }
      }
    };

    Observable.prototype.once = function(topics, fn) {
      return this.on(topics, fn, true);
    };

    Observable.prototype.off = function(ids) {
      var id, topic, _i, _len;
      ids = utils.toArray(ids);
      for (_i = 0, _len = ids.length; _i < _len; _i++) {
        id = ids[_i];
        if (typeof id !== 'string') {
          continue;
        }
        topic = id.substr(0, id.lastIndexOf(';')).split(' ')[0];
        if ((this.__observable.events[topic] != null) && (this.__observable.events[topic][id] != null)) {
          delete this.__observable.events[topic][id];
        }
      }
      return this;
    };

    Observable.prototype.trigger = function(topic, args) {
      var fn, id, _ref;
      if (this.__observable.events[topic] == null) {
        return this;
      }
      _ref = this.__observable.events[topic];
      for (id in _ref) {
        fn = _ref[id];
        fn.apply(null, args);
        if (id.lastIndexOf(' once') === id.length - 1) {
          this.off(id);
        }
      }
      return this;
    };

    return Observable;

  })();

  if (typeof define === 'function' && define.amd) {
    define('observable', function() {
      return Observable;
    });
  } else if (typeof exports !== 'undefined') {
    module.exports = Observable;
  } else {
    window.Observable = Observable;
  }

}).call(this);

(function() {
  var base,
    __slice = [].slice,
    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  base = function(Observable) {
    var x18n;
    return x18n = (function() {
      var eventSystem, oldT;

      function x18n() {}

      x18n.dict = {};

      x18n.defaultlocal = 'en';

      x18n.chosenLocal = void 0;

      x18n.availableLocales = [];

      x18n.locales = [];

      x18n.dynamicBindings = true;

      x18n.missingTranslations = {};

      eventSystem = new Observable;

      x18n.__observable = eventSystem.__observable;

      x18n.on = eventSystem.on;

      x18n.once = eventSystem.once;

      x18n.off = eventSystem.off;

      x18n.trigger = eventSystem.trigger;

      x18n.utils = {
        merge: function(one, two) {
          var k, v, _results;
          _results = [];
          for (k in two) {
            v = two[k];
            if (typeof v === 'object' && typeof one[k] === 'object') {
              _results.push(this.merge(one[k], v));
            } else {
              _results.push(one[k] = v);
            }
          }
          return _results;
        },
        filter: function(arr, fn) {
          var v, _i, _len, _results;
          _results = [];
          for (_i = 0, _len = arr.length; _i < _len; _i++) {
            v = arr[_i];
            if (fn(v)) {
              _results.push(v);
            }
          }
          return _results;
        },
        unique: function(arr) {
          var k, ret, v, _i, _len, _results;
          ret = {};
          for (_i = 0, _len = arr.length; _i < _len; _i++) {
            v = arr[_i];
            ret[v] = v;
          }
          _results = [];
          for (k in ret) {
            v = ret[k];
            _results.push(v);
          }
          return _results;
        },
        getByDotNotation: function(obj, key) {
          var keys;
          keys = key.split('.');
          while (!(keys.length === 0 || obj === void 0)) {
            obj = obj[keys[0]];
            keys.shift();
          }
          return obj;
        },
        isPlainObject: function(value) {
          return !!value && Object.prototype.toString.call(value) === '[object Object]';
        }
      };

      x18n.register = function(local, dict) {
        if (!(local in this.dict)) {
          this.dict[local] = {};
          this.availableLocales.push(local);
        }
        this.utils.merge(this.dict[local], dict);
        return this.trigger('dict:change');
      };

      x18n.set = function(local) {
        this.chosenLocal = local;
        return this.sortLocales();
      };

      x18n.setDefault = function(local) {
        this.defaultLocal = local;
        return this.sortLocales();
      };

      x18n.detectLocal = function() {
        return navigator.userLanguage || navigator.language;
      };

      x18n.similiarLocales = function(local) {
        local = String(local).slice(0, 2).toLowerCase();
        return this.utils.filter(this.availableLocales, function(l) {
          if (local === l) {
            return false;
          }
          return l.toLowerCase().indexOf(local) === 0;
        });
      };

      x18n.sortLocales = function() {
        var local, locales, _i, _len, _locales;
        _locales = [this.chosenLocal].concat(__slice.call(this.similiarLocales(this.chosenLocal)), [this.detectLocal()], __slice.call(this.similiarLocales(this.detectLocal)), [this.defaultlocal], [this.similiarLocales(this.defaultlocal)], ['en'], __slice.call(this.similiarLocales('en')));
        locales = [];
        for (_i = 0, _len = _locales.length; _i < _len; _i++) {
          local = _locales[_i];
          if (__indexOf.call(this.availableLocales, local) >= 0) {
            locales.push(local);
          }
        }
        locales.push.apply(locales, this.availableLocales);
        this.locales = this.utils.unique(locales);
        return this.trigger('lang:change');
      };

      x18n.resolveBindings = function(str) {
        str = String(str);
        if (!this.dynamicBindings) {
          return str;
        }
        return str.replace(/\$\{([^}]+)\}/g, function(_, src) {
          return x18n.globalEval(src);
        });
      };

      x18n.interpolate = function() {
        var interpolation, str;
        str = arguments[0], interpolation = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
        if (this.utils.isPlainObject(interpolation[0])) {
          str = str.replace(/%\{([^}]+)\}/g, function(_, key) {
            return interpolation[0][key];
          });
        } else {
          str = str.replace(/%(\d+)/g, function(_, n) {
            return interpolation[Number(n) - 1];
          });
        }
        return this.resolveBindings(str);
      };

      x18n.globalEval = function(src) {
        return (window.execScript || function(src) {
          return eval.call(window, src);
        })(src);
      };

      oldT = window.t;

      x18n.t = function() {
        var interpolation, key, local, tr, _i, _len, _ref;
        key = arguments[0], interpolation = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
        tr = void 0;
        _ref = x18n.locales;
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          local = _ref[_i];
          tr = x18n.utils.getByDotNotation(x18n.dict[local], key);
          if (tr) {
            break;
          } else {
            if (!(local in x18n.missingTranslations)) {
              x18n.missingTranslations[local] = [];
            }
            x18n.missingTranslations[local].push(key);
            x18n.missingTranslations[local] = x18n.utils.unique(x18n.missingTranslations[local]);
            x18n.trigger('missing-translation', [local, key]);
          }
        }
        if (typeof tr === 'string') {
          tr = x18n.interpolate.apply(x18n, [x18n.resolveBindings(tr)].concat(__slice.call(interpolation)));
        } else if (tr !== void 0) {
          tr.plural = function(n) {
            n = x18n.resolveBindings(n);
            if (n in tr) {
              return tr[n];
            } else {
              return x18n.interpolate(tr.n, n);
            }
          };
        }
        return tr;
      };

      x18n.t.noConflict = function() {
        window.t = oldT;
        return x18n.t;
      };

      window.t = x18n.t;

      x18n.on('dict:change', function() {
        return x18n.sortLocales();
      });

      return x18n;

    }).call(this);
  };

  if (typeof define === 'function' && define.amd) {
    define('x18n', ['observable'], function(Observable) {
      return base(Observable);
    });
  } else {
    window.x18n = base(Observable);
  }

}).call(this);

// Copyright (c) 2012 Florian H., https://github.com/js-coder/jQuery.x18n

(function() {
  var $, config, plural, setTranslation,
    __slice = [].slice;

  $ = jQuery;

  $.x18n = {
    config: {
      key: 't',
      interpolation: 'interpolation',
      plural: 'plural'
    }
  };

  config = $.x18n.config;

  setTranslation = function(el, tr) {
    if (el.is('input:submit, :reset, input[type=button]')) {
      return el.val(tr);
    } else if (el.is('input')) {
      return el.attr('placeholder', tr);
    } else {
      return el.html(tr);
    }
  };

  plural = function(n) {
    var tr;
    tr = this.x18n.tr.plural(n);
    setTranslation(this, tr);
    return this.attr("data-" + config.plural, n);
  };

  $.fn.t = function() {
    var interpolation, key, tr;
    key = arguments[0], interpolation = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
    tr = x18n.t.apply(x18n, [key].concat(__slice.call(interpolation)));
    this.attr("data-" + config.key, key);
    if ($.isPlainObject(tr)) {
      this.x18n.tr = tr;
      this.plural = plural;
    } else {
      setTranslation(this, tr);
      this.plural = function() {
        return this;
      };
      this.attr("data-" + config.interpolation, JSON.stringify(interpolation));
    }
    return this;
  };

  $.fn.x18n = function() {
    $("[data-" + config.key + "]").each(function() {
      var $this, interpolation, key, n, tr;
      $this = $(this);
      key = $this.attr("data-" + config.key);
      interpolation = JSON.parse($this.attr("data-" + config.interpolation) || '[]');
      n = $this.attr("data-" + config.plural);
      tr = x18n.t.apply(x18n, [key].concat(__slice.call(interpolation)));
      if ($.isPlainObject(tr)) {
        tr = tr.plural(n);
      }
      return setTranslation($this, tr);
    });
    return this;
  };

  x18n.on(['lang:change', 'dict:change'], function() {
    return $('body').x18n();
  });

}).call(this);
<|endoftext|>


<commit_before>var sqlite3 = require('sqlite3'),
    rs = require('recursive-search'),
    fs = require('fs'),
    path = require('path'),
    async = require('async'),
    classes = require('./classes.js');

function importDirectory(db, directory, callback) {
  console.error("Importing.");
  console.error("  - finding trace files...");
  var exp = /(.gpx|.csv)$/;
  var files = fs.readdirSync(directory).filter(function (f) { return exp.exec(f); }).map(function(f) { return path.join(directory, f); });
  // check if we need to do it recursively: WARNING does not scale for some reason.
  if (files.filter(function(f) { return fs.statSync(f).isDirectory();}).length > 0)
  {
    files = rs.recursiveSearchSync(exp, directory);
  }

  files = files.map(function(f, i) { return [i, f]; });

  console.error("  - adding " + files.length + " files to database...");

  db.run("CREATE TABLE traces (id INTEGER PRIMARY KEY, file TEXT)");
  db.run("CREATE TABLE matchings (id INTEGER, subIdx INTEGER, cls INTEGER, data TEXT, PRIMARY KEY (id, subIdx))");

  db.run("BEGIN TRANSACTION");
  var traceStatement = db.prepare("INSERT INTO traces(id, file) VALUES (?, ?)");
  files.forEach(function(file) { traceStatement.run(file[0], file[1]); });
  traceStatement.finalize();
  db.run("END TRANSACTION");

  db.run("BEGIN TRANSACTION");
  var matchingStatement = db.prepare("INSERT INTO matchings(id, subIdx, cls) VALUES (?, ?, ?)");
  files.forEach(function(file) { matchingStatement.run(file[0], 0, 0); });
  matchingStatement.finalize();
  db.run("END TRANSACTION");

  console.error("done.");
}

function loadDB(directory) {
  var targetFilename = path.join(directory, 'classification_db.sqlite'),
      db = new sqlite3.Database(targetFilename);

  // run in sequential mode to avoid callback hell
  db.serialize();

  if (!fs.existsSync(targetFilename)) {
    importDirectory(db, directory);
  }

  return db;
}

module.exports = loadDB;
<commit_msg>Added geojson as input format<commit_after>var sqlite3 = require('sqlite3'),
    rs = require('recursive-search'),
    fs = require('fs'),
    path = require('path'),
    async = require('async'),
    classes = require('./classes.js');

function importDirectory(db, directory, callback) {
  console.error("Importing.");
  console.error("  - finding trace files...");
  var exp = /(.gpx|.csv|.geojson)$/;
  var files = fs.readdirSync(directory).filter(function (f) { return exp.exec(f); }).map(function(f) { return path.join(directory, f); });
  // check if we need to do it recursively: WARNING does not scale for some reason.
  if (files.filter(function(f) { return fs.statSync(f).isDirectory();}).length > 0)
  {
    files = rs.recursiveSearchSync(exp, directory);
  }

  files = files.map(function(f, i) { return [i, f]; });

  console.error("  - adding " + files.length + " files to database...");

  db.run("CREATE TABLE traces (id INTEGER PRIMARY KEY, file TEXT)");
  db.run("CREATE TABLE matchings (id INTEGER, subIdx INTEGER, cls INTEGER, data TEXT, PRIMARY KEY (id, subIdx))");

  db.run("BEGIN TRANSACTION");
  var traceStatement = db.prepare("INSERT INTO traces(id, file) VALUES (?, ?)");
  files.forEach(function(file) { traceStatement.run(file[0], file[1]); });
  traceStatement.finalize();
  db.run("END TRANSACTION");

  db.run("BEGIN TRANSACTION");
  var matchingStatement = db.prepare("INSERT INTO matchings(id, subIdx, cls) VALUES (?, ?, ?)");
  files.forEach(function(file) { matchingStatement.run(file[0], 0, 0); });
  matchingStatement.finalize();
  db.run("END TRANSACTION");

  console.error("done.");
}

function loadDB(directory) {
  var targetFilename = path.join(directory, 'classification_db.sqlite'),
      db = new sqlite3.Database(targetFilename);

  // run in sequential mode to avoid callback hell
  db.serialize();

  if (!fs.existsSync(targetFilename)) {
    importDirectory(db, directory);
  }

  return db;
}

module.exports = loadDB;
<|endoftext|>


<commit_before>// UI
function datetime() {
    $('#feed > .list > li').each(function() {
        var datetime = $(`#${this.id} > .head > time`).attr('datetime'),
            time = moment(datetime).fromNow();

        $(`#${this.id} > .head > time`).html(time);
    });
}
setInterval(function() {
    datetime();
}, 60000);

function feedFilter() {
    $(".follow")
        .mouseover(function() {
            $('.list > .subscription, .list > .host, .list > .donation').css('opacity', '0.3');
        })
        .mouseout(function() {
            $('.list > .subscription, .list > .host, .list > .donation').css('opacity', '1');
        });
    $(".subscription")
        .mouseover(function() {
            $('.list > .follow, .list > .host, .list > .donation').css('opacity', '0.3');
        })
        .mouseout(function() {
            $('.list > .follow, .list > .host, .list > .donation').css('opacity', '1');
        });
    $(".host")
        .mouseover(function() {
            $('.list > .follow, .list > .subscription, .list > .donation').css('opacity', '0.3');
        })
        .mouseout(function() {
            $('.list > .follow, .list > .subscription, .list > .donation').css('opacity', '1');
        });
    $(".donation")
        .mouseover(function() {
            $('.list > .follow, .list > .host, .list > .subscription').css('opacity', '0.3');
        })
        .mouseout(function() {
            $('.list > .follow, .list > .host, .list > .subscription').css('opacity', '1');
        });
}

$(document).ready(function() {
    feedFilter();
    datetime();
});

var socket = io.connect(host),
    connected = false;

socket.on('connect', () => {
    connected = true;

    $('body').removeClass('greyOut');
    $('#message').remove();

    socket.on('stats', (data) => {

        if (data.qCount !== undefined) {
            if (data.qCount !== qCount) {
                qCount = data.qCount;
                $("#qCount").html(qCount);
            }
        }

        if (data.charts !== undefined && page === 'dashboard') {

            // subscriptions
            chartSubscriptions = data.charts.subs;
            chart1.data.datasets[0].data = chartSubscriptions;
            chart1.update();

            // follows
            chartFollows = data.charts.follows;
            chart1.data.datasets[1].data = chartFollows;
            chart1.update();

            // donations
            chartDonations.count = data.charts.donations.count;
            chartDonations.amount = data.charts.donations.amount;
            chart2.data.datasets[0].data = data.charts.donations.count;
            chart2.data.datasets[1].data = data.charts.donations.amount;
        }

        if (data.feed !== undefined && page === 'dashboard') {
            if (data.feed.remove) {
                $(`#${data.feed.remove}`).remove();
            }

            if (data.feed.list !== feed && page === 'dashboard') {
                feed = data.feed.list;

                for (let el of feed) {

                    var uuid = $(`#${el.uuid}`).length,
                        time = moment(el.date).fromNow();

                    if (uuid === 0) {

                        $('#feed > .list')
                            .append(`

${el.type}
<time class="date" datetime="${el.date}">${time}</time>

                              ${el.name}

`);

                        if (el.type === 'follow') {
                            $(`#${el.uuid} > .body`)
                                .append(' is now following you');
                        }
                        if (el.type === 'subscription') {
                            if (el.resubs > 0) {
                                $(`#${el.uuid} > .body`)
                                    .append(` has re-subscribed (${el.resubs}x) you`);
                            } else {
                                $(`#${el.uuid} > .body`)
                                    .append(' has subscribed you');
                            }
                        }
                        if (el.type === 'host') {
                            $(`#${el.uuid} > .body`)
                                .append(` host you with <span class="viewer">${el.viewer}</span> viewer`);
                        }
                        if (el.type === 'donation') {
                            $(`#${el.uuid} > .body`)
                                .append(` has <span class="amount">${el.amount}</span> donated`);
                        }
                    } else {
                        //console.log('already exists ' + el.uuid);
                    }

                }

                feedFilter();
            }
        }

    });

    // settings
    socket.on('dashboard', (type, data) => {

        window[data.name] = data.value;

        if (data.type === 'notification' || 'service') {
            if (data.value) {
                $("#" + data.name).addClass('active');
            } else {
                $("#" + data.name).removeClass('active');
            }
        }

    });

    // notification
    socket.on('notification', (data) => {

        if (dPopups) {

            $("#notificationInfo").hide();

            setTimeout(function() {

                let type = data.type,
                    name,
                    resubs,
                    amount,
                    currency,
                    message;

                if (!data.test) {
                    name = data.name;
                } else {
                    name = 'Mr. X';
                }

                if (type === 'subscription') {
                    if (!data.test) {
                        resubs = data.resubs;
                    } else {
                        resubs = '3';
                    }
                    $("#notiName").html(`${name} ${resubs}`);
                } else {
                    $("#notiName").html(name);
                }

                if (type === 'donation') {

                    $("#amount").empty();
                    $("#message").empty();

                    if (!data.test) {
                        amount = data.amount;
                        currency = data.currency;
                        message = data.message;
                    } else {
                        amount = '25';
                        currency = 'EUR';
                        message = 'This is a test donation';
                    }

                    $("#amount").html(amount);
                    $("#message").html(message);
                }

                if (type === 'follow' || type === 'subscription' || type === 'host') {

                    if (type === 'follow') {
                        $("#notiType").html('New follower');
                    }
                    if (type === 'subscription') {
                        $("#notiType").html('New subscriber');
                    }
                    if (type === 'host') {
                        $("#notiType").html('New host');
                    }

                    $("#notificationInfo").show();
                }

                if (type === 'donation') {
                    $("#notiType").html('New donation');
                    $("#amount").append(`${amount} ${currency}`);
                    $("#message").append(message);
                    $("#notificationInfo").show();
                }

            }, 400);
        }
    });

    socket.on('general', (data) => {

        // client-server version matching
        if (data.version !== undefined) {
            if (data.version !== version) {
                let count = 10;

                $('body').addClass('greyOut');
                $('body').append(`

Server has been updated!

page reload in ${count}

`);

                setInterval(() => {
                    if (count) {
                        count = count - 1;
                        document.getElementById("reloadCount").innerHTML = count;
                    } else {
                        location.reload(true);
                    }
                }, 1000);

                version = data.version;
            }
        }
    });

});

socket.on('disconnect', () => {
    connected = false;

    $('body').addClass('greyOut');
    $('body').append(`

Lost connection to server!

`);
});

function set(type, option, value) {
    if (connected && value === true || value === false) {
        if (value) {
            socket.emit('dashboard', {
                type: type,
                name: option,
                value: false
            });
        } else {
            socket.emit('dashboard', {
                type: type,
                name: option,
                value: true
            });
        }
    } else {
        socket.emit('dashboard', {
            type: type,
            name: option,
            value: value
        });
    }
}

// notification test
testType = 'follow';

function typeTest(value) {
    testType = value;
}

function pushTest() {
    if (connected) {
        socket.emit('dashboard', {
            type: testType,
            name: 'testNoti'
        });
    }
}
<commit_msg>optimize socket if statements and variables<commit_after>// UI
function datetime() {
    $('#feed > .list > li').each(function() {
        var datetime = $(`#${this.id} > .head > time`).attr('datetime'),
            time = moment(datetime).fromNow();

        $(`#${this.id} > .head > time`).html(time);
    });
}
setInterval(function() {
    datetime();
}, 60000);

function feedFilter() {
    $(".follow")
        .mouseover(function() {
            $('.list > .subscription, .list > .host, .list > .donation').css('opacity', '0.3');
        })
        .mouseout(function() {
            $('.list > .subscription, .list > .host, .list > .donation').css('opacity', '1');
        });
    $(".subscription")
        .mouseover(function() {
            $('.list > .follow, .list > .host, .list > .donation').css('opacity', '0.3');
        })
        .mouseout(function() {
            $('.list > .follow, .list > .host, .list > .donation').css('opacity', '1');
        });
    $(".host")
        .mouseover(function() {
            $('.list > .follow, .list > .subscription, .list > .donation').css('opacity', '0.3');
        })
        .mouseout(function() {
            $('.list > .follow, .list > .subscription, .list > .donation').css('opacity', '1');
        });
    $(".donation")
        .mouseover(function() {
            $('.list > .follow, .list > .host, .list > .subscription').css('opacity', '0.3');
        })
        .mouseout(function() {
            $('.list > .follow, .list > .host, .list > .subscription').css('opacity', '1');
        });
}

$(document).ready(function() {
    feedFilter();
    datetime();
});

var socket = io.connect(host),
    connected = false;

socket.on('connect', () => {
    connected = true;

    $('body').removeClass('greyOut');
    $('#message').remove();

    socket.on('stats', (data) => {

        if (data.qCount !== undefined) {
            if (data.qCount !== qCount) {
                qCount = data.qCount;
                $("#qCount").html(qCount);
            }
        }

        if (data.charts !== undefined && page === 'dashboard') {

            // subscriptions
            chartSubscriptions = data.charts.subs;
            chart1.data.datasets[0].data = chartSubscriptions;

            // follows
            chartFollows = data.charts.follows;
            chart1.data.datasets[1].data = chartFollows;

            // donations
            chartDonations.count = data.charts.donations.count;
            chartDonations.amount = data.charts.donations.amount;
            chart2.data.datasets[0].data = data.charts.donations.count;
            chart2.data.datasets[1].data = data.charts.donations.amount;

            chart1.update();
            chart2.update();
        }

        if (data.feed !== undefined && page === 'dashboard') {

            if (data.feed.remove) {
                $(`#${data.feed.remove}`).remove();
            }

            let feed = data.feed.list;

            for (let el of feed) {

                var uuid = $(`#${el.uuid}`).length,
                    time = moment(el.date).fromNow();

                if (uuid === 0) {

                    $('#feed > .list')
                        .append(`

${el.type}
<time class="date" datetime="${el.date}">${time}</time>

                          ${el.name}

`);

                    if (el.type === 'follow') {
                        $(`#${el.uuid} > .body`)
                            .append(' is now following you');
                    }
                    if (el.type === 'subscription') {
                        if (el.resubs > 0) {
                            $(`#${el.uuid} > .body`)
                                .append(` has re-subscribed (${el.resubs}x) you`);
                        } else {
                            $(`#${el.uuid} > .body`)
                                .append(' has subscribed you');
                        }
                    }
                    if (el.type === 'host') {
                        $(`#${el.uuid} > .body`)
                            .append(` host you with <span class="viewer">${el.viewer}</span> viewer`);
                    }
                    if (el.type === 'donation') {
                        $(`#${el.uuid} > .body`)
                            .append(` has <span class="amount">${el.amount}</span> donated`);
                    }
                } else {
                    //console.log('already exists ' + el.uuid);
                }

            }

            feedFilter();
        }

    });

    // settings
    socket.on('dashboard', (type, data) => {

        window[data.name] = data.value;

        if (data.type === 'notification' || 'service') {
            if (data.value) {
                $("#" + data.name).addClass('active');
            } else {
                $("#" + data.name).removeClass('active');
            }
        }

    });

    // notification
    socket.on('notification', (data) => {

        if (dPopups) {

            $("#notificationInfo").hide();

            setTimeout(function() {

                let type = data.type,
                    name,
                    resubs,
                    amount,
                    currency,
                    message;

                if (!data.test) {
                    name = data.name;
                } else {
                    name = 'Mr. X';
                }

                if (type === 'subscription') {
                    if (!data.test) {
                        resubs = data.resubs;
                    } else {
                        resubs = '3';
                    }
                    $("#notiName").html(`${name} ${resubs}`);
                } else {
                    $("#notiName").html(name);
                }

                if (type === 'donation') {

                    $("#amount").empty();
                    $("#message").empty();

                    if (!data.test) {
                        amount = data.amount;
                        currency = data.currency;
                        message = data.message;
                    } else {
                        amount = '25';
                        currency = 'EUR';
                        message = 'This is a test donation';
                    }

                    $("#amount").html(amount);
                    $("#message").html(message);
                }

                if (type === 'follow' || type === 'subscription' || type === 'host') {

                    if (type === 'follow') {
                        $("#notiType").html('New follower');
                    }
                    if (type === 'subscription') {
                        $("#notiType").html('New subscriber');
                    }
                    if (type === 'host') {
                        $("#notiType").html('New host');
                    }

                    $("#notificationInfo").show();
                }

                if (type === 'donation') {
                    $("#notiType").html('New donation');
                    $("#amount").append(`${amount} ${currency}`);
                    $("#message").append(message);
                    $("#notificationInfo").show();
                }

            }, 400);
        }
    });

    socket.on('general', (data) => {

        // client-server version matching
        if (data.version !== undefined) {
            if (data.version !== version) {
                let count = 10;

                $('body').addClass('greyOut');
                $('body').append(`

Server has been updated!

page reload in ${count}

`);

                setInterval(() => {
                    if (count) {
                        count = count - 1;
                        document.getElementById("reloadCount").innerHTML = count;
                    } else {
                        location.reload(true);
                    }
                }, 1000);

                version = data.version;
            }
        }
    });

});

socket.on('disconnect', () => {
    connected = false;

    $('body').addClass('greyOut');
    $('body').append(`

Lost connection to server!

`);
});

function set(type, option, value) {
    if (connected && value === true || value === false) {
        if (value) {
            socket.emit('dashboard', {
                type: type,
                name: option,
                value: false
            });
        } else {
            socket.emit('dashboard', {
                type: type,
                name: option,
                value: true
            });
        }
    } else {
        socket.emit('dashboard', {
            type: type,
            name: option,
            value: value
        });
    }
}

// notification test
testType = 'follow';

function typeTest(value) {
    testType = value;
}

function pushTest() {
    if (connected) {
        socket.emit('dashboard', {
            type: testType,
            name: 'testNoti'
        });
    }
}
<|endoftext|>


<commit_before>function parseStateRef(ref, current) {
  var preparsed = ref.match(/^\s*({[^}]*})\s*$/), parsed;
  if (preparsed) ref = current + '(' + preparsed[1] + ')';
  parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/);
  if (!parsed || parsed.length !== 4) throw new Error("Invalid state ref '" + ref + "'");
  return { state: parsed[1], paramExpr: parsed[3] || null };
}

function stateContext(el) {
  var stateData = el.parent().inheritedData('$uiView');

  if (stateData && stateData.state && stateData.state.name) {
    return stateData.state;
  }
}

/**
 * @ngdoc directive
 * @name ui.router.state.directive:ui-sref
 *
 * @requires ui.router.state.$state
 * @requires $timeout
 *
 * @restrict A
 *
 * @description
 * A directive that binds a link (`<a>` tag) to a state. If the state has an associated
 * URL, the directive will automatically generate & update the `href` attribute via
 * the {@link ui.router.state.$state#methods_href $state.href()} method. Clicking
 * the link will trigger a state transition with optional parameters.
 *
 * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be
 * handled natively by the browser.
 *
 * You can also use relative state paths within ui-sref, just like the relative
 * paths passed to `$state.go()`. You just need to be aware that the path is relative
 * to the state that the link lives in, in other words the state that loaded the
 * template containing the link.
 *
 * You can specify options to pass to {@link ui.router.state.$state#go $state.go()}
 * using the `ui-sref-opts` attribute. Options are restricted to `location`, `inherit`,
 * and `reload`.
 *
 * @example
 * Here's an example of how you'd use ui-sref and how it would compile. If you have the
 * following template:
 *

 * Home | About | Next page
 *
 *

 *

 *         {{ contact.name }}
 *

 *

 *

 *
 * Then the compiled html would be (assuming Html5Mode is off and current state is contacts):
 *

 * Home | About | Next page
 *
 *

 *

 *         Joe
 *

 *

 *         Alice
 *

 *

 *         Bob
 *

 *

 *
 * Home
 *

 *
 * @param {string} ui-sref 'stateName' can be any valid absolute or relative state
 * @param {Object} ui-sref-opts options to pass to {@link ui.router.state.$state#go $state.go()}
 */
$StateRefDirective.$inject = ['$state', '$timeout'];
function $StateRefDirective($state, $timeout) {
  var allowedOptions = ['location', 'inherit', 'reload'];

  return {
    restrict: 'A',
    require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
    link: function(scope, element, attrs, uiSrefActive) {
      var ref = parseStateRef(attrs.uiSref, $state.current.name);
      var params = null, url = null, base = stateContext(element) || $state.$current;
      var isForm = element[0].nodeName === "FORM";
      var attr = isForm ? "action" : "href", nav = true;

      var options = { relative: base, inherit: true };
      var optionsOverride = scope.$eval(attrs.uiSrefOpts) || {};

      angular.forEach(allowedOptions, function(option) {
        if (option in optionsOverride) {
          options[option] = optionsOverride[option];
        }
      });

      var update = function(newVal) {
        if (newVal) params = newVal;
        if (!nav) return;

        var newHref = $state.href(ref.state, params, options);

        var activeDirective = uiSrefActive[1] || uiSrefActive[0];
        if (activeDirective) {
          activeDirective.$$setStateInfo(ref.state, params);
        }
        if (newHref === null) {
          nav = false;
          return false;
        }
        attrs.$set(attr, newHref);
      };

      if (ref.paramExpr) {
        scope.$watch(ref.paramExpr, function(newVal, oldVal) {
          if (newVal !== params) update(newVal);
        }, true);
        params = scope.$eval(ref.paramExpr);
      }
      update();

      if (isForm) return;

      element.bind("click", function(e) {
        var button = e.which || e.button;
        if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {
          // HACK: This is to allow ng-clicks to be processed before the transition is initiated:
          var transition = $timeout(function() {
            $state.go(ref.state, params, options);
          });
          e.preventDefault();

          e.preventDefault = function() {
            $timeout.cancel(transition);
          };
        }
      });
    }
  };
}

/**
 * @ngdoc directive
 * @name ui.router.state.directive:ui-sref-active
 *
 * @requires ui.router.state.$state
 * @requires ui.router.state.$stateParams
 * @requires $interpolate
 *
 * @restrict A
 *
 * @description
 * A directive working alongside ui-sref to add classes to an element when the
 * related ui-sref directive's state is active, and removing them when it is inactive.
 * The primary use-case is to simplify the special appearance of navigation menus
 * relying on `ui-sref`, by having the "active" state's menu button appear different,
 * distinguishing it from the inactive menu items.
 *
 * ui-sref-active can live on the same element as ui-sref or on a parent element. The first
 * ui-sref-active found at the same level or above the ui-sref will be used.
 *
 * Will activate when the ui-sref's target state or any child state is active. If you
 * need to activate only when the ui-sref target state is active and *not* any of
 * it's children, then you will use
 * {@link ui.router.state.directive:ui-sref-active-eq ui-sref-active-eq}
 *
 * @example
 * Given the following template:
 *

 *

 *

 *     @bilbobaggins
 *

 *

 *

 *
 *
 * When the app state is "app.user" (or any children states), and contains the state parameter "user" with value "bilbobaggins",
 * the resulting HTML will appear as (note the 'active' class):
 *

 *

 *

 *     @bilbobaggins
 *

 *

 *

 *
 * The class name is interpolated **once** during the directives link time (any further changes to the
 * interpolated value are ignored).
 *
 * Multiple classes may be specified in a space-separated format:
 *

 *

 *

 *     link
 *

 *

 *

 */

/**
 * @ngdoc directive
 * @name ui.router.state.directive:ui-sref-active-eq
 *
 * @requires ui.router.state.$state
 * @requires ui.router.state.$stateParams
 * @requires $interpolate
 *
 * @restrict A
 *
 * @description
 * The same as {@link ui.router.state.directive:ui-sref-active ui-sref-active} but will will only activate
 * when the exact target state used in the `ui-sref` is active; no child states.
 *
 */
$StateRefActiveDirective.$inject = ['$state', '$stateParams', '$interpolate'];
function $StateRefActiveDirective($state, $stateParams, $interpolate) {
  return  {
    restrict: "A",
    controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
      var state, params, activeClass;

      // There probably isn't much point in $observing this
      // uiSrefActive and uiSrefActiveEq share the same directive object with some
      // slight difference in logic routing
      activeClass = $interpolate($attrs.uiSrefActiveEq || $attrs.uiSrefActive || '', false)($scope);

      // Allow uiSref to communicate with uiSrefActive[Equals]
      this.$$setStateInfo = function (newState, newParams) {
        state = $state.get(newState, stateContext($element));
        params = newParams;
        update();
      };

      $scope.$on('$stateChangeSuccess', update);

      // Update route state
      function update() {
        if (isMatch()) {
          $element.addClass(activeClass);
        } else {
          $element.removeClass(activeClass);
        }
      }

      function isMatch() {
        if (typeof $attrs.uiSrefActiveEq !== 'undefined') {
          return $state.$current.self === state && matchesParams();
        } else {
          return $state.includes(state.name) && matchesParams();
        }
      }

      function matchesParams() {
        return !params || equalForKeys(params, $stateParams);
      }
    }]
  };
}

angular.module('ui.router.state')
  .directive('uiSref', $StateRefDirective)
  .directive('uiSrefActive', $StateRefActiveDirective)
  .directive('uiSrefActiveEq', $StateRefActiveDirective);
<commit_msg>fix(uiSref): Check that state is defined in isMatch()<commit_after>function parseStateRef(ref, current) {
  var preparsed = ref.match(/^\s*({[^}]*})\s*$/), parsed;
  if (preparsed) ref = current + '(' + preparsed[1] + ')';
  parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/);
  if (!parsed || parsed.length !== 4) throw new Error("Invalid state ref '" + ref + "'");
  return { state: parsed[1], paramExpr: parsed[3] || null };
}

function stateContext(el) {
  var stateData = el.parent().inheritedData('$uiView');

  if (stateData && stateData.state && stateData.state.name) {
    return stateData.state;
  }
}

/**
 * @ngdoc directive
 * @name ui.router.state.directive:ui-sref
 *
 * @requires ui.router.state.$state
 * @requires $timeout
 *
 * @restrict A
 *
 * @description
 * A directive that binds a link (`<a>` tag) to a state. If the state has an associated
 * URL, the directive will automatically generate & update the `href` attribute via
 * the {@link ui.router.state.$state#methods_href $state.href()} method. Clicking
 * the link will trigger a state transition with optional parameters.
 *
 * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be
 * handled natively by the browser.
 *
 * You can also use relative state paths within ui-sref, just like the relative
 * paths passed to `$state.go()`. You just need to be aware that the path is relative
 * to the state that the link lives in, in other words the state that loaded the
 * template containing the link.
 *
 * You can specify options to pass to {@link ui.router.state.$state#go $state.go()}
 * using the `ui-sref-opts` attribute. Options are restricted to `location`, `inherit`,
 * and `reload`.
 *
 * @example
 * Here's an example of how you'd use ui-sref and how it would compile. If you have the
 * following template:
 *

 * Home | About | Next page
 *
 *

 *

 *         {{ contact.name }}
 *

 *

 *

 *
 * Then the compiled html would be (assuming Html5Mode is off and current state is contacts):
 *

 * Home | About | Next page
 *
 *

 *

 *         Joe
 *

 *

 *         Alice
 *

 *

 *         Bob
 *

 *

 *
 * Home
 *

 *
 * @param {string} ui-sref 'stateName' can be any valid absolute or relative state
 * @param {Object} ui-sref-opts options to pass to {@link ui.router.state.$state#go $state.go()}
 */
$StateRefDirective.$inject = ['$state', '$timeout'];
function $StateRefDirective($state, $timeout) {
  var allowedOptions = ['location', 'inherit', 'reload'];

  return {
    restrict: 'A',
    require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
    link: function(scope, element, attrs, uiSrefActive) {
      var ref = parseStateRef(attrs.uiSref, $state.current.name);
      var params = null, url = null, base = stateContext(element) || $state.$current;
      var isForm = element[0].nodeName === "FORM";
      var attr = isForm ? "action" : "href", nav = true;

      var options = { relative: base, inherit: true };
      var optionsOverride = scope.$eval(attrs.uiSrefOpts) || {};

      angular.forEach(allowedOptions, function(option) {
        if (option in optionsOverride) {
          options[option] = optionsOverride[option];
        }
      });

      var update = function(newVal) {
        if (newVal) params = newVal;
        if (!nav) return;

        var newHref = $state.href(ref.state, params, options);

        var activeDirective = uiSrefActive[1] || uiSrefActive[0];
        if (activeDirective) {
          activeDirective.$$setStateInfo(ref.state, params);
        }
        if (newHref === null) {
          nav = false;
          return false;
        }
        attrs.$set(attr, newHref);
      };

      if (ref.paramExpr) {
        scope.$watch(ref.paramExpr, function(newVal, oldVal) {
          if (newVal !== params) update(newVal);
        }, true);
        params = scope.$eval(ref.paramExpr);
      }
      update();

      if (isForm) return;

      element.bind("click", function(e) {
        var button = e.which || e.button;
        if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {
          // HACK: This is to allow ng-clicks to be processed before the transition is initiated:
          var transition = $timeout(function() {
            $state.go(ref.state, params, options);
          });
          e.preventDefault();

          e.preventDefault = function() {
            $timeout.cancel(transition);
          };
        }
      });
    }
  };
}

/**
 * @ngdoc directive
 * @name ui.router.state.directive:ui-sref-active
 *
 * @requires ui.router.state.$state
 * @requires ui.router.state.$stateParams
 * @requires $interpolate
 *
 * @restrict A
 *
 * @description
 * A directive working alongside ui-sref to add classes to an element when the
 * related ui-sref directive's state is active, and removing them when it is inactive.
 * The primary use-case is to simplify the special appearance of navigation menus
 * relying on `ui-sref`, by having the "active" state's menu button appear different,
 * distinguishing it from the inactive menu items.
 *
 * ui-sref-active can live on the same element as ui-sref or on a parent element. The first
 * ui-sref-active found at the same level or above the ui-sref will be used.
 *
 * Will activate when the ui-sref's target state or any child state is active. If you
 * need to activate only when the ui-sref target state is active and *not* any of
 * it's children, then you will use
 * {@link ui.router.state.directive:ui-sref-active-eq ui-sref-active-eq}
 *
 * @example
 * Given the following template:
 *

 *

 *

 *     @bilbobaggins
 *

 *

 *

 *
 *
 * When the app state is "app.user" (or any children states), and contains the state parameter "user" with value "bilbobaggins",
 * the resulting HTML will appear as (note the 'active' class):
 *

 *

 *

 *     @bilbobaggins
 *

 *

 *

 *
 * The class name is interpolated **once** during the directives link time (any further changes to the
 * interpolated value are ignored).
 *
 * Multiple classes may be specified in a space-separated format:
 *

 *

 *

 *     link
 *

 *

 *

 */

/**
 * @ngdoc directive
 * @name ui.router.state.directive:ui-sref-active-eq
 *
 * @requires ui.router.state.$state
 * @requires ui.router.state.$stateParams
 * @requires $interpolate
 *
 * @restrict A
 *
 * @description
 * The same as {@link ui.router.state.directive:ui-sref-active ui-sref-active} but will will only activate
 * when the exact target state used in the `ui-sref` is active; no child states.
 *
 */
$StateRefActiveDirective.$inject = ['$state', '$stateParams', '$interpolate'];
function $StateRefActiveDirective($state, $stateParams, $interpolate) {
  return  {
    restrict: "A",
    controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
      var state, params, activeClass;

      // There probably isn't much point in $observing this
      // uiSrefActive and uiSrefActiveEq share the same directive object with some
      // slight difference in logic routing
      activeClass = $interpolate($attrs.uiSrefActiveEq || $attrs.uiSrefActive || '', false)($scope);

      // Allow uiSref to communicate with uiSrefActive[Equals]
      this.$$setStateInfo = function (newState, newParams) {
        state = $state.get(newState, stateContext($element));
        params = newParams;
        update();
      };

      $scope.$on('$stateChangeSuccess', update);

      // Update route state
      function update() {
        if (isMatch()) {
          $element.addClass(activeClass);
        } else {
          $element.removeClass(activeClass);
        }
      }

      function isMatch() {
        if (typeof $attrs.uiSrefActiveEq !== 'undefined') {
          return $state.$current.self === state && matchesParams();
        } else {
          return state && $state.includes(state.name) && matchesParams();
        }
      }

      function matchesParams() {
        return !params || equalForKeys(params, $stateParams);
      }
    }]
  };
}

angular.module('ui.router.state')
  .directive('uiSref', $StateRefDirective)
  .directive('uiSrefActive', $StateRefActiveDirective)
  .directive('uiSrefActiveEq', $StateRefActiveDirective);
<|endoftext|>


<commit_before>import { WidthSpriteSheetHero, HeightSpriteSheetHero, Size, CursorSize, Width, Height, HudText, HudTextX, HudTextY } from '../Constants.js';
import { Tileset, Level1, Levels, HeroSprite } from '../ConstantsKey.js';
import Character from 'objects/Character';
import InformationString from 'objects/InformationString';

import MapManager from "objects/MapManager";
import Controls from "objects/Controls";

class MainView extends Phaser.State {

  constructor() {
    super();
  }

  init(indexLevel) {
    this.indexLevel = indexLevel || 1;
    this.hasLevel = Object.keys(Levels).length >= this.indexLevel;
    if(!this.game.controls) {
      let controls = new Controls();
      controls.PostMortemDefaultConfig();
      this.game.controls = controls;
    }
    //no more levels :|
  }

  create() {
    if(!this.hasLevel) {
      this.game.goToMenu();
    } else {

      this.game.physics.startSystem(Phaser.Physics.ARCADE);
      // Add the physics engine to all game objects
      this.game.world.enableBody = true;

      this.map = this.game.add.tilemap(Levels[`Level${this.indexLevel}`].key);
      this.map.addTilesetImage(Levels[`Level${this.indexLevel}`].key, Tileset.key);

      this.map.createLayer('thirdLayer');
      this.map.createLayer('secondLayer');
      this.map.createLayer('firstLayer');
      // This resizes the game world to match the layer dimensions
      this.collisionLayer = this.map.createLayer('colissionLayer');
      this.map.setCollisionByExclusion([], true, this.collisionLayer);

      this.collisionLayer.resizeWorld();

      this.hero = new Character(this.game, Levels[`Level${this.indexLevel}`].playerPosition.x , Levels[`Level${this.indexLevel}`].playerPosition.y, HeroSprite.key, 0);
      this.game.add.existing(this.hero);
      this.game.camera.follow(this.hero);

      this.marker = null;
      this.createTileSelector();
      this.game.input.addMoveCallback(this.updateMarker, this);

      this.mapManager = new MapManager(this.map, Levels[`Level${this.indexLevel}`].lastLayer);
      this.mapManager.setUpCollisionLayer(this.collisionLayer);

      this.text = new InformationString(this.game, Width/2, Levels[`Level${this.indexLevel}`].text );
      this.game.add.existing(this.text);
      this.text.blink();

      this.hud = this.game.add.text(400, 400, HudText, { font: "bold 22px Arial", fill: '#FFFFFF' });
      this.hud.x = this.game.camera.x + HudTextX;
      this.hud.y = this.game.camera.y + HudTextY;

      this.keyRemoveLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("undoLayer"));
      this.keyRemoveLayer.onDown.add(this.eraseBlockKeyboard, this);
      this.keyUndoLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("removeLayer"));
      this.keyUndoLayer.onDown.add(this.undoBlockKeyboard, this);

      this.keyUpLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("moveUpCursor"));
      this.keyUpLayer.onDown.add(this.moveUp, this);
      this.keyDownLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("moveDownCursor"));
      this.keyDownLayer.onDown.add(this.moveDown, this);
      this.keyLeftLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("moveLeftCursor"));
      this.keyLeftLayer.onDown.add(this.moveLeft, this);
      this.keyRightLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("moveRightCursor"));
      this.keyRightLayer.onDown.add(this.moveRight, this);

      this.game.time.advancedTiming = true;
    }
  }

  update() {
    this.game.physics.arcade.overlap(this.hero, this.collisionLayer, this.additionalCheck, this.hasPortal , this);
    this.game.physics.arcade.collide(this.hero, this.collisionLayer);
    if(this.hero.y > Height + this.hero.height) {
      this.game.reset();
    }

    this.updateGui();
  }

  updateGui() {
    this.hud.setText(HudText + this.mapManager.currentGems + " / " + this.mapManager.nbGems);
    this.hud.x = this.game.camera.x + HudTextX;
    this.hud.y = this.game.camera.y + HudTextY;

  }

  hasPortal(tile1, tile2) {
    if(tile2.properties && tile2.properties.portal == 1 && !this.mapManager.portalEnable()) {
      return false;
    }
    return true;
  }

  additionalCheck(tile1, tile2) {
    if(!tile2.properties) {
      return;
    }

    if(tile2.properties.layer_gem == 1) {
      if(tile2.properties.layer_destroy) {
        this.mapManager.removeLayer();
      } else if (tile2.properties.layer_rollback) {
        this.mapManager.undoLayer();
      }
      return;
    }

    if(tile2.properties.is_gem == 1) {
      this.map.removeTile(tile2.x, tile2.y, "colissionLayer").destroy();
      this.mapManager.killGem();
      return;
    }

    if(tile2.properties.portal == 1 && this.mapManager.portalEnable()) {
      //maybe make an animation
      this.game.nextLevel();
    }
  }

  preload() {
    this.game.load.spritesheet(HeroSprite.key, `res/${HeroSprite.path}`, WidthSpriteSheetHero, HeightSpriteSheetHero);
    this.game.load.image(Tileset.key, `res/${Tileset.path}`);
    if(this.hasLevel) {
      this.game.load.tilemap(Levels[`Level${this.indexLevel}`].key, `res/${Levels[`Level${this.indexLevel}`].path}` , null, Phaser.Tilemap.TILED_JSON);
    }
  }

  render() {
    //this.game.debug.text(this.game.time.fps, 2, 16, "#00ff00");
  }

  eraseBlockKeyboard() {
    this.mapManager.eraseBlock(this.marker.x / Size, this.marker.y / Size);
    this.hero.eraseBlocksAnimation(this.marker);
  }

  undoBlockKeyboard() {
    this.mapManager.undoBlock(this.marker.x / Size, this.marker.y / Size);
    this.hero.eraseBlocksAnimation(this.marker);
  }

  updateMarker() {
    this.marker.x = this.game.math.snapToFloor(this.game.input.activePointer.worldX, CursorSize, 0);
    this.marker.y = this.game.math.snapToFloor(this.game.input.activePointer.worldY, CursorSize, 0);

    if (this.game.input.mousePointer.isDown && this.marker.y > Size) {
      this.mapManager.eraseBlock(this.marker.x / Size, this.marker.y / Size);
      this.hero.eraseBlocksAnimation(this.marker);
    }
  }

  createTileSelector() {
    //Our painting marker
    this.marker = this.game.add.graphics();
    this.marker.lineStyle(2, 0xea4335, 1);
    this.marker.drawRect(0, 0, CursorSize, CursorSize);
    this.marker.x = 4 * CursorSize;
    this.marker.y = 4 * CursorSize;
  }

  moveUp() {
    this.marker.y -= CursorSize;
    if(this.marker.y < 0) {
      this.marker.y = 0;
    }
  }

  moveDown() {
    this.marker.y += CursorSize;
    if(this.marker.y > Height - CursorSize) {
      this.marker.y = Height - CursorSize;
    }
  }

  moveLeft() {
    this.marker.x -= CursorSize;
    if(this.marker.x < 0) {
      this.marker.x = 0;
    }
  }

  moveRight() {
    this.marker.x += CursorSize;
    if(this.marker.x > Width - CursorSize) {
      this.marker.x = Width - CursorSize;
    }
  }

}

export default MainView;
<commit_msg>remove tile<commit_after>import { WidthSpriteSheetHero, HeightSpriteSheetHero, Size, CursorSize, Width, Height, HudText, HudTextX, HudTextY } from '../Constants.js';
import { Tileset, Level1, Levels, HeroSprite } from '../ConstantsKey.js';
import Character from 'objects/Character';
import InformationString from 'objects/InformationString';

import MapManager from "objects/MapManager";
import Controls from "objects/Controls";

class MainView extends Phaser.State {

  constructor() {
    super();
  }

  init(indexLevel) {
    this.indexLevel = indexLevel || 1;
    this.hasLevel = Object.keys(Levels).length >= this.indexLevel;
    if(!this.game.controls) {
      let controls = new Controls();
      controls.PostMortemDefaultConfig();
      this.game.controls = controls;
    }
    //no more levels :|
  }

  create() {
    if(!this.hasLevel) {
      this.game.goToMenu();
    } else {

      this.game.physics.startSystem(Phaser.Physics.ARCADE);
      // Add the physics engine to all game objects
      this.game.world.enableBody = true;

      this.map = this.game.add.tilemap(Levels[`Level${this.indexLevel}`].key);
      this.map.addTilesetImage(Levels[`Level${this.indexLevel}`].key, Tileset.key);

      this.map.createLayer('thirdLayer');
      this.map.createLayer('secondLayer');
      this.map.createLayer('firstLayer');
      // This resizes the game world to match the layer dimensions
      this.collisionLayer = this.map.createLayer('colissionLayer');
      this.map.setCollisionByExclusion([], true, this.collisionLayer);

      this.collisionLayer.resizeWorld();

      this.hero = new Character(this.game, Levels[`Level${this.indexLevel}`].playerPosition.x , Levels[`Level${this.indexLevel}`].playerPosition.y, HeroSprite.key, 0);
      this.game.add.existing(this.hero);
      this.game.camera.follow(this.hero);

      this.marker = null;
      this.createTileSelector();
      this.game.input.addMoveCallback(this.updateMarker, this);

      this.mapManager = new MapManager(this.map, Levels[`Level${this.indexLevel}`].lastLayer);
      this.mapManager.setUpCollisionLayer(this.collisionLayer);

      this.text = new InformationString(this.game, Width/2, Levels[`Level${this.indexLevel}`].text );
      this.game.add.existing(this.text);
      this.text.blink();

      this.hud = this.game.add.text(400, 400, HudText, { font: "bold 22px Arial", fill: '#FFFFFF' });
      this.hud.x = this.game.camera.x + HudTextX;
      this.hud.y = this.game.camera.y + HudTextY;

      this.keyRemoveLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("undoLayer"));
      this.keyRemoveLayer.onDown.add(this.eraseBlockKeyboard, this);
      this.keyUndoLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("removeLayer"));
      this.keyUndoLayer.onDown.add(this.undoBlockKeyboard, this);

      this.keyUpLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("moveUpCursor"));
      this.keyUpLayer.onDown.add(this.moveUp, this);
      this.keyDownLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("moveDownCursor"));
      this.keyDownLayer.onDown.add(this.moveDown, this);
      this.keyLeftLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("moveLeftCursor"));
      this.keyLeftLayer.onDown.add(this.moveLeft, this);
      this.keyRightLayer = this.game.input.keyboard.addKey(this.game.controls.getKey("moveRightCursor"));
      this.keyRightLayer.onDown.add(this.moveRight, this);

      this.game.time.advancedTiming = true;
    }
  }

  update() {
    this.game.physics.arcade.overlap(this.hero, this.collisionLayer, this.additionalCheck, this.hasPortal , this);
    this.game.physics.arcade.collide(this.hero, this.collisionLayer);
    if(this.hero.y > Height + this.hero.height) {
      this.game.reset();
    }

    this.updateGui();
  }

  updateGui() {
    this.hud.setText(HudText + this.mapManager.currentGems + " / " + this.mapManager.nbGems);
    this.hud.x = this.game.camera.x + HudTextX;
    this.hud.y = this.game.camera.y + HudTextY;

  }

  hasPortal(tile1, tile2) {
    if(tile2.properties && tile2.properties.portal == 1 && !this.mapManager.portalEnable()) {
      return false;
    }
    return true;
  }

  additionalCheck(tile1, tile2) {
    if(!tile2.properties) {
      return;
    }

    if(tile2.properties.layer_gem == 1) {
      if(tile2.properties.layer_destroy) {
        this.mapManager.removeLayer();
      } else if (tile2.properties.layer_rollback) {
        this.mapManager.undoLayer();
      }
      this.map.removeTile(tile2.x, tile2.y, "colissionLayer");
      return;
    }

    if(tile2.properties.is_gem == 1) {
      this.map.removeTile(tile2.x, tile2.y, "colissionLayer").destroy();
      this.mapManager.killGem();
      return;
    }

    if(tile2.properties.portal == 1 && this.mapManager.portalEnable()) {
      //maybe make an animation
      this.game.nextLevel();
    }
  }

  preload() {
    this.game.load.spritesheet(HeroSprite.key, `res/${HeroSprite.path}`, WidthSpriteSheetHero, HeightSpriteSheetHero);
    this.game.load.image(Tileset.key, `res/${Tileset.path}`);
    if(this.hasLevel) {
      this.game.load.tilemap(Levels[`Level${this.indexLevel}`].key, `res/${Levels[`Level${this.indexLevel}`].path}` , null, Phaser.Tilemap.TILED_JSON);
    }
  }

  render() {
    //this.game.debug.text(this.game.time.fps, 2, 16, "#00ff00");
  }

  eraseBlockKeyboard() {
    this.mapManager.eraseBlock(this.marker.x / Size, this.marker.y / Size);
    this.hero.eraseBlocksAnimation(this.marker);
  }

  undoBlockKeyboard() {
    this.mapManager.undoBlock(this.marker.x / Size, this.marker.y / Size);
    this.hero.eraseBlocksAnimation(this.marker);
  }

  updateMarker() {
    this.marker.x = this.game.math.snapToFloor(this.game.input.activePointer.worldX, CursorSize, 0);
    this.marker.y = this.game.math.snapToFloor(this.game.input.activePointer.worldY, CursorSize, 0);

    if (this.game.input.mousePointer.isDown && this.marker.y > Size) {
      this.mapManager.eraseBlock(this.marker.x / Size, this.marker.y / Size);
      this.hero.eraseBlocksAnimation(this.marker);
    }
  }

  createTileSelector() {
    //Our painting marker
    this.marker = this.game.add.graphics();
    this.marker.lineStyle(2, 0xea4335, 1);
    this.marker.drawRect(0, 0, CursorSize, CursorSize);
    this.marker.x = 4 * CursorSize;
    this.marker.y = 4 * CursorSize;
  }

  moveUp() {
    this.marker.y -= CursorSize;
    if(this.marker.y < 0) {
      this.marker.y = 0;
    }
  }

  moveDown() {
    this.marker.y += CursorSize;
    if(this.marker.y > Height - CursorSize) {
      this.marker.y = Height - CursorSize;
    }
  }

  moveLeft() {
    this.marker.x -= CursorSize;
    if(this.marker.x < 0) {
      this.marker.x = 0;
    }
  }

  moveRight() {
    this.marker.x += CursorSize;
    if(this.marker.x > Width - CursorSize) {
      this.marker.x = Width - CursorSize;
    }
  }

}

export default MainView;
<|endoftext|>


<commit_before>var match = require('../lib/match'),
    ranking = require('../lib/ranking'),
    player = require('../lib/player'),
    gameres = require('../lib/gameres'),
    auth = require('basic-auth'),
    debug = require('debug')('wol:leaderboard');

exports.submit = function (req, res, next) {
    res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
    res.header('Expires', '-1');
    res.header('Pragma', 'no-cache');

    /* discontinue if missing request data */
    if (!req.body || !req.params.game) return res.send(400);

    var credentials = auth(req) || {},
        dump = gameres.parse(req.body) || {};

    /* discontinue if missing gameres data */
    if (!dump.client || !dump.client.nick) return res.send(400);

    var _success = function() {
        res.send(202);
        match.process(req.params.game, dump);
    };

    var _error = function() {
        res.writeHead(401, {
            'WWW-Authenticate': 'Basic realm="CnCNet 5 Leaderboard"'
        });

        res.end();
    };

    /* dirty hack for td, since they have no accounts */
    if (req.params.game === 'td') return _success();

    if (!credentials.name || !credentials.pass) return _error();
    player.auth(dump.client.nick, credentials.name, credentials.pass).then(_success, _error);
};

exports.ladder = function (req, res, next) {
    ranking.ladder(req.params.game, (req.params.limit || 150)).then(function(data) {
        if (data && data.length > 0) {
            res.header('Cache-Control', 'public, max-age=60');
        }

        res.send(data);
    });
};

exports.search = function (req, res, next) {
    var _success = function (data) {
        res.send(data);
    };
    var _error = function () {
        res.send(404);
    };

    if (!req.body || !req.body.player) return _error();
    player.search(req.params.game, req.body.player).then(_success, _error);
};

exports.player = function(req, res, next) {
    var _success = function (data) {
        res.header('Cache-Control', 'public, max-age=30');
        res.send(data);
    };
    var _error = function () {
        res.send(404);
    };

    player.stats(req.params.game, req.params.player, req.params.games).then(_success, _error);
};

exports.clan = function(req, res, next) {
  res.send(200);
};

exports.match = function(req, res) {
    var _success = function (data) {
        res.header('Cache-Control', 'public, max-age=950400');
        res.send(data);
    };
    var _error = function () {
        res.send(404);
    };

    match.information(req.params.game, parseInt(req.params.gameId)).then(_success, _error);
};
<commit_msg>removing unused route<commit_after>var match = require('../lib/match'),
    ranking = require('../lib/ranking'),
    player = require('../lib/player'),
    gameres = require('../lib/gameres'),
    auth = require('basic-auth'),
    debug = require('debug')('wol:leaderboard');

exports.submit = function (req, res, next) {
    res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
    res.header('Expires', '-1');
    res.header('Pragma', 'no-cache');

    /* discontinue if missing request data */
    if (!req.body || !req.params.game) return res.send(400);

    var credentials = auth(req) || {},
        dump = gameres.parse(req.body) || {};

    /* discontinue if missing gameres data */
    if (!dump.client || !dump.client.nick) return res.send(400);

    var _success = function() {
        res.send(202);
        match.process(req.params.game, dump);
    };

    var _error = function() {
        res.writeHead(401, {
            'WWW-Authenticate': 'Basic realm="CnCNet 5 Leaderboard"'
        });

        res.end();
    };

    /* dirty hack for td, since they have no accounts */
    if (req.params.game === 'td') return _success();

    if (!credentials.name || !credentials.pass) return _error();
    player.auth(dump.client.nick, credentials.name, credentials.pass).then(_success, _error);
};

exports.ladder = function (req, res, next) {
    ranking.ladder(req.params.game, (req.params.limit || 150)).then(function(data) {
        if (data && data.length > 0) {
            res.header('Cache-Control', 'public, max-age=60');
        }

        res.send(data);
    });
};

exports.search = function (req, res, next) {
    var _success = function (data) {
        res.send(data);
    };
    var _error = function () {
        res.send(404);
    };

    if (!req.body || !req.body.player) return _error();
    player.search(req.params.game, req.body.player).then(_success, _error);
};

exports.player = function(req, res, next) {
    var _success = function (data) {
        res.header('Cache-Control', 'public, max-age=30');
        res.send(data);
    };
    var _error = function () {
        res.send(404);
    };

    player.stats(req.params.game, req.params.player, req.params.games).then(_success, _error);
};

exports.match = function(req, res) {
    var _success = function (data) {
        res.header('Cache-Control', 'public, max-age=950400');
        res.send(data);
    };
    var _error = function () {
        res.send(404);
    };

    match.information(req.params.game, parseInt(req.params.gameId)).then(_success, _error);
};
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const express = require('express');
const Meter = require('../models/Meter');
const { log } = require('../log');
const validate = require('jsonschema').validate;

const router = express.Router();

/**
 * Defines the format in which we want to send meters and controls what information we send to the client.
 * @param meter
 * @returns {{id, name}}
 */
function formatMeterForResponse(meter) {
	return { id: meter.id, name: meter.name };
}

/**
 * GET information on all meters
 */
router.get('/', async (req, res) => {
	try {
		const rows = await Meter.getAll();
		res.json(rows.map(formatMeterForResponse));
	} catch (err) {
		log.error(`Error while performing GET all meters query: ${err}`, err);
	}
});

/**
 * GET information for a specific meter by id
 * @param {int} meter_id
 */
router.get('/:meter_id', async (req, res) => {
	const validParams = {
		type: 'object',
		maxProperties: 1,
		required: ['meter_id'],
		properties: {
			group_id: {
				type: 'number'
			}
		}
	};
	if (!validate(req.params, validParams).valid) {
		res.sendStatus(400);
	} else {
		try {
			const meter = await Meter.getByID(req.params.meter_id);
			res.json(formatMeterForResponse(meter));
		} catch (err) {
			log.error(`Error while performing GET specific meter by id query: ${err}`, err);
			res.sendStatus(500);
		}
	}
});

module.exports = router;
<commit_msg>Fix validation for meter routes<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const express = require('express');
const Meter = require('../models/Meter');
const { log } = require('../log');
const validate = require('jsonschema').validate;

const router = express.Router();

/**
 * Defines the format in which we want to send meters and controls what information we send to the client.
 * @param meter
 * @returns {{id, name}}
 */
function formatMeterForResponse(meter) {
	return { id: meter.id, name: meter.name };
}

/**
 * GET information on all meters
 */
router.get('/', async (req, res) => {
	try {
		const rows = await Meter.getAll();
		res.json(rows.map(formatMeterForResponse));
	} catch (err) {
		log.error(`Error while performing GET all meters query: ${err}`, err);
	}
});

/**
 * GET information for a specific meter by id
 * @param {int} meter_id
 */
router.get('/:meter_id', async (req, res) => {
	const validParams = {
		type: 'object',
		maxProperties: 1,
		required: ['meter_id'],
		properties: {
			meter_id: {
				type: 'string',
				pattern: '^\\d+$'
			}
		}
	};
	if (!validate(req.params, validParams).valid) {
		res.sendStatus(400);
	} else {
		try {
			const meter = await Meter.getByID(req.params.meter_id);
			res.json(formatMeterForResponse(meter));
		} catch (err) {
			log.error(`Error while performing GET specific meter by id query: ${err}`, err);
			res.sendStatus(500);
		}
	}
});

module.exports = router;
<|endoftext|>