<commit_before>var system = require('system');
var fs = require('fs');
var page = require('webpage').create();

console.log('Accessing page...')
page.open(system.args[1], function () {

    window.setTimeout(function () {
      console.log('Setting HTML...');
      var html = page.evaluate(function(){
        var frames = document.getElementsByClassName("MathJax_SVG");
        var hiddenDiv = document.getElementById('MathJax_SVG_Hidden');
        var svgs = document.getElementsByTagName('svg');
        // var origDefs = svgs[0];
        var origDefs = hiddenDiv.nextSibling.firstChild;
        for (var i = 1; i < svgs.length; ++i)  {
          var defs = origDefs.cloneNode(false);
          var svg = svgs[i];
          var parent = svg.parent;
          // var frame = frames[i];
          // var svg = frame.children[0];
          // var svg = frame.getElementsByTagName('svg')[0];

          // append shallow defs and change xmlns.
          svg.insertBefore(defs, svg.firstChild);
          svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");

          // clone and copy all used paths into local defs.
          // xlink:href in uses FIX
          var uses = svg.getElementsByTagName("use");
          for (var k = 0; k < uses.length; ++k) {
            var id = uses[k].getAttribute("href");
            defs.appendChild(
              document.getElementById(id.substr(1)).cloneNode(true)
            );
            uses[k].setAttribute("xlink:href", id);
          }
          svg.style.position = "static";
          // var tmpDiv = document.createElement('div');
          // tmpDiv.appendChild(svg);
          // frames[i-1].innerHTML = tmpDiv.innerHTML;
          // n = i + 1;
          // // frame = document.getElementById('MathJax-Element-' + n + '-Frame');
          // frame.appendChild(svg);
        }
        svg_crud = document.getElementsByTagName('div')[0];
        svg_crud.parentNode.removeChild(svg_crud);
        return document.body.innerHTML;
      });

      utf8 = '<meta http-equiv="Content-type" content="text/html; charset=utf-8">'
      fs.write('phantomjs_source.html', utf8 + html, 'w');
      phantom.exit();
    }, 600);
});<commit_msg>[Delivers #52604151]<commit_after>var system = require('system');
var fs = require('fs');
var page = require('webpage').create();

console.log('Accessing page...')
page.open(system.args[1], function (status) {
    if (status !== "success") {
      console.log("Unable to access network");
    } else {
      //
      //  This gets called when MathJax is done
      //
      page.onAlert = function (msg) {
        if (msg === "MathJax Done") {
          console.log('Setting HTML...');
          var html = page.evaluate(function(){
            var frames = document.getElementsByClassName("MathJax_SVG");
            var hiddenDiv = document.getElementById('MathJax_SVG_Hidden');
            var svgs = document.getElementsByTagName('svg');
            var origDefs = hiddenDiv.nextSibling.firstChild;
            for (var i = 1; i < svgs.length; ++i)  {
              var defs = origDefs.cloneNode(false);
              var svg = svgs[i];
              // append shallow defs and change xmlns.
              svg.insertBefore(defs, svg.firstChild);
              svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
              // clone and copy all used paths into local defs.
              var uses = svg.getElementsByTagName("use");
              for (var k = 0; k < uses.length; ++k) {
                var id = uses[k].getAttribute("href");
                defs.appendChild(
                  document.getElementById(id.substr(1)).cloneNode(true)
                );
                uses[k].setAttribute("xlink:href", id);
              }
              svg.style.position = "static";
            }
            svg_defs = document.getElementsByTagName('div')[0];
            svg_defs.parentNode.removeChild(svg_defs);
            return document.body.innerHTML;
          });

          utf8 = '<meta http-equiv="Content-type" content="text/html; charset=utf-8">'
          fs.write('phantomjs_source.html', utf8 + html, 'w');
          phantom.exit();
        } else if (msg === "MathJax Timeout") {
            console.log("Timed out waiting for MathJax");
            phantom.exit();
        } else { console.log(msg) }
      }
    }

    page.evaluate(function () {
      var script = document.createElement("script");
      script.type = "text/x-mathjax-config";
      script.text = "MathJax.Hub.Queue([alert,'MathJax Done'])";
      document.head.appendChild(script);
      // Time out after 60 seconds, which should be long enough for
      // almost all documents.
      setTimeout(function () { alert("MathJax Timeout") }, 60000);
    });
});<|endoftext|>


<commit_before>var matrix = require('../src/matrix').matrix;
var assert = require('assert');

describe('matrix.dimensions', function() {
    it('should return the dimensions of an empty matrix', function() {
        var a = [];
        var expected = { rows: 0, columns: 0 };
        var actual = matrix.dimensions(a);
        assert.deepEqual(expected, actual);
    });

    it('should return the dimensions of a valid matrix', function() {
        var a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
        var expected = { rows: 3, columns: 3 };
        var actual = matrix.dimensions(a);
        assert.deepEqual(expected, actual);
    });

    it('should throw MatrixError when given an invalid matrix', function() {
        var a = [[1, 2, 3], [4, 5], [6, 7, 8]];
        assert.throws(function() {
            matrix.dimensions(a);
        }, matrix.MatrixError, 'Given matrix is invalid.');
    });

    it('should be integated to Array.prototype', function() {
        var expected = true;
        var actual = Array.prototype.hasOwnProperty('dimensions');
        assert.equal(expected, actual);
    });
});
<commit_msg>converted tests for matrix.dimensions to es2015<commit_after>import { dimensions, MatrixError } from '../src/matrix';
import assert from 'assert';

describe('matrix.dimensions', () => {
    it('should return the dimensions of an empty matrix', () => {
        var a = [];
        var expected = { rows: 0, columns: 0 };
        var actual = dimensions(a);
        assert.deepEqual(expected, actual);
    });

    it('should return the dimensions of a valid matrix', () => {
        var a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
        var expected = { rows: 3, columns: 3 };
        var actual = dimensions(a);
        assert.deepEqual(expected, actual);
    });

    it('should throw MatrixError when given an invalid matrix', () => {
        var a = [[1, 2, 3], [4, 5], [6, 7, 8]];
        assert.throws(() => {
            dimensions(a);
        }, MatrixError, 'Given matrix is invalid.');
    });

    it('should be integated to Array.prototype', () => {
        var expected = true;
        var actual = Array.prototype.hasOwnProperty('dimensions');
        assert.equal(expected, actual);
    });
});
<|endoftext|>


<commit_before>(function() {
  'use strict';

  var yo = function() {};

  yo.prototype.isUndefined = function(val) {
    return val === void 0;
  };

  yo.prototype.isString = function(val) {
    return typeof val === 'string';
  };

  yo.prototype.isNumber = function(val) {
    return typeof val === 'number' && val.constructor === Number;
  };

  yo.prototype.isObject = function(val) {
    return typeof val === 'object';
  };

  yo.prototype.isFunction = function(val) {
    return typeof val === 'function';
  };

  yo.prototype.isArray = function(val) {
    return val && yo.isObject(val) && val.constructor === Array;
  };

  yo.prototype.isEqual = function(a, b) {
    return a === b;
  };

  yo.prototype.isFinite = function(n) {
    return yo.isNumber(n) && Number.isFinite(n);
  };

  yo.prototype.flatten = function(arr) {
    return yo.reduce(arr, function(a, b) {
      return a.concat(b);
    }, []);
  };

  yo.prototype.error = function(str) {
    throw new Error(str);
  };

  yo.prototype.random = function(min, max) {
    if(yo.isUndefined(min)) {
      min = 0;
    }

    if(yo.isUndefined(max)) {
      max = 1;
    }

    if(!yo.isNumber(min) || !yo.isNumber(max)) {
      yo.error('No numbers provided');
    }

    return Math.floor(Math.random() * (max - min + 1) + min);
  };

  yo.prototype.$ = function(selector, context) {
    var element;

    if(typeof document === 'undefined') {
      yo.error('document object not found, are you in node?');
    }

    if(yo.isUndefined(selector)) {
      yo.error('No selector provided');
    }

    if(yo.isObject(selector) || yo.isArray(selector)) {
      element = selector;
    } else {

      var isClass = selector.match(/^\.[\w\d]/);
      var isId = selector.match(/^\#[\w\d]/);

      if(yo.isString(context)) {
        context = yo.$(context);
      }

      context = context || document;

      if(context.querySelectorAll) {
        if(isId) {
          element = context.querySelector(selector);
        } else {
          element = context.querySelectorAll(selector);
        }
      } else {
        if(isClass) {
          element = context.getElementsByClassName(selector.replace('.', ''));
        } else if(isId) {
          element = context.getElementById(selector.replace('#', ''));
        }
      }
    }

    return element;
  };

  yo.prototype.keys = function(obj) {
    var keys = [];
    for(var prop in obj) {
      keys.push(prop);
    }
    return keys;
  };

  yo.prototype.range = yo.prototype.times = function(n) {
    var arr = [];
    for(var i = 0; i < n; i++) {
      arr.push(i);
    }
    return arr;
  }

  yo.prototype.map = function(arr, callback) {
    if(!yo.isArray(arr)) {
      yo.error('No array given');
    }

    if(yo.isFunction(arr.map)) {
      return arr.map(callback);
    }

    var result = [];
    yo.each(arr, function(data) {
      result.push(callback(data));
    });

    return result;
  };

  yo.prototype.each = function(arr, callback) {
    if(yo.isFunction(arr.forEach)) {
      return arr.forEach(callback);
    }

    for(var i = 0; i < arr.length; ++i) {
      callback(arr[i]);
    }
  };

  yo.prototype.extend = function(obj, val) {
    var newObj = {};

    for(var prop in obj) {
      newObj[prop] = obj[prop];
    }

    for(var prop in val) {
      newObj[prop] = val[prop];
    }

    return newObj;
  };

  yo.prototype.css = function(selector, attr) {
    var elements = yo.$(selector);

    var setStyle = function(element) {
      yo.each(yo.keys(attr), function(prop) {
        element.style[prop] = attr[prop];
      });
    };

    if(elements.length) {
      yo.each(elements, setStyle);
    } else {
      setStyle(elements)
    }
  };

  yo.prototype.isPalindrome = function(str) {
    if(!yo.isString(str)) {
      return false;
    }
    if(!str || str.length < 2) {
      return true;
    }

    var word = yo.lowercase(str).replace(/[\W_]/g, '');

    return word === word.split('').reverse().join('');
  };

  yo.prototype.fibonacci = function(n) {
    n = n || 0;

    if(n < 1) {
      return 0;
    }

    if(n <= 2) {
      return 1;
    }

    return yo.fibonacci(n - 1) + yo.fibonacci(n - 2);
  };

  yo.prototype.reduce = function(arr, callback, initialValue) {
    if(yo.isUndefined(arr)) {
      yo.error('No array given');
    }

    if(yo.isFunction(arr.reduce)) {
      return arr.reduce(callback, initialValue);
    }

    yo.each(arr, function(value) {
      initialValue = callback(initialValue, value, arr);
    });

    return initialValue;
  };

  yo.prototype.listMethods = function(func) {
    return yo.keys(func || yo);
  };

  yo.prototype.reservedWords = function() {
    return [
      'abstract', 'else', 'instanceof', 'super',
      'boolean','enum', 'int', 'switch',
      'break','export', 'interface', 'synchronized',
      'byte', 'extends', 'let', 'this',
      'case', 'false', 'long', 'throw',
      'catch', 'final', 'native', 'throws',
      'char', 'finally', 'new', 'transient',
      'class', 'float', 'null', 'true',
      'const', 'for', 'package', 'try',
      'continue', 'function', 'private', 'typeof',
      'debugger', 'goto', 'protected', 'var',
      'default', 'if', 'public', 'void',
      'delete', 'implements', 'return', 'volatile',
      'do', 'import', 'short', 'while',
      'double', 'in', 'static', 'with'
    ];
  };

  yo.prototype.find = function(arr, item, useBinarySearch) {
    var result;

    if(useBinarySearch) {
      return yo.binarySearch(arr, item);
    }

    for (var i = arr.length - 1; i >= 0; i--) {
      if(arr[i] === item) {
        result = arr[i];
        break;
      }
    };

    return result;
  };

  yo.prototype.findKey = function(obj, item) {
    return obj[item] || false;
  };

  yo.prototype.pick = function(arr, query) {
    return yo.reduce(arr, function(value, item) {
      for(var prop in query) {
        if(item[prop] && yo.isEqual(item[prop], query[prop])) {
          value.push(item);
        }
      }

      return value;
    }, []);
  };

  yo.prototype.arrayToObject = function(arr, value) {
    value = value || true;

    return yo.reduce(arr, function(obj, key) {
      obj[key] = value;
      return obj;
    }, {});
  };

  yo.prototype.binarySearch = function(arr, value) {
    var search = function(start, end) {
      if(start > end) {
        return null;
      }
      if(arr[start] === value) {
        return start;
      }
      if(arr[end] === value) {
        return end;
      }

      var middle = Math.floor((start + end) / 2);
      var middleValue = arr[middle];

      if(middleValue === value) {
        return middleValue;
      } else if(middleValue > value) {
        return search(start + 1, middle);
      } else if(middleValue < value) {
        return search(middle, end - 1);
      }

      return null;
    };

    return search(0, yo.size(arr) - 1);
  };

  yo.prototype.size = function(val) {
    if(yo.isString(val) || yo.isArray(val)) {
      return val.length;
    }

    if(yo.isObject(val)) {
      return yo.size(yo.keys(val));
    }

    yo.error('yo.size only accepts: arrays, strings, objects');
  };

  yo.prototype.validateMethodNames = function(func) {
    var invalidMethodNames = yo.reduce(yo.listMethods(func), function(value, method) {
      var match = yo.findKey(yo.arrayToObject(yo.reservedWords()), method);
      if(match) {
        value.push(match);
      }

      return value;
    }, []);

    return yo.size(invalidMethodNames) ? invalidMethodNames : true;
  };

  yo.prototype.first = function(arr) {
    return arr[0];
  };

  yo.prototype.last = function(arr) {
    return arr[arr.length - 1];
  };

  yo.prototype.rest = function(arr) {
    return arr.slice(1, arr.length);
  };

  yo.prototype.drop = function(arr, n) {
    return arr.slice(n);
  };

  yo.prototype.dropRight = function(arr, n) {
    if(n > arr.length - 1) {
      return [];
    }
    return arr.slice(0, arr.length - n);
  };

  yo.prototype.gt = function(a, b) {
    return a > b;
  };

  yo.prototype.gte = function(a, b) {
    return a >= b;
  };

  yo.prototype.lt = function(a, b) {
    return a < b;
  };

  yo.prototype.lte = function(a, b) {
    return a <= b;
  };

  yo.prototype.uppercase = function(str) {
    return str.toUpperCase();
  };

  yo.prototype.lowercase = function(str) {
    return str.toLowerCase();
  };

  var noLocalStorage = function() {
    if(yo.isUndefined(window) || yo.isUndefined(window.localStorage)) {
      yo.error('No localStorage support');
    }
  };

  yo.prototype.localstorage = {
    get: function(key) {
      noLocalStorage();
      return JSON.parse(window.localStorage.getItem(key));
    },
    set: function(key, value) {
      noLocalStorage();

      window.localStorage.setItem(key, JSON.stringify(value));
    },
    remove: function(key) {
      noLocalStorage();
      window.localStorage.removeItem(key);
    }
  };

  yo.prototype.filter = function(arr, callback) {
    if(yo.isUndefined(arr)) {
      yo.error('No array provided');
    }
    if(yo.isFunction(arr.filter)) {
      return arr.filter(callback);
    }

    return yo.reduce(arr, function(value, item) {
      if(callback(item)) {
        value.push(item);
      }
      return value;
    }, []);
  };

  yo.prototype.chain = function(data) {
    return {
      filter: function(callback) {
        data = yo.filter(data, callback);
        return this;
      },
      map: function(callback) {
        data = yo.map(data, callback);
        return this;
      },
      reduce: function(callback, initialValue) {
        data = yo.reduce(data, callback, initialValue);
        return this;
      },
      find: function(callback) {
        data = yo.find(data, callback);
        return this;
      },
      findKey: function(callback) {
        data = yo.findKey(data, callback);
        return this;
      },
      pick: function(callback) {
        data = yo.pick(data, callback);
        return this;
      },
      flatten: function(callback) {
        data = yo.flatten(data, callback);
        return this;
      },
      first: function() {
        data = yo.first(data);
        return this;
      },
      rest: function() {
        data = yo.rest(data);
        return this;
      },
      drop: function(n) {
        data = yo.drop(data, n);
        return this;
      },
      dropRight: function(n) {
        data = yo.dropRight(data, n);
        return this;
      },
      value: function() {
        return data;
      }
    };
  };

  yo.prototype.kitten = function() {
    yo.each(yo.times(yo.random(5, 20)), function() {
      var color = (yo.random() ? yo.random() ? 'green' : 'red' : yo.random() ? 'orange': 'blue')
      var meow = function() { return yo.random() ? 'meow' : 'purrr'; };
      var allTheMeows = yo.map(yo.times(yo.random(1, yo.random(2, 4))), meow).join(' ')
      console.log('%c' + allTheMeows, 'color: ' + color);
    });
  }

  yo.prototype.exportModule = function(name, func) {
    if(typeof module !== 'undefined' && module.exports) {
      module.exports = func;
    }

    if(typeof window !== 'undefined') {
      window[name] = func;
    }

    if (typeof define === 'function' && define.amd) {
      define([name], func);
    }
  };

  yo = new yo();
  yo.exportModule('yo', yo);

  var validatedMethodNames = yo.validateMethodNames();
  if(validatedMethodNames !== true) {
    yo.error('Invalid method names in yo library!\nInvalid method names: ' + validatedMethodNames.join(', '));
  }

})();<commit_msg>Added fizzbuzz<commit_after>(function() {
  'use strict';

  var yo = function() {};

  yo.prototype.isUndefined = function(val) {
    return val === void 0;
  };

  yo.prototype.isString = function(val) {
    return typeof val === 'string';
  };

  yo.prototype.isNumber = function(val) {
    return typeof val === 'number' && val.constructor === Number;
  };

  yo.prototype.isObject = function(val) {
    return typeof val === 'object';
  };

  yo.prototype.isFunction = function(val) {
    return typeof val === 'function';
  };

  yo.prototype.isArray = function(val) {
    return val && yo.isObject(val) && val.constructor === Array;
  };

  yo.prototype.isEqual = function(a, b) {
    return a === b;
  };

  yo.prototype.isFinite = function(n) {
    return yo.isNumber(n) && Number.isFinite(n);
  };

  yo.prototype.flatten = function(arr) {
    return yo.reduce(arr, function(a, b) {
      return a.concat(b);
    }, []);
  };

  yo.prototype.error = function(str) {
    throw new Error(str);
  };

  yo.prototype.random = function(min, max) {
    if(yo.isUndefined(min)) {
      min = 0;
    }

    if(yo.isUndefined(max)) {
      max = 1;
    }

    if(!yo.isNumber(min) || !yo.isNumber(max)) {
      yo.error('No numbers provided');
    }

    return Math.floor(Math.random() * (max - min + 1) + min);
  };

  yo.prototype.$ = function(selector, context) {
    var element;

    if(typeof document === 'undefined') {
      yo.error('document object not found, are you in node?');
    }

    if(yo.isUndefined(selector)) {
      yo.error('No selector provided');
    }

    if(yo.isObject(selector) || yo.isArray(selector)) {
      element = selector;
    } else {

      var isClass = selector.match(/^\.[\w\d]/);
      var isId = selector.match(/^\#[\w\d]/);

      if(yo.isString(context)) {
        context = yo.$(context);
      }

      context = context || document;

      if(context.querySelectorAll) {
        if(isId) {
          element = context.querySelector(selector);
        } else {
          element = context.querySelectorAll(selector);
        }
      } else {
        if(isClass) {
          element = context.getElementsByClassName(selector.replace('.', ''));
        } else if(isId) {
          element = context.getElementById(selector.replace('#', ''));
        }
      }
    }

    return element;
  };

  yo.prototype.keys = function(obj) {
    var keys = [];
    for(var prop in obj) {
      keys.push(prop);
    }
    return keys;
  };

  yo.prototype.range = yo.prototype.times = function(n) {
    var arr = [];
    for(var i = 0; i < n; i++) {
      arr.push(i);
    }
    return arr;
  }

  yo.prototype.map = function(arr, callback) {
    if(!yo.isArray(arr)) {
      yo.error('No array given');
    }

    if(yo.isFunction(arr.map)) {
      return arr.map(callback);
    }

    var result = [];
    yo.each(arr, function(data) {
      result.push(callback(data));
    });

    return result;
  };

  yo.prototype.each = function(arr, callback) {
    if(yo.isFunction(arr.forEach)) {
      return arr.forEach(callback);
    }

    for(var i = 0; i < arr.length; ++i) {
      callback(arr[i]);
    }
  };

  yo.prototype.extend = function(obj, val) {
    var newObj = {};

    for(var prop in obj) {
      newObj[prop] = obj[prop];
    }

    for(var prop in val) {
      newObj[prop] = val[prop];
    }

    return newObj;
  };

  yo.prototype.css = function(selector, attr) {
    var elements = yo.$(selector);

    var setStyle = function(element) {
      yo.each(yo.keys(attr), function(prop) {
        element.style[prop] = attr[prop];
      });
    };

    if(elements.length) {
      yo.each(elements, setStyle);
    } else {
      setStyle(elements)
    }
  };

  yo.prototype.isPalindrome = function(str) {
    if(!yo.isString(str)) {
      return false;
    }
    if(!str || str.length < 2) {
      return true;
    }

    var word = yo.lowercase(str).replace(/[\W_]/g, '');

    return word === word.split('').reverse().join('');
  };

  yo.prototype.fibonacci = function(n) {
    n = n || 0;

    if(n < 1) {
      return 0;
    }

    if(n <= 2) {
      return 1;
    }

    return yo.fibonacci(n - 1) + yo.fibonacci(n - 2);
  };

  yo.prototype.fizzbuzz = function() {
    return yo.chain(yo.range(101))
      .rest()
      .map(function(i) {
        var fizz = 'Fizz';
        var buzz = 'Buzz';
        var three = i % 3 === 0;
        var five = i % 5 === 0;

        if(three && five) {
          return fizz + buzz;
        } else if(three) {
          return fizz;
        } else if(five) {
          return buzz;
        }

        return i;
      })
      .value();
  };

  yo.prototype.reduce = function(arr, callback, initialValue) {
    if(yo.isUndefined(arr)) {
      yo.error('No array given');
    }

    if(yo.isFunction(arr.reduce)) {
      return arr.reduce(callback, initialValue);
    }

    yo.each(arr, function(value) {
      initialValue = callback(initialValue, value, arr);
    });

    return initialValue;
  };

  yo.prototype.listMethods = function(func) {
    return yo.keys(func || yo);
  };

  yo.prototype.reservedWords = function() {
    return [
      'abstract', 'else', 'instanceof', 'super',
      'boolean','enum', 'int', 'switch',
      'break','export', 'interface', 'synchronized',
      'byte', 'extends', 'let', 'this',
      'case', 'false', 'long', 'throw',
      'catch', 'final', 'native', 'throws',
      'char', 'finally', 'new', 'transient',
      'class', 'float', 'null', 'true',
      'const', 'for', 'package', 'try',
      'continue', 'function', 'private', 'typeof',
      'debugger', 'goto', 'protected', 'var',
      'default', 'if', 'public', 'void',
      'delete', 'implements', 'return', 'volatile',
      'do', 'import', 'short', 'while',
      'double', 'in', 'static', 'with'
    ];
  };

  yo.prototype.find = function(arr, item, useBinarySearch) {
    var result;

    if(useBinarySearch) {
      return yo.binarySearch(arr, item);
    }

    for (var i = arr.length - 1; i >= 0; i--) {
      if(arr[i] === item) {
        result = arr[i];
        break;
      }
    };

    return result;
  };

  yo.prototype.findKey = function(obj, item) {
    return obj[item] || false;
  };

  yo.prototype.pick = function(arr, query) {
    return yo.reduce(arr, function(value, item) {
      for(var prop in query) {
        if(item[prop] && yo.isEqual(item[prop], query[prop])) {
          value.push(item);
        }
      }

      return value;
    }, []);
  };

  yo.prototype.arrayToObject = function(arr, value) {
    value = value || true;

    return yo.reduce(arr, function(obj, key) {
      obj[key] = value;
      return obj;
    }, {});
  };

  yo.prototype.binarySearch = function(arr, value) {
    var search = function(start, end) {
      if(start > end) {
        return null;
      }
      if(arr[start] === value) {
        return start;
      }
      if(arr[end] === value) {
        return end;
      }

      var middle = Math.floor((start + end) / 2);
      var middleValue = arr[middle];

      if(middleValue === value) {
        return middleValue;
      } else if(middleValue > value) {
        return search(start + 1, middle);
      } else if(middleValue < value) {
        return search(middle, end - 1);
      }

      return null;
    };

    return search(0, yo.size(arr) - 1);
  };

  yo.prototype.size = function(val) {
    if(yo.isString(val) || yo.isArray(val)) {
      return val.length;
    }

    if(yo.isObject(val)) {
      return yo.size(yo.keys(val));
    }

    yo.error('yo.size only accepts: arrays, strings, objects');
  };

  yo.prototype.validateMethodNames = function(func) {
    var invalidMethodNames = yo.reduce(yo.listMethods(func), function(value, method) {
      var match = yo.findKey(yo.arrayToObject(yo.reservedWords()), method);
      if(match) {
        value.push(match);
      }

      return value;
    }, []);

    return yo.size(invalidMethodNames) ? invalidMethodNames : true;
  };

  yo.prototype.first = function(arr) {
    return arr[0];
  };

  yo.prototype.last = function(arr) {
    return arr[arr.length - 1];
  };

  yo.prototype.rest = function(arr) {
    return arr.slice(1, arr.length);
  };

  yo.prototype.drop = function(arr, n) {
    return arr.slice(n);
  };

  yo.prototype.dropRight = function(arr, n) {
    if(n > arr.length - 1) {
      return [];
    }
    return arr.slice(0, arr.length - n);
  };

  yo.prototype.gt = function(a, b) {
    return a > b;
  };

  yo.prototype.gte = function(a, b) {
    return a >= b;
  };

  yo.prototype.lt = function(a, b) {
    return a < b;
  };

  yo.prototype.lte = function(a, b) {
    return a <= b;
  };

  yo.prototype.uppercase = function(str) {
    return str.toUpperCase();
  };

  yo.prototype.lowercase = function(str) {
    return str.toLowerCase();
  };

  var noLocalStorage = function() {
    if(yo.isUndefined(window) || yo.isUndefined(window.localStorage)) {
      yo.error('No localStorage support');
    }
  };

  yo.prototype.localstorage = {
    get: function(key) {
      noLocalStorage();
      return JSON.parse(window.localStorage.getItem(key));
    },
    set: function(key, value) {
      noLocalStorage();

      window.localStorage.setItem(key, JSON.stringify(value));
    },
    remove: function(key) {
      noLocalStorage();
      window.localStorage.removeItem(key);
    }
  };

  yo.prototype.filter = function(arr, callback) {
    if(yo.isUndefined(arr)) {
      yo.error('No array provided');
    }
    if(yo.isFunction(arr.filter)) {
      return arr.filter(callback);
    }

    return yo.reduce(arr, function(value, item) {
      if(callback(item)) {
        value.push(item);
      }
      return value;
    }, []);
  };

  yo.prototype.chain = function(data) {
    return {
      filter: function(callback) {
        data = yo.filter(data, callback);
        return this;
      },
      map: function(callback) {
        data = yo.map(data, callback);
        return this;
      },
      reduce: function(callback, initialValue) {
        data = yo.reduce(data, callback, initialValue);
        return this;
      },
      find: function(callback) {
        data = yo.find(data, callback);
        return this;
      },
      findKey: function(callback) {
        data = yo.findKey(data, callback);
        return this;
      },
      pick: function(callback) {
        data = yo.pick(data, callback);
        return this;
      },
      flatten: function(callback) {
        data = yo.flatten(data, callback);
        return this;
      },
      first: function() {
        data = yo.first(data);
        return this;
      },
      rest: function() {
        data = yo.rest(data);
        return this;
      },
      drop: function(n) {
        data = yo.drop(data, n);
        return this;
      },
      dropRight: function(n) {
        data = yo.dropRight(data, n);
        return this;
      },
      value: function() {
        return data;
      }
    };
  };

  yo.prototype.kitten = function() {
    yo.each(yo.times(yo.random(5, 20)), function() {
      var color = (yo.random() ? yo.random() ? 'green' : 'red' : yo.random() ? 'orange': 'blue')
      var meow = function() { return yo.random() ? 'meow' : 'purrr'; };
      var allTheMeows = yo.map(yo.times(yo.random(1, yo.random(2, 4))), meow).join(' ')
      console.log('%c' + allTheMeows, 'color: ' + color);
    });
  }

  yo.prototype.exportModule = function(name, func) {
    if(typeof module !== 'undefined' && module.exports) {
      module.exports = func;
    }

    if(typeof window !== 'undefined') {
      window[name] = func;
    }

    if (typeof define === 'function' && define.amd) {
      define([name], func);
    }
  };

  yo = new yo();
  yo.exportModule('yo', yo);

  var validatedMethodNames = yo.validateMethodNames();
  if(validatedMethodNames !== true) {
    yo.error('Invalid method names in yo library!\nInvalid method names: ' + validatedMethodNames.join(', '));
  }

})();<|endoftext|>


<commit_before>var raspi = require('raspi-io'),
    five = require('johnny-five'),
    board = new five.Board({
      io: new raspi()
    });

board.on('ready', function() {

  // Create an Led on pin 7 (GPIO4) and strobe it on/off
  // Optionally set the speed; defaults to 100ms
  //(new five.Led(7)).strobe();
  (new five.Led(11)).strobe(); // PIN GPIO17

  // Create a new `sensor` hardware instance.
  var sensor = new five.Sensor("13");

  sensor.scale([ 0, 10 ]).on("data", function() {
    console.log( this.value );
  });

});<commit_msg>Detection on blowing in test app<commit_after>var raspi = require('raspi-io'),
    five = require('johnny-five'),
    board = new five.Board({
      io: new raspi()
    });

board.on('ready', function() {

  // Create an Led on pin 7 (GPIO4) and strobe it on/off
  // Optionally set the speed; defaults to 100ms
  //(new five.Led(7)).strobe();
  (new five.Led(11)).strobe(); // PIN GPIO17

  // Create a new `sensor` hardware instance.
  /*var sensor = new five.Sensor("13");

  sensor.scale([ 0, 10 ]).on("data", function() {
    console.log( this.value );
  });*/

  var count = 0;
  var previousValue = board.pins[13].value;
  board.digitalRead(13, function(value) {
    if(previousValue !== value) {
      // The user is blowing
      count++;
      if(count % 100) { // Filter the output because there is a lot of notification
        console.log(count);
      }

      previousValue = value;
    }
  })

});<|endoftext|>


<commit_before>(function() {
    var Help = function(json) {
      view.View.call(this, json);
      this.clickFocusable = true;
      this.el.addClass("help");
      this.el.append('
' +
        "
Welcome to Riemann-Dash.
" +
        "
Need a refresher on the query language? See the query tests for examples, or read the spec.
" +
        "
Press Control/Meta+click  to select a view. Escape unfocuses. Use the arrow keys to move a view. Use Control+arrow to split a view in the given direction.
" +
        "
To edit a view, hit e. Use enter, or click 'apply', to apply your changes. Escape cancels.
" +
        "
To save your changes to the server, press s. To display the configuration, press c.
" +
        "
You can refresh the page, or press r to reload.
" +
        "
Make views bigger and smaller with the +/- keys. Pageup selects the parent of the current view. To delete a view, use the delete key.
" +
        "
Switch between workspaces with alt-1, alt-2, etc.
" +
        "
View is an empty space. Title is an editable text title. Fullscreen and Balloon are top-level container views; you probably won't use them. HStack and VStack are the horizontal and vertical container views; they're implicitly created by splits, but you can create them yourself for fine control. Gauge shows a single event. Grid shows a table of events. Timeseries and Flot show metrics over time--Timeseries is deprecated; Flot will probably replace it.
" +
        "
My sincere apologies for layout jankiness. There are a few gross bugs and incapabilities in the current hstack/vstack system; if things get really bad, you can always edit ws/config.json on the server. The control scheme will probably change; I appreciate your ideas and patches.
" +
        '
'
    );
    }

    view.inherit(view.View, Help);
    view.Help = Help;
    view.types.Help = Help;

    Help.prototype.json = function() {
      return {
        type: 'Help',
        title: this.title
      };
    }
})();
<commit_msg>Improve help view on how to delete a view<commit_after>(function() {
    var Help = function(json) {
      view.View.call(this, json);
      this.clickFocusable = true;
      this.el.addClass("help");
      this.el.append('
' +
        "
Welcome to Riemann-Dash.
" +
        "
Need a refresher on the query language? See the query tests for examples, or read the spec.
" +
        "
Press Control/Meta+click  to select a view. Escape unfocuses. Use the arrow keys to move a view. Use Control+arrow to split a view in the given direction.
" +
        "
To edit a view, hit e. Use enter, or click 'apply', to apply your changes. Escape cancels.
" +
        "
To save your changes to the server, press s. To display the configuration, press c.
" +
        "
You can refresh the page, or press r to reload.
" +
        "
Make views bigger and smaller with the +/- keys. Pageup selects the parent of the current view. To delete a view, use the delete key or press d.
" +
        "
Switch between workspaces with alt-1, alt-2, etc.
" +
        "
View is an empty space. Title is an editable text title. Fullscreen and Balloon are top-level container views; you probably won't use them. HStack and VStack are the horizontal and vertical container views; they're implicitly created by splits, but you can create them yourself for fine control. Gauge shows a single event. Grid shows a table of events. Timeseries and Flot show metrics over time--Timeseries is deprecated; Flot will probably replace it.
" +
        "
My sincere apologies for layout jankiness. There are a few gross bugs and incapabilities in the current hstack/vstack system; if things get really bad, you can always edit ws/config.json on the server. The control scheme will probably change; I appreciate your ideas and patches.
" +
        '
'
    );
    }

    view.inherit(view.View, Help);
    view.Help = Help;
    view.types.Help = Help;

    Help.prototype.json = function() {
      return {
        type: 'Help',
        title: this.title
      };
    }
})();
<|endoftext|>


<commit_before>#!/usr/bin/env node
<commit_msg>small demonstration<commit_after>#!/usr/bin/env node

const exec = require('child_process').exec;
<|endoftext|>


<commit_before>/*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/
/*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/
/*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/

define(function(require){
	var $ = require('jquery');
	var html = require('text!test/markup/scheduler-markup.html');
	/* FOR DEV TESTING */
	// html = require('text!index.html!strip');
	html = $('<div>'+html+'<div>').find('#MyScheduler');

	require('bootstrap');
	require('fuelux/scheduler');

	module('Fuel UX Scheduler');

	test('should be defined on the jQuery object', function(){
		ok( $(document.body).scheduler, 'scheduler method is defined' );
	});

	test('should return element', function (){
		ok($(document.body).scheduler()[0] === document.body, 'document.body returned');
	});

	test('should disable control (all inputs)', function (){
		var disabled = true;
		var $scheduler = $(html).scheduler();

		$scheduler.scheduler('disable');

		$scheduler.find('.combobox .btn').each(function(){
			if(!$(this).hasClass('disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all combobox controls disabled');

		$scheduler.find('.datepicker input').each(function(){
			if(!$(this).prop('disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all datepicker controls disabled');

		$scheduler.find('.radio input').each(function(){
			if(!$(this).is(':disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all radio button controls disabled');

		$scheduler.find('.selectlist .btn').each(function(){
			if(!$(this).hasClass('disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all select controls disabled');

		$scheduler.find('.spinbox .spinbox-input').each(function(){
			if(!$(this).prop('disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all spinbox controls disabled');

		disabled = $scheduler.find('.repeat-days-of-the-week .btn-group').hasClass('disabled');
		equal(disabled, true, 'scheduler weekly btn-group disabled');
	});

	test('should enable control (all inputs)', function () {
		var enabled = true;
		var $scheduler = $(html).scheduler();

		$scheduler.scheduler('disable');
		$scheduler.scheduler('enable');

		$scheduler.find('.combobox .btn').each(function(){
			if($(this).hasClass('disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all combobox controls enabled');

		$scheduler.find('.datepicker input').each(function(){
			if($(this).prop('disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all datepicker controls enabled');

		$scheduler.find('.radio input').each(function(){
			if($(this).is(':disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all radio button controls enabled');

		$scheduler.find('.selectlist .btn').each(function(){
			if($(this).hasClass('disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all select controls enabled');

		$scheduler.find('.spinbox .spinbox-input').each(function(){
			if($(this).prop('disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all spinbox controls enabled');

		enabled = ($scheduler.find('.repeat-days-of-the-week .btn-group').hasClass('disabled')) ? false : true;
		equal(enabled, true, 'scheduler weekly btn-group enabled');
	});

	test('should return proper value object', function (){
		var $scheduler = $(html).scheduler();
		var obj = 'object';
		var str = 'string';
		var val = $scheduler.scheduler('value');

		ok(typeof(val)===obj, 'return value is object');
		ok(typeof(val.recurrencePattern)===str, 'return value contains recurrencePattern string');
		ok(typeof(val.startDateTime)===str, 'return value contains startDateTime string');
		ok(typeof(val.timeZone)===obj, 'return value contains timeZone object');
		ok(typeof(val.timeZone.name)===str, 'timeZone contains name string');
		ok(typeof(val.timeZone.offset)===str, 'timeZone contains offset string');
	});

	test('should set value properly', function (){
		//needed due to PhantomJS bug: https://github.com/ariya/phantomjs/issues/11151
		var isPhantomJS = (window.navigator.userAgent.search('PhantomJS')>=0);
		var $scheduler = $(html).scheduler();
		var $repIntSelDrop = $scheduler.find('.repeat-options .selected-label');
		var $repPanSpinbox = $scheduler.find('.repeat-every');
		var test;
		var tmpDatepickerVal;
		var tmpValBool = false;

		$scheduler.scheduler('value', { startDateTime: '2050-03-31T05:00' });
		//make this test always present once PhantomJS fixes their bug
		if(!isPhantomJS){
			tmpDatepickerVal = $scheduler.find('.start-datetime .datepicker input').val();
			if( tmpDatepickerVal === '03-31-2050' || tmpDatepickerVal === '03/31/2050' ) {
				tmpValBool = true;
			}
			equal( tmpValBool, true, 'startDate set correctly');
		}
		equal($scheduler.find('.start-datetime .combobox input').val(), '5:00 AM', 'startTime set correctly');

		$scheduler.scheduler('value', { timeZone: { name: 'Namibia Standard Time', offset: '+02:00' }});
		equal($scheduler.find('.timezone-container .selected-label').html(), '(GMT+02:00) Windhoek *', 'timeZone set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;INTERVAL=1;COUNT=1;' });
		equal($repIntSelDrop.html(), 'None (run once)', 'no recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=HOURLY;INTERVAL=3;' });
		ok(($repIntSelDrop.html()==='Hourly' && $repPanSpinbox.spinbox('value')===3), 'hourly recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;INTERVAL=4;' });
		ok(($repIntSelDrop.html()==='Daily' && $repPanSpinbox.spinbox('value')===4), 'daily recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;INTERVAL=1;' });
		equal($repIntSelDrop.html(), 'Weekdays', 'weekday recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=WEEKLY;BYDAY=MO,TH;INTERVAL=7;' });
		test = $scheduler.find('.repeat-days-of-the-week .btn-group');
		test = (test.find('[data-value="MO"]').parent().hasClass('active') && test.find('[data-value="TH"]').parent().hasClass('active')) ? true : false;
		ok(($repIntSelDrop.html()==='Weekly' && $repPanSpinbox.spinbox('value')===7 && test), 'weekly recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=MONTHLY;INTERVAL=9;BYDAY=SA;BYSETPOS=4;' });
		test = $scheduler.find('.repeat-monthly-day');
		ok(($repIntSelDrop.html()==='Monthly' && $repPanSpinbox.spinbox('value')===9 && test.find('div.radio input').hasClass('checked') &&
			test.find('.month-day-pos .selected-label').html()==='Fourth' && test.find('.month-days .selected-label').html()==='Saturday'),
			'monthly recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=YEARLY;BYDAY=WE;BYSETPOS=3;BYMONTH=10;' });
		test = $scheduler.find('.repeat-yearly-day');
		ok(($repIntSelDrop.html()==='Yearly' && test.find('div.radio input').hasClass('checked') &&
			test.find('.year-month-day-pos .selected-label').html()==='Third' && test.find('.year-month-days .selected-label').html()==='Wednesday' &&
			test.find('.year-month .selected-label').html()==='October'), 'yearly recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;INTERVAL=9;COUNT=4;' });
		ok(($scheduler.find('.repeat-end .selectlist .selected-label').html()==='After' && $scheduler.find('.repeat-end .spinbox').spinbox('value')===4),
			'end after occurence(s) set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;INTERVAL=9;UNTIL=20510331;' });
		//make this test always present once PhantomJS fixes their bug
		test = (!isPhantomJS) ? ($scheduler.find('.repeat-end .datepicker input').val() ==='03-31-2051' || $scheduler.find('.repeat-end .datepicker input').val() ==='03/31/2051' ) : true;
		ok(($scheduler.find('.repeat-end .selectlist .selected-label').html()==='On date' && test), 'end on date set correctly');
	});
});<commit_msg>scheduler namespaced<commit_after>/*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/
/*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/
/*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/

define(function(require){
	var $ = require('jquery');
	var html = require('text!test/markup/scheduler-markup.html');
	/* FOR DEV TESTING */
	// html = require('text!index.html!strip');
	html = $('<div>'+html+'<div>').find('#MyScheduler');

	require('bootstrap');
	require('fuelux/scheduler');

	// TODO: Test 'changed.fu.scheduler' event

	module('Fuel UX Scheduler');

	test('should be defined on the jQuery object', function(){
		ok( $(document.body).scheduler, 'scheduler method is defined' );
	});

	test('should return element', function (){
		ok($(document.body).scheduler()[0] === document.body, 'document.body returned');
	});

	test('should disable control (all inputs)', function (){
		var disabled = true;
		var $scheduler = $(html).scheduler();

		$scheduler.scheduler('disable');

		$scheduler.find('.combobox .btn').each(function(){
			if(!$(this).hasClass('disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all combobox controls disabled');

		$scheduler.find('.datepicker input').each(function(){
			if(!$(this).prop('disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all datepicker controls disabled');

		$scheduler.find('.radio input').each(function(){
			if(!$(this).is(':disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all radio button controls disabled');

		$scheduler.find('.selectlist .btn').each(function(){
			if(!$(this).hasClass('disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all select controls disabled');

		$scheduler.find('.spinbox .spinbox-input').each(function(){
			if(!$(this).prop('disabled')){
				disabled = false;
			}
		});
		equal(disabled, true, 'all spinbox controls disabled');

		disabled = $scheduler.find('.repeat-days-of-the-week .btn-group').hasClass('disabled');
		equal(disabled, true, 'scheduler weekly btn-group disabled');
	});

	test('should enable control (all inputs)', function () {
		var enabled = true;
		var $scheduler = $(html).scheduler();

		$scheduler.scheduler('disable');
		$scheduler.scheduler('enable');

		$scheduler.find('.combobox .btn').each(function(){
			if($(this).hasClass('disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all combobox controls enabled');

		$scheduler.find('.datepicker input').each(function(){
			if($(this).prop('disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all datepicker controls enabled');

		$scheduler.find('.radio input').each(function(){
			if($(this).is(':disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all radio button controls enabled');

		$scheduler.find('.selectlist .btn').each(function(){
			if($(this).hasClass('disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all select controls enabled');

		$scheduler.find('.spinbox .spinbox-input').each(function(){
			if($(this).prop('disabled')){
				enabled = false;
			}
		});
		equal(enabled, true, 'all spinbox controls enabled');

		enabled = ($scheduler.find('.repeat-days-of-the-week .btn-group').hasClass('disabled')) ? false : true;
		equal(enabled, true, 'scheduler weekly btn-group enabled');
	});

	test('should return proper value object', function (){
		var $scheduler = $(html).scheduler();
		var obj = 'object';
		var str = 'string';
		var val = $scheduler.scheduler('value');

		ok(typeof(val)===obj, 'return value is object');
		ok(typeof(val.recurrencePattern)===str, 'return value contains recurrencePattern string');
		ok(typeof(val.startDateTime)===str, 'return value contains startDateTime string');
		ok(typeof(val.timeZone)===obj, 'return value contains timeZone object');
		ok(typeof(val.timeZone.name)===str, 'timeZone contains name string');
		ok(typeof(val.timeZone.offset)===str, 'timeZone contains offset string');
	});

	test('should set value properly', function (){
		//needed due to PhantomJS bug: https://github.com/ariya/phantomjs/issues/11151
		var isPhantomJS = (window.navigator.userAgent.search('PhantomJS')>=0);
		var $scheduler = $(html).scheduler();
		var $repIntSelDrop = $scheduler.find('.repeat-options .selected-label');
		var $repPanSpinbox = $scheduler.find('.repeat-every');
		var test;
		var tmpDatepickerVal;
		var tmpValBool = false;

		$scheduler.scheduler('value', { startDateTime: '2050-03-31T05:00' });
		//make this test always present once PhantomJS fixes their bug
		if(!isPhantomJS){
			tmpDatepickerVal = $scheduler.find('.start-datetime .datepicker input').val();
			if( tmpDatepickerVal === '03-31-2050' || tmpDatepickerVal === '03/31/2050' ) {
				tmpValBool = true;
			}
			equal( tmpValBool, true, 'startDate set correctly');
		}
		equal($scheduler.find('.start-datetime .combobox input').val(), '5:00 AM', 'startTime set correctly');

		$scheduler.scheduler('value', { timeZone: { name: 'Namibia Standard Time', offset: '+02:00' }});
		equal($scheduler.find('.timezone-container .selected-label').html(), '(GMT+02:00) Windhoek *', 'timeZone set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;INTERVAL=1;COUNT=1;' });
		equal($repIntSelDrop.html(), 'None (run once)', 'no recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=HOURLY;INTERVAL=3;' });
		ok(($repIntSelDrop.html()==='Hourly' && $repPanSpinbox.spinbox('value')===3), 'hourly recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;INTERVAL=4;' });
		ok(($repIntSelDrop.html()==='Daily' && $repPanSpinbox.spinbox('value')===4), 'daily recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;INTERVAL=1;' });
		equal($repIntSelDrop.html(), 'Weekdays', 'weekday recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=WEEKLY;BYDAY=MO,TH;INTERVAL=7;' });
		test = $scheduler.find('.repeat-days-of-the-week .btn-group');
		test = (test.find('[data-value="MO"]').parent().hasClass('active') && test.find('[data-value="TH"]').parent().hasClass('active')) ? true : false;
		ok(($repIntSelDrop.html()==='Weekly' && $repPanSpinbox.spinbox('value')===7 && test), 'weekly recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=MONTHLY;INTERVAL=9;BYDAY=SA;BYSETPOS=4;' });
		test = $scheduler.find('.repeat-monthly-day');
		ok(($repIntSelDrop.html()==='Monthly' && $repPanSpinbox.spinbox('value')===9 && test.find('div.radio input').hasClass('checked') &&
			test.find('.month-day-pos .selected-label').html()==='Fourth' && test.find('.month-days .selected-label').html()==='Saturday'),
			'monthly recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=YEARLY;BYDAY=WE;BYSETPOS=3;BYMONTH=10;' });
		test = $scheduler.find('.repeat-yearly-day');
		ok(($repIntSelDrop.html()==='Yearly' && test.find('div.radio input').hasClass('checked') &&
			test.find('.year-month-day-pos .selected-label').html()==='Third' && test.find('.year-month-days .selected-label').html()==='Wednesday' &&
			test.find('.year-month .selected-label').html()==='October'), 'yearly recurrence set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;INTERVAL=9;COUNT=4;' });
		ok(($scheduler.find('.repeat-end .selectlist .selected-label').html()==='After' && $scheduler.find('.repeat-end .spinbox').spinbox('value')===4),
			'end after occurence(s) set correctly');

		$scheduler.scheduler('value', { recurrencePattern: 'FREQ=DAILY;INTERVAL=9;UNTIL=20510331;' });
		//make this test always present once PhantomJS fixes their bug
		test = (!isPhantomJS) ? ($scheduler.find('.repeat-end .datepicker input').val() ==='03-31-2051' || $scheduler.find('.repeat-end .datepicker input').val() ==='03/31/2051' ) : true;
		ok(($scheduler.find('.repeat-end .selectlist .selected-label').html()==='On date' && test), 'end on date set correctly');
	});
});<|endoftext|>


<commit_before>// VexFlow - Basic Tests

Vex.Flow.Test.Clef = {}

Vex.Flow.Test.Clef.Start = function() {
  module("Clef");
  Vex.Flow.Test.runTest("Clef Test", Vex.Flow.Test.Clef.draw);
  Vex.Flow.Test.runRaphaelTest("Clef Test (Raphael)",
      Vex.Flow.Test.Clef.draw);
}

Vex.Flow.Test.Clef.draw = function(options, contextBuilder) {
  var ctx = new contextBuilder(options.canvas_sel, 400, 120);
  var stave = new Vex.Flow.Stave(10, 10, 300);

  stave.addClef("treble");
  stave.addClef("bass");
  stave.addClef("alto");

  stave.setContext(ctx);
  stave.draw();

  ok(true, "all pass");
}

<commit_msg>Update test/clef_tests.js to display Old Clefs(tenor, french_violin, soprano, mezzo_soprano, baritone, baritone_bass, sub_bass)<commit_after>// VexFlow - Basic Tests

Vex.Flow.Test.Clef = {}

Vex.Flow.Test.Clef.Start = function() {
  module("Clef");
  Vex.Flow.Test.runTest("Clef Test", Vex.Flow.Test.Clef.draw);
  Vex.Flow.Test.runRaphaelTest("Clef Test (Raphael)",
      Vex.Flow.Test.Clef.draw);
}

Vex.Flow.Test.Clef.draw = function(options, contextBuilder) {
  var ctx = new contextBuilder(options.canvas_sel, 400, 120);
  var stave = new Vex.Flow.Stave(10, 10, 350);

  stave.addClef("treble");
  stave.addClef("bass");
  stave.addClef("alto");
  stave.addClef("tenor");
  stave.addClef("french_violin");
  stave.addClef("soprano");
  stave.addClef("mezzo_soprano");
  stave.addClef("baritone");
  stave.addClef("baritone_bass");
  stave.addClef("sub_bass");

  stave.setContext(ctx);
  stave.draw();

  ok(true, "all pass");
}

<|endoftext|>


<commit_before>var util = require('../lib/test-utils.js');
var expect = require('chai').expect;

describe('fs.link', function() {
  beforeEach(util.setup);
  afterEach(util.cleanup);

  it('should be a function', function() {
    var fs = util.fs();
    expect(fs.link).to.be.a('function');
  });

  it('should create a link to an existing file', function(done) {
    var fs = util.fs();

    fs.open('/myfile', 'w+', function(error, fd) {
      if(error) throw error;

      fs.close(fd, function(error) {
        if(error) throw error;

        fs.link('/myfile', '/myotherfile', function(error) {
          if(error) throw error;

          fs.stat('/myfile', function(error, result) {
            if(error) throw error;

            var _oldstats = result;
            fs.stat('/myotherfile', function(error, result) {
              expect(error).not.to.exist;
              expect(result.nlinks).to.equal(2);
              expect(result.dev).to.equal(_oldstats.dev);
              expect(result.node).to.equal(_oldstats.node);
              expect(result.size).to.equal(_oldstats.size);
              expect(result.type).to.equal(_oldstats.type);
              done();
            });
          });
        });
      });
    });
  });

  it('should create hard link to identical data node', function(done) {
    var fs = util.fs();
    var contents = 'Hello World!';

    fs.writeFile('/file', contents, function(err) {
      if(err) throw err;

      fs.link('/file', '/hlink', function(err) {
        if(err) throw err;

        fs.readFile('/file', 'utf8', function(err, fileData) {
          if(err) throw err;

          fs.readFile('/hlink', 'utf8', function(err, hlinkData) {
            if(err) throw err;

            expect(fileData).to.equal(hlinkData);
            done();
          });
        });
      });
    });
  });

  it('should not follow symbolic links', function(done) {
    var fs = util.fs();

    fs.stat('/', function (error, result) {
      if (error) throw error;
      expect(result).to.exist;

      fs.symlink('/', '/myfileLink', function (error) {
        if (error) throw error;

        fs.link('/myfileLink', '/myotherfile', function (error) {
          if (error) throw error;

          fs.lstat('/myfileLink', function (error, result) {
            if (error) throw error;
            var _linkstats = result;
            fs.lstat('/myotherfile', function (error, result) {
              expect(error).not.to.exist;
              expect(result.dev).to.equal(_linkstats.dev);
              expect(result.node).to.equal(_linkstats.node);
              expect(result.size).to.equal(_linkstats.size);
              expect(result.type).to.equal(_linkstats.type);
              expect(result.nlinks).to.equal(2);
              done();
            });
          });
        });
      });
    });
  });

  it('should not allow links to a directory', function(done) {
    var fs = util.fs();

    fs.mkdir('/mydir', function(error) {
      if(error) throw error;

      fs.link('/mydir', '/mydirlink', function(error) {
        expect(error).to.exist;
        expect(error.code).to.equal('EPERM');
        done();
      });
    });
  });

});

describe('fs.promises.link', function() {

  beforeEach(util.setup);
  afterEach(util.cleanup);

  it('should be a function', function(){
    var fsPromises = util.fs().promises;
    expect(fsPromises.link).to.be.a('function');
  });

  it('should return a promise', function() {
    var fsPromise = util.fs().promises;

    var p = fsPromise
      .writeFile('/myfile', '')
      .then(() => fsPromise.link('/myfile', '/myotherfile'));

    expect(p).to.be.a('promise');

    return p;
  });
});
<commit_msg>Added fsPromises.link() tests<commit_after>var util = require('../lib/test-utils.js');
var expect = require('chai').expect;

describe('fs.link', function() {
  beforeEach(util.setup);
  afterEach(util.cleanup);

  it('should be a function', function() {
    var fs = util.fs();
    expect(fs.link).to.be.a('function');
  });

  it('should create a link to an existing file', function(done) {
    var fs = util.fs();

    fs.open('/myfile', 'w+', function(error, fd) {
      if(error) throw error;

      fs.close(fd, function(error) {
        if(error) throw error;

        fs.link('/myfile', '/myotherfile', function(error) {
          if(error) throw error;

          fs.stat('/myfile', function(error, result) {
            if(error) throw error;

            var _oldstats = result;
            fs.stat('/myotherfile', function(error, result) {
              expect(error).not.to.exist;
              expect(result.nlinks).to.equal(2);
              expect(result.dev).to.equal(_oldstats.dev);
              expect(result.node).to.equal(_oldstats.node);
              expect(result.size).to.equal(_oldstats.size);
              expect(result.type).to.equal(_oldstats.type);
              done();
            });
          });
        });
      });
    });
  });

  it('should create hard link to identical data node', function(done) {
    var fs = util.fs();
    var contents = 'Hello World!';

    fs.writeFile('/file', contents, function(err) {
      if(err) throw err;

      fs.link('/file', '/hlink', function(err) {
        if(err) throw err;

        fs.readFile('/file', 'utf8', function(err, fileData) {
          if(err) throw err;

          fs.readFile('/hlink', 'utf8', function(err, hlinkData) {
            if(err) throw err;

            expect(fileData).to.equal(hlinkData);
            done();
          });
        });
      });
    });
  });

  it('should not follow symbolic links', function(done) {
    var fs = util.fs();

    fs.stat('/', function (error, result) {
      if (error) throw error;
      expect(result).to.exist;

      fs.symlink('/', '/myfileLink', function (error) {
        if (error) throw error;

        fs.link('/myfileLink', '/myotherfile', function (error) {
          if (error) throw error;

          fs.lstat('/myfileLink', function (error, result) {
            if (error) throw error;
            var _linkstats = result;
            fs.lstat('/myotherfile', function (error, result) {
              expect(error).not.to.exist;
              expect(result.dev).to.equal(_linkstats.dev);
              expect(result.node).to.equal(_linkstats.node);
              expect(result.size).to.equal(_linkstats.size);
              expect(result.type).to.equal(_linkstats.type);
              expect(result.nlinks).to.equal(2);
              done();
            });
          });
        });
      });
    });
  });

  it('should not allow links to a directory', function(done) {
    var fs = util.fs();

    fs.mkdir('/mydir', function(error) {
      if(error) throw error;

      fs.link('/mydir', '/mydirlink', function(error) {
        expect(error).to.exist;
        expect(error.code).to.equal('EPERM');
        done();
      });
    });
  });

});

describe('fs.promises.link', function() {

  beforeEach(util.setup);
  afterEach(util.cleanup);

  it('should be a function', function(){
    var fsPromises = util.fs().promises;
    expect(fsPromises.link).to.be.a('function');
  });

  it('should return a promise', function() {
    var fsPromise = util.fs().promises;

    var p = fsPromise
      .writeFile('/myfile', '')
      .then(() => fsPromise.link('/myfile', '/myotherfile'));

    expect(p).to.be.a('promise');

    return p;
  });
});

describe('fs.promises.link', function() {
  beforeEach(util.setup);
  afterEach(util.cleanup);

  it('should be a function', function() {
    var fs = util.fs();
    expect(fs.promises.link).to.be.a('function');
  });

  it('should create a link to an existing file', function(done) {
    var fs = util.fs();

    fs.open('/myfile', 'w+', function(error, fd) {
      if(error) throw error;

      fs.close(fd, function(error) {
        if(error) throw error;

        fs.promises.link('/myfile', '/myotherfile', function(error) {
          if(error) throw error;

          fs.stat('/myfile', function(error, result) {
            if(error) throw error;

            var _oldstats = result;
            fs.stat('/myotherfile', function(error, result) {
              expect(error).not.to.exist;
              expect(result.nlinks).to.equal(2);
              expect(result.dev).to.equal(_oldstats.dev);
              expect(result.node).to.equal(_oldstats.node);
              expect(result.size).to.equal(_oldstats.size);
              expect(result.type).to.equal(_oldstats.type);
              done();
            });
          });
        });
      });
    });
  });

  it('should create hard link to identical data node', function(done) {
    var fs = util.fs();
    var contents = 'Hello World!';

    fs.writeFile('/file', contents, function(err) {
      if(err) throw err;

      fs.promises.link('/file', '/hlink', function(err) {
        if(err) throw err;

        fs.readFile('/file', 'utf8', function(err, fileData) {
          if(err) throw err;

          fs.readFile('/hlink', 'utf8', function(err, hlinkData) {
            if(err) throw err;

            expect(fileData).to.equal(hlinkData);
            done();
          });
        });
      });
    });
  });

  it('should not follow symbolic links', function(done) {
    var fs = util.fs();

    fs.stat('/', function (error, result) {
      if (error) throw error;
      expect(result).to.exist;

      fs.symlink('/', '/myfileLink', function (error) {
        if (error) throw error;

        fs.promises.link('/myfileLink', '/myotherfile', function (error) {
          if (error) throw error;

          fs.lstat('/myfileLink', function (error, result) {
            if (error) throw error;

            var _linkstats = result;
            fs.lstat('/myotherfile', function (error, result) {
              expect(error).not.to.exist;
              expect(result.dev).to.equal(_linkstats.dev);
              expect(result.node).to.equal(_linkstats.node);
              expect(result.size).to.equal(_linkstats.size);
              expect(result.type).to.equal(_linkstats.type);
              expect(result.nlinks).to.equal(2);
              done();
            });
          });
        });
      });
    });
  });

  it('should not allow links to a directory', function(done) {
    var fs = util.fs();

    fs.mkdir('/mydir', function(error) {
      if(error) throw error;

      fs.promises.link('/mydir', '/mydirlink', function(error) {
        expect(error).to.exist;
        expect(error.code).to.equal('EPERM');
        done();
      });
    });
  });

});
<|endoftext|>


<commit_before>'use strict';

/**
 * Controller for the BreakOut-Member-Page.
 */

const Promise = require('bluebird');
const GoogleSpreadsheet = require('google-spreadsheet');
const co = require('co');
const _ = require('lodash');
const fs = require('co-fs-extra');

const config = {
  doc_id: process.env.FRONTEND_GDRIVE_DOCUMENT_ID,
  client_email: process.env.FRONTEND_GDRIVE_CLIENT_EMAIL,
  private_key: process.env.FRONTEND_GDRIVE_PRIVATE_KEY
};

/**
 * GET route for the BreakOut-Member-Page.
 * @param language
 * @param res
 */
module.exports.teamPage = (language, res) => co(function* () {
  const cachePath = ROOT + '/rendered/cache/teams.json.cache';

  const fetchMemberList = () => co(function* () {
    const doc = new GoogleSpreadsheet(config.doc_id);
    var credsJson = {
      client_email: config.client_email,
      private_key: config.private_key.replace(/\\n/g, '\n')
    };

    logger.info('Trying to authenticate with Google Docs');
    yield Promise.promisify(doc.useServiceAccountAuth)(credsJson);
    logger.info('Authenticated with Google Docs');

    logger.info('Trying to get info from Google Docs');
    const info = yield Promise.promisify(doc.getInfo)();
    logger.info('Got info from Google Docs');
    const sheet = info.worksheets[0];

    logger.info('Trying to get all rows from sheet');
    const rows = yield Promise.promisify(sheet.getRows)({
      offset: 3
    });
    logger.info('Got all rows from sheet');

    const allMember = _.sortBy(rows.reduce((init, curr) => _.concat(init, {
      name: curr.name,
      surname: curr.surname,
      url: curr.link,
      role: curr.role,
      active: curr.active
    }), []), m => m.surname);

    return [
      _.filter(allMember, m => m.active === 'ja'),
      _.filter(allMember, m => m.active === 'nein')
    ];
  }).catch(ex => {
    throw ex;
  });

  let finalMembers;

  const cacheExists = yield fs.exists(cachePath);

  // Cache file does exist
  if (cacheExists && process.env.NODE_ENV === 'production') {
    const fileStats = yield fs.stat(cachePath);

    // Cache file is outdated
    if ((new Date(fileStats.mtime).getDay()) != (new Date).getDay()) {
      logger.info('File', cachePath, 'is out of date, renewing');

      const member = yield fetchMemberList();

      yield fs.writeJson(cachePath, member);
      finalMembers = member;
    } else { // Cache file is up to date
      finalMembers = yield fs.readJson(cachePath);
    }
  } else { // Cache file does not exist
    const member = yield fetchMemberList();
    yield fs.writeJson(cachePath, member);
    finalMembers = member;
  }

  res.render('static/team/content', {
    layout: 'master',
    member: finalMembers,
    language: language
  });

}).catch(ex => {
  throw ex;
});
<commit_msg>adds changes from member page<commit_after>'use strict';

/**
 * Controller for the BreakOut-Member-Page.
 */

const Promise = require('bluebird');
const GoogleSpreadsheet = require('google-spreadsheet');
const co = require('co');
const _ = require('lodash');
const fs = require('co-fs-extra');

const config = requireLocal('config/config.js');

/**
 * GET route for the BreakOut-Member-Page.
 * @param language
 * @param res
 */
module.exports.teamPage = (language, res) => co(function*() {
  const cachePath = ROOT + '/rendered/cache/teams.json.cache';

  const fetchMemberList = () => co(function* () {
    const doc = new GoogleSpreadsheet(config.gdrive.document_id);
    var credsJson = {
      client_email: config.gdrive.client_email,
      private_key: config.gdrive.private_key.replace(/\\n/g, '\n')
    };

    logger.info('Trying to authenticate with Google Docs');
    yield Promise.promisify(doc.useServiceAccountAuth)(credsJson);
    logger.info('Authenticated with Google Docs');

    logger.info('Trying to get info from Google Docs');
    const info = yield Promise.promisify(doc.getInfo)();
    logger.info('Got info from Google Docs');
    const sheet = info.worksheets[0];

    logger.info('Trying to get all rows from sheet');
    const rows = yield Promise.promisify(sheet.getRows)({
      offset: 3
    });
    logger.info('Got all rows from sheet');

    const allMember = _.sortBy(rows.reduce((init, curr) => _.concat(init, {
      name: curr.name,
      surname: curr.surname,
      url: curr.link,
      role: curr.role,
      active: curr.active
    }), []), m => m.surname);

    return [
      _.filter(allMember, m => m.active === 'ja'),
      _.filter(allMember, m => m.active === 'nein')
    ];
  }).catch(ex => {
    throw ex;
  });

  let finalMembers;

  const cacheExists = yield fs.exists(cachePath);

  // Cache file does exist
  if (cacheExists && process.env.NODE_ENVIRONMENT === 'prod') {
    const fileStats = yield fs.stat(cachePath);

    // Cache file is outdated
    if ((new Date(fileStats.mtime).getDay()) != (new Date).getDay()) {
      logger.info('File', cachePath, 'is out of date, renewing');

      const member = yield fetchMemberList();

      yield fs.writeJson(cachePath, member);
      finalMembers = member;
    } else { // Cache file is up to date
      finalMembers = yield fs.readJson(cachePath);
    }
  } else { // Cache file does not exist
    const member = yield fetchMemberList();
    yield fs.writeJson(cachePath, member);
    finalMembers = member;
  }

  res.render('static/team/content', {
    layout: 'master',
    member: finalMembers,
    language: language
  });

}).catch(ex => {
  throw ex;
});
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');

var outputDir = path.join(__dirname, 'build');
var outputFile = path.join(outputDir, 'glimpse.js');
var sourceDir = path.join(__dirname, 'source');

var buildManifest = path.join(sourceDir, '_build.js');

var regex = /\/\*\(import:\S*\)\*\//g;

var process = function (data) {
    return data.replace(regex, function (match) {
        var matchIdentifier = match.substring(10, match.length - 3);
        var matchFileName = matchIdentifier;
        var tabIndex = 0;

        if (matchFileName.indexOf('|') > -1) {
            tabIndex = matchFileName.substring(matchFileName.indexOf('|') + 1, matchFileName.length - matchFileName.indexOf('|') - 1) * 1;
            matchFileName = matchFileName.substring(0, matchFileName.indexOf('|'));
        }

        var tabs = '';
        for (var i = 0; i < tabIndex; i++) {
            tabs += '    ';
        }

        var matchContent = '';
        matchContent = process(fs.readFileSync(path.join(sourceDir, matchFileName), 'UTF-8'));

        if (/(.htm|.css)/g.test(matchFileName)) {
            matchContent = matchContent.replace(/[\r|\n|\r\n|\t]/gi, '');
            matchContent = matchContent.replace(/\s{2,}/gi, '');
        }

        if (tabIndex > 0)
            matchContent = tabs + matchContent.replace(/\n/, '\n' + tabs);

        return matchContent;
    });
};

fs.readFile(buildManifest, 'UTF-8', function (err, data) {
    if (err) {
        throw err;
    }

    data = process(data);

    fs.exists(outputDir, function (exists) {
        if (!exists) {
            fs.mkdirSync(outputDir);
        }

        fs.exists(outputFile, function (exists) {
            if (exists) {
                fs.unlinkSync(outputFile);
            }

            fs.writeFile(outputFile, data, function (err) {
                if (err) {
                    throw err;
                }

                console.log('Glimpse has been generated at ' + outputFile);
            });
        });
    });
});<commit_msg>adding test file build<commit_after>var fs = require('fs');
var path = require('path');

var outputDir = path.join(__dirname, 'build');
var outputFile = path.join(outputDir, 'glimpse.js');
var outputTestsFile = path.join(outputDir, 'glimpseTest.js');
var sourceDir = path.join(__dirname, 'source');
var testsDir = path.join(sourceDir, 'test', 'mock');

var buildManifest = path.join(sourceDir, '_build.js');
var testsManifest = path.join(testsDir, 'test.glimpse.ajax.js');

var regex = /\/\*\(import:\S*\)\*\//g;

var process = function (data, dir) {
    return data.replace(regex, function (match) {
        var matchIdentifier = match.substring(10, match.length - 3);
        var matchFileName = matchIdentifier;
        var tabIndex = 0;

        if (matchFileName.indexOf('|') > -1) {
            tabIndex = matchFileName.substring(matchFileName.indexOf('|') + 1, matchFileName.length - matchFileName.indexOf('|') - 1) * 1;
            matchFileName = matchFileName.substring(0, matchFileName.indexOf('|'));
        }

        var tabs = '';
        for (var i = 0; i < tabIndex; i++) {
            tabs += '    ';
        }

        var matchContent = '';
        matchContent = process(fs.readFileSync(path.join(dir, matchFileName), 'UTF-8'), dir);

        if (/(.htm|.css)/g.test(matchFileName)) {
            matchContent = matchContent.replace(/[\r|\n|\r\n|\t]/gi, '');
            matchContent = matchContent.replace(/\s{2,}/gi, '');
        }

        if (tabIndex > 0)
            matchContent = tabs + matchContent.replace(/\n/, '\n' + tabs);

        return matchContent;
    });
};

fs.readFile(buildManifest, 'UTF-8', function (err, data) {
    if (err) {
        throw err;
    }

    data = process(data, sourceDir);

    fs.exists(outputDir, function (exists) {
        if (!exists) {
            fs.mkdirSync(outputDir);
        }

        fs.exists(outputFile, function (exists) {
            if (exists) {
                fs.unlinkSync(outputFile);
            }

            fs.writeFile(outputFile, data, function (err) {
                if (err) {
                    throw err;
                }

                console.log('Glimpse has been generated at ' + outputFile);
            });
        });
    });
});

fs.readFile(testsManifest, 'UTF-8', function (err, data) {
    if (err) {
        throw err;
    }

    data = process(data, testsDir);

    fs.exists(outputDir, function (exists) {
        if (!exists) {
            fs.mkdirSync(outputDir);
        }

        fs.exists(outputTestsFile, function (exists) {
            if (exists) {
                fs.unlinkSync(outputTestsFile);
            }

            fs.writeFile(outputTestsFile, data, function (err) {
                if (err) {
                    throw err;
                }

                console.log('Glimpse Tests has been generated at ' + outputTestsFile);
            });
        });
    });
});<|endoftext|>


<commit_before>var
  q = require('q'),
  CircularList = require('easy-circular-list'),
  InternalError = require('kuzzle-common-objects').Errors.internalError,
  WS = require('ws').Server,
  _kuzzle;

/**
 * Web Socket server implementation of Kuzzle's internal broker.
 *
 * @param kuzzle
 * @constructor
 */
function WSBrokerServer (kuzzle) {
  this.server = null;
  this.rooms = {};
  this.handlers = {};

  this.options = {
    server: {
      port: kuzzle.config.broker.port,
      perMessageDeflate: false
    }
  };

  this.ws = (options, cb) => new WS(options, cb);

  _kuzzle = kuzzle;
}

/**
 * Initializes the server by setting the underlying ws.WebSocket.Server up.
 *
 * @returns {promise}
 */
WSBrokerServer.prototype.init = function () {
  var
    deferred = q.defer();

  if (this.server) {
    deferred.reject(new InternalError('Websocket server already started'));
    return deferred.promise;
  }

  this.server = this.ws(this.options.server, () => {
    deferred.resolve();
  });

  this.server.on('connection', clientSocket => {
    clientSocket.on('message', msg => {
      msg = JSON.parse(msg);

      switch (msg.action) {
        // the listen action is called by the client to inform the server it
        // wants to be notified on the room activity
        case 'listen':
          if (this.rooms[msg.room] === undefined) {
            this.rooms[msg.room] = new CircularList([]);
          }
          if (this.rooms[msg.room].getArray().indexOf(clientSocket) === -1) {
            this.rooms[msg.room].add(clientSocket);
          }
          break;
        case 'unsubscribe':
          if (this.rooms[msg.room]) {
            this.rooms[msg.room].remove(clientSocket);
            if (this.rooms[msg.room].getSize() === 0) {
              delete this.rooms[msg.room];
            }
          }
          break;

        // broadcast & send can be used in 2 ways:
        //   1 - (most common): pass a message to the server to a room on which
        //                      a callback was set to trigger a remote action
        //   2 - If some other clients have subscribed to the room, they will
        //       be also notified
        case 'send':
          this.dispatch(msg.room, msg.data);
          this.send(msg.room, msg.data, clientSocket);
          break;
        case 'broadcast':
          this.dispatch(msg.room, msg.data);
          this.broadcast(msg.room, msg.data, clientSocket);
          break;
      }
    });

    clientSocket.on('close', (code, message) => {
      _kuzzle.pluginsManager.trigger('log:info', `client disconnected [${code}] ${message}`);
      removeClient.call(this, clientSocket);
    });

    clientSocket.on('error', err => {
      _kuzzle.pluginsManager.trigger('log:error', err);
    });
  });

  return deferred.promise;
};

/**
 * Broadcasts `data` to *all* clients that have subscribed to the `room` but
 * the emitter.
 *
 * @param {string} room
 * @param {object} data
 * @returns {int} Number of clients the message was sent to ; -1 if the room does not exist.
 */
WSBrokerServer.prototype.broadcast = function (room, data, emitterSocket) {
  var
    clients = 0,
    serializedMessage = JSON.stringify({
      room: room,
      data: data
    });

  if (!this.rooms[room]) {
    return -1;
  }

  this.rooms[room].getArray().forEach(clientSocket => {
    if (clientSocket === emitterSocket) {
      return;
    }

    try {
      clientSocket.send(serializedMessage);
      clients++;
    }
    catch(err) {
      // could not broadcast to one child, we let the other ones recieve the message
      _kuzzle.pluginsManager.trigger('log:error', err);
    }
  });

  return clients;
};

/**
 * Sends `data` to *one* of the *other* clients that has subscribed to the `room`.
 *
 * @param {string} room
 * @param {object} data
 * @returns {Websocket|undefined} The socket to which the data was sent ; undefined if the room does not exist
 */
WSBrokerServer.prototype.send = function (room, data, emitterSocket) {
  var clientSocket;

  if (!this.rooms[room]) {
    return;
  }

  clientSocket = this.rooms[room].getNext();

  if (clientSocket === emitterSocket) {
    if (this.rooms[room].getSize() === 1) {
      return;
    }

    clientSocket = this.rooms[room].getNext();
  }

  clientSocket.send(JSON.stringify({
    room: room,
    data: data
  }));

  return clientSocket;
};

/**
 * Calls all callbacks registered to `room` passing them `data` as argument.
 *
 * @param {string} room
 * @param {object} data
 * @returns {int} the number of triggered callbacks ; -1 if the room does not exist
 */
WSBrokerServer.prototype.dispatch = function (room, data) {
  if (!this.handlers[room]) {
    return -1;
  }
  this.handlers[room].forEach(cb => cb(data));

  return this.handlers[room].length;
};

/**
 * Attaches a callback to a `room`
 *
 * @param {string} room
 * @param {function} cb   The callback to execute
 */
WSBrokerServer.prototype.listen = function (room, cb) {
  if (this.handlers[room] === undefined) {
    this.handlers[room] = [];
  }
  this.handlers[room].push(cb);
};

/**
 * Returns a promise that resolves only when a first client registers itself
 * to the `room`.
 *
 * @param {string} room
 * @returns {promise}
 */
WSBrokerServer.prototype.waitForClients = function (room) {
  var
    deferred,
    interval;

  if (this.rooms[room]) {
    return q();
  }

  deferred = q.defer();

  interval = setInterval(() => {
    if (this.rooms[room]) {
      deferred.resolve();
      clearInterval(interval);
    }
  }, 100);

  return deferred.promise;
};

/**
 * Stops listening to `room` notifications
 *
 * @param {string} room
 */
WSBrokerServer.prototype.unsubscribe = function (room) {
  if (this.handlers[room]) {
    delete this.handlers[room];
  }
};

/**
 * Closes the server underlying Web socket.
 */
WSBrokerServer.prototype.close = function () {
  this.server.close();
  this.server = null;
};

module.exports = WSBrokerServer;

/**
 * Given a client Web socket, closes it and removes all related subscribtions
 * and callbacks.
 *
 * @param {ws.WebSocket} clientSocket
 */
function removeClient (clientSocket) {
  clientSocket.close();

  Object.keys(this.rooms).forEach(room => {
    this.rooms[room].remove(clientSocket);
    if (this.rooms[room].getSize() === 0) {
      delete this.rooms[room];
    }
  });
}

<commit_msg>kuz-555 - eslint<commit_after>var
  q = require('q'),
  CircularList = require('easy-circular-list'),
  InternalError = require('kuzzle-common-objects').Errors.internalError,
  WS = require('ws').Server,
  _kuzzle;

/**
 * Web Socket server implementation of Kuzzle's internal broker.
 *
 * @param kuzzle
 * @constructor
 */
function WSBrokerServer (kuzzle) {
  this.server = null;
  this.rooms = {};
  this.handlers = {};

  this.options = {
    server: {
      port: kuzzle.config.broker.port,
      perMessageDeflate: false
    }
  };

  this.ws = (options, cb) => new WS(options, cb);

  _kuzzle = kuzzle;
}

/**
 * Initializes the server by setting the underlying ws.WebSocket.Server up.
 *
 * @returns {promise}
 */
WSBrokerServer.prototype.init = function () {
  var
    deferred = q.defer();

  if (this.server) {
    deferred.reject(new InternalError('Websocket server already started'));
    return deferred.promise;
  }

  this.server = this.ws(this.options.server, () => {
    deferred.resolve();
  });

  this.server.on('connection', clientSocket => {
    clientSocket.on('message', msg => {
      msg = JSON.parse(msg);

      switch (msg.action) {
        // the listen action is called by the client to inform the server it
        // wants to be notified on the room activity
        case 'listen':
          if (this.rooms[msg.room] === undefined) {
            this.rooms[msg.room] = new CircularList([]);
          }
          if (this.rooms[msg.room].getArray().indexOf(clientSocket) === -1) {
            this.rooms[msg.room].add(clientSocket);
          }
          break;
        case 'unsubscribe':
          if (this.rooms[msg.room]) {
            this.rooms[msg.room].remove(clientSocket);
            if (this.rooms[msg.room].getSize() === 0) {
              delete this.rooms[msg.room];
            }
          }
          break;

        // broadcast & send can be used in 2 ways:
        //   1 - (most common): pass a message to the server to a room on which
        //                      a callback was set to trigger a remote action
        //   2 - If some other clients have subscribed to the room, they will
        //       be also notified
        case 'send':
          this.dispatch(msg.room, msg.data);
          this.send(msg.room, msg.data, clientSocket);
          break;
        case 'broadcast':
          this.dispatch(msg.room, msg.data);
          this.broadcast(msg.room, msg.data, clientSocket);
          break;
      }
    });

    clientSocket.on('close', (code, message) => {
      _kuzzle.pluginsManager.trigger('log:info', `client disconnected [${code}] ${message}`);
      removeClient.call(this, clientSocket);
    });

    clientSocket.on('error', err => {
      _kuzzle.pluginsManager.trigger('log:error', err);
    });
  });

  return deferred.promise;
};

/**
 * Broadcasts `data` to *all* clients that have subscribed to the `room` but
 * the emitter.
 *
 * @param {string} room
 * @param {object} data
 * @returns {int} Number of clients the message was sent to ; -1 if the room does not exist.
 */
WSBrokerServer.prototype.broadcast = function (room, data, emitterSocket) {
  var
    clients = 0,
    serializedMessage = JSON.stringify({
      room: room,
      data: data
    });

  if (!this.rooms[room]) {
    return -1;
  }

  this.rooms[room].getArray().forEach(clientSocket => {
    if (clientSocket === emitterSocket) {
      return;
    }

    try {
      clientSocket.send(serializedMessage);
      clients++;
    }
    catch (err) {
      // could not broadcast to one child, we let the other ones recieve the message
      _kuzzle.pluginsManager.trigger('log:error', err);
    }
  });

  return clients;
};

/**
 * Sends `data` to *one* of the *other* clients that has subscribed to the `room`.
 *
 * @param {string} room
 * @param {object} data
 * @returns {Websocket|undefined} The socket to which the data was sent ; undefined if the room does not exist
 */
WSBrokerServer.prototype.send = function (room, data, emitterSocket) {
  var clientSocket;

  if (!this.rooms[room]) {
    return;
  }

  clientSocket = this.rooms[room].getNext();

  if (clientSocket === emitterSocket) {
    if (this.rooms[room].getSize() === 1) {
      return;
    }

    clientSocket = this.rooms[room].getNext();
  }

  clientSocket.send(JSON.stringify({
    room: room,
    data: data
  }));

  return clientSocket;
};

/**
 * Calls all callbacks registered to `room` passing them `data` as argument.
 *
 * @param {string} room
 * @param {object} data
 * @returns {int} the number of triggered callbacks ; -1 if the room does not exist
 */
WSBrokerServer.prototype.dispatch = function (room, data) {
  if (!this.handlers[room]) {
    return -1;
  }
  this.handlers[room].forEach(cb => cb(data));

  return this.handlers[room].length;
};

/**
 * Attaches a callback to a `room`
 *
 * @param {string} room
 * @param {function} cb   The callback to execute
 */
WSBrokerServer.prototype.listen = function (room, cb) {
  if (this.handlers[room] === undefined) {
    this.handlers[room] = [];
  }
  this.handlers[room].push(cb);
};

/**
 * Returns a promise that resolves only when a first client registers itself
 * to the `room`.
 *
 * @param {string} room
 * @returns {promise}
 */
WSBrokerServer.prototype.waitForClients = function (room) {
  var
    deferred,
    interval;

  if (this.rooms[room]) {
    return q();
  }

  deferred = q.defer();

  interval = setInterval(() => {
    if (this.rooms[room]) {
      deferred.resolve();
      clearInterval(interval);
    }
  }, 100);

  return deferred.promise;
};

/**
 * Stops listening to `room` notifications
 *
 * @param {string} room
 */
WSBrokerServer.prototype.unsubscribe = function (room) {
  if (this.handlers[room]) {
    delete this.handlers[room];
  }
};

/**
 * Closes the server underlying Web socket.
 */
WSBrokerServer.prototype.close = function () {
  this.server.close();
  this.server = null;
};

module.exports = WSBrokerServer;

/**
 * Given a client Web socket, closes it and removes all related subscribtions
 * and callbacks.
 *
 * @param {ws.WebSocket} clientSocket
 */
function removeClient (clientSocket) {
  clientSocket.close();

  Object.keys(this.rooms).forEach(room => {
    this.rooms[room].remove(clientSocket);
    if (this.rooms[room].getSize() === 0) {
      delete this.rooms[room];
    }
  });
}

<|endoftext|>