<commit_before>'use strict';

function Utils() {
  // Constants
  const REGEX = {
    directive: /(<(.+)(?:\s([^>]+))*>)(.*)<\/\2>/,
    selfClosingDirective: /<[^>]+?\/[ ]*>/,
    removeQuotes: /["']/g,
    curlyBrackets: /\{\{(\s*?.*?)*?\}\}/g,
    tagName: /<(\w+)\s+\w+.*?>/
  };

  // Methods
  this.forEach = forEach;
  this.getJson = getJson;
  this.getRegex = getRegex;
  this.getRegexMatch = getRegexMatch;
  this.getStringFromJson = getStringFromJson;
  this.inArray = inArray;
  this.inObject = inObject;
  this.isArray = isArray;
  this.isDefined = isDefined;
  this.isDirective = isDirective;
  this.isFunction = isFunction;
  this.isJson = isJson;
  this.isNull = isNull;
  this.isObject = isObject;
  this.isSelfClosingDirective = isSelfClosingDirective;
  this.isString = isString;
  this.log = log;
  this.merge = merge;
  this.search = search;

  return this;

  /**
   * Easy way to iterate over arrays and objects.
   *
   * @param {array || object} items
   * @param {function} callback
   * @protected
   */
  function forEach(items, callback, isHTMLCollection) {
    if (isArray(items)) {
      for (var i = 0; i < items.length; i++) {
        callback(items[i]);
      }
    } else if (callback === true) {
      console.log(items);
      return [].slice.call(items);
    } else {
      Object.keys(items).forEach(callback);
    }
  }

  /**
   * Get Json from string
   *
   * @param {string} str
   * @returns {object} json
   * @protected
   */
  function getJson(str) {
    if (isJson(str)) {
      return JSON.parse(str);
    }

    return str;
  }

  /**
   * Get a stored regular expression.
   *
   * @param {string} regex
   * @returns {regex} from REGEX constant
   * @protected
   */
  function getRegex(regex) {
    return REGEX[regex] || false;
  }

  /**
   * Get match from passed regular expression.
   *
   * @param {string} element
   * @param {regex} pattern
   * @returns {array} matches
   * @protected
   */
  function getRegexMatch(element, regex) {
    var match = element.match(new RegExp(regex));

    return !isNull(match) ? match : false;
  }

  /**
   * Get a string from json object
   *
   * @param {object} obj
   * @returns {string} json
   * @protected
   */
  function getStringFromJson(obj) {
    return JSON.stringify(obj);
  }

  /**
   * Validates if an item exists into an array.
   *
   * @param {string} item
   * @param {array} obj
   * @returns {boolean} true if the item exists, false if not.
   * @protected
   */
  function inArray(item, array) {
    return array instanceof Array && array.indexOf(item) >= 0;
  }

  /**
   * Validates if an item exists into an object.
   *
   * @param {string} item
   * @param {object} obj
   * @returns {boolean} true if the item exists, false if not.
   * @protected
   */
  function inObject(item, obj) {
    return typeof obj[item] !== 'undefined';
  }

  /**
   * Validates if a passed variable is an array
   *
   * @param {array} array
   * @returns {boolean} true if is Array
   * @protected
   */
  function isArray(array) {
    return array instanceof Array;
  }

  /**
   * Validates if a passed value is defined
   *
   * @param {mixed} value
   * @param {boolean} isNot
   * @returns {boolean} true if is defined
   * @protected
   */
  function isDefined(value, isNot) {
    if (typeof isNot === 'undefined') {
      return typeof value !== 'undefined';
    } else {
      return typeof value !== 'undefined' && value !== isNot;
    }
  }

  /**
   * Returns true if an element is a directive
   *
   * @param {string} element
   * @returns {boolean} true if is a directive
   * @protected
   */
  function isDirective(element) {
    if (isString(element) && getRegexMatch(element, getRegex('directive'))) {
      return true;
    } else if (isString(element)) {
      return !!getRegexMatch(element, getRegex('selfClosingDirective'));
    }

    return false;
  }

  /**
   * Validates if a passed variable is function
   *
   * @param {function} func
   * @returns {boolean} true if is function
   * @protected
   */
  function isFunction(func) {
    return typeof func === 'function';
  }

  /**
   * Validates if a passed string is a valid json
   *
   * @param {string} str
   * @returns {boolean} true if is Json
   * @protected
   */
  function isJson(str) {
    if (str === null) {
      return false;
    }

    try {
      JSON.parse(str);
    } catch (e) {
      return false;
    }

    return true;
  }

  /**
   * Validates if a passed value is null
   *
   * @param {mixed} value
   * @returns {boolean} true if is null
   * @protected
   */
  function isNull(value) {
    return value === null;
  }

  /**
   * Validates if a passed variable is an object
   *
   * @param {object} obj
   * @returns {boolean} true if is Object
   * @protected
   */
  function isObject(obj) {
    return obj instanceof Object && !isArray(obj) && typeof obj !== 'function';
  }

  /**
   * Returns true if an element is a self closing directive
   *
   * @param {string} element
   * @returns {boolean} true if is a self closing directive
   * @protected
   */
  function isSelfClosingDirective(element) {
    var match = getRegexMatch(element, getRegex('selfClosingDirective'));
    var directiveName;

    if (match) {
      directiveName = match[0].replace('<', '').replace('/', '').replace('>', '').trim();

      return directiveName;
    }

    return false;
  }

  /**
   * Validates if a value is String
   *
   * @param {string} value
   * @returns {boolean} true if is String
   * @protected
   */
  function isString(value) {
    return typeof value === 'string';
  }

  /**
   * Logs a message.
   *
   * @param {string} message
   * @returns {void}
   * @internal
   */
  function log(message) {
    console.log('eXtended:', message);
  }

  /**
   * Easy way to merge two objects.
   *
   * @param {object} obj1
   * @param {object} obj2
   * @returns {object} merged obj1
   * @protected
   */
  function merge(obj1, obj2) {
    if (isFunction(Object.assign)) {
      return Object.assign(obj1, obj2);
    } else {
      for (var key in obj2) {
        if (obj2.hasOwnProperty(key)) {
          obj1[key] = obj2[key];
        }
      }

      return obj1;
    }
  }

  /**
   * Search a string inside other string
   *
   * @param {string} word
   * @param {string} string
   * @returns {boolean} true if found the string
   * @protected
   */
  function search(word, string) {
    return string.search(word) !== -1;
  }
}

// Exporting object
module.exports = new Utils();
<commit_msg>Fixing some stuffs on utils<commit_after>'use strict';

function Utils() {
  // Methods
  this.forEach = forEach;
  this.getJson = getJson;
  this.getRegex = getRegex;
  this.getRegexMatch = getRegexMatch;
  this.getStringFromJson = getStringFromJson;
  this.inArray = inArray;
  this.inObject = inObject;
  this.isArray = isArray;
  this.isDefined = isDefined;
  this.isDirective = isDirective;
  this.isFunction = isFunction;
  this.isJson = isJson;
  this.isNull = isNull;
  this.isObject = isObject;
  this.isSelfClosingDirective = isSelfClosingDirective;
  this.isString = isString;
  this.merge = merge;
  this.search = search;

  return this;

  /**
   * Easy way to iterate over arrays and objects.
   *
   * @param {array || object} items
   * @param {function} callback
   * @protected
   */
  function forEach(items, callback, isHTMLCollection) {
    var i;

    if (isArray(items) || isHTMLCollection) {
      for (i = 0; i < items.length; i++) {
        callback(items[i]);
      }
    } else {
      Object.keys(items).forEach(callback);
    }
  }

  /**
   * Get Json from string
   *
   * @param {string} str
   * @returns {object} json
   * @protected
   */
  function getJson(str) {
    if (isJson(str)) {
      return JSON.parse(str);
    }

    return str;
  }

  /**
   * Get a stored regular expression.
   *
   * @param {string} regex
   * @returns {regex} from REGEX constant
   * @protected
   */
  function getRegex(regex) {
    // Constants
    const REGEX = {
      directive: /(<(.+)(?:\s([^>]+))*>)(.*)<\/\2>/,
      selfClosingDirective: /<[^>]+?\/[ ]*>/,
      removeQuotes: /["']/g,
      curlyBrackets: /\{\{(\s*?.*?)*?\}\}/g,
      tagName: /<(\w+)\s+\w+.*?>/
    };

    return REGEX[regex] || false;
  }

  /**
   * Get match from passed regular expression.
   *
   * @param {string} element
   * @param {regex} pattern
   * @returns {array} matches
   * @protected
   */
  function getRegexMatch(element, regex) {
    var match = element.match(new RegExp(regex));

    return !isNull(match) ? match : false;
  }

  /**
   * Get a string from json object
   *
   * @param {object} obj
   * @returns {string} json
   * @protected
   */
  function getStringFromJson(obj) {
    return JSON.stringify(obj);
  }

  /**
   * Validates if an item exists into an array.
   *
   * @param {string} item
   * @param {array} obj
   * @returns {boolean} true if the item exists, false if not.
   * @protected
   */
  function inArray(item, array) {
    return array instanceof Array && array.indexOf(item) >= 0;
  }

  /**
   * Validates if an item exists into an object.
   *
   * @param {string} item
   * @param {object} obj
   * @returns {boolean} true if the item exists, false if not.
   * @protected
   */
  function inObject(item, obj) {
    return typeof obj[item] !== 'undefined';
  }

  /**
   * Validates if a passed variable is an array
   *
   * @param {array} array
   * @returns {boolean} true if is Array
   * @protected
   */
  function isArray(array) {
    return array instanceof Array;
  }

  /**
   * Validates if a passed value is defined
   *
   * @param {mixed} value
   * @param {boolean} isNot
   * @returns {boolean} true if is defined
   * @protected
   */
  function isDefined(value, isNot) {
    if (typeof isNot === 'undefined') {
      return typeof value !== 'undefined';
    }

    return typeof value !== 'undefined' && value !== isNot;
  }

  /**
   * Returns true if an element is a directive
   *
   * @param {string} element
   * @returns {boolean} true if is a directive
   * @protected
   */
  function isDirective(element) {
    if (isString(element) && getRegexMatch(element, getRegex('directive'))) {
      return true;
    } else if (isString(element)) {
      return !!getRegexMatch(element, getRegex('selfClosingDirective'));
    }

    return false;
  }

  /**
   * Validates if a passed variable is function
   *
   * @param {function} func
   * @returns {boolean} true if is function
   * @protected
   */
  function isFunction(func) {
    return typeof func === 'function';
  }

  /**
   * Validates if a passed string is a valid json
   *
   * @param {string} str
   * @returns {boolean} true if is Json
   * @protected
   */
  function isJson(str) {
    if (str === null) {
      return false;
    }

    try {
      JSON.parse(str);
    } catch (e) {
      return false;
    }

    return true;
  }

  /**
   * Validates if a passed value is null
   *
   * @param {mixed} value
   * @returns {boolean} true if is null
   * @protected
   */
  function isNull(value) {
    return value === null;
  }

  /**
   * Validates if a passed variable is an object
   *
   * @param {object} obj
   * @returns {boolean} true if is Object
   * @protected
   */
  function isObject(obj) {
    return obj instanceof Object && !isArray(obj) && typeof obj !== 'function';
  }

  /**
   * Returns true if an element is a self closing directive
   *
   * @param {string} element
   * @returns {boolean} true if is a self closing directive
   * @protected
   */
  function isSelfClosingDirective(element) {
    var match = getRegexMatch(element, getRegex('selfClosingDirective'));
    var directiveName;

    if (match) {
      directiveName = match[0].replace('<', '').replace('/', '').replace('>', '').trim();

      return directiveName;
    }

    return false;
  }

  /**
   * Validates if a value is String
   *
   * @param {string} value
   * @returns {boolean} true if is String
   * @protected
   */
  function isString(value) {
    return typeof value === 'string';
  }

  /**
   * Easy way to merge two objects.
   *
   * @param {object} obj1
   * @param {object} obj2
   * @returns {object} merged obj1
   * @protected
   */
  function merge(obj1, obj2) {
    var key;

    if (isFunction(Object.assign)) {
      return Object.assign(obj1, obj2);
    }

    for (key in obj2) {
      if (obj2.hasOwnProperty(key)) {
        obj1[key] = obj2[key];
      }
    }

    return obj1;
  }

  /**
   * Search a string inside other string
   *
   * @param {string} word
   * @param {string} string
   * @returns {boolean} true if found the string
   * @protected
   */
  function search(word, string) {
    return isDefined(string) && string.search(word) !== -1;
  }
}

// Exporting object
module.exports = new Utils();
<|endoftext|>


<commit_before>solarEvent = function(angles, imageTextureIndex) {
    this.L0 = angles[0];
    this.B0 = angles[1];
    this.imageTextureIndex = imageTextureIndex;
}

sunPoints = function() {
    this.initialized = false;
    this.textures = [ "./images/EventIcons/ar_icon.png" ];
    this.images = {};
    this.imageTextures = {};
    this.amountOfTexturesLoaded = 0;
    this.texturesLoaded = false;
    this.textureLoadStarted = false;
    this.supportedModes = [ '2D', '3D' ];// , '3D', 'limb', 'limb-conformal'
    this.optionsPanel = document.createElement("div");
    this.optionsPanel.innerHTML = "
TBD
";
    core.gui.addTypePanel("sunPoints");
    core.gui.addLayer("sunPoints", "SUNP", this.optionsPanel);
    this.viewportIndices = [ 0, 1, 2, 3 ];
    this.verticesBuffer = {};
    this.textureCoordsBuffer = {};
    this.solarEvents = [];
    var angs = [ [ 0., 0. ], [ Math.PI / 2., 0. ], [ Math.PI, 0. ], [ 3 * Math.PI / 2., 0. ], [ 0., Math.PI / 4. ] ];

    for (var i = 0; i < angs.length; i++) {
        var event = new solarEvent(angs[i], this.textures.indexOf("./images/EventIcons/ar_icon.png"));
        this.solarEvents.push(event);
    }

    this.init();
}

sunPoints.prototype.init = function(gl) {
    ref = this;
    onsuccess = function(data) {
        for (var i = 0; i < data.result.length; i++) {
            var event = new solarEvent([ data.event_coords1 / 180. * Math.PI, data.event_coord2 / 180. * Math.PI ], ref.textures.indexOf("./images/EventIcons/ar_icon.png"));
            ref.solarEvents.push(event);
        }
        console.log()
    };
    onfail = function(data) {
        console.log(data)
    };
    // getJSON("http://www.lmsal.com/hek/her?cosec=2&cmd=search&type=column&event_type=ar,fl,ef&event_starttime=2015-01-24T00:00:00&event_endtime=2015-01-25T00:00:00&event_coordsys=helioprojective&x1=-1200&x2=1200&y1=-1200&y2=1200&&param0=FRM_Name&op0==&value0=NOAA%20SWPC%20Observer",
    // onsuccess, onfail);
    if (!this.textureLoadStarted) {
        var ref = this;
        for (var i = 0; i < this.textures.length; i++) {
            var image = new Image();
            image["index"] = i;
            image.onload = function() {
                ref.images[image["index"]] = image;
                ref.texturesLoaded = true;
                ref.amountOfTexturesLoaded++;
                if (ref.amountOfTexturesLoaded === ref.textures.length) {
                    ref.texturesLoaded = true;
                }
            }
            image.src = this.textures[i];
        }
        this.textureLoadStarted = true;
    }
    if (!this.initialized && this.texturesLoaded) {
        this.loadTextures(gl);
        this.loadGUIElements();
        for (var i = 0; i < this.supportedModes.length; i++) {
            this.initShaders(gl, this.supportedModes[i]);
        }
        for (var i = 0; i < this.supportedModes.length; i++) {
            this.initBuffers(gl, this.supportedModes[i]);
        }
        for (var i = 0; i < this.supportedModes.length; i++) {
            this.initShaders(gl, this.supportedModes[i]);
        }
        this.initialized = true;
    }
}

sunPoints.prototype.loadTextures = function(gl) {
    for (var i = 0; i < this.textures.length; i++) {
        this.imageTextures[i] = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, this.imageTextures[i]);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.images[i]);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.bindTexture(gl.TEXTURE_2D, null);
    }
}

sunPoints.prototype.loadGUIElements = function() {

}
sunPoints.prototype.initBuffers = function(gl, key) {
    this.verticesBuffer[key] = gl.createBuffer();
    var f = 0.05;
    this.vertices = new Float32Array([ f, f, f, -f, -f, -f, -f, -f, -f, f, f, f ]);
    gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer[key]);
    gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);

    this.textureCoordsBuffer[key] = gl.createBuffer();
    var h = 1.;
    this.textureCoords = new Float32Array([ h, 0, h, h, 0, h, 0, h, 0, 0, h, 0 ]);
    gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordsBuffer[key]);
    gl.bufferData(gl.ARRAY_BUFFER, this.textureCoords, gl.DYNAMIC_DRAW);
}

sunPoints.prototype.initShaders = function(gl, key) {

    if (sunPoints.prototype.shaderProgram === undefined) {
        sunPoints.prototype.shaderProgram = {};
        sunPoints.prototype.vertexPositionAttribute = {};
        sunPoints.prototype.textureCoordsAttribute = {};
    }
    if (sunPoints.prototype.shaderProgram[key] !== undefined) {
        return;
    }
    console.log("shader-fs-" + key);
    var fragmentShader = getShader(gl, "shader-fs-sunpoints-" + key);
    var vertexShader = getShader(gl, "shader-vs-sunpoints-" + key);

    sunPoints.prototype.shaderProgram[key] = gl.createProgram();
    gl.attachShader(sunPoints.prototype.shaderProgram[key], vertexShader);
    gl.attachShader(sunPoints.prototype.shaderProgram[key], fragmentShader);
    gl.linkProgram(sunPoints.prototype.shaderProgram[key]);

    if (!gl.getProgramParameter(sunPoints.prototype.shaderProgram[key], gl.LINK_STATUS)) {
        alert("Unable to initialize the shader program.");
    }

    gl.useProgram(sunPoints.prototype.shaderProgram[key]);

    sunPoints.prototype.vertexPositionAttribute[key] = gl.getAttribLocation(sunPoints.prototype.shaderProgram[key], "aVertexPosition");
    gl.enableVertexAttribArray(sunPoints.prototype.vertexPositionAttribute[key]);

    sunPoints.prototype.textureCoordsAttribute[key] = gl.getAttribLocation(sunPoints.prototype.shaderProgram[key], "aTextureCoords");
    gl.enableVertexAttribArray(sunPoints.prototype.textureCoordsAttribute[key]);
}

sunPoints.prototype.prerender = function(gl) {

}
sunPoints.prototype.extendBackwards = function(gl) {

}
sunPoints.prototype.computeMatrix = function(L0, B0, mvMatrix) {
    var M1 = Matrix.Rotation(B0, $V([ 1, 0, 0 ]));
    var M2 = Matrix.Rotation(L0, $V([ 0, 1, 0 ]));
    var V = $V([ 0., 0., 1., 1. ]);
    var M = M2.x(M1).ensure4x4();
    var V = M.x(V);

    var MM = mvMatrix.x(Matrix.Translation($V([ V.elements[0], V.elements[1], V.elements[2] ])));

    MM = MM.x(M);
    return MM;
}
sunPoints.prototype.render = function(gl, mvMatrix, time, viewportIndex) {
    var key = core.viewport.viewportDetails[viewportIndex].mode;
    gl.useProgram(sunPoints.prototype.shaderProgram[key]);

    if (this.initialized) {
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
        gl.enableVertexAttribArray(this.textureCoordsAttribute[key]);
        gl.enableVertexAttribArray(this.vertexPositionAttribute[key]);
        {
            var vpDetail = core.viewport.viewportDetails[viewportIndex];
            this.solarEvents[this.solarEvents.length - 1].L0 = vpDetail.L0click;
            this.solarEvents[this.solarEvents.length - 1].B0 = vpDetail.B0click;

            for (var i = 0; i < this.solarEvents.length; i++) {
                var event = this.solarEvents[i];
                var MM = this.computeMatrix(event.L0, event.B0, mvMatrix)
                var mvUniform = gl.getUniformLocation(sunPoints.prototype.shaderProgram[key], "uMVMatrix");
                gl.uniformMatrix4fv(mvUniform, false, new Float32Array(MM.flatten()));
                gl.activeTexture(gl.TEXTURE0);
                gl.bindTexture(gl.TEXTURE_2D, this.imageTextures[event.imageTextureIndex]);
                gl.uniform1i(gl.getUniformLocation(this.shaderProgram[key], "uSampler"), 0);

                gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordsBuffer[key]);
                gl.vertexAttribPointer(this.textureCoordsAttribute[key], 2, gl.FLOAT, false, 0, 0);
                gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer[key]);
                gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);

                gl.vertexAttribPointer(this.vertexPositionAttribute[key], 2, gl.FLOAT, false, 0, 0);

                gl.drawArrays(gl.TRIANGLES, 0, 6);
            }
        }
        gl.disableVertexAttribArray(this.vertexPositionAttribute[key]);
        gl.disableVertexAttribArray(this.textureCoordsAttribute[key]);
        gl.disable(gl.BLEND);
    }
}
sunPoints.prototype.updateGUI = function() {

}<commit_msg>bugfix<commit_after>solarEvent = function(angles, imageTextureIndex) {
    this.L0 = angles[0];
    this.B0 = angles[1];
    this.imageTextureIndex = imageTextureIndex;
}

sunPoints = function() {
    this.initialized = false;
    this.textures = [ "./images/EventIcons/ar_icon.png" ];
    this.images = {};
    this.imageTextures = {};
    this.amountOfTexturesLoaded = 0;
    this.texturesLoaded = false;
    this.textureLoadStarted = false;
    this.supportedModes = [ '2D', '3D' ];// , '3D', 'limb', 'limb-conformal'
    this.optionsPanel = document.createElement("div");
    this.optionsPanel.innerHTML = "
TBD
";
    core.gui.addTypePanel("sunPoints");
    core.gui.addLayer("sunPoints", "SUNP", this.optionsPanel);
    this.viewportIndices = [ 0, 1, 2, 3 ];
    this.verticesBuffer = {};
    this.textureCoordsBuffer = {};
    this.solarEvents = [];
    var angs = [ [ 0., 0. ], [ Math.PI / 2., 0. ], [ Math.PI, 0. ], [ 3 * Math.PI / 2., 0. ], [ 0., Math.PI / 4. ] ];

    for (var i = 0; i < angs.length; i++) {
        var event = new solarEvent(angs[i], this.textures.indexOf("./images/EventIcons/ar_icon.png"));
        this.solarEvents.push(event);
    }

    this.init();
}

sunPoints.prototype.init = function(gl) {
    ref = this;
    onsuccess = function(data) {
        for (var i = 0; i < data.result.length; i++) {
            var event = new solarEvent([ data.event_coords1 / 180. * Math.PI, data.event_coord2 / 180. * Math.PI ], ref.textures.indexOf("./images/EventIcons/ar_icon.png"));
            ref.solarEvents.push(event);
        }
        console.log()
    };
    onfail = function(data) {
        console.log(data)
    };
    // getJSON("http://www.lmsal.com/hek/her?cosec=2&cmd=search&type=column&event_type=ar,fl,ef&event_starttime=2015-01-24T00:00:00&event_endtime=2015-01-25T00:00:00&event_coordsys=helioprojective&x1=-1200&x2=1200&y1=-1200&y2=1200&&param0=FRM_Name&op0==&value0=NOAA%20SWPC%20Observer",
    // onsuccess, onfail);
    if (!this.textureLoadStarted) {
        var ref = this;
        for (var i = 0; i < this.textures.length; i++) {
            var image = new Image();
            image["index"] = i;
            image.onload = function() {
                ref.images[image["index"]] = image;
                ref.texturesLoaded = true;
                ref.amountOfTexturesLoaded++;
                if (ref.amountOfTexturesLoaded === ref.textures.length) {
                    ref.texturesLoaded = true;
                }
            }
            image.src = this.textures[i];
        }
        this.textureLoadStarted = true;
    }
    if (!this.initialized && this.texturesLoaded) {
        this.loadTextures(gl);
        this.loadGUIElements();
        for (var i = 0; i < this.supportedModes.length; i++) {
            this.initShaders(gl, this.supportedModes[i]);
        }
        for (var i = 0; i < this.supportedModes.length; i++) {
            this.initBuffers(gl, this.supportedModes[i]);
        }
        for (var i = 0; i < this.supportedModes.length; i++) {
            this.initShaders(gl, this.supportedModes[i]);
        }
        this.initialized = true;
    }
}

sunPoints.prototype.loadTextures = function(gl) {
    for (var i = 0; i < this.textures.length; i++) {
        this.imageTextures[i] = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, this.imageTextures[i]);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.images[i]);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.bindTexture(gl.TEXTURE_2D, null);
    }
}

sunPoints.prototype.loadGUIElements = function() {

}
sunPoints.prototype.initBuffers = function(gl, key) {
    this.verticesBuffer[key] = gl.createBuffer();
    var f = 0.05;
    this.vertices = new Float32Array([ f, f, f, -f, -f, -f, -f, -f, -f, f, f, f ]);
    gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer[key]);
    gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);

    this.textureCoordsBuffer[key] = gl.createBuffer();
    var h = 1.;
    this.textureCoords = new Float32Array([ h, 0, h, h, 0, h, 0, h, 0, 0, h, 0 ]);
    gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordsBuffer[key]);
    gl.bufferData(gl.ARRAY_BUFFER, this.textureCoords, gl.DYNAMIC_DRAW);
}

sunPoints.prototype.initShaders = function(gl, key) {

    if (sunPoints.prototype.shaderProgram === undefined) {
        sunPoints.prototype.shaderProgram = {};
        sunPoints.prototype.vertexPositionAttribute = {};
        sunPoints.prototype.textureCoordsAttribute = {};
    }
    if (sunPoints.prototype.shaderProgram[key] !== undefined) {
        return;
    }
    console.log("shader-fs-" + key);
    var fragmentShader = getShader(gl, "shader-fs-sunpoints-" + key);
    var vertexShader = getShader(gl, "shader-vs-sunpoints-" + key);

    sunPoints.prototype.shaderProgram[key] = gl.createProgram();
    gl.attachShader(sunPoints.prototype.shaderProgram[key], vertexShader);
    gl.attachShader(sunPoints.prototype.shaderProgram[key], fragmentShader);
    gl.linkProgram(sunPoints.prototype.shaderProgram[key]);

    if (!gl.getProgramParameter(sunPoints.prototype.shaderProgram[key], gl.LINK_STATUS)) {
        alert("Unable to initialize the shader program.");
    }

    gl.useProgram(sunPoints.prototype.shaderProgram[key]);

    sunPoints.prototype.vertexPositionAttribute[key] = gl.getAttribLocation(sunPoints.prototype.shaderProgram[key], "aVertexPosition");
    gl.enableVertexAttribArray(sunPoints.prototype.vertexPositionAttribute[key]);

    sunPoints.prototype.textureCoordsAttribute[key] = gl.getAttribLocation(sunPoints.prototype.shaderProgram[key], "aTextureCoords");
    gl.enableVertexAttribArray(sunPoints.prototype.textureCoordsAttribute[key]);
}

sunPoints.prototype.prerender = function(gl) {

}
sunPoints.prototype.extendBackwards = function(gl) {

}
sunPoints.prototype.computeMatrix = function(L0, B0, mvMatrix) {
    var M1 = Matrix.Rotation(B0, $V([ 1, 0, 0 ]));
    var M2 = Matrix.Rotation(L0, $V([ 0, 1, 0 ]));
    var V = $V([ 0., 0., 1., 1. ]);
    var M = M2.x(M1).ensure4x4();
    var V = M.x(V);

    var MM = mvMatrix.x(Matrix.Translation($V([ V.elements[0], V.elements[1], V.elements[2] ])));

    MM = MM.x(M);
    return MM;
}
sunPoints.prototype.render = function(gl, mvMatrix, time, viewportIndex) {
    if (sunPoints.prototype.shaderProgram === undefined) {
        return;
    }
    var key = core.viewport.viewportDetails[viewportIndex].mode;
    gl.useProgram(sunPoints.prototype.shaderProgram[key]);

    if (this.initialized) {
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
        gl.enableVertexAttribArray(this.textureCoordsAttribute[key]);
        gl.enableVertexAttribArray(this.vertexPositionAttribute[key]);
        {
            var vpDetail = core.viewport.viewportDetails[viewportIndex];
            this.solarEvents[this.solarEvents.length - 1].L0 = vpDetail.L0click;
            this.solarEvents[this.solarEvents.length - 1].B0 = vpDetail.B0click;

            for (var i = 0; i < this.solarEvents.length; i++) {
                var event = this.solarEvents[i];
                var MM = this.computeMatrix(event.L0, event.B0, mvMatrix)
                var mvUniform = gl.getUniformLocation(sunPoints.prototype.shaderProgram[key], "uMVMatrix");
                gl.uniformMatrix4fv(mvUniform, false, new Float32Array(MM.flatten()));
                gl.activeTexture(gl.TEXTURE0);
                gl.bindTexture(gl.TEXTURE_2D, this.imageTextures[event.imageTextureIndex]);
                gl.uniform1i(gl.getUniformLocation(this.shaderProgram[key], "uSampler"), 0);

                gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordsBuffer[key]);
                gl.vertexAttribPointer(this.textureCoordsAttribute[key], 2, gl.FLOAT, false, 0, 0);
                gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer[key]);
                gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);

                gl.vertexAttribPointer(this.vertexPositionAttribute[key], 2, gl.FLOAT, false, 0, 0);

                gl.drawArrays(gl.TRIANGLES, 0, 6);
            }
        }
        gl.disableVertexAttribArray(this.vertexPositionAttribute[key]);
        gl.disableVertexAttribArray(this.textureCoordsAttribute[key]);
        gl.disable(gl.BLEND);
    }
}
sunPoints.prototype.updateGUI = function() {

}<|endoftext|>


<commit_before>import TinyRange from 'tiny-range';
import isNumber from 'is-number';
import assert from 'assert';

class ContiguousRange {
    constructor(x, y) {
        if (y == undefined) {
            if (typeof x === 'string') {
                // Range('0-2')
                const range = TinyRange.parse(x);
                assert(range.length == 1);
                this.start = range.start;
                this.end = range.end;
            } else if (Array.isArray(x)) {
                // Range([0, 2])
                assert(
                    x.length == 2
                    && isNumber(x[0])
                    && isNumber(x[1])
                    && x[0] <= x[1],
                    'Array initializer must contain 2 numbers, the first > the second.'
                );
                this.start = x[0];
                this.end = x[1];
            } else if (x instanceof ContiguousRange) {
                this.start = x.start;
                this.end = x.end;
            } else {
                assert(false, 'Invalid ContiguousRange constructor arguments: ' + Array.prototype.slice.call(arguments));
            }
        } else {
            // Range(0, 2)
            assert(isNumber(x) && isNumber(y) && x <= y);
            this.start = x;
            this.end = y;
        }

    }

    toString() {
        return this.length() == 1 ? this.start : '[' + this.start + ' ' + this.end + ')';
    }

    length() {
        return this.end - this.start;
    }

    empty() {
        return this.length() == 0;
    }

    subtract(other) {
        let distance = undefined;
        if (this.start < other.start) {
            if (this.end > other.start) {
                if (this.end > other.end) {
                    // [return[0].start return[0].end]                     [return[1].start return[1].end]
                    // [this.start                   [other.start other.end]                     this.end]
                    return new Range([this.start, other.start], [other.end, this.end]);
                } else {
                    // [return.start return.end]
                    // [this.start             [other.start this.end] other.end]
                    return new Range(this.start, other.start);
                }
            } else {
                // [return.start return.end]
                // [this.start     this.end] [other.start other.end]
                return new Range(this);
            }
        } else {
            if (other.end > this.start) {
                if (other.end > this.end) {
                    // return is empty.
                    // [other.start [this.start this.end] other.end]
                    return new Range();
                } else {
                    //                                    [return.start return.end]
                    // [other.start [this.start  other.end]               this.end]
                    return new Range(other.end, this.end);
                }
            } else {
                //                         [return.start return.end]
                // [other.start other.end] [this.start     this.end]
                return new Range(this);
            }
        }
    }
}

class Range {

    static MAX = Number.POSITIVE_INFINITY;
    static MIN = Number.NEGATIVE_INFINITY;

    constructor() {
        const args = Array.prototype.slice.call(arguments);
        if (args.length == 0) {
            // Range() -> empty range
            this.contiguous_ranges = [];
        } else if (args.length == 1) {
            let a = args[0];
            if (typeof a === 'string') {
                    // Range('0-2, 4-7')
                this.contiguous_ranges = TinyRange.parse(a);
            } else if (Array.isArray(a)) {
                if (Array.isArray(a[0])) {
                    // Range([[0, 2], [4, 7]])
                    const raw_ranges = a.map(contiguous_range_init => new ContiguousRange(contiguous_range_init));
                    this.contiguous_ranges = [];
                    raw_ranges.forEach(contiguous_range => {
                        this.contiguous_ranges = this.add(new Range(contiguous_range)).contiguous_ranges;
                    });
                    console.log(this.contiguous_ranges);
                } else if (isNumber(a[0])) {
                    // Range([0, 2])
                    this.contiguous_ranges = [new ContiguousRange(a)];
                } else if (a[0] instanceof ContiguousRange) {
                    // Range([[new ContiguousRange(0, 1), new ContiguousRange(2, 4)]])
                    this.contiguous_ranges = a.map(a => a);
                } else {
                    assert(false, 'Invalid Range constructor args: ' + args);
                }
            } else if (a instanceof Range) {
                // Range(other_range)
                this.contiguous_ranges = a.contiguous_ranges;
            } else if (a instanceof ContiguousRange) {
                this.contiguous_ranges = [a];
            } else {
                assert(false, 'Invalid Range constructor args: ' + args);
            }
        } else if (args.length == 2 && isNumber(args[0])) {
            // Range(0, 2);
            this.contiguous_ranges = [new ContiguousRange(args)];
        } else {
            // Range([0, 2], [4, 7]);
            this.contiguous_ranges = args.map(contiguous_range_init => new ContiguousRange(contiguous_range_init));
        }
    }

    toString() {
        return '[' + this.contiguous_ranges.map(r => r.toString()).join(', ') + ']';
    }

    empty() {
        return this.length() == 0;
    }

    length() {
        return this.contiguous_ranges.reduce((total, contiguous_range) => total + contiguous_range.length(), 0);
    }

    contiguousParts() {
        return this.contiguous_ranges;
    }

    isContiguous() {
        return this.contiguous_ranges.length <= 1;
    }

    enclosingContiguousRange() {
        return this.isContiguous() ? this : new ContiguousRange(this.contiguous_ranges[0].start, this.contiguous_ranges[this.contiguous_ranges.length - 1].end);
    }

    equals(other) {
        return this.includes(other) && other.includes(this);
    }

    includes(other) {
        return this.subtract(other).empty()
    }

    overlaps(other) {
        return !this.subtract(other).equals(this);
    }

    subtract(other) {
        let difference_ranges = [];
        this.contiguous_ranges.forEach(contiguous_range => {
            let remaining = [contiguous_range];
            other.contiguous_ranges.forEach(other_contiguous_range => {
                let new_remaining = [];
                remaining.forEach(remaining_contiguous_range => {
                    new_remaining = new_remaining.concat(remaining_contiguous_range.subtract(other_contiguous_range).contiguous_ranges)
                });
                remaining = new_remaining;
            });
            difference_ranges = difference_ranges.concat(remaining);
        });
        return new Range(difference_ranges);
    }

    add(other) {
        if (other.empty()) {
            return this;
        }
        if (this.empty()) {
            return other;
        }
        const enclosing = new Range(
            Math.min(
                this.contiguous_ranges[0].start,
                other.contiguous_ranges[0].start
            ),
            Math.max(
                this.contiguous_ranges[this.contiguous_ranges.length - 1].end,
                other.contiguous_ranges[other.contiguous_ranges.length - 1].end
            )
        );
        return enclosing.subtract(enclosing.subtract(this).subtract(other));
    }
}

module.exports = Range;<commit_msg>[+] Added support for initialization with an empty array.<commit_after>import TinyRange from 'tiny-range';
import isNumber from 'is-number';
import assert from 'assert';

class ContiguousRange {
    constructor(x, y) {
        if (y == undefined) {
            if (typeof x === 'string') {
                // Range('0-2')
                const range = TinyRange.parse(x);
                assert(range.length == 1);
                this.start = range.start;
                this.end = range.end;
            } else if (Array.isArray(x)) {
                // Range([0, 2])
                assert(
                    x.length == 2
                    && isNumber(x[0])
                    && isNumber(x[1])
                    && x[0] <= x[1],
                    'Array initializer must contain 2 numbers, the first > the second.'
                );
                this.start = x[0];
                this.end = x[1];
            } else if (x instanceof ContiguousRange) {
                this.start = x.start;
                this.end = x.end;
            } else {
                assert(false, 'Invalid ContiguousRange constructor arguments: ' + Array.prototype.slice.call(arguments));
            }
        } else {
            // Range(0, 2)
            assert(isNumber(x) && isNumber(y) && x <= y);
            this.start = x;
            this.end = y;
        }

    }

    toString() {
        return this.length() == 1 ? this.start : '[' + this.start + ' ' + this.end + ')';
    }

    length() {
        return this.end - this.start;
    }

    empty() {
        return this.length() == 0;
    }

    subtract(other) {
        let distance = undefined;
        if (this.start < other.start) {
            if (this.end > other.start) {
                if (this.end > other.end) {
                    // [return[0].start return[0].end]                     [return[1].start return[1].end]
                    // [this.start                   [other.start other.end]                     this.end]
                    return new Range([this.start, other.start], [other.end, this.end]);
                } else {
                    // [return.start return.end]
                    // [this.start             [other.start this.end] other.end]
                    return new Range(this.start, other.start);
                }
            } else {
                // [return.start return.end]
                // [this.start     this.end] [other.start other.end]
                return new Range(this);
            }
        } else {
            if (other.end > this.start) {
                if (other.end > this.end) {
                    // return is empty.
                    // [other.start [this.start this.end] other.end]
                    return new Range();
                } else {
                    //                                    [return.start return.end]
                    // [other.start [this.start  other.end]               this.end]
                    return new Range(other.end, this.end);
                }
            } else {
                //                         [return.start return.end]
                // [other.start other.end] [this.start     this.end]
                return new Range(this);
            }
        }
    }
}

class Range {

    static MAX = Number.POSITIVE_INFINITY;
    static MIN = Number.NEGATIVE_INFINITY;

    constructor() {
        const args = Array.prototype.slice.call(arguments);
        if (args.length == 0) {
            // Range() -> empty range
            this.contiguous_ranges = [];
        } else if (args.length == 1) {
            let a = args[0];
            if (typeof a === 'string') {
                    // Range('0-2, 4-7')
                this.contiguous_ranges = TinyRange.parse(a);
            } else if (Array.isArray(a)) {
                if (a.length == 0) {
                    // Range([])
                    this.contiguous_ranges = [];
                } else if (Array.isArray(a[0])) {
                    // Range([[0, 2], [4, 7]])
                    const raw_ranges = a.map(contiguous_range_init => new ContiguousRange(contiguous_range_init));
                    this.contiguous_ranges = [];
                    raw_ranges.forEach(contiguous_range => {
                        this.contiguous_ranges = this.add(new Range(contiguous_range)).contiguous_ranges;
                    });
                    console.log(this.contiguous_ranges);
                } else if (isNumber(a[0])) {
                    // Range([0, 2])
                    this.contiguous_ranges = [new ContiguousRange(a)];
                } else if (a[0] instanceof ContiguousRange) {
                    // Range([[new ContiguousRange(0, 1), new ContiguousRange(2, 4)]])
                    this.contiguous_ranges = a.map(a => a);
                } else {
                    assert(false, 'Invalid Range constructor args: ' + args);
                }
            } else if (a instanceof Range) {
                // Range(other_range)
                this.contiguous_ranges = a.contiguous_ranges;
            } else if (a instanceof ContiguousRange) {
                this.contiguous_ranges = [a];
            } else {
                assert(false, 'Invalid Range constructor args: ' + args);
            }
        } else if (args.length == 2 && isNumber(args[0])) {
            // Range(0, 2);
            this.contiguous_ranges = [new ContiguousRange(args)];
        } else {
            // Range([0, 2], [4, 7]);
            this.contiguous_ranges = args.map(contiguous_range_init => new ContiguousRange(contiguous_range_init));
        }
    }

    toString() {
        return '[' + this.contiguous_ranges.map(r => r.toString()).join(', ') + ']';
    }

    empty() {
        return this.length() == 0;
    }

    length() {
        return this.contiguous_ranges.reduce((total, contiguous_range) => total + contiguous_range.length(), 0);
    }

    contiguousParts() {
        return this.contiguous_ranges;
    }

    isContiguous() {
        return this.contiguous_ranges.length <= 1;
    }

    enclosingContiguousRange() {
        return this.isContiguous() ? this : new ContiguousRange(this.contiguous_ranges[0].start, this.contiguous_ranges[this.contiguous_ranges.length - 1].end);
    }

    equals(other) {
        return this.includes(other) && other.includes(this);
    }

    includes(other) {
        return this.subtract(other).empty()
    }

    overlaps(other) {
        return !this.subtract(other).equals(this);
    }

    subtract(other) {
        let difference_ranges = [];
        this.contiguous_ranges.forEach(contiguous_range => {
            let remaining = [contiguous_range];
            other.contiguous_ranges.forEach(other_contiguous_range => {
                let new_remaining = [];
                remaining.forEach(remaining_contiguous_range => {
                    new_remaining = new_remaining.concat(remaining_contiguous_range.subtract(other_contiguous_range).contiguous_ranges)
                });
                remaining = new_remaining;
            });
            difference_ranges = difference_ranges.concat(remaining);
        });
        return new Range(difference_ranges);
    }

    add(other) {
        if (other.empty()) {
            return this;
        }
        if (this.empty()) {
            return other;
        }
        const enclosing = new Range(
            Math.min(
                this.contiguous_ranges[0].start,
                other.contiguous_ranges[0].start
            ),
            Math.max(
                this.contiguous_ranges[this.contiguous_ranges.length - 1].end,
                other.contiguous_ranges[other.contiguous_ranges.length - 1].end
            )
        );
        return enclosing.subtract(enclosing.subtract(this).subtract(other));
    }
}

module.exports = Range;<|endoftext|>


<commit_before>import 'svg-innerhtml';
import d3 from 'd3';
import axis from '../series/axis';
import '../layout/layout';
import line from '../series/line';
import dataJoin from '../util/dataJoin';
import expandRect from '../util/expandRect';
import {noop} from '../util/fn';
import {rebindAll} from '../util/rebind';
import {isOrdinal, range, setRange} from '../util/scale';

export default function(xScale, yScale) {

    xScale = xScale || d3.scale.linear();
    yScale = yScale || d3.scale.linear();

    var margin = {
            bottom: 30,
            right: 30
        },
        yLabel = '',
        xLabel = '',
        xBaseline = null,
        yBaseline = null,
        chartLabel = '',
        plotArea = line(),
        decorate = noop;

    // Each axis-series has a cross-scale which is defined as an identity
    // scale. If no baseline function is supplied, the axis is positioned
    // using the cross-scale range extents. If a baseline function is supplied
    // it is transformed via the respective scale.
    var xAxis = axis()
        .orient('bottom')
        .baseline(function() {
            if (xBaseline !== null) {
                return yScale(xBaseline.apply(this, arguments));
            } else {
                var r = range(yScale);
                return xAxis.orient() === 'bottom' ? r[0] : r[1];
            }
        });

    var yAxis = axis()
        .orient('right')
        .baseline(function() {
            if (yBaseline !== null) {
                return xScale(yBaseline.apply(this, arguments));
            } else {
                var r = range(xScale);
                return yAxis.orient() === 'left' ? r[0] : r[1];
            }
        });

    var containerDataJoin = dataJoin()
        .selector('svg.cartesian-chart')
        .element('svg')
        .attr({'class': 'cartesian-chart', 'layout-style': 'flex: 1'});

    var cartesian = function(selection) {

        selection.each(function(data, index) {

            var container = d3.select(this);

            var svg = containerDataJoin(container, [data]);
            svg.enter().html(
                '<g class="plot-area-container"> \
                    <rect class="background" \
                        layout-style="position: absolute; top: 0; bottom: 0; left: 0; right: 0"/> \
                    <g class="axes-container" \
                        layout-style="position: absolute; top: 0; bottom: 0; left: 0; right: 0"> \
                        <g class="x-axis" layout-style="height: 0; width: 0"/> \
                        <g class="y-axis" layout-style="height: 0; width: 0"/> \
                    </g> \
                    <svg class="plot-area" \
                        layout-style="position: absolute; top: 0; bottom: 0; left: 0; right: 0"/> \
                </g> \
                <g class="x-axis label-container"> \
                    <g layout-style="height: 0; width: 0"> \
                        <text class="label"/> \
                    </g> \
                </g> \
                <g class="y-axis label-container"> \
                    <g layout-style="height: 0; width: 0"> \
                        <text class="label"/> \
                    </g> \
                </g> \
                <g class="title label-container"> \
                    <g layout-style="height: 0; width: 0"> \
                        <text class="label"/> \
                    </g> \
                </g>');

            var expandedMargin = expandRect(margin);

            svg.select('.plot-area-container')
                .layout({
                    position: 'absolute',
                    top: expandedMargin.top,
                    left: expandedMargin.left,
                    bottom: expandedMargin.bottom,
                    right: expandedMargin.right
                });

            svg.select('.title')
                .layout({
                    position: 'absolute',
                    top: 0,
                    alignItems: 'center',
                    left: expandedMargin.left,
                    right: expandedMargin.right
                });

            var yAxisLayout = {
                position: 'absolute',
                top: expandedMargin.top,
                bottom: expandedMargin.bottom,
                alignItems: 'center',
                flexDirection: 'row'
            };
            yAxisLayout[yAxis.orient()] = 0;
            svg.select('.y-axis.label-container')
                .attr('class', 'y-axis ' + yAxis.orient())
                .layout(yAxisLayout);

            var xAxisLayout = {
                position: 'absolute',
                left: expandedMargin.left,
                right: expandedMargin.right,
                alignItems: 'center'
            };
            xAxisLayout[xAxis.orient()] = 0;
            svg.select('.x-axis.label-container')
                .attr('class', 'x-axis ' + xAxis.orient())
                .layout(xAxisLayout);

            // perform the flexbox / css layout
            container.layout();

            // update the label text
            svg.select('.title .label')
                .text(chartLabel);

            svg.select('.y-axis .label')
                .text(yLabel)
                .attr('transform', yAxis.orient() === 'right' ? 'rotate(90)' : 'rotate(-90)');

            svg.select('.x-axis .label')
                .text(xLabel);

            // set the axis ranges
            var plotAreaContainer = svg.select('.plot-area');
            setRange(xScale, [0, plotAreaContainer.layout('width')]);
            setRange(yScale, [plotAreaContainer.layout('height'), 0]);

            // render the axes
            xAxis.xScale(xScale)
                .yScale(d3.scale.identity());

            yAxis.yScale(yScale)
                .xScale(d3.scale.identity());

            svg.select('.axes-container .x-axis')
                .call(xAxis);

            svg.select('.axes-container .y-axis')
                .call(yAxis);

            // render the plot area
            plotArea.xScale(xScale)
                .yScale(yScale);
            plotAreaContainer.call(plotArea);

            decorate(svg, data, index);
        });
    };

    var scaleExclusions = [
        /range\w*/,   // the scale range is set via the component layout
        /tickFormat/  // use axis.tickFormat instead (only present on linear scales)
    ];
    rebindAll(cartesian, xScale, 'x', scaleExclusions);
    rebindAll(cartesian, yScale, 'y', scaleExclusions);

    var axisExclusions = [
        'baseline',         // the axis baseline is adapted so is not exposed directly
        'xScale', 'yScale'  // these are set by this components
    ];
    rebindAll(cartesian, xAxis, 'x', axisExclusions);
    rebindAll(cartesian, yAxis, 'y', axisExclusions);

    cartesian.xBaseline = function(x) {
        if (!arguments.length) {
            return xBaseline;
        }
        xBaseline = d3.functor(x);
        return cartesian;
    };
    cartesian.yBaseline = function(x) {
        if (!arguments.length) {
            return yBaseline;
        }
        yBaseline = d3.functor(x);
        return cartesian;
    };
    cartesian.chartLabel = function(x) {
        if (!arguments.length) {
            return chartLabel;
        }
        chartLabel = x;
        return cartesian;
    };
    cartesian.plotArea = function(x) {
        if (!arguments.length) {
            return plotArea;
        }
        plotArea = x;
        return cartesian;
    };
    cartesian.xLabel = function(x) {
        if (!arguments.length) {
            return xLabel;
        }
        xLabel = x;
        return cartesian;
    };
    cartesian.margin = function(x) {
        if (!arguments.length) {
            return margin;
        }
        margin = x;
        return cartesian;
    };
    cartesian.yLabel = function(x) {
        if (!arguments.length) {
            return yLabel;
        }
        yLabel = x;
        return cartesian;
    };
    cartesian.decorate = function(x) {
        if (!arguments.length) {
            return decorate;
        }
        decorate = x;
        return cartesian;
    };

    return cartesian;
}
<commit_msg>Prevent label-container class being removed when axis orient class is added<commit_after>import 'svg-innerhtml';
import d3 from 'd3';
import axis from '../series/axis';
import '../layout/layout';
import line from '../series/line';
import dataJoin from '../util/dataJoin';
import expandRect from '../util/expandRect';
import {noop} from '../util/fn';
import {rebindAll} from '../util/rebind';
import {isOrdinal, range, setRange} from '../util/scale';

export default function(xScale, yScale) {

    xScale = xScale || d3.scale.linear();
    yScale = yScale || d3.scale.linear();

    var margin = {
            bottom: 30,
            right: 30
        },
        yLabel = '',
        xLabel = '',
        xBaseline = null,
        yBaseline = null,
        chartLabel = '',
        plotArea = line(),
        decorate = noop;

    // Each axis-series has a cross-scale which is defined as an identity
    // scale. If no baseline function is supplied, the axis is positioned
    // using the cross-scale range extents. If a baseline function is supplied
    // it is transformed via the respective scale.
    var xAxis = axis()
        .orient('bottom')
        .baseline(function() {
            if (xBaseline !== null) {
                return yScale(xBaseline.apply(this, arguments));
            } else {
                var r = range(yScale);
                return xAxis.orient() === 'bottom' ? r[0] : r[1];
            }
        });

    var yAxis = axis()
        .orient('right')
        .baseline(function() {
            if (yBaseline !== null) {
                return xScale(yBaseline.apply(this, arguments));
            } else {
                var r = range(xScale);
                return yAxis.orient() === 'left' ? r[0] : r[1];
            }
        });

    var containerDataJoin = dataJoin()
        .selector('svg.cartesian-chart')
        .element('svg')
        .attr({'class': 'cartesian-chart', 'layout-style': 'flex: 1'});

    var cartesian = function(selection) {

        selection.each(function(data, index) {

            var container = d3.select(this);

            var svg = containerDataJoin(container, [data]);
            svg.enter().html(
                '<g class="plot-area-container"> \
                    <rect class="background" \
                        layout-style="position: absolute; top: 0; bottom: 0; left: 0; right: 0"/> \
                    <g class="axes-container" \
                        layout-style="position: absolute; top: 0; bottom: 0; left: 0; right: 0"> \
                        <g class="x-axis" layout-style="height: 0; width: 0"/> \
                        <g class="y-axis" layout-style="height: 0; width: 0"/> \
                    </g> \
                    <svg class="plot-area" \
                        layout-style="position: absolute; top: 0; bottom: 0; left: 0; right: 0"/> \
                </g> \
                <g class="x-axis label-container"> \
                    <g layout-style="height: 0; width: 0"> \
                        <text class="label"/> \
                    </g> \
                </g> \
                <g class="y-axis label-container"> \
                    <g layout-style="height: 0; width: 0"> \
                        <text class="label"/> \
                    </g> \
                </g> \
                <g class="title label-container"> \
                    <g layout-style="height: 0; width: 0"> \
                        <text class="label"/> \
                    </g> \
                </g>');

            var expandedMargin = expandRect(margin);

            svg.select('.plot-area-container')
                .layout({
                    position: 'absolute',
                    top: expandedMargin.top,
                    left: expandedMargin.left,
                    bottom: expandedMargin.bottom,
                    right: expandedMargin.right
                });

            svg.select('.title')
                .layout({
                    position: 'absolute',
                    top: 0,
                    alignItems: 'center',
                    left: expandedMargin.left,
                    right: expandedMargin.right
                });

            var yAxisLayout = {
                position: 'absolute',
                top: expandedMargin.top,
                bottom: expandedMargin.bottom,
                alignItems: 'center',
                flexDirection: 'row'
            };
            yAxisLayout[yAxis.orient()] = 0;
            svg.select('.y-axis.label-container')
                .attr('class', 'y-axis label-container ' + yAxis.orient())
                .layout(yAxisLayout);

            var xAxisLayout = {
                position: 'absolute',
                left: expandedMargin.left,
                right: expandedMargin.right,
                alignItems: 'center'
            };
            xAxisLayout[xAxis.orient()] = 0;
            svg.select('.x-axis.label-container')
                .attr('class', 'x-axis label-container ' + xAxis.orient())
                .layout(xAxisLayout);

            // perform the flexbox / css layout
            container.layout();

            // update the label text
            svg.select('.title .label')
                .text(chartLabel);

            svg.select('.y-axis.label-container .label')
                .text(yLabel)
                .attr('transform', yAxis.orient() === 'right' ? 'rotate(90)' : 'rotate(-90)');

            svg.select('.x-axis.label-container .label')
                .text(xLabel);

            // set the axis ranges
            var plotAreaContainer = svg.select('.plot-area');
            setRange(xScale, [0, plotAreaContainer.layout('width')]);
            setRange(yScale, [plotAreaContainer.layout('height'), 0]);

            // render the axes
            xAxis.xScale(xScale)
                .yScale(d3.scale.identity());

            yAxis.yScale(yScale)
                .xScale(d3.scale.identity());

            svg.select('.axes-container .x-axis')
                .call(xAxis);

            svg.select('.axes-container .y-axis')
                .call(yAxis);

            // render the plot area
            plotArea.xScale(xScale)
                .yScale(yScale);
            plotAreaContainer.call(plotArea);

            decorate(svg, data, index);
        });
    };

    var scaleExclusions = [
        /range\w*/,   // the scale range is set via the component layout
        /tickFormat/  // use axis.tickFormat instead (only present on linear scales)
    ];
    rebindAll(cartesian, xScale, 'x', scaleExclusions);
    rebindAll(cartesian, yScale, 'y', scaleExclusions);

    var axisExclusions = [
        'baseline',         // the axis baseline is adapted so is not exposed directly
        'xScale', 'yScale'  // these are set by this components
    ];
    rebindAll(cartesian, xAxis, 'x', axisExclusions);
    rebindAll(cartesian, yAxis, 'y', axisExclusions);

    cartesian.xBaseline = function(x) {
        if (!arguments.length) {
            return xBaseline;
        }
        xBaseline = d3.functor(x);
        return cartesian;
    };
    cartesian.yBaseline = function(x) {
        if (!arguments.length) {
            return yBaseline;
        }
        yBaseline = d3.functor(x);
        return cartesian;
    };
    cartesian.chartLabel = function(x) {
        if (!arguments.length) {
            return chartLabel;
        }
        chartLabel = x;
        return cartesian;
    };
    cartesian.plotArea = function(x) {
        if (!arguments.length) {
            return plotArea;
        }
        plotArea = x;
        return cartesian;
    };
    cartesian.xLabel = function(x) {
        if (!arguments.length) {
            return xLabel;
        }
        xLabel = x;
        return cartesian;
    };
    cartesian.margin = function(x) {
        if (!arguments.length) {
            return margin;
        }
        margin = x;
        return cartesian;
    };
    cartesian.yLabel = function(x) {
        if (!arguments.length) {
            return yLabel;
        }
        yLabel = x;
        return cartesian;
    };
    cartesian.decorate = function(x) {
        if (!arguments.length) {
            return decorate;
        }
        decorate = x;
        return cartesian;
    };

    return cartesian;
}
<|endoftext|>


<commit_before>const fs = require("fs");
const path = require("path");
const matter = require("gray-matter");
const toml = require("@iarna/toml");
const Feed = require("feed").Feed;

const options = {
  engines: {
    toml: toml.parse.bind(toml),
  },
  language: "toml",
  delimiters: "+++",
};

const generateRSSFeed = () => {
  let posts = [];

  const getAllChildren = (dir) => {
    const children = fs.readdirSync(dir, { withFileTypes: true });
    return children
      .filter((f) => f.isFile() && f.name !== "_index.md")
      .map((post) => {
        const { data: pageData, content: pageContent } = matter(
          fs.readFileSync(path.join(dir, post.name)),
          options
        );
        return {
          title: pageData.title,
          descripton: pageData.description || "",
          author: pageData.extra.author || "",
          date: pageData.date,
          link: path.join(
            "https://urbit.org/",
            dir.substr(dir.indexOf("content") + 7),
            "/",
            post.name.replace(/.md$/, "")
          ),
          content: pageContent,
        };
      });
  };
  posts.push(
    ...getAllChildren(path.join(process.cwd(), "content/blog")),
    ...getAllChildren(path.join(process.cwd(), "content/updates")),
    ...getAllChildren(path.join(process.cwd(), "content/events"))
  );
  posts = posts.sort((a, b) => (a.date > b.date ? -1 : 1));

  const baseUrl = "https://urbit.org";
  const author = {
    name: "Urbit.org",
    email: "support@urbit.org",
    link: "https://urbit.org",
  };

  // Construct a new Feed object
  const feed = new Feed({
    title: "Urbit",
    description: "Urbit is a personal server built from scratch",
    id: baseUrl,
    link: baseUrl,
    language: "en",
    feedLinks: {
      rss2: `${baseUrl}/rss.xml`,
    },
    author,
  });

  // Add each article to the feed
  posts.forEach((post) => {
    const { title, description, author, date, link, content } = post;
    feed.addItem({
      title,
      id: link,
      link: link,
      description,
      content,
      author: [
        {
          name: author,
          email: "",
          link: "",
        },
      ],
      date: new Date(date),
    });
  });
  try {
    fs.readdirSync("public");
  } catch (err) {
    fs.mkdirSync("public");
  }

  fs.writeFileSync("public/rss.xml", feed.rss2());
};

generateRSSFeed();
<commit_msg>rss: fix link building<commit_after>const fs = require("fs");
const path = require("path");
const matter = require("gray-matter");
const toml = require("@iarna/toml");
const Feed = require("feed").Feed;

const options = {
  engines: {
    toml: toml.parse.bind(toml),
  },
  language: "toml",
  delimiters: "+++",
};

const generateRSSFeed = () => {
  let posts = [];

  const getAllChildren = (dir) => {
    const children = fs.readdirSync(dir, { withFileTypes: true });
    return children
      .filter((f) => f.isFile() && f.name !== "_index.md")
      .map((post) => {
        const { data: pageData, content: pageContent } = matter(
          fs.readFileSync(path.join(dir, post.name)),
          options
        );
        const leadingDir = dir.substr(dir.indexOf("content") + 8);
        const name = post.name.replace(/.md$/, "");

        return {
          title: pageData.title,
          descripton: pageData.description || "",
          author: pageData.extra.author || "",
          date: pageData.date,
          link: `https://urbit.org/${leadingDir}/${name}`,
          content: pageContent,
        };
      });
  };
  posts.push(
    ...getAllChildren(path.join(process.cwd(), "content/blog")),
    ...getAllChildren(path.join(process.cwd(), "content/updates")),
    ...getAllChildren(path.join(process.cwd(), "content/events"))
  );
  posts = posts.sort((a, b) => (a.date > b.date ? -1 : 1));

  const baseUrl = "https://urbit.org";
  const author = {
    name: "Urbit.org",
    email: "support@urbit.org",
    link: "https://urbit.org",
  };

  // Construct a new Feed object
  const feed = new Feed({
    title: "Urbit",
    description: "Urbit is a personal server built from scratch",
    id: baseUrl,
    link: baseUrl,
    language: "en",
    feedLinks: {
      rss2: `${baseUrl}/rss.xml`,
    },
    author,
  });

  // Add each article to the feed
  posts.forEach((post) => {
    const { title, description, author, date, link, content } = post;
    feed.addItem({
      title,
      id: link,
      link: link,
      description,
      content,
      author: [
        {
          name: author,
          email: "",
          link: "",
        },
      ],
      date: new Date(date),
    });
  });
  try {
    fs.readdirSync("public");
  } catch (err) {
    fs.mkdirSync("public");
  }

  fs.writeFileSync("public/rss.xml", feed.rss2());
};

generateRSSFeed();
<|endoftext|>


<commit_before>import linearSystem from '../index.js'
import sinon from 'sinon'
describe('linearSystem', () => {
    let linSys;
    let data;
    beforeEach(function() {
        linSys = new linearSystem();
        data = {
          s : [[2,2,6],[9,9,30]]
        };
    });
    describe('_switch', () => {
      it('linearSystem._switch should exchange places of two diffrent rows', () => {
        let thing = linSys._switch(data,0,1);
        expect(thing.s).toEqual([[9,9,30],[2,2,6]]);
        //mutation check
      });

      it('_switch mutation check', () => {
        let thing = linSys._switch(data,0,1);
        expect(thing.s).toEqual([[9,9,30],[2,2,6]]);
        expect(data).toEqual({ s : [[2,2,6],[9,9,30]]});
      });
    });
    describe("_getRowScaledBy", () => {
      it('_getRowScaledBy should return array mulitplied by scale', () => {
        let row = linSys._getRowScaledBy([2,0,6],2);
        expect(row).toEqual([4,0,12]);
      });

      it('_getRowScaledBy should return array mulitplied to negitive scale', () => {
        let row = linSys._getRowScaledBy([2,0,-6],-1);
        expect(row).toEqual([-2,0,6]);
      });

      it('_getRowScaledBy mutation check', () => {
        let row = linSys._getRowScaledBy([2,0,-6],-1);
        expect(data).toEqual({s : [[2,2,6],[9,9,30]]});
      });
    });

    describe("_rowReplacement", () => {
      it('_rowReplacement should call _getRowScaledBy with data', () => {
        let scaledBy = sinon.spy(linSys, '_getRowScaledBy');
        let rowToBeReplaced = 0, otherRow = 1, scale = 2;
        linSys._rowReplacement(data, rowToBeReplaced, otherRow, scale);
        scaledBy.restore();
        sinon.assert.calledWith(scaledBy, [9,9,30], 2);
      });

      it('_rowReplacement should return array with a row replaced by itself mulitplied to scale', () => {
        let rowToBeReplaced = 0,otherRow = 1,scale = 2;
        let newthing = linSys._rowReplacement(data, rowToBeReplaced, otherRow, scale);
        expect(newthing).toEqual({s : [[20,20,66],[9,9,30]]});
      });

      it('_rowReplacement mutation test', () => {
        let rowToBeReplaced = 0, otherRow = 1, scale = 2;
        linSys._rowReplacement(data, rowToBeReplaced, otherRow, scale);
        expect(data).toEqual({ s : [[2,2,6],[9,9,30]]});
      });
    });

    describe("_largestAbsoluteMovedToTopOfColumn", () => {
      it('should return array with largest absolute value to top of each pivot', () => {
        let inputSystem = {
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        };
        let expectedOutput = {
          s : [
            [-3,2,1,5],
            [1,2,3,4],
            [0,1,2,3]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        };
        let output = linSys._largestAbsoluteMovedToTopOfColumn(inputSystem);
        expect(output).toEqual(expectedOutput);
      });

      it("calls _switch with correct values", () => {
        let switchy = sinon.spy(linSys, '_switch');
        let inputSystem = {
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        };
        let output = linSys._largestAbsoluteMovedToTopOfColumn(inputSystem);
        switchy.restore();
        sinon.assert.calledWith(switchy, {
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        });
      });
      it("mutation check", () => {
        let inputSystem = {
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        };
        linSys._largestAbsoluteMovedToTopOfColumn(inputSystem);
        expect(inputSystem).toEqual({
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        });
      });
    });

  it('_zeroAllRowsUnderThePivot returns correct value', () => {
    let inputSystem = {
      s : [
        [5,1,1,10],
        [-1,1,1,-2],
        [1,1,1,2]
      ],
      pivot : {
        column : 0,
        row : 0
      }
    };
    let outSystem = linSys._zeroAllRowsUnderThePivot(inputSystem);
    expect(outSystem.s).toEqual(
      [
        [ 5, 1, 1, 10 ],
        [ 0, 1.2, 1.2, 0 ],
        [ 0, 0.8, 0.8, 0 ]
      ]);
  });

  it('_zeroAllRowsUnderThePivot mutation check', () => {
    let inputSystem = {
      s : [
        [5,1,1,10],
        [-1,1,1,-2],
        [1,1,1,2]
      ],
      pivot : {
        column : 0,
        row : 0
      }
    };
    let outSystem = linSys._zeroAllRowsUnderThePivot(inputSystem);
    expect(inputSystem).toEqual({
      s : [
        [5,1,1,10],
        [-1,1,1,-2],
        [1,1,1,2]
      ],
      pivot : {
        column : 0,
        row : 0
      }
    });
  });
});
<commit_msg>test code style<commit_after>import linearSystem from '../index.js'
import sinon from 'sinon'
describe('linearSystem', () => {
    let linSys;
    let data;
    beforeEach(function() {
        linSys = new linearSystem();
        data = {
          s : [[2,2,6],[9,9,30]]
        };
    });
    describe('_switch', () => {
      it('should exchange places of two diffrent rows', () => {
        let thing = linSys._switch(data,0,1);
        expect(thing.s).toEqual([[9,9,30],[2,2,6]]);
        //mutation check
      });

      it('mutation check', () => {
        let thing = linSys._switch(data,0,1);
        expect(thing.s).toEqual([[9,9,30],[2,2,6]]);
        expect(data).toEqual({ s : [[2,2,6],[9,9,30]]});
      });
    });
    describe("_getRowScaledBy", () => {
      it('should return array mulitplied by scale', () => {
        let row = linSys._getRowScaledBy([2,0,6],2);
        expect(row).toEqual([4,0,12]);
      });

      it('should return array mulitplied to negitive scale', () => {
        let row = linSys._getRowScaledBy([2,0,-6],-1);
        expect(row).toEqual([-2,0,6]);
      });

      it('mutation check', () => {
        let row = linSys._getRowScaledBy([2,0,-6],-1);
        expect(data).toEqual({s : [[2,2,6],[9,9,30]]});
      });
    });

    describe("_rowReplacement", () => {
      it('should call _getRowScaledBy with data', () => {
        let scaledBy = sinon.spy(linSys, '_getRowScaledBy');
        let rowToBeReplaced = 0, otherRow = 1, scale = 2;
        linSys._rowReplacement(data, rowToBeReplaced, otherRow, scale);
        scaledBy.restore();
        sinon.assert.calledWith(scaledBy, [9,9,30], 2);
      });

      it('should return array with a row replaced by itself mulitplied to scale', () => {
        let rowToBeReplaced = 0,otherRow = 1,scale = 2;
        let newthing = linSys._rowReplacement(data, rowToBeReplaced, otherRow, scale);
        expect(newthing).toEqual({s : [[20,20,66],[9,9,30]]});
      });

      it('mutation test', () => {
        let rowToBeReplaced = 0, otherRow = 1, scale = 2;
        linSys._rowReplacement(data, rowToBeReplaced, otherRow, scale);
        expect(data).toEqual({ s : [[2,2,6],[9,9,30]]});
      });
    });

    describe("_largestAbsoluteMovedToTopOfColumn", () => {
      it('should return array with largest absolute value to top of each pivot', () => {
        let inputSystem = {
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        };
        let expectedOutput = {
          s : [
            [-3,2,1,5],
            [1,2,3,4],
            [0,1,2,3]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        };
        let output = linSys._largestAbsoluteMovedToTopOfColumn(inputSystem);
        expect(output).toEqual(expectedOutput);
      });

      it("calls _switch with correct values", () => {
        let switchy = sinon.spy(linSys, '_switch');
        let inputSystem = {
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        };
        let output = linSys._largestAbsoluteMovedToTopOfColumn(inputSystem);
        switchy.restore();
        sinon.assert.calledWith(switchy, {
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        });
      });
      it("mutation check", () => {
        let inputSystem = {
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        };
        linSys._largestAbsoluteMovedToTopOfColumn(inputSystem);
        expect(inputSystem).toEqual({
          s : [
            [0,1,2,3],
            [1,2,3,4],
            [-3,2,1,5]
          ],
          pivot : {
            column : 0,
            row : 0
          }
        });
      });
    });

  it('_zeroAllRowsUnderThePivot returns correct value', () => {
    let inputSystem = {
      s : [
        [5,1,1,10],
        [-1,1,1,-2],
        [1,1,1,2]
      ],
      pivot : {
        column : 0,
        row : 0
      }
    };
    let outSystem = linSys._zeroAllRowsUnderThePivot(inputSystem);
    expect(outSystem.s).toEqual(
      [
        [ 5, 1, 1, 10 ],
        [ 0, 1.2, 1.2, 0 ],
        [ 0, 0.8, 0.8, 0 ]
      ]);
  });

  it('_zeroAllRowsUnderThePivot mutation check', () => {
    let inputSystem = {
      s : [
        [5,1,1,10],
        [-1,1,1,-2],
        [1,1,1,2]
      ],
      pivot : {
        column : 0,
        row : 0
      }
    };
    let outSystem = linSys._zeroAllRowsUnderThePivot(inputSystem);
    expect(inputSystem).toEqual({
      s : [
        [5,1,1,10],
        [-1,1,1,-2],
        [1,1,1,2]
      ],
      pivot : {
        column : 0,
        row : 0
      }
    });
  });
});
<|endoftext|>


<commit_before><commit_msg>feat(examples/materials): replace null material with default material<commit_after><|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'

import ActionBar from './actionbar/ActionBar'
import Messages from './messages/Messages'

import './ChatBot.css'

class ChatBot extends Component {

  constructor (props) {
    super(props)

    this.state = {
      actions: [props.startButton],
      messages: []
    }

    this._onQuickReplyAction = this._onQuickReplyAction.bind(this)
  }

  _onQuickReplyAction (text, action) {
    let reply = this.props.onQuickReplyAction(action)
    if (reply) {
      reply = (reply instanceof Array) ? reply : [reply]
    }

    let messages = [{
      text: text,
      isInbound: true
    }]

    let actions

    if (reply) {
      messages = messages.concat(reply.map((m, i) => Object.assign({}, m.message, {isInbound: false})))
      actions = reply.pop().actions
    }

    this.setState({
      messages: this.state.messages.concat(messages),
      actions: actions
    })
  }

  render () {
    let actions
    let actionBarType

    if (this.state.actions) {
      actions = this.state.actions
      actions = actions.map((action) => Object.assign({}, action, {onAction: this._onQuickReplyAction}))
      actionBarType = 'quick-reply'
    }

    return (

        <Messages messages={this.state.messages} />
        <ActionBar actions={actions} type={actionBarType} />

    )
  }

  static textMessage (text, ...actions) {
    return {
      message: {
        text: text
      },
      actions: actions
    }
  }

  static makeReplyButton (text, postback) {
    return {
      title: text,
      postback: postback
    }
  }
}

ChatBot.propTypes = {
  onQuickReplyAction: PropTypes.func.isRequired,
  startButton: PropTypes.object.isRequired
}

export default ChatBot
<commit_msg>Typing state<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'

import ActionBar from './actionbar/ActionBar'
import Messages from './messages/Messages'

import MessageProcessor from './MessageProcessor'

import './ChatBot.css'

class ChatBot extends Component {

  constructor (props) {
    super(props)

    this.state = {
      actions: [props.startButton],
      messages: []
    }

    this._onQuickReplyAction = this._onQuickReplyAction.bind(this)
    this._onProcessed = this._onProcessed(this)

    this._messageProcessor = new MessageProcessor(this._onProcessed)
  }

  _onQuickReplyAction (text, action) {
    let reply = this.props.onQuickReplyAction(action)
    if (reply) {
      reply = (reply instanceof Array) ? reply : [reply]
    }

    let messages = [{
      text: text,
      isInbound: true
    }]

    let actions

    if (reply) {
      messages = messages.concat(reply.map((m, i) => Object.assign({}, m.message, {isInbound: false})))
      actions = reply.pop().actions
    }

    this.setState({
      messages: this.state.messages.concat(messages),
      actions: actions
    })
  }

  _onProcessed (message) {
  }

  render () {
    let actions
    let actionBarType

    if (this.state.actions) {
      actions = this.state.actions
      actions = actions.map((action) => Object.assign({}, action, {onAction: this._onQuickReplyAction}))
      actionBarType = 'quick-reply'
    }

    return (

        <Messages messages={this.state.messages} isTyping={this.props.isTypingEnabled && this._messageProcessor.isProcessing} />
        <ActionBar actions={actions} type={actionBarType} />

    )
  }

  static textMessage (text, ...actions) {
    return {
      message: {
        text: text
      },
      actions: actions
    }
  }

  static makeReplyButton (text, postback) {
    return {
      title: text,
      postback: postback
    }
  }
}

ChatBot.defaultProps = {
  isTypingEnabled: true
}

ChatBot.propTypes = {
  onQuickReplyAction: PropTypes.func.isRequired,
  startButton: PropTypes.object.isRequired,
  isTypingEnabled: PropTypes.bool
}

export default ChatBot
<|endoftext|>


<commit_before>var
	util = require("util"),
	request = require("request"),
	querystring = require("querystring"),
	options = null,
	cservice = require("../cluster-service")
;

exports.start = function(o, cb) {
	options = o;

	run(options.run, cb);
};

function run(question, cb) {
	var split = question.split(" ");
	var qs = querystring.stringify({
		cmd: question,
		accessKey: options.accessKey
	});
	var url = "http://" + (options.host || "localhost") + ":" + (options.port || 11987) + "/cli"
		+ "?" + qs
	;
	cservice.log("Running remote command: ".warn + url.data);
	request.post(url, function (err, res, body) {
	    if (res.statusCode !== 200 && !err && body) {
	        err = body;
	    }
	    if (err) {
			cservice.error("Error: ", err);
			body = { statusCode: res.statusCode, error: err };
		} else if (body) {
			if (typeof body === "string" && (body.indexOf("{") === 0 || body.indexOf("[") === 0)) {
				body = JSON.parse(body); // deserialize
			}
		}
		if (options.json === true) {
			cservice.results(JSON.stringify(body));
		} else {
			cservice.results(util.inspect(body, { depth: null, colors: true }));
		}

		cb && cb(err, body);
	});
}
<commit_msg>#23 fix status code error on 'run' if error<commit_after>var
	util = require("util"),
	request = require("request"),
	querystring = require("querystring"),
	options = null,
	cservice = require("../cluster-service")
;

exports.start = function(o, cb) {
	options = o;

	run(options.run, cb);
};

function run(question, cb) {
	var split = question.split(" ");
	var qs = querystring.stringify({
		cmd: question,
		accessKey: options.accessKey
	});
	var url = "http://" + (options.host || "localhost") + ":" + (options.port || 11987) + "/cli"
		+ "?" + qs
	;
	cservice.log("Running remote command: ".warn + url.data);
	request.post(url, function (err, res, body) {
	    if (res && res.statusCode !== 200 && !err && body) {
	        err = body;
	    }
	    if (err) {
			cservice.error("Error: ", err);
			body = { statusCode: res ? res.statusCode : "no response", error: err };
		} else if (body) {
			if (typeof body === "string" && (body.indexOf("{") === 0 || body.indexOf("[") === 0)) {
				body = JSON.parse(body); // deserialize
			}
		}
		if (options.json === true) {
			cservice.results(JSON.stringify(body));
		} else {
			cservice.results(util.inspect(body, { depth: null, colors: true }));
		}

		cb && cb(err, body);
	});
}
<|endoftext|>


<commit_before>var crypto = require('crypto');

var ERRORS = {
    settingsRequired: {err:'Settings required', des: 'Settings must have at least cipherKey and firmKey'},
    cipherKeyRequired: {err: 'CipherKey required', des: 'CipherKey parameter is mandatory'},
    firmKeyRequired: {err: 'FirmKey required',des: 'FirmKey parameter is mandatory'},
    badFirm: {err: 'Bad firm',des: 'Firm is not valid'},
    badToken: {err: 'Bad token', des: 'Token is not valid'},
    serializationError: {err: 'Serialization error', des: 'Error during data serialization'},
    unserializationError: {err: 'Unserialization error', des: 'Error during data unserialization'}
};

const DEFAULT_SETTINGS = {
    cipherAlgorithm : 'aes-256-cbc',
    hmacAlgorithm : 'md5',
    hmacDigestEncoding : 'hex',
    plainEncoding : 'utf8',
    tokenEncoding : 'base64',
    tokenExpirationMinutes : 90,
    enableSessionId: false
};

function enrich_settings(settings, ckb){
    if (typeof settings === 'undefined' || isEmpty(settings)){
        ckb(ERRORS.settingsRequired);
        return;
    } else if (!settings.hasOwnProperty('cipherKey')) {
        ckb(ERRORS.cipherKeyRequired);
        return;
    } else if (!settings.hasOwnProperty('firmKey')) {
        ckb(ERRORS.firmKeyRequired);
        return;
    }
    for (var p in DEFAULT_SETTINGS){
        if (settings.hasOwnProperty(p) == false) {
            settings[p] = DEFAULT_SETTINGS[p];
        }
    }
    ckb(null, settings);
}

function isEmpty(obj) {
    return !Object.keys(obj).length > 0;
}

function serialize(data) {
    try {
        return JSON.stringify(data);
    } catch (e) {
        throw ERRORS.serializationError;
    }
}

function unserialize(data) {
    try {
        return JSON.parse(data);
    } catch (e) {
        throw ERRORS.unserializationError;
    }
}

function standarizeToken(token){
    return token.
        replace(/\+/g, '-'). 	// Convert '+' to '-'
        replace(/\//g, '_'). 	// Convert '/' to '_'
        replace(/=+$/, '') 		// Remove ending '='
        ;
}

function firmToken(settings, userId, expiresAtTimestamp, data) {
    var notFirmedToken = serialize({
        'userId': userId,
        'expiresAtTimestamp': expiresAtTimestamp,
        'data': data
    });
    var firmedToken = crypto.createHmac(settings.hmacAlgorithm, settings.firmKey)
        .update(notFirmedToken)
        .digest(settings.hmacDigestEncoding);
    return firmedToken;
}

function checkTokenFirm(settings, cipheredToken){
    var tokenSet = decipherToken(settings, cipheredToken);

    var firm = firmToken(settings, tokenSet.userId, tokenSet.expiresAtTimestamp, tokenSet.data);
    return firm === tokenSet.firm;
}

function decipherToken (settings, cipheredToken){
    var decipher = crypto.createDecipher(settings.cipherAlgorithm, settings.cipherKey);
    var decodedToken = decipher.update(cipheredToken, settings.tokenEncoding, settings.plainEncoding);
    if (!decodedToken) return null;
    decodedToken = (decodedToken + decipher.final(settings.plainEncoding));

    decodedToken = unserialize(decodedToken);
    return decodedToken;
}

exports.createToken = function(settings, userId, data, callback) {
    enrich_settings(settings, function(err, settings){
        if(err){
            callback(err);
        } else {

            var expiresAtTimestamp = new Date().getTime() + settings.tokenExpirationMinutes*60*1000;
            data = data || {};

            var firm = firmToken(settings, userId, expiresAtTimestamp, data);
            var cipher = crypto.createCipher(settings.cipherAlgorithm, settings.cipherKey);

            var tokenSet = {
                'userId': userId,
                'expiresAtTimestamp': expiresAtTimestamp,
                'data': data,
                'firm': firm
            };
            if (settings.enableSessionId) {
                tokenSet.sessionId = userId + '-' + crypto.pseudoRandomBytes(12).toString('hex');
            }
            var encodedData = cipher.update(serialize(tokenSet), settings.plainEncoding, settings.tokenEncoding);

            callback(null, standarizeToken(encodedData + cipher.final(settings.tokenEncoding)));
        }
    });

};

exports.getTokenSet = function(settings, cipheredToken, callback){
    enrich_settings(settings, function(err, settings){
        if (err) {
            callback(err);

        } else {
            var tokenSet = {};

            var token = decipherToken(settings, cipheredToken);
            if (!token){
                callback(ERRORS.badToken);
                return;
            } else if(!checkTokenFirm(settings, cipheredToken)){
                callback(ERRORS.badFirm);
                return;
            } else {
                tokenSet = {
                    userId : token.userId,
                    expiresAtTimestamp : token.expiresAtTimestamp,
                    data: token.data
                };
                if (settings.enableSessionId) {
                    tokenSet.sessionId = token.sessionId
                }
            }
            callback(null, tokenSet);
        }
    });
};
<commit_msg>changed way of exporting functions<commit_after>var crypto = require('crypto');

var ERRORS = {
    settingsRequired: {err:'Settings required', des: 'Settings must have at least cipherKey and firmKey'},
    cipherKeyRequired: {err: 'CipherKey required', des: 'CipherKey parameter is mandatory'},
    firmKeyRequired: {err: 'FirmKey required',des: 'FirmKey parameter is mandatory'},
    badFirm: {err: 'Bad firm',des: 'Firm is not valid'},
    badToken: {err: 'Bad token', des: 'Token is not valid'},
    serializationError: {err: 'Serialization error', des: 'Error during data serialization'},
    unserializationError: {err: 'Unserialization error', des: 'Error during data unserialization'}
};

const DEFAULT_SETTINGS = {
    cipherAlgorithm : 'aes-256-cbc',
    hmacAlgorithm : 'md5',
    hmacDigestEncoding : 'hex',
    plainEncoding : 'utf8',
    tokenEncoding : 'base64',
    tokenExpirationMinutes : 90,
    enableSessionId: false
};

function enrich_settings(settings, ckb){
    if (typeof settings === 'undefined' || isEmpty(settings)){
        return ckb(ERRORS.settingsRequired);
    } else if (!settings.hasOwnProperty('cipherKey')) {
        return ckb(ERRORS.cipherKeyRequired);
    } else if (!settings.hasOwnProperty('firmKey')) {
        return ckb(ERRORS.firmKeyRequired);
    }
    for (var p in DEFAULT_SETTINGS){
        if (settings.hasOwnProperty(p) == false) {
            settings[p] = DEFAULT_SETTINGS[p];
        }
    }
    ckb(null, settings);
}

function isEmpty(obj) {
    return !Object.keys(obj).length > 0;
}

function serialize(data) {
    try {
        return JSON.stringify(data);
    } catch (e) {
        throw ERRORS.serializationError;
    }
}

function unserialize(data) {
    try {
        return JSON.parse(data);
    } catch (e) {
        throw ERRORS.unserializationError;
    }
}

function standarizeToken(token){
    return token.
        replace(/\+/g, '-'). 	// Convert '+' to '-'
        replace(/\//g, '_'). 	// Convert '/' to '_'
        replace(/=+$/, '') 		// Remove ending '='
        ;
}

function firmToken(settings, userId, expiresAtTimestamp, data) {
    var notFirmedToken = serialize({
        'userId': userId,
        'expiresAtTimestamp': expiresAtTimestamp,
        'data': data
    });
    var firmedToken = crypto.createHmac(settings.hmacAlgorithm, settings.firmKey)
        .update(notFirmedToken)
        .digest(settings.hmacDigestEncoding);
    return firmedToken;
}

function checkTokenFirm(settings, cipheredToken){
    var tokenSet = decipherToken(settings, cipheredToken);

    var firm = firmToken(settings, tokenSet.userId, tokenSet.expiresAtTimestamp, tokenSet.data);
    return firm === tokenSet.firm;
}

function decipherToken (settings, cipheredToken){
    var decipher = crypto.createDecipher(settings.cipherAlgorithm, settings.cipherKey);
    var decodedToken = decipher.update(cipheredToken, settings.tokenEncoding, settings.plainEncoding);
    if (!decodedToken) return null;
    decodedToken = (decodedToken + decipher.final(settings.plainEncoding));

    decodedToken = unserialize(decodedToken);
    return decodedToken;
}

function createToken(settings, userId, data, callback) {
    enrich_settings(settings, function(err, settings){
        if(err){
            callback(err);
        } else {

            var expiresAtTimestamp = new Date().getTime() + settings.tokenExpirationMinutes*60*1000;
            data = data || {};

            var firm = firmToken(settings, userId, expiresAtTimestamp, data);
            var cipher = crypto.createCipher(settings.cipherAlgorithm, settings.cipherKey);

            var tokenSet = {
                'userId': userId,
                'expiresAtTimestamp': expiresAtTimestamp,
                'data': data,
                'firm': firm
            };
            if (settings.enableSessionId) {
                tokenSet.sessionId = userId + '-' + crypto.pseudoRandomBytes(12).toString('hex');
            }
            var encodedData = cipher.update(serialize(tokenSet), settings.plainEncoding, settings.tokenEncoding);

            callback(null, standarizeToken(encodedData + cipher.final(settings.tokenEncoding)));
        }
    });

};

function getTokenSet(settings, cipheredToken, callback){
    enrich_settings(settings, function(err, settings){
        if (err) {
            callback(err);

        } else {
            var tokenSet = {};

            var token = decipherToken(settings, cipheredToken);
            if (!token){
                return callback(ERRORS.badToken);
            } else if(!checkTokenFirm(settings, cipheredToken)){
                return callback(ERRORS.badFirm);
            } else {
                tokenSet = {
                    userId : token.userId,
                    expiresAtTimestamp : token.expiresAtTimestamp,
                    data: token.data
                };
                if (settings.enableSessionId) {
                    tokenSet.sessionId = token.sessionId
                }
            }
            callback(null, tokenSet);
        }
    });
};

module.exports = {
    createToken: createToken,
    getTokenSet: getTokenSet
};
<|endoftext|>


<commit_before>var EMPTY = '';

function Scope(parent) {
	Watcher.call(this);

	if(parent) {
		this.parentScope = parent;
	}

	this.childScopes = [];
}

inherits(Scope, Watcher, {
  watch: function(exp, listener) {
    var normalWatcher = bind(Watcher.prototype.watch, this);

    if(Scope.isComplexExpression(exp)) {
      var finder = Scope.extractExpressions(exp),
      identifiers = finder.identifiers,
      exps = finder.allExps.map(function(exp) {
        return exp.join('.');
      });

      var oldValue;

      return this.watchGroup(exps.concat(identifiers), function() {
        var value = this.eval(exp);

        listener.call(this, value, oldValue);

        oldValue = clone(value);
      });
    } else {
      return normalWatcher(exp, listener);
    }
  },

  eval: function(exp) {
    return isFunction(exp) ? exp(this) : renderer.parse(exp)(this);
  },

	clone: function(isolate, parent) {
		var child;

		parent = parent || this;

		if(isolate) {
			child = new Scope(parent);
		} else {
			// Only create a child scope class if somebody asks for one,
			// but cache it to allow the VM to optimize lookups.
			if (!this.ChildScopeClass) {
				this.ChildScopeClass = Scope.createChildScopeClass(this);
			}

			child = new this.ChildScopeClass();
		}

    var childScopeIndex = this.childScopes.length;

		this.childScopes[childScopeIndex] = child;

    child.on('destroy', function() {
      this.parentScope.childScopes.splice(childScopeIndex, 1);
    });

		return child;
	},

  broadcast: function(name, fn) {
    if(this.parentScope) {
      this.parentScope.broadcast(name, fn);
    }

    this.emit(name, fn);
  },

	deliverChangeRecords: function() {
    if(this.parentScope) {
      this.parentScope.deliverChangeRecords();
    }

    Watcher.prototype.deliverChangeRecords.call(this);

		return this;
	},

  apply: function(fn) {
    var topLevelScope = this.topLevelScope;

    try {
      Scope.beginPhase(topLevelScope, 'apply');

      try {
        return this.eval(fn);
      } finally {
        Scope.clearPhase(topLevelScope);
      }
    } catch (e) {
      throw e;
    } finally {
      try {
        this.deliverChangeRecords();
      } catch(e) {
        throw e;
      }
    }

    return this;
  },

  destroy: function() {
    this.emit('destroy');
  }
}, {
  extractExpressions: function(exps) {
    var lexer = new Lexer(),
        astBuilder = new AST(lexer),
        astFinder = new ASTFinder(astBuilder);

    return astFinder.find(exps) && astFinder;
  },

  isComplexExpression: function(exp) {
    var i,
        token,
        tokens = this.complexTokens.split(EMPTY);

    for(i = tokens.length - 1; i >= 0; i--) {
      token = tokens[i];

      if(exp.indexOf(token) > -1) {
        return true;
      }
    }

    return false;
  },

  createChildScopeClass: function(parent) {
    function ChildScope() {
      Scope.call(this, parent);
    }

    ChildScope.prototype = parent;

    return ChildScope;
  },

  complexTokens: '[]()&!`/*+-='
});
<commit_msg>chore(src/Scope.js): Removed the pre definition of an variable that we do not have certainty that we are going to use until the `if()` statement. So we just put the entire Watcher prototype call on the `else()`<commit_after>var EMPTY = '';

function Scope(parent) {
	Watcher.call(this);

	if(parent) {
		this.parentScope = parent;
	}

	this.childScopes = [];
}

inherits(Scope, Watcher, {
  watch: function(exp, listener) {
    if(Scope.isComplexExpression(exp)) {
      var finder = Scope.extractExpressions(exp),
      identifiers = finder.identifiers,
      exps = finder.allExps.map(function(exp) {
        return exp.join('.');
      });

      var oldValue;

      return this.watchGroup(exps.concat(identifiers), function() {
        var value = this.eval(exp);

        listener.call(this, value, oldValue);

        oldValue = clone(value);
      });
    } else {
      return Watcher.prototype.watch.call(this, exp, listener);
    }
  },

  eval: function(exp) {
    return isFunction(exp) ? exp(this) : renderer.parse(exp)(this);
  },

	clone: function(isolate, parent) {
		var child;

		parent = parent || this;

		if(isolate) {
			child = new Scope(parent);
		} else {
			// Only create a child scope class if somebody asks for one,
			// but cache it to allow the VM to optimize lookups.
			if (!this.ChildScopeClass) {
				this.ChildScopeClass = Scope.createChildScopeClass(this);
			}

			child = new this.ChildScopeClass();
		}

    var childScopeIndex = this.childScopes.length;

		this.childScopes[childScopeIndex] = child;

    child.on('destroy', function() {
      this.parentScope.childScopes.splice(childScopeIndex, 1);
    });

		return child;
	},

  broadcast: function(name, fn) {
    if(this.parentScope) {
      this.parentScope.broadcast(name, fn);
    }

    this.emit(name, fn);
  },

	deliverChangeRecords: function() {
    if(this.parentScope) {
      this.parentScope.deliverChangeRecords();
    }

    Watcher.prototype.deliverChangeRecords.call(this);

		return this;
	},

  apply: function(fn) {
    var topLevelScope = this.topLevelScope;

    try {
      Scope.beginPhase(topLevelScope, 'apply');

      try {
        return this.eval(fn);
      } finally {
        Scope.clearPhase(topLevelScope);
      }
    } catch (e) {
      throw e;
    } finally {
      try {
        this.deliverChangeRecords();
      } catch(e) {
        throw e;
      }
    }

    return this;
  },

  destroy: function() {
    this.emit('destroy');
  }
}, {
  extractExpressions: function(exps) {
    var lexer = new Lexer(),
        astBuilder = new AST(lexer),
        astFinder = new ASTFinder(astBuilder);

    return astFinder.find(exps) && astFinder;
  },

  isComplexExpression: function(exp) {
    var i,
        token,
        tokens = this.complexTokens.split(EMPTY);

    for(i = tokens.length - 1; i >= 0; i--) {
      token = tokens[i];

      if(exp.indexOf(token) > -1) {
        return true;
      }
    }

    return false;
  },

  createChildScopeClass: function(parent) {
    function ChildScope() {
      Scope.call(this, parent);
    }

    ChildScope.prototype = parent;

    return ChildScope;
  },

  complexTokens: '[]()&!`/*+-='
});
<|endoftext|>