<commit_before>require.paths.push("./lib");
require.paths.push(__dirname);
var fs       = require('fs'),
    spawn    = require('child_process').spawn,
    mustache = require('mustache'),
    callback = require('callback'),
    Showdown = require('showdown').Showdown;

var documentation = {
    pages:[],
    byName: {}
};
var keywordPages = [];

var SRC_DIR = "docs/";
var OUTPUT_DIR = "build/docs/";
var NEW_LINE = /\n\r?/;

var work = callback.chain(function () {
  console.log('Parsing Angular Reference Documentation');
  mkdirPath(OUTPUT_DIR, work.waitFor(function(){
    findJsFiles('src', work.waitMany(function(file) {
      //console.log('reading', file, '...');
      findNgDoc(file, work.waitMany(function(doc) {
        parseNgDoc(doc);
        processNgDoc(documentation, doc);
      }));
    }));
  }));
}).onError(function(err){
  console.log('ERROR:', err.stack || err);
}).onDone(function(){
  keywordPages.sort(function(a,b){ return a.name == b.name ? 0:(a.name < b.name ? -1 : 1);});
  writeDoc(documentation.pages);
  mergeTemplate('docs-data.js', 'docs-data.js', {JSON:JSON.stringify(keywordPages)}, callback.chain());
  mergeTemplate('docs-scenario.js', 'docs-scenario.js', documentation, callback.chain());
  copy('docs-scenario.html', callback.chain());
  copy('index.html', callback.chain());
  copy('docs.css', callback.chain());
  mergeTemplate('docs.js', 'docs.js', documentation, callback.chain());
  mergeTemplate('doc_widgets.css', 'doc_widgets.css', documentation, callback.chain());
  mergeTemplate('doc_widgets.js', 'doc_widgets.js', documentation, callback.chain());
  console.log('DONE');
});
if (!this.testmode) work();
////////////////////

function keywords(text){
  var keywords = {};
  var words = [];
  var tokens = text.toLowerCase().split(/[,\.\`\'\"\s]+/mg);
  tokens.forEach(function(key){
    var match = key.match(/^(([a-z]|ng\:)[\w\_\-]{2,})/);
    if (match){
      key = match[1];
      if (!keywords[key]) {
        keywords[key] = true;
        words.push(key);
      }
    }
  });
  words.sort();
  return words.join(' ');
}

function noop(){}
function mkdirPath(path, callback) {
  var parts = path.split(/\//);
  path = '.';
  (function next(){
    if (parts.length) {
      path += '/' + parts.shift();
      fs.mkdir(path, 0777, next);
    } else {
      callback();
    }
  })();
}

function copy(name, callback){
  fs.readFile(SRC_DIR + name, callback.waitFor(function(err, content){
    if (err) return this.error(err);
    fs.writeFile(OUTPUT_DIR + name, content, callback);
  }));
}

function mergeTemplate(template, output, doc, callback){
  fs.readFile(SRC_DIR + template,
    callback.waitFor(function(err, template){
      if (err) return this.error(err);
      var content = mustache.to_html(template.toString(), doc);
      fs.writeFile(OUTPUT_DIR + output, content, callback);
    }));
}

function trim(text) {
  var MAX = 9999;
  var empty = RegExp.prototype.test.bind(/^\s*$/);
  var lines = text.split('\n');
  var minIndent = MAX;
  lines.forEach(function(line){
    minIndent = Math.min(minIndent, indent(line));
  });
  for ( var i = 0; i < lines.length; i++) {
    lines[i] = lines[i].substring(minIndent);
  }
  // remove leading lines
  while (empty(lines[0])) {
    lines.shift();
  }
  // remove trailing
  while (empty(lines[lines.length - 1])) {
    lines.pop();
  }
  return lines.join('\n');

  function indent(line) {
    for(var i = 0; i < line.length; i++) {
      if (line.charAt(i) != ' ')  {
        return i;
      }
    }
    return MAX;
  }
}

function unknownTag(doc, name) {
  var error = "[" + doc.raw.file + ":" + doc.raw.line + "]: unknown tag: " + name;
  console.log(error);
  throw new Error(error);
}

function valueTag(doc, name, value) {
  doc[name] = value;
}

function escapedHtmlTag(doc, name, value) {
  doc[name] = value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
}

function markdownTag(doc, name, value) {
  doc[name] = markdown(value.replace(/^#/gm, '##')).
    replace(/\
/gmi, '

').
    replace(/\<\/pre\>/gmi, '

');
}

function markdown(text) {
  var parts = text.split(/(
[\s\S]*<\/pre>)/);
  parts.forEach(function(text, i){
    if (!text.match(/^
/)) {
      text = text.replace(/<angular\/>/gm, '<tt><angular/></tt>');
      text = new Showdown.converter().makeHtml(text);
      text = text.replace(/(angular\.[\$\w\._\-:]+)/gm, '$1');
      text = text.replace(/(`(ng:[\w\._\-]+)`)/gm, '$1');
      parts[i] = text;
    }
  });
  return parts.join('');
}

function markdownNoP(text) {
  var lines = markdown(text).split(NEW_LINE);
  var last = lines.length - 1;
  lines[0] = lines[0].replace(/^
/, '');
  lines[last] = lines[last].replace(/<\/p>$/, '');
  return lines.join('\n');
}

function requiresTag(doc, name, value) {
  doc.requires = doc.requires || [];
  doc.requires.push({name: value});
}

function propertyTag(doc, name, value) {
  doc[name] = doc[name] || [];
  var match = value.match(/^({(\S+)}\s*)?(\S+)(\s+(.*))?/);

  if (match) {
    var tag = {
      type: match[2],
      name: match[3],
      description: match[5] || false
    };
  } else {
    throw "[" + doc.raw.file + ":" + doc.raw.line +
          "]: @" + name + " must be in format '{type} name description' got: " + value;
  }
  return doc[name].push(tag);
}

function returnsTag(doc, name, value) {
  var match = value.match(/^({(\S+)}\s*)?(.*)?/);

  if (match) {
    var tag = {
      type: match[2],
      description: match[3] || false
    };
  } else {
    throw "[" + doc.raw.file + ":" + doc.raw.line +
          "]: @" + name + " must be in format '{type} description' got: " + value;
  }
  return doc[name] = tag;
}

var TAG = {
  ngdoc: valueTag,
  example: escapedHtmlTag,
  scenario: valueTag,
  namespace: valueTag,
  css: valueTag,
  see: valueTag,
  usageContent: valueTag,
  'function': valueTag,
  description: markdownTag,
  TODO: markdownTag,
  returns: markdownTag,
  paramDescription: markdownTag,
  exampleDescription: markdownTag,
  element: valueTag,
  methodOf: valueTag,
  name: function(doc, name, value) {
    doc.name = value;
    doc.shortName  = value.split(/\./).pop();
    doc.depth = value.split(/\./).length - 1;
  },
  param: function(doc, name, value){
    doc.param = doc.param || [];
    doc.paramRest = doc.paramRest || [];
    var match = value.match(/^({([^\s=]+)(=)?}\s*)?(([^\s=]+)|\[(\S+)+=([^\]]+)\])\s+(.*)/);
    if (match) {
      var param = {
          type: match[2],
          name: match[6] || match[5],
          'default':match[7],
          description:markdownNoP(value.replace(match[0], match[8]))
        };
      doc.param.push(param);
      if (!doc.paramFirst) {
        doc.paramFirst = param;
      } else {
        doc.paramRest.push(param);
      }
    } else {
      throw "[" + doc.raw.file + ":" + doc.raw.line +
            "]: @param must be in format '{type} name=value description' got: " + value;
    }
  },
  property: propertyTag,
  requires: requiresTag,
  returns: returnsTag
};

function parseNgDoc(doc){
  var atName;
  var atText;
  var match;
  doc.raw.text.split(NEW_LINE).forEach(function(line, lineNumber){
    if (match = line.match(/^\s*@(\w+)(\s+(.*))?/)) {
      // we found @name ...
      // if we have existing name
      if (atName) {
        (TAG[atName] || unknownTag)(doc, atName, trim(atText.join('\n')));
      }
      atName = match[1];
      atText = [];
      if(match[3]) atText.push(match[3]);
    } else {
      if (atName) {
        atText.push(line);
      } else {
        // ignore
      }
    }
  });
  if (atName) {
    (TAG[atName] || unknownTag)(doc, atName, atText.join('\n'));
  }
}

function findNgDoc(file, callback) {
  fs.readFile(file, callback.waitFor(function(err, content){
    var lines = content.toString().split(NEW_LINE);
    var doc;
    var match;
    var inDoc = false;
    lines.forEach(function(line, lineNumber){
      lineNumber++;
      // is the comment starting?
      if (!inDoc && (match = line.match(/^\s*\/\*\*\s*(.*)$/))) {
        line = match[1];
        inDoc = true;
        doc = {raw:{file:file, line:lineNumber, text:[]}};
      }
      // are we done?
      if (inDoc && line.match(/\*\//)) {
        doc.raw.text = doc.raw.text.join('\n');
        doc.raw.text = doc.raw.text.replace(/^\n/, '');
        if (doc.raw.text.match(/@ngdoc/)){
          callback(doc);
        }
        doc = null;
        inDoc = false;
      }
      // is the comment add text
      if (inDoc){
        doc.raw.text.push(line.replace(/^\s*\*\s?/, ''));
      }
    });
    callback.done();
  }));
}

function findJsFiles(dir, callback){
  fs.readdir(dir, callback.waitFor(function(err, files){
    if (err) return this.error(err);
    files.forEach(function(file){
      var path = dir + '/' + file;
      fs.lstat(path, callback.waitFor(function(err, stat){
        if (err) return this.error(err);
        if (stat.isDirectory())
          findJsFiles(path, callback.waitMany(callback));
        else if (/\.js$/.test(path))
          callback(path);
      }));
    });
    callback.done();
  }));
}

function processNgDoc(documentation, doc) {
  if (!doc.ngdoc) return;
  console.log('Found:', doc.ngdoc + ':' + doc.name);

  documentation.byName[doc.name] = doc;

  if (doc.methodOf) {
    if (parent = documentation.byName[doc.methodOf]) {
      (parent.method = parent.method || []).push(doc);
    } else {
      throw 'Owner "' + doc.methodOf + '" is not defined.';
    }
  } else {
    documentation.pages.push(doc);
    keywordPages.push({
      name:doc.name,
      keywords:keywords(doc.raw.text)
    });
  }
}

function writeDoc(pages) {
  pages.forEach(function(doc) {
    mergeTemplate(
        doc.ngdoc + '.template',
        doc.name + '.html', doc, callback.chain());
  });
}
<commit_msg>fix regexp for @param parsing in ng:docs<commit_after>require.paths.push("./lib");
require.paths.push(__dirname);
var fs       = require('fs'),
    spawn    = require('child_process').spawn,
    mustache = require('mustache'),
    callback = require('callback'),
    Showdown = require('showdown').Showdown;

var documentation = {
    pages:[],
    byName: {}
};
var keywordPages = [];

var SRC_DIR = "docs/";
var OUTPUT_DIR = "build/docs/";
var NEW_LINE = /\n\r?/;

var work = callback.chain(function () {
  console.log('Parsing Angular Reference Documentation');
  mkdirPath(OUTPUT_DIR, work.waitFor(function(){
    findJsFiles('src', work.waitMany(function(file) {
      //console.log('reading', file, '...');
      findNgDoc(file, work.waitMany(function(doc) {
        parseNgDoc(doc);
        processNgDoc(documentation, doc);
      }));
    }));
  }));
}).onError(function(err){
  console.log('ERROR:', err.stack || err);
}).onDone(function(){
  keywordPages.sort(function(a,b){ return a.name == b.name ? 0:(a.name < b.name ? -1 : 1);});
  writeDoc(documentation.pages);
  mergeTemplate('docs-data.js', 'docs-data.js', {JSON:JSON.stringify(keywordPages)}, callback.chain());
  mergeTemplate('docs-scenario.js', 'docs-scenario.js', documentation, callback.chain());
  copy('docs-scenario.html', callback.chain());
  copy('index.html', callback.chain());
  copy('docs.css', callback.chain());
  mergeTemplate('docs.js', 'docs.js', documentation, callback.chain());
  mergeTemplate('doc_widgets.css', 'doc_widgets.css', documentation, callback.chain());
  mergeTemplate('doc_widgets.js', 'doc_widgets.js', documentation, callback.chain());
  console.log('DONE');
});
if (!this.testmode) work();
////////////////////

function keywords(text){
  var keywords = {};
  var words = [];
  var tokens = text.toLowerCase().split(/[,\.\`\'\"\s]+/mg);
  tokens.forEach(function(key){
    var match = key.match(/^(([a-z]|ng\:)[\w\_\-]{2,})/);
    if (match){
      key = match[1];
      if (!keywords[key]) {
        keywords[key] = true;
        words.push(key);
      }
    }
  });
  words.sort();
  return words.join(' ');
}

function noop(){}
function mkdirPath(path, callback) {
  var parts = path.split(/\//);
  path = '.';
  (function next(){
    if (parts.length) {
      path += '/' + parts.shift();
      fs.mkdir(path, 0777, next);
    } else {
      callback();
    }
  })();
}

function copy(name, callback){
  fs.readFile(SRC_DIR + name, callback.waitFor(function(err, content){
    if (err) return this.error(err);
    fs.writeFile(OUTPUT_DIR + name, content, callback);
  }));
}

function mergeTemplate(template, output, doc, callback){
  fs.readFile(SRC_DIR + template,
    callback.waitFor(function(err, template){
      if (err) return this.error(err);
      var content = mustache.to_html(template.toString(), doc);
      fs.writeFile(OUTPUT_DIR + output, content, callback);
    }));
}

function trim(text) {
  var MAX = 9999;
  var empty = RegExp.prototype.test.bind(/^\s*$/);
  var lines = text.split('\n');
  var minIndent = MAX;
  lines.forEach(function(line){
    minIndent = Math.min(minIndent, indent(line));
  });
  for ( var i = 0; i < lines.length; i++) {
    lines[i] = lines[i].substring(minIndent);
  }
  // remove leading lines
  while (empty(lines[0])) {
    lines.shift();
  }
  // remove trailing
  while (empty(lines[lines.length - 1])) {
    lines.pop();
  }
  return lines.join('\n');

  function indent(line) {
    for(var i = 0; i < line.length; i++) {
      if (line.charAt(i) != ' ')  {
        return i;
      }
    }
    return MAX;
  }
}

function unknownTag(doc, name) {
  var error = "[" + doc.raw.file + ":" + doc.raw.line + "]: unknown tag: " + name;
  console.log(error);
  throw new Error(error);
}

function valueTag(doc, name, value) {
  doc[name] = value;
}

function escapedHtmlTag(doc, name, value) {
  doc[name] = value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
}

function markdownTag(doc, name, value) {
  doc[name] = markdown(value.replace(/^#/gm, '##')).
    replace(/\
/gmi, '

').
    replace(/\<\/pre\>/gmi, '

');
}

function markdown(text) {
  var parts = text.split(/(
[\s\S]*<\/pre>)/);
  parts.forEach(function(text, i){
    if (!text.match(/^
/)) {
      text = text.replace(/<angular\/>/gm, '<tt><angular/></tt>');
      text = new Showdown.converter().makeHtml(text);
      text = text.replace(/(angular\.[\$\w\._\-:]+)/gm, '$1');
      text = text.replace(/(`(ng:[\w\._\-]+)`)/gm, '$1');
      parts[i] = text;
    }
  });
  return parts.join('');
}

function markdownNoP(text) {
  var lines = markdown(text).split(NEW_LINE);
  var last = lines.length - 1;
  lines[0] = lines[0].replace(/^
/, '');
  lines[last] = lines[last].replace(/<\/p>$/, '');
  return lines.join('\n');
}

function requiresTag(doc, name, value) {
  doc.requires = doc.requires || [];
  doc.requires.push({name: value});
}

function propertyTag(doc, name, value) {
  doc[name] = doc[name] || [];
  var match = value.match(/^({(\S+)}\s*)?(\S+)(\s+(.*))?/);

  if (match) {
    var tag = {
      type: match[2],
      name: match[3],
      description: match[5] || false
    };
  } else {
    throw "[" + doc.raw.file + ":" + doc.raw.line +
          "]: @" + name + " must be in format '{type} name description' got: " + value;
  }
  return doc[name].push(tag);
}

function returnsTag(doc, name, value) {
  var match = value.match(/^({(\S+)}\s*)?(.*)?/);

  if (match) {
    var tag = {
      type: match[2],
      description: match[3] || false
    };
  } else {
    throw "[" + doc.raw.file + ":" + doc.raw.line +
          "]: @" + name + " must be in format '{type} description' got: " + value;
  }
  return doc[name] = tag;
}

var TAG = {
  ngdoc: valueTag,
  example: escapedHtmlTag,
  scenario: valueTag,
  namespace: valueTag,
  css: valueTag,
  see: valueTag,
  usageContent: valueTag,
  'function': valueTag,
  description: markdownTag,
  TODO: markdownTag,
  returns: markdownTag,
  paramDescription: markdownTag,
  exampleDescription: markdownTag,
  element: valueTag,
  methodOf: valueTag,
  name: function(doc, name, value) {
    doc.name = value;
    doc.shortName  = value.split(/\./).pop();
    doc.depth = value.split(/\./).length - 1;
  },
  param: function(doc, name, value){
    doc.param = doc.param || [];
    doc.paramRest = doc.paramRest || [];
    var match = value.match(/^({([^\s=]+)(=)?}\s*)?(([^\s=]+)|\[(\S+)=([^\]]+)\])\s+(.*)/);
                           // 1 2       23 3     1 45       5   6   6 7      7  4   8  8
    if (match) {
      var param = {
          type: match[2],
          name: match[6] || match[5],
          'default':match[7],
          description:markdownNoP(value.replace(match[0], match[8]))
        };
      doc.param.push(param);
      if (!doc.paramFirst) {
        doc.paramFirst = param;
      } else {
        doc.paramRest.push(param);
      }
    } else {
      throw "[" + doc.raw.file + ":" + doc.raw.line +
            "]: @param must be in format '{type} name=value description' got: " + value;
    }
  },
  property: propertyTag,
  requires: requiresTag,
  returns: returnsTag
};

function parseNgDoc(doc){
  var atName;
  var atText;
  var match;
  doc.raw.text.split(NEW_LINE).forEach(function(line, lineNumber){
    if (match = line.match(/^\s*@(\w+)(\s+(.*))?/)) {
      // we found @name ...
      // if we have existing name
      if (atName) {
        (TAG[atName] || unknownTag)(doc, atName, trim(atText.join('\n')));
      }
      atName = match[1];
      atText = [];
      if(match[3]) atText.push(match[3]);
    } else {
      if (atName) {
        atText.push(line);
      } else {
        // ignore
      }
    }
  });
  if (atName) {
    (TAG[atName] || unknownTag)(doc, atName, atText.join('\n'));
  }
}

function findNgDoc(file, callback) {
  fs.readFile(file, callback.waitFor(function(err, content){
    var lines = content.toString().split(NEW_LINE);
    var doc;
    var match;
    var inDoc = false;
    lines.forEach(function(line, lineNumber){
      lineNumber++;
      // is the comment starting?
      if (!inDoc && (match = line.match(/^\s*\/\*\*\s*(.*)$/))) {
        line = match[1];
        inDoc = true;
        doc = {raw:{file:file, line:lineNumber, text:[]}};
      }
      // are we done?
      if (inDoc && line.match(/\*\//)) {
        doc.raw.text = doc.raw.text.join('\n');
        doc.raw.text = doc.raw.text.replace(/^\n/, '');
        if (doc.raw.text.match(/@ngdoc/)){
          callback(doc);
        }
        doc = null;
        inDoc = false;
      }
      // is the comment add text
      if (inDoc){
        doc.raw.text.push(line.replace(/^\s*\*\s?/, ''));
      }
    });
    callback.done();
  }));
}

function findJsFiles(dir, callback){
  fs.readdir(dir, callback.waitFor(function(err, files){
    if (err) return this.error(err);
    files.forEach(function(file){
      var path = dir + '/' + file;
      fs.lstat(path, callback.waitFor(function(err, stat){
        if (err) return this.error(err);
        if (stat.isDirectory())
          findJsFiles(path, callback.waitMany(callback));
        else if (/\.js$/.test(path))
          callback(path);
      }));
    });
    callback.done();
  }));
}

function processNgDoc(documentation, doc) {
  if (!doc.ngdoc) return;
  console.log('Found:', doc.ngdoc + ':' + doc.name);

  documentation.byName[doc.name] = doc;

  if (doc.methodOf) {
    if (parent = documentation.byName[doc.methodOf]) {
      (parent.method = parent.method || []).push(doc);
    } else {
      throw 'Owner "' + doc.methodOf + '" is not defined.';
    }
  } else {
    documentation.pages.push(doc);
    keywordPages.push({
      name:doc.name,
      keywords:keywords(doc.raw.text)
    });
  }
}

function writeDoc(pages) {
  pages.forEach(function(doc) {
    mergeTemplate(
        doc.ngdoc + '.template',
        doc.name + '.html', doc, callback.chain());
  });
}
<|endoftext|>


<commit_before>var fc = require('fc');
var v3normalize = require('gl-vec3/normalize');
var v3sub = require('gl-vec3/subtract');
var v3dist = require('gl-vec3/distance');
var m4create = require('gl-mat4/create');
var m4perspective = require('gl-mat4/perspective');
var m4invert = require('gl-mat4/invert');
var m4mutiply = require('gl-mat4/multiply');
var createRay = require('../ray-aabb');
var ndarray = require('ndarray');
var fill = require('ndarray-fill');
var unproject = require('camera-unproject');

var createOrbitCamera = require("orbit-camera")

var camera = createOrbitCamera([5, 5, -10],
                               [0, 0, 0],
                               [0, 1, 0])
var projection = m4create();
var view = m4create();
var m4inverted = m4create();
var m4scratch = m4create();
var box = [[0, 0], [0, 0]];
var mouse = [0, 0];
var mouseDown = false;

var rayOrigin = [0, 0, 0];
var rayDirection = [0, 0, 0];

var ray = createRay(rayOrigin, rayDirection);
var model = ndarray(new Uint8Array(16*16*16), [16, 16, 16]);

fill(model, function(x, y, z) {
  var dx = 8 - x;
  var dy = 8 - y;
  var dz = 8 - z;
  var d = Math.sqrt(dx*dx + dy*dy + dz*dz);
  if (d < 4) {
    return 255;
  }
  return 0;
})

function getEye(out, view) {
  m4invert(m4scratch, view);
  out[0] = m4scratch[12];
  out[1] = m4scratch[13];
  out[2] = m4scratch[14]
  return out;
}

window.addEventListener('mousedown', function() {
  mouseDown = true;
});

window.addEventListener('mouseup', function() {
  mouseDown = false;
});

window.addEventListener('mousemove', function(ev) {
  var x = ev.clientX;
  var y = ev.clientY;

  if (mouseDown) {
    var w = ctx.canvas.width;
    var h = ctx.canvas.height;
    camera.rotate(
      [x/w-0.5, y/h-0.5],
      [mouse[0]/w-0.5, mouse[1]/h-0.5]
    );
    ctx.dirty();
  }
  mouse[0] = x;
  mouse[1] = y;

});

window.addEventListener('mousewheel', function(ev) {
  camera.zoom(ev.wheelDeltaY * -.001);
  ctx.dirty();
  ev.preventDefault();
});

var viewport = [0, 0, 0, 0];
var near = [0, 0, 0];

var ctx = fc(function() {
  ctx.clear();
  var w = viewport[2] = ctx.canvas.width;
  var h = viewport[3] = ctx.canvas.height;
  var aspect = w/h
  m4perspective(
    projection,
    Math.PI/4.0,
    aspect,
    0.1,
    1000.0
  )

  camera.view(view)

  m4invert(
    m4inverted,
    m4mutiply(m4inverted, projection, view)
  );

  var step = 5;
  var halfstep = (step/2)|0;
  getEye(rayOrigin, view);

  for (var x = 0; x<w; x+=step) {
    near[0] = x;
    for (var y=0; y<h; y+=step) {
      near[1] = y;

      unproject(rayDirection, near, viewport, m4inverted)

      v3normalize(
        rayDirection,
        v3sub(rayDirection, rayDirection, rayOrigin)
      );

      ray.update(rayOrigin, rayDirection);

      var d = ray.intersects([
        [-1, -1, -1],
        [1, 1, 1]
      ], true)
      if (d !== false) {
        ctx.fillStyle = "green";
      } else {
        ctx.fillStyle = "red"
      }

      ctx.fillRect(2+x-halfstep, 2+y-halfstep, step-2, step-2)
    }
  }
})
<commit_msg>use a buffer instead of filling rects<commit_after>var fc = require('fc');
var v3normalize = require('gl-vec3/normalize');
var v3sub = require('gl-vec3/subtract');
var v3dist = require('gl-vec3/distance');
var m4create = require('gl-mat4/create');
var m4perspective = require('gl-mat4/perspective');
var m4invert = require('gl-mat4/invert');
var m4mutiply = require('gl-mat4/multiply');
var createRay = require('../ray-aabb');
var ndarray = require('ndarray');
var fill = require('ndarray-fill');
var unproject = require('camera-unproject');

var createOrbitCamera = require("orbit-camera")

var camera = createOrbitCamera([5, 5, -10],
                               [0, 0, 0],
                               [0, 1, 0])
var projection = m4create();
var view = m4create();
var m4inverted = m4create();
var m4scratch = m4create();
var box = [[0, 0], [0, 0]];
var mouse = [0, 0];
var mouseDown = false;

var rayOrigin = [0, 0, 0];
var rayDirection = [0, 0, 0];

var ray = createRay(rayOrigin, rayDirection);
var model = ndarray(new Uint8Array(16*16*16), [16, 16, 16]);

fill(model, function(x, y, z) {
  var dx = 8 - x;
  var dy = 8 - y;
  var dz = 8 - z;
  var d = Math.sqrt(dx*dx + dy*dy + dz*dz);
  if (d < 4) {
    return 255;
  }
  return 0;
})

function getEye(out, view) {
  m4invert(m4scratch, view);
  out[0] = m4scratch[12];
  out[1] = m4scratch[13];
  out[2] = m4scratch[14]
  return out;
}

window.addEventListener('mousedown', function() {
  mouseDown = true;
});

window.addEventListener('mouseup', function() {
  mouseDown = false;
});

window.addEventListener('mousemove', function(ev) {
  var x = ev.clientX;
  var y = ev.clientY;

  if (mouseDown) {
    var w = ctx.canvas.width;
    var h = ctx.canvas.height;
    camera.rotate(
      [x/w-0.5, y/h-0.5],
      [mouse[0]/w-0.5, mouse[1]/h-0.5]
    );
    ctx.dirty();
  }
  mouse[0] = x;
  mouse[1] = y;

});

window.addEventListener('mousewheel', function(ev) {
  camera.zoom(ev.wheelDeltaY * -.001);
  ctx.dirty();
  ev.preventDefault();
});

var viewport = [0, 0, 0, 0];
var near = [0, 0, 0];

var ctx = fc(function() {
  ctx.clear();
  var w = viewport[2] = ctx.canvas.width;
  var h = viewport[3] = ctx.canvas.height;
  var imageData = ctx.createImageData(w, h);
  var buffer = imageData.data;

  var aspect = w/h
  m4perspective(
    projection,
    Math.PI/4.0,
    aspect,
    0.1,
    1000.0
  )

  camera.view(view)

  m4invert(
    m4inverted,
    m4mutiply(m4inverted, projection, view)
  );
  var step = 1;
  getEye(rayOrigin, view);
  for (var y=0; y<h; y+=step) {
    near[1] = y;

    for (var x = 0; x<w; x+=step) {
      near[0] = x;

      unproject(rayDirection, near, viewport, m4inverted)

      v3normalize(
        rayDirection,
        v3sub(rayDirection, rayDirection, rayOrigin)
      );

      ray.update(rayOrigin, rayDirection);

      var d = ray.intersects([
        [-1, -1, -1],
        [1, 1, 1]
      ], true)

      var c = x*4 + y*w*4;

      if (d !== false) {
        buffer[c+1] = 255;
        buffer[c+3] = 255;
      } else {
        buffer[c+0] = 0x11;
        buffer[c+1] = 0x11;
        buffer[c+2] = 0x22;
        buffer[c+3] = 0xff;
      }
    }
  }

  ctx.putImageData(imageData, 0, 0);
})
<|endoftext|>


<commit_before>'use strict';

Connector.playerSelector = '#d-content';
Connector.albumSelector = '#d-info-text .d-sub-text-2';
Connector.remainingTimeSelector = '.d-np-time-display.remaining-time';
Connector.currentTimeSelector = '.d-np-time-display.elapsed-time';

Connector.getDuration = () => {
	let elapsed = Util.stringToSeconds($(Connector.currentTimeSelector).text());
	let remaining = -Util.stringToSeconds($(Connector.remainingTimeSelector).text());
	return (remaining + elapsed);
};

Connector.getRemainingTime = () => {
	let remaining = -Util.stringToSeconds($(Connector.remainingTimeSelector).text());
	return remaining;
};

Connector.getArtistTrack = () => {
	if (isPlayingLiveRadio()) {
		let songTitle = $('.d-queue-info .song-title').text();
		return Util.splitArtistTrack(songTitle);
	}

	let artist = $('#d-info-text .d-sub-text-1').text();
	let track = $('#d-info-text .d-main-text').text();
	return { artist, track };
};

Connector.isPlaying = () => {
	let duration = Connector.getDuration();

	// The app doesn't update the remaining and elapsed times straight away when changing songs. The remaining time rolls over and starts counting down from an hour.
	// This is a workaround to avoid detecting an incorrect duration time.
	if (duration > 3600) {
		return false;
	}

	return $('#d-primary-control .play').size() === 0;
};

function isPlayingLiveRadio() {
	return $('#d-secondary-control-left .disabled').size() === 1 &&
		$('#d-secondary-control-right .disabled').size() === 1;
}
<commit_msg>Replace size func calls with length prop<commit_after>'use strict';

Connector.playerSelector = '#d-content';
Connector.albumSelector = '#d-info-text .d-sub-text-2';
Connector.remainingTimeSelector = '.d-np-time-display.remaining-time';
Connector.currentTimeSelector = '.d-np-time-display.elapsed-time';

Connector.getDuration = () => {
	let elapsed = Util.stringToSeconds($(Connector.currentTimeSelector).text());
	let remaining = -Util.stringToSeconds($(Connector.remainingTimeSelector).text());
	return (remaining + elapsed);
};

Connector.getRemainingTime = () => {
	let remaining = -Util.stringToSeconds($(Connector.remainingTimeSelector).text());
	return remaining;
};

Connector.getArtistTrack = () => {
	if (isPlayingLiveRadio()) {
		let songTitle = $('.d-queue-info .song-title').text();
		return Util.splitArtistTrack(songTitle);
	}

	let artist = $('#d-info-text .d-sub-text-1').text();
	let track = $('#d-info-text .d-main-text').text();
	return { artist, track };
};

Connector.isPlaying = () => {
	let duration = Connector.getDuration();

	// The app doesn't update the remaining and elapsed times straight away when changing songs. The remaining time rolls over and starts counting down from an hour.
	// This is a workaround to avoid detecting an incorrect duration time.
	if (duration > 3600) {
		return false;
	}

	return $('#d-primary-control .play').length === 0;
};

function isPlayingLiveRadio() {
	return $('#d-secondary-control-left .disabled').length === 1 &&
		$('#d-secondary-control-right .disabled').length === 1;
}
<|endoftext|>


<commit_before>/**
 * @fileoverview Provides a D3js component to be used to draw an elevation
 * profile chart.
 *
 * Example usage:
 *
 * var selection = d3.select('#element_id');
 * var profile = ngeo.profile({
 *  elevationExtractor: {
 *    z: function (item) {return item['values']['z'];)},
 *    dist: function (item) {return item['dist'];)}
 *  },
 *  hoverCallback: function(point) {
 *    console.log(point.x, point.y);
 *  },
 *  outCallback: function() {
 *    console.log("out");
 *  }});
 * selection.datum(data).call(profile);
 *
 * The selection data must be an array.
 * The layout for the items of this array is unconstrained: the elevation
 * and distance values are extracted using the elevationExtractor config
 * option. Optionally, POIs can be displayed and depend on a poiExtractor
 * config option.
 *
 * The data below will work for the above example:
 * [
 *     {
 *         "y": 199340,
 *         "values": {"z": 788.7},
 *         "dist": 0.0,
 *         "x": 541620
 *     }, ...
 * ]
 */
goog.provide('ngeo.profile');

/**
 *
 * @return {Object}
 * @param {ngeox.profile.ProfileOptions} options
 * @export
 *
 */
ngeo.profile = function(options) {
  /**
   * @type {boolean}
   * Whether the simplified profile should be shown.
   */
  var light = goog.isDef(options.light) ? options.light : false;

  /**
   * The values for margins around the chart defined in pixels.
   */
  var margin = light ? {top: 0, right: 0, bottom: 0, left: 0} :
      {top: 10, right: 20, bottom: 30, left: 40};

  /**
   * Method to get the coordinate in pixels from a distance.
   */
  var bisectDistance = d3.bisector(function(d) {
    return elevationExtractor.dist(d);
  }).left;

  /**
   * Distance units. Either 'm' or 'km'.
   */
  var units;

  /**
   * Factor to determine whether to use 'm' or 'km'.
   */
  var xFactor;

  /**
   * @type {function(Object)}
   * Hover callback function.
   */
  var hoverCallback = goog.isDef(options.hoverCallback) ?
      options.hoverCallback : goog.nullFunction;

  /**
   * @type {function()}
   * Out callback function.
   */
  var outCallback = goog.isDef(options.outCallback) ?
      options.outCallback : goog.nullFunction;

  /**
   * The color to be used for filling the area.
   * Can be overriden using the '.area' CSS selector.
   * @type {string}
   */
  var fill_color = 'rgba(222, 222, 222, 0.5)';

  /**
   * The color to be used the line stroke.
   * Can be overriden using the '.line' CSS selector.
   * @type {string}
   */
  var stroke_color = '#F00';

  /**
   * @type {Object}
   */
  var svg;

  /**
   * D3 x scale.
   */
  var x;

  /**
   * D3 y scale.
   */
  var y;

  /**
   * Elevation data extractor used to get the dist and elevation values.
   */
  var elevationExtractor = options.elevationExtractor;

  /**
   * POI data extractor.
   */
  var poiExtractor = options.poiExtractor;

  /**
   * Optional SVG inline style.
   */
  var styleDefs = options.styleDefs;

  /**
   * @type {number}
   */
  var poiLabelAngle = goog.isDef(options.poiLabelAngle) ?
      options.poiLabelAngle : -60;

  /**
   * @type {ngeox.profile.ProfileFormatter}
   */
  var formatter = goog.isDef(options.formatter) ?
      options.formatter : {
        xhover: function(dist, units) {
          return parseFloat(dist.toPrecision(3)) + ' ' + units;
        },
        yhover: function(ele, units) { return Math.round(ele) + ' m'; },
        xtick: function(dist, units) { return dist; },
        ytick: function(ele, units) { return ele; }
      };

  /**
   * @type {boolean}
   */
  var lightXAxis = goog.isDef(options.lightXAxis) ? options.lightXAxis : false;

  var profile = function(selection) {
    selection.each(function(data) {
      var extractor = elevationExtractor;

      var width = Math.max(this.clientWidth - margin.right - margin.left, 0);
      x = d3.scale.linear().range([0, width]);

      var height = Math.max(this.clientHeight - margin.top - margin.bottom, 0);
      y = d3.scale.linear().range([height, 0]);

      var xAxis = d3.svg.axis().scale(x).orient('bottom');
      var yAxis = d3.svg.axis()
          .scale(y)
          .orient('left');

      var area = d3.svg.area()
          .x(function(d) { return x(extractor.dist(d)); })
          .y0(height)
          .y1(function(d) { return y(extractor.z(d)); });
      var line = d3.svg.line()
          .x(function(d) { return x(extractor.dist(d)); })
          .y(function(d) { return y(extractor.z(d)); });

      // Select the svg element, if it exists.
      svg = d3.select(this).selectAll('svg').data([data]);

      // Otherwise, create the skeletal chart.
      var svgEnter = svg.enter().append('svg');
      if (goog.isDef(styleDefs)) {
        svgEnter.append('defs').append('style')
          .attr('type', 'text/css')
          .text(styleDefs);
      }
      var gEnter = svgEnter.append('g');
      clearPois();

      gEnter.style('font', '11px Arial');
      gEnter.append('path').attr('class', 'area')
          .style('fill', fill_color);
      gEnter.append('path').attr('class', 'line')
          .style('stroke', stroke_color)
          .style('fill', 'none');

      gEnter.insert('g', ':first-child')
          .attr('class', 'grid-y');

      if (!light) {
        gEnter.append('g')
          .attr('class', 'x axis')
          .attr('transform', 'translate(0,' + height + ')');

        gEnter.append('text')
          .attr('class', 'x label')
          .attr('text-anchor', 'end')
          .attr('x', width - 4)
          .attr('y', height - 4);

        gEnter.append('g')
          .attr('class', 'y axis');

        gEnter.append('text')
          .attr('class', 'y label')
          .attr('text-anchor', 'end')
          .attr('y', 6)
          .attr('dy', '.75em')
          .attr('transform', 'rotate(-90)')
          .style('fill', 'grey')
          .text('elevation (m)');

        gEnter.append('g')
          .attr('class', 'metas')
          .attr('transform', 'translate(' + (width + 3) + ', 0)');
      }

      gEnter.append('g').attr('class', 'pois');

      var yHover = gEnter.append('g').attr('class', 'y grid-hover');
      yHover.append('svg:line').attr('stroke-dasharray', '5,5');
      yHover.append('text');

      var xHover = gEnter.append('g').attr('class', 'x grid-hover');
      xHover.append('svg:line').attr('stroke-dasharray', '5,5');
      xHover.append('text');

      gEnter.append('rect')
          .attr('class', 'overlay')
          .attr('width', width)
          .attr('height', height)
          .style('fill', 'none')
          .style('pointer-events', 'all');

      // Update the outer dimensions.
      svg.attr('width', width + margin.left + margin.right)
          .attr('height', height + margin.top + margin.bottom);

      // Update the inner dimensions.
      var g = svg.select('g')
          .attr('transform', 'translate(' + margin.left + ',' +
              margin.top + ')');

      var xDomain = d3.extent(data, function(d) { return extractor.dist(d); });
      x.domain(xDomain);

      var yDomain = [d3.min(data, function(d) { return extractor.z(d); }),
            d3.max(data, function(d) { return extractor.z(d); })];

      var padding = (yDomain[1] - yDomain[0]) * 0.1;
      y.domain([yDomain[0] - padding, yDomain[1] + padding]);

      // Update the area path.
      g.select('.area')
          .transition()
          .attr('d', area);
      g.select('.line')
          .transition()
          .attr('d', line);

      if (xDomain[1] > 2000) {
        xFactor = 1000;
        units = 'km';
      } else {
        xFactor = 1;
        units = 'm';
      }

      if (!light) {
        xAxis.tickFormat(function(d) {
          return formatter.xtick(d / xFactor, units);
        });
        if (lightXAxis) {
          xAxis.tickValues([0, x.domain()[1]]);
        }

        yAxis.tickFormat(function(d) {
          return formatter.ytick(d, 'm');
        });

        g.select('.x.axis')
          .transition()
          .call(xAxis);

        g.select('.x.label')
          .text('distance (' + units + ')')
          .style('fill', 'grey')
          .style('shape-rendering', 'crispEdges');

        g.select('.y.axis')
          .transition()
          .call(yAxis);
      }

      g.select('.grid-y')
          .transition()
          .call(yAxis.tickSize(-width, 0, 0).tickFormat(''))
          .selectAll('.tick line')
          .style('stroke', '#ccc')
          .style('opacity', 0.7);

      g.selectAll('.axis').selectAll('path, line')
          .style('fill', 'none')
          .style('stroke', '#000')
          .style('shape-rendering', 'crispEdges');

      g.selectAll('.grid-hover line')
          .style('stroke', '#222')
          .style('opacity', 0.8);

      g.select('.overlay')
          .on('mouseout', mouseout)
          .on('mousemove', mousemove);

      function mousemove() {
        var mouseX = d3.mouse(this)[0];
        var x0 = x.invert(mouseX);
        var i = bisectDistance(data, x0, 1);

        var point = data[i];
        var elevation = extractor.z(point);
        var dist = extractor.dist(point);

        g.select('.x.grid-hover')
            .style('display', 'inline')
            .select('line')
            .attr('x1', x(dist))
            .attr('y1', height)
            .attr('x2', x(dist))
            .attr('y2', y(elevation));

        g.select('.y.grid-hover')
            .style('display', 'inline')
            .select('line')
            .attr('x1', x(0))
            .attr('y1', y(elevation))
            .attr('x2', width)
            .attr('y2', y(elevation));

        var right = x0 > xDomain[1] / 2;
        var xtranslate = x(dist);
        xtranslate += right ? -10 : 10;

        g.select('.x.grid-hover text')
            .text(formatter.xhover(dist / xFactor, units))
            .style('text-anchor', right ? 'end' : 'start')
            .attr('transform', 'translate(' + xtranslate + ',' +
                (height - 10) + ')');

        g.select('.y.grid-hover text')
            .text(formatter.yhover(elevation, 'm'))
            .style('text-anchor', right ? 'end' : 'start')
            .attr('transform', 'translate(' + xtranslate + ',' +
                (y(elevation) - 10) + ')');
        hoverCallback.call(null, point);
      }

      function mouseout() {
        g.selectAll('.grid-hover')
            .style('display', 'none');
        outCallback.call(null);
      }
    });
  };

  profile.showPois = function(pois) {
    pois = goog.isDef(pois) ? pois : [];
    goog.asserts.assert(pois.length === 0 || goog.isDef(poiExtractor));

    var pe = poiExtractor;
    var g = svg.select('g');
    var profileData = svg.datum();
    var ps = g.select('.pois');

    var p = ps.selectAll('.poi').data(pois, function(d) {
      var i = bisectDistance(profileData, Math.round(pe.dist(d) * 10) / 10, 1);
      var point = profileData[i];
      if (point) {
        var z = elevationExtractor.z(point);
        pe.z(d, z);
      }
      return pe.id(d);
    });

    var poiEnterG = p.enter()
      .append('g')
      .attr('class', 'poi');

    poiEnterG.append('text')
      .attr('x', light ? 0 : 9)
      .attr('dy', '.35em')
      .attr('text-anchor', light ? 'middle' : 'start');

    poiEnterG.append('line')
      .style('shape-rendering', 'crispEdges');

    p.style('opacity', 0)
      .transition()
      .duration(1000)
      .delay(100)
      .style('opacity', 1);

    p.selectAll('text')
      .attr('transform', function(d) {
          if (light) {
            return ['translate(',
              x(pe.dist(d)), ',',
              y(pe.z(d)) - 10, ')'
            ].join('');
          } else {
            return ['translate(',
              x(pe.dist(d)), ',',
              y(pe.z(d)) - 20, ') rotate(', poiLabelAngle, ')'
            ].join('');
          }
        })
      .text(function(d) {
          return pe.sort(d) + (light ? '' : (' - ' + pe.title(d)));
        });

    p.selectAll('line')
       .style('stroke', 'grey')
       .attr('x1', function(d) { return x(pe.dist(d));})
       .attr('y1', function(d) { return y(y.domain()[0]);})
       .attr('x2', function(d) { return x(pe.dist(d));})
       .attr('y2', function(d) { return y(pe.z(d));});

    // remove unused pois
    p.exit().remove();
  };

  function clearPois() {
    profile.showPois([]);
  }

  return profile;
};
<commit_msg>Use d3.extent to compute the profile y domain<commit_after>/**
 * @fileoverview Provides a D3js component to be used to draw an elevation
 * profile chart.
 *
 * Example usage:
 *
 * var selection = d3.select('#element_id');
 * var profile = ngeo.profile({
 *  elevationExtractor: {
 *    z: function (item) {return item['values']['z'];)},
 *    dist: function (item) {return item['dist'];)}
 *  },
 *  hoverCallback: function(point) {
 *    console.log(point.x, point.y);
 *  },
 *  outCallback: function() {
 *    console.log("out");
 *  }});
 * selection.datum(data).call(profile);
 *
 * The selection data must be an array.
 * The layout for the items of this array is unconstrained: the elevation
 * and distance values are extracted using the elevationExtractor config
 * option. Optionally, POIs can be displayed and depend on a poiExtractor
 * config option.
 *
 * The data below will work for the above example:
 * [
 *     {
 *         "y": 199340,
 *         "values": {"z": 788.7},
 *         "dist": 0.0,
 *         "x": 541620
 *     }, ...
 * ]
 */
goog.provide('ngeo.profile');

/**
 *
 * @return {Object}
 * @param {ngeox.profile.ProfileOptions} options
 * @export
 *
 */
ngeo.profile = function(options) {
  /**
   * @type {boolean}
   * Whether the simplified profile should be shown.
   */
  var light = goog.isDef(options.light) ? options.light : false;

  /**
   * The values for margins around the chart defined in pixels.
   */
  var margin = light ? {top: 0, right: 0, bottom: 0, left: 0} :
      {top: 10, right: 20, bottom: 30, left: 40};

  /**
   * Method to get the coordinate in pixels from a distance.
   */
  var bisectDistance = d3.bisector(function(d) {
    return elevationExtractor.dist(d);
  }).left;

  /**
   * Distance units. Either 'm' or 'km'.
   */
  var units;

  /**
   * Factor to determine whether to use 'm' or 'km'.
   */
  var xFactor;

  /**
   * @type {function(Object)}
   * Hover callback function.
   */
  var hoverCallback = goog.isDef(options.hoverCallback) ?
      options.hoverCallback : goog.nullFunction;

  /**
   * @type {function()}
   * Out callback function.
   */
  var outCallback = goog.isDef(options.outCallback) ?
      options.outCallback : goog.nullFunction;

  /**
   * The color to be used for filling the area.
   * Can be overriden using the '.area' CSS selector.
   * @type {string}
   */
  var fill_color = 'rgba(222, 222, 222, 0.5)';

  /**
   * The color to be used the line stroke.
   * Can be overriden using the '.line' CSS selector.
   * @type {string}
   */
  var stroke_color = '#F00';

  /**
   * @type {Object}
   */
  var svg;

  /**
   * D3 x scale.
   */
  var x;

  /**
   * D3 y scale.
   */
  var y;

  /**
   * Elevation data extractor used to get the dist and elevation values.
   */
  var elevationExtractor = options.elevationExtractor;

  /**
   * POI data extractor.
   */
  var poiExtractor = options.poiExtractor;

  /**
   * Optional SVG inline style.
   */
  var styleDefs = options.styleDefs;

  /**
   * @type {number}
   */
  var poiLabelAngle = goog.isDef(options.poiLabelAngle) ?
      options.poiLabelAngle : -60;

  /**
   * @type {ngeox.profile.ProfileFormatter}
   */
  var formatter = goog.isDef(options.formatter) ?
      options.formatter : {
        xhover: function(dist, units) {
          return parseFloat(dist.toPrecision(3)) + ' ' + units;
        },
        yhover: function(ele, units) { return Math.round(ele) + ' m'; },
        xtick: function(dist, units) { return dist; },
        ytick: function(ele, units) { return ele; }
      };

  /**
   * @type {boolean}
   */
  var lightXAxis = goog.isDef(options.lightXAxis) ? options.lightXAxis : false;

  var profile = function(selection) {
    selection.each(function(data) {
      var extractor = elevationExtractor;

      var width = Math.max(this.clientWidth - margin.right - margin.left, 0);
      x = d3.scale.linear().range([0, width]);

      var height = Math.max(this.clientHeight - margin.top - margin.bottom, 0);
      y = d3.scale.linear().range([height, 0]);

      var xAxis = d3.svg.axis().scale(x).orient('bottom');
      var yAxis = d3.svg.axis()
          .scale(y)
          .orient('left');

      var area = d3.svg.area()
          .x(function(d) { return x(extractor.dist(d)); })
          .y0(height)
          .y1(function(d) { return y(extractor.z(d)); });
      var line = d3.svg.line()
          .x(function(d) { return x(extractor.dist(d)); })
          .y(function(d) { return y(extractor.z(d)); });

      // Select the svg element, if it exists.
      svg = d3.select(this).selectAll('svg').data([data]);

      // Otherwise, create the skeletal chart.
      var svgEnter = svg.enter().append('svg');
      if (goog.isDef(styleDefs)) {
        svgEnter.append('defs').append('style')
          .attr('type', 'text/css')
          .text(styleDefs);
      }
      var gEnter = svgEnter.append('g');
      clearPois();

      gEnter.style('font', '11px Arial');
      gEnter.append('path').attr('class', 'area')
          .style('fill', fill_color);
      gEnter.append('path').attr('class', 'line')
          .style('stroke', stroke_color)
          .style('fill', 'none');

      gEnter.insert('g', ':first-child')
          .attr('class', 'grid-y');

      if (!light) {
        gEnter.append('g')
          .attr('class', 'x axis')
          .attr('transform', 'translate(0,' + height + ')');

        gEnter.append('text')
          .attr('class', 'x label')
          .attr('text-anchor', 'end')
          .attr('x', width - 4)
          .attr('y', height - 4);

        gEnter.append('g')
          .attr('class', 'y axis');

        gEnter.append('text')
          .attr('class', 'y label')
          .attr('text-anchor', 'end')
          .attr('y', 6)
          .attr('dy', '.75em')
          .attr('transform', 'rotate(-90)')
          .style('fill', 'grey')
          .text('elevation (m)');

        gEnter.append('g')
          .attr('class', 'metas')
          .attr('transform', 'translate(' + (width + 3) + ', 0)');
      }

      gEnter.append('g').attr('class', 'pois');

      var yHover = gEnter.append('g').attr('class', 'y grid-hover');
      yHover.append('svg:line').attr('stroke-dasharray', '5,5');
      yHover.append('text');

      var xHover = gEnter.append('g').attr('class', 'x grid-hover');
      xHover.append('svg:line').attr('stroke-dasharray', '5,5');
      xHover.append('text');

      gEnter.append('rect')
          .attr('class', 'overlay')
          .attr('width', width)
          .attr('height', height)
          .style('fill', 'none')
          .style('pointer-events', 'all');

      // Update the outer dimensions.
      svg.attr('width', width + margin.left + margin.right)
          .attr('height', height + margin.top + margin.bottom);

      // Update the inner dimensions.
      var g = svg.select('g')
          .attr('transform', 'translate(' + margin.left + ',' +
              margin.top + ')');

      var xDomain = d3.extent(data, function(d) { return extractor.dist(d); });
      x.domain(xDomain);

      var yDomain = d3.extent(data, function(d) { return extractor.z(d); });
      var padding = (yDomain[1] - yDomain[0]) * 0.1;
      y.domain([yDomain[0] - padding, yDomain[1] + padding]);

      // Update the area path.
      g.select('.area')
          .transition()
          .attr('d', area);
      g.select('.line')
          .transition()
          .attr('d', line);

      if (xDomain[1] > 2000) {
        xFactor = 1000;
        units = 'km';
      } else {
        xFactor = 1;
        units = 'm';
      }

      if (!light) {
        xAxis.tickFormat(function(d) {
          return formatter.xtick(d / xFactor, units);
        });
        if (lightXAxis) {
          xAxis.tickValues([0, x.domain()[1]]);
        }

        yAxis.tickFormat(function(d) {
          return formatter.ytick(d, 'm');
        });

        g.select('.x.axis')
          .transition()
          .call(xAxis);

        g.select('.x.label')
          .text('distance (' + units + ')')
          .style('fill', 'grey')
          .style('shape-rendering', 'crispEdges');

        g.select('.y.axis')
          .transition()
          .call(yAxis);
      }

      g.select('.grid-y')
          .transition()
          .call(yAxis.tickSize(-width, 0, 0).tickFormat(''))
          .selectAll('.tick line')
          .style('stroke', '#ccc')
          .style('opacity', 0.7);

      g.selectAll('.axis').selectAll('path, line')
          .style('fill', 'none')
          .style('stroke', '#000')
          .style('shape-rendering', 'crispEdges');

      g.selectAll('.grid-hover line')
          .style('stroke', '#222')
          .style('opacity', 0.8);

      g.select('.overlay')
          .on('mouseout', mouseout)
          .on('mousemove', mousemove);

      function mousemove() {
        var mouseX = d3.mouse(this)[0];
        var x0 = x.invert(mouseX);
        var i = bisectDistance(data, x0, 1);

        var point = data[i];
        var elevation = extractor.z(point);
        var dist = extractor.dist(point);

        g.select('.x.grid-hover')
            .style('display', 'inline')
            .select('line')
            .attr('x1', x(dist))
            .attr('y1', height)
            .attr('x2', x(dist))
            .attr('y2', y(elevation));

        g.select('.y.grid-hover')
            .style('display', 'inline')
            .select('line')
            .attr('x1', x(0))
            .attr('y1', y(elevation))
            .attr('x2', width)
            .attr('y2', y(elevation));

        var right = x0 > xDomain[1] / 2;
        var xtranslate = x(dist);
        xtranslate += right ? -10 : 10;

        g.select('.x.grid-hover text')
            .text(formatter.xhover(dist / xFactor, units))
            .style('text-anchor', right ? 'end' : 'start')
            .attr('transform', 'translate(' + xtranslate + ',' +
                (height - 10) + ')');

        g.select('.y.grid-hover text')
            .text(formatter.yhover(elevation, 'm'))
            .style('text-anchor', right ? 'end' : 'start')
            .attr('transform', 'translate(' + xtranslate + ',' +
                (y(elevation) - 10) + ')');
        hoverCallback.call(null, point);
      }

      function mouseout() {
        g.selectAll('.grid-hover')
            .style('display', 'none');
        outCallback.call(null);
      }
    });
  };

  profile.showPois = function(pois) {
    pois = goog.isDef(pois) ? pois : [];
    goog.asserts.assert(pois.length === 0 || goog.isDef(poiExtractor));

    var pe = poiExtractor;
    var g = svg.select('g');
    var profileData = svg.datum();
    var ps = g.select('.pois');

    var p = ps.selectAll('.poi').data(pois, function(d) {
      var i = bisectDistance(profileData, Math.round(pe.dist(d) * 10) / 10, 1);
      var point = profileData[i];
      if (point) {
        var z = elevationExtractor.z(point);
        pe.z(d, z);
      }
      return pe.id(d);
    });

    var poiEnterG = p.enter()
      .append('g')
      .attr('class', 'poi');

    poiEnterG.append('text')
      .attr('x', light ? 0 : 9)
      .attr('dy', '.35em')
      .attr('text-anchor', light ? 'middle' : 'start');

    poiEnterG.append('line')
      .style('shape-rendering', 'crispEdges');

    p.style('opacity', 0)
      .transition()
      .duration(1000)
      .delay(100)
      .style('opacity', 1);

    p.selectAll('text')
      .attr('transform', function(d) {
          if (light) {
            return ['translate(',
              x(pe.dist(d)), ',',
              y(pe.z(d)) - 10, ')'
            ].join('');
          } else {
            return ['translate(',
              x(pe.dist(d)), ',',
              y(pe.z(d)) - 20, ') rotate(', poiLabelAngle, ')'
            ].join('');
          }
        })
      .text(function(d) {
          return pe.sort(d) + (light ? '' : (' - ' + pe.title(d)));
        });

    p.selectAll('line')
       .style('stroke', 'grey')
       .attr('x1', function(d) { return x(pe.dist(d));})
       .attr('y1', function(d) { return y(y.domain()[0]);})
       .attr('x2', function(d) { return x(pe.dist(d));})
       .attr('y2', function(d) { return y(pe.z(d));});

    // remove unused pois
    p.exit().remove();
  };

  function clearPois() {
    profile.showPois([]);
  }

  return profile;
};
<|endoftext|>


<commit_before>var gulp = require('gulp');
var prompt = require('gulp-prompt');
var tap = require('gulp-tap');
var path = require('path');
var yaml = require('js-yaml');
var fs = require('fs-extra');
var rename = require('gulp-rename');

var scaffoldUtils = require('./scaffold.utils.js');

var nodeName = {};
var nodeType = '';

gulp.task('addGeneratorPrompts', function() {
  return gulp.src('./config/scaffold/add.js')
    .pipe(prompt.prompt([{
      type: 'list',
      name: 'nodeType',
      message: 'What would you like to add',
      choices: scaffoldUtils.ADDABLE_NODES
    },{
      type: 'input',
      name: 'nodeName',
      message: 'Name?'
    }], function(res) {
      nodeName = scaffoldUtils.normalizeNodeName(res.nodeName, res.nodeType);
      nodeType = res.nodeType;
    }))
});

gulp.task('addGenerator', ['addGeneratorPrompts'], function() {
  var folder = nodeType.toLowerCase();

  return gulp.src(`./config/scaffold/${folder}/*.{js,twig,yml,scss}`)
    .pipe(tap(function(file, t) {
      var extension = path.extname(file.path);

      scaffoldUtils.FIND_REPLACES.forEach(function(replaceItem) {
        var regex = new RegExp(`{% ${replaceItem.label} %}`, 'g');

        file.contents = Buffer.from(file.contents.toString().replace(regex, nodeName[replaceItem.value]));
      });
    }))
    .pipe(rename({
      basename: nodeName.fileAndComponent
    }))
    .pipe(gulp.dest(`./src/${folder}s/${nodeName.directory}/`))
})

<commit_msg>Removed unused variable<commit_after>var gulp = require('gulp');
var prompt = require('gulp-prompt');
var tap = require('gulp-tap');
var path = require('path');
var fs = require('fs-extra');
var rename = require('gulp-rename');

var scaffoldUtils = require('./scaffold.utils.js');

var nodeName = {};
var nodeType = '';

gulp.task('addGeneratorPrompts', function() {
  return gulp.src('./config/scaffold/add.js')
    .pipe(prompt.prompt([{
      type: 'list',
      name: 'nodeType',
      message: 'What would you like to add',
      choices: scaffoldUtils.ADDABLE_NODES
    },{
      type: 'input',
      name: 'nodeName',
      message: 'Name?'
    }], function(res) {
      nodeName = scaffoldUtils.normalizeNodeName(res.nodeName, res.nodeType);
      nodeType = res.nodeType;
    }))
});

gulp.task('addGenerator', ['addGeneratorPrompts'], function() {
  var folder = nodeType.toLowerCase();

  return gulp.src(`./config/scaffold/${folder}/*.{js,twig,yml,scss}`)
    .pipe(tap(function(file, t) {
      var extension = path.extname(file.path);

      scaffoldUtils.FIND_REPLACES.forEach(function(replaceItem) {
        var regex = new RegExp(`{% ${replaceItem.label} %}`, 'g');

        file.contents = Buffer.from(file.contents.toString().replace(regex, nodeName[replaceItem.value]));
      });
    }))
    .pipe(rename({
      basename: nodeName.fileAndComponent
    }))
    .pipe(gulp.dest(`./src/${folder}s/${nodeName.directory}/`))
})

<|endoftext|>


<commit_before>// user interface helpers ---------------------------------------------------

// toggles visiblity of a single element based on the element's id
function toggle_display(tid) {
    el = $(tid);
    if(document.getElementById(tid).style.display == "none") {
        document.getElementById(tid).style.display = "";
        img = document.getElementById(tid + "_expander");
        img.src = img.src.replace('expand', 'collapse');
    }
    else {
        document.getElementById(tid).style.display = "none";
        img = document.getElementById(tid + "_expander");
        img.src = img.src.replace('collapse', 'expand');
    }
}

// similar to toggle_display, except does multiple elements based on name
function toggle_display_by_name(elName) {
    var el_ary = document.getElementsByName(elName);
    for (var i=0; i < el_ary.length; i++) {
        if (el_ary[i].style.display == "none") {
            el_ary[i].style.display = "";
        }
        else if (el_ary[i].style.display == "") {
            el_ary[i].style.display = "none";
        }
    }
}

// appends a new item to a select element
function appendToSelect(select, value, content, className) {
    var o = document.createElement("option");
    o.value = value;
    o.className = className;
    o.appendChild(content);
    select.appendChild(o);
}

// clears the contents of a selectelement
function clearSelection(select) {
    while (select.length > 0) {
        select.remove(0);
    }
}

// returns the value of a named cookie
function getCookieValue (cookie) {
    var e= new RegExp(escape(cookie) + "=([^;]+)");
    if(e.test(document.cookie + ";")) {
        e.exec(document.cookie + ";");
        return unescape(RegExp.$1);
    }
    else
        return false;
}

// RPC callbacks ------------------------------------------------------------

var STATUS_WAITING = 0;
var STATUS_RUNNING = 1;
var STATUS_FINISHED = 2;
var STATUS_DELETED = 3;
var STATUS_ERROR = 4;
var STATUS_NOJOB = 5;
var refreshed = false;
var oldStatus = -1;
var cookStatusRefreshTime    = 2000; /* 2 seconds */
var cookStatusId;
var releaseStatusRefreshTime = 5000; /* 5 seconds */
var releaseStatusId;
var archDict = "global";
var cookStatus = "global";
var releaseStatus = "global";

function processGetReleaseStatus(aReq) {
    var el = $("jobStatus");
    var statusText = "";

    logDebug("[JSON] response: ", aReq.responseText);
    releaseStatus = evalJSONRequest(aReq);

    if(releaseStatus.status > STATUS_RUNNING) {
        hideElement('editOptionsDisabled');
        showElement('editOptions');
        showElement('downloads');
    } else {
        showElement('editOptionsDisabled');
        hideElement('editOptions');
        hideElement('downloads');
    }

    if(!releaseStatus.message) {
        statusText = "No status";
        status = STATUS_NOJOB;
    } else {
        statusText = textWithBaton(releaseStatus.message);
    }

    replaceChildNodes(el, statusText);
}

function processGetCookStatus(aReq) {
    var el = $("jobStatus");

    logDebug("[JSON] response: ", aReq.responseText);
    cookStatus = evalJSONRequest(aReq);

    replaceChildNodes(el, textWithBaton(cookStatus.message));

}

function processGetTroveList(aReq) {
    var sel = $("trove");
    logDebug("[JSON] response: ", aReq.responseText);
    var trovelist = evalJSONRequest(aReq);

    /* make an empty selection, forcing user to pick */
    clearSelection(sel);
    appendToSelect(sel, "", document.createTextNode("---"), "trove");

    for (var label in trovelist) {
        var troveNames = trovelist[label];
        for (var troveNameIdx in troveNames) {
            var troveName = troveNames[troveNameIdx];
            appendToSelect(sel, troveName + "=" + label, document.createTextNode(troveName), "trove");
        }
    }

}

function processGetTroveVersionsByArch(aReq) {
    logDebug("[JSON] response: ", aReq.responseText);
    archDict = evalJSONRequest(aReq);

    // handle archs
    var archs = keys(archDict).sort();
    var archSel = $("arch");
    clearSelection(archSel);
    appendToSelect(archSel, "", document.createTextNode("---"), "arch");
    for (var i in archs) {
        var archStr = archs[i];
        appendToSelect(archSel, archStr, document.createTextNode(archStr), "arch");
    }
    archSel.disabled = false;

}

// RPC calls ----------------------------------------------------------------

function getReleaseStatus(releaseId) {
    var req = new JsonRpcRequest("/jsonrpc", "getReleaseStatus");
    req.setAuth(getCookieValue("pysid"));
    req.setCallback(processGetReleaseStatus);
    req.send(false, [releaseId]);
    if (releaseStatus != null && releaseStatus.status < STATUS_FINISHED) {
        releaseStatusId = setTimeout("getReleaseStatus("+releaseId+")", releaseStatusRefreshTime);
    }
}

function getCookStatus(jobId) {
    var req = new JsonRpcRequest("/jsonrpc", "getJobStatus");
    req.setAuth(getCookieValue("pysid"));
    req.setCallback(processGetCookStatus);
    req.send(false, [jobId]);
    // continue calling self until we're finished
    if (cookStatus != null && cookStatus.status < STATUS_FINISHED) {
        cookStatusId = setTimeout("getCookStatus("+jobId+")", cookStatusRefreshTime);
    }
}

function getTroveList(projectId) {
    var req = new JsonRpcRequest("/jsonrpc", "getGroupTroves");
    req.setAuth(getCookieValue("pysid"));
    req.setCallback(processGetTroveList);
    req.send(true, [projectId]);
}

function getTroveVersionsByArch(projectId, troveNameWithLabel) {
    var req = new JsonRpcRequest("/jsonrpc", "getTroveVersionsByArch");
    req.setAuth(getCookieValue("pysid"));
    req.setCallback(processGetTroveVersionsByArch);
    req.send(true, [projectId, troveNameWithLabel]);
}

// baton --------------------------------------------------------------------

var ticks = 0;
var baton = '-\\|/';

function textWithBaton(text) {

    var newText = text;
    newText += "  " + baton[ticks];
    ticks = ((ticks + 1) % baton.length);
    return newText;

}

// NOTE: ticker removed for now until we come up with something better

// event handlers -----------------------------------------------------------

// called when a user selects a trove in the new/edit releases page
function onTroveChange(projectId) {
    var sel = document.getElementById("trove");
    var vSel = document.getElementById("version");
    var archSel = document.getElementById("arch");
    var sb = document.getElementById("submitButton");
    var i = sel.selectedIndex;

    // bail out if selector is changed to a non-trove header selection
    if (i < 1) {
        clearSelection(vSel);
        vSel.disabled = true;
        clearSelection(archSel);
        archSel.disabled = true;
        sb.disabled = true;
        return;
    }

    var troveNameWithLabel = sel.options[sel.selectedIndex].value;
    // XXX: cache values?
    getTroveVersionsByArch(projectId, troveNameWithLabel);
}

function onArchChange() {

    var archSel = $("arch");
    var vSel = $("version");
    var sb = $("submitButton");
    var i = archSel.selectedIndex;

    // handle versions
    clearSelection(vSel);
    appendToSelect(vSel, "", document.createTextNode("---"), "version");
    vSel.disabled = true;

    if (i > 0) {
        selectedArch = archSel.value;
        var versionlist = archDict[selectedArch];
        logDebug(versionlist);
        for (var i in versionlist) {
            appendToSelect(vSel, versionlist[i][1] + " " + versionlist[i][2], document.createTextNode(versionlist[i][0]), "version");
        }
        vSel.disabled = false;
    }
    else {
        sb.disabled = true;
    }

}

function onVersionChange() {

    var vSel = $("version");
    var sb = $("submitButton");
    var i = vSel.selectedIndex;

    if (i > 0) {
       sb.disabled = false;
    }
    else {
       sb.disabled = true;
    }

}
<commit_msg>possible bugfix for #715<commit_after>// user interface helpers ---------------------------------------------------

// toggles visiblity of a single element based on the element's id
function toggle_display(tid) {
    el = $(tid);
    if(document.getElementById(tid).style.display == "none") {
        document.getElementById(tid).style.display = "";
        img = document.getElementById(tid + "_expander");
        img.src = img.src.replace('expand', 'collapse');
    }
    else {
        document.getElementById(tid).style.display = "none";
        img = document.getElementById(tid + "_expander");
        img.src = img.src.replace('collapse', 'expand');
    }
}

// similar to toggle_display, except does multiple elements based on name
function toggle_display_by_name(elName) {
    var el_ary = document.getElementsByName(elName);
    for (var i=0; i < el_ary.length; i++) {
        if (el_ary[i].style.display == "none") {
            el_ary[i].style.display = "";
        }
        else if (el_ary[i].style.display == "") {
            el_ary[i].style.display = "none";
        }
    }
}

// appends a new item to a select element
function appendToSelect(select, value, content, className) {
    var o = document.createElement("option");
    o.value = value;
    o.className = className;
    o.appendChild(content);
    select.appendChild(o);
}

// clears the contents of a selectelement
function clearSelection(select) {
    while (select.length > 0) {
        select.remove(0);
    }
}

// returns the value of a named cookie
function getCookieValue (cookie) {
    var e= new RegExp(escape(cookie) + "=([^;]+)");
    if(e.test(document.cookie + ";")) {
        e.exec(document.cookie + ";");
        return unescape(RegExp.$1);
    }
    else
        return false;
}

// RPC callbacks ------------------------------------------------------------

var STATUS_WAITING = 0;
var STATUS_RUNNING = 1;
var STATUS_FINISHED = 2;
var STATUS_DELETED = 3;
var STATUS_ERROR = 4;
var STATUS_NOJOB = 5;
var refreshed = false;
var oldStatus = -1;
var cookStatusRefreshTime    = 2000; /* 2 seconds */
var cookStatusId;
var releaseStatusRefreshTime = 5000; /* 5 seconds */
var releaseStatusId;
var archDict = "global";
var cookStatus = "global";
var releaseStatus = "global";

function processGetReleaseStatus(aReq) {
    var el = $("jobStatus");
    var statusText = "";

    logDebug("[JSON] response: ", aReq.responseText);
    releaseStatus = evalJSONRequest(aReq);

    if(releaseStatus.status > STATUS_RUNNING) {
        hideElement('editOptionsDisabled');
        showElement('editOptions');
        showElement('downloads');
    } else {
        showElement('editOptionsDisabled');
        hideElement('editOptions');
        hideElement('downloads');
    }

    if(!releaseStatus.message) {
        statusText = "No status";
        status = STATUS_NOJOB;
    } else {
        statusText = textWithBaton(releaseStatus.message);
    }

    replaceChildNodes(el, statusText);
}

function processGetCookStatus(aReq) {
    var el = $("jobStatus");

    logDebug("[JSON] response: ", aReq.responseText);
    cookStatus = evalJSONRequest(aReq);

    replaceChildNodes(el, textWithBaton(cookStatus.message));

}

function processGetTroveList(aReq) {
    var sel = $("trove");
    logDebug("[JSON] response: ", aReq.responseText);
    var trovelist = evalJSONRequest(aReq);

    /* make an empty selection, forcing user to pick */
    clearSelection(sel);
    appendToSelect(sel, "", document.createTextNode("---"), "trove");

    for (var label in trovelist) {
        var troveNames = trovelist[label];
        for (var troveNameIdx in troveNames) {
            var troveName = troveNames[troveNameIdx];
            appendToSelect(sel, troveName + "=" + label, document.createTextNode(troveName), "trove");
        }
    }

}

function processGetTroveVersionsByArch(aReq) {
    logDebug("[JSON] response: ", aReq.responseText);
    archDict = evalJSONRequest(aReq);

    // handle archs
    var archs = keys(archDict).sort();
    var archSel = $("arch");
    clearSelection(archSel);
    appendToSelect(archSel, "", document.createTextNode("---"), "arch");
    for (var i in archs) {
        var archStr = archs[i];
        appendToSelect(archSel, archStr, document.createTextNode(archStr), "arch");
    }
    archSel.disabled = false;

}

// RPC calls ----------------------------------------------------------------

function getReleaseStatus(releaseId) {
    var req = new JsonRpcRequest("/jsonrpc", "getReleaseStatus");
    req.setAuth(getCookieValue("pysid"));
    req.setCallback(processGetReleaseStatus);
    req.send(false, [releaseId]);
    if (releaseStatus != null && releaseStatus.status < STATUS_FINISHED) {
        releaseStatusId = setTimeout("getReleaseStatus("+releaseId+")", releaseStatusRefreshTime);
    }
}

function getCookStatus(jobId) {
    var req = new JsonRpcRequest("/jsonrpc", "getJobStatus");
    req.setAuth(getCookieValue("pysid"));
    req.setCallback(processGetCookStatus);
    req.send(false, [jobId]);
    // continue calling self until we're finished
    if (cookStatus != null && cookStatus.status < STATUS_FINISHED) {
        cookStatusId = setTimeout("getCookStatus("+jobId+")", cookStatusRefreshTime);
    }
}

function getTroveList(projectId) {
    var req = new JsonRpcRequest("/jsonrpc", "getGroupTroves");
    req.setAuth(getCookieValue("pysid"));
    req.setCallback(processGetTroveList);
    req.send(true, [projectId]);
}

function getTroveVersionsByArch(projectId, troveNameWithLabel) {
    var req = new JsonRpcRequest("/jsonrpc", "getTroveVersionsByArch");
    req.setAuth(getCookieValue("pysid"));
    req.setCallback(processGetTroveVersionsByArch);
    req.send(true, [projectId, troveNameWithLabel]);
}

// baton --------------------------------------------------------------------

var ticks = 0;
var baton = '-\\|/';

function textWithBaton(text) {

    var newText = text;
    newText += "  " + baton[ticks];
    ticks = ((ticks + 1) % baton.length);
    return newText;

}

// NOTE: ticker removed for now until we come up with something better

// event handlers -----------------------------------------------------------

// called when a user selects a trove in the new/edit releases page
function onTroveChange(projectId) {
    var sel = document.getElementById("trove");
    var vSel = document.getElementById("version");
    var archSel = document.getElementById("arch");
    var sb = document.getElementById("submitButton");
    var i = sel.selectedIndex;

    // bail out if selector is changed to a non-trove header selection
    if (i < 1) {
        clearSelection(vSel);
        vSel.disabled = true;
        clearSelection(archSel);
        archSel.disabled = true;
        sb.disabled = true;
        return;
    }

    var troveNameWithLabel = sel.options[sel.selectedIndex].value;
    // XXX: cache values?
    getTroveVersionsByArch(projectId, troveNameWithLabel);
}

function onArchChange() {

    var archSel = $("arch");
    var vSel = $("version");
    var sb = $("submitButton");
    var i = archSel.selectedIndex;

    // handle versions
    clearSelection(vSel);
    appendToSelect(vSel, "", document.createTextNode("---"), "version");
    vSel.disabled = true;

    if (i > 0) {
        selectedArch = archSel.value;
        var versionlist = archDict[selectedArch];
        logDebug(versionlist);
        for (var i in versionlist) {
            appendToSelect(vSel, versionlist[i][1] + " " + versionlist[i][2], document.createTextNode(versionlist[i][0]), "version");
        }
        vSel.disabled = false;
        handleReleaseTypes(selectedArch);
    }
    else {
        sb.disabled = true;
    }

}

function onVersionChange() {

    var vSel = $("version");
    var sb = $("submitButton");
    var i = vSel.selectedIndex;

    if (i > 0) {
       sb.disabled = false;
    }
    else {
       sb.disabled = true;
    }

}

/* TODO: This begs for a more configurable way based on supported
         available job server capabilities.  */
function handleReleaseTypes(aSelectedArch) {

    var arch = $('arch');
    var isoImageSel  = $('imagetype_1');
    var qemuImageSel = $('imagetype_7');
    var vmwareImageSel = $('imagetype_8');

    if (aSelectedArch == "x86_64") {
        isoImageSel.disabled = false;
        qemuImageSel.disabled = true;
        vmwareImage.disabled = true;
        isoImage.click();
    } else {
        isoImageSel.disabled = false;
        qemuImageSel.disabled = false;
        vmwareImage.disabled = false;
    }

}
<|endoftext|>


<commit_before>// Capabilities of the two different server types that are currently able to
// provide the DELPH-IN restful API.
CAPABILITIES = {
    'lkb' : {
        'tree' : ['json'],
        'mrs' : ['json', 'latex'],
        'eds' : ['json', 'latex'],
        'dmrs' : []
    },
    'pydelphin' : {
        'tree' : ['json'],
        'mrs' : ['json'],
        'eds' : [],
        'dmrs' : ['json', 'latex']
    }
};

// Ordered list of grammar resource identifiers for presenting in the demo.
// Should correspond to keys of RESOURCES object.
var GRAMMARS = [
    'erg-uw',
    'erg-uio',
    'jacy-uw',
    'indra-uw',
    'zhong-uw',
    'gg-um',
    'hag-um'
];

var RESOURCES = {
    'erg-uio': {
        grammar: 'ERG',
        lang: 'eng',
        server: 'lkb',
        location: 'UiO',
        url: 'http://erg.delph-in.net/rest/0.9/parse',
        inputs: ['Abrams knew that it rained.']
    },
    'erg-uw': {
        grammar: 'ERG',
        lang: 'eng',
        server: 'pydelphin',
        location: 'UW',
        url: 'http://chimpanzee.ling.washington.edu/bottlenose/erg/parse',
        inputs: ['Abrams knew that it rained.']
    },
    'jacy-uw': {
        grammar: 'Jacy',
        lang: 'jpn',
        server: 'pydelphin',
        location: 'UW',
        url: 'http://chimpanzee.ling.washington.edu/bottlenose/jacy/parse',
        inputs: ['太郎 が 雨 が 降っ た こと を 知っ て い た ．']
    },
    'indra-uw': {
        grammar: 'Indra',
        lang: 'ind',
        server: 'pydelphin',
        location: 'UW',
        url: 'http://chimpanzee.ling.washington.edu/bottlenose/indra/parse',
        inputs: ['Adi tahu bahwa hujan sudah turun.']
    },
    'zhong-uw': {
        grammar: 'Zhong',
        lang: 'cmn',
        server: 'pydelphin',
        location: 'UW',
        url: 'http://chimpanzee.ling.washington.edu/bottlenose/zhong/parse',
        inputs: ['张三 知道 下 过 雨 。']
    }
    // currently offline
    // 'gg-um': {
    //     grammar: 'gg',
    //     lang: 'deu',
    //     server: 'pydelphin',
    //     location: 'UM',
    //     url: 'http://nedned.cis.unimelb.edu.au/bottlenose/gg/parse',
    //     inputs: ['Abrams wusste, dass es regnete.']
    // },
    // 'hag-um': {
    //     grammar: 'Hausa',
    //     lang: 'hau',
    //     server: 'pydelphin',
    //     location: 'UM',
    //     url: 'http://nedned.cis.unimelb.edu.au/bottlenose/hag/parse',
    //     inputs: ['Állàh yà gáafàrtà máalàm']
    // }
};
<commit_msg>Add ERG trunk<commit_after>// Capabilities of the two different server types that are currently able to
// provide the DELPH-IN restful API.
CAPABILITIES = {
    'lkb' : {
        'tree' : ['json'],
        'mrs' : ['json', 'latex'],
        'eds' : ['json', 'latex'],
        'dmrs' : []
    },
    'pydelphin' : {
        'tree' : ['json'],
        'mrs' : ['json'],
        'eds' : [],
        'dmrs' : ['json', 'latex']
    }
};

// Ordered list of grammar resource identifiers for presenting in the demo.
// Should correspond to keys of RESOURCES object.
var GRAMMARS = [
    'erg-uw',
    'erg-uio',
    'ergtrunk-uw',
    'jacy-uw',
    'indra-uw',
    'zhong-uw',
    'gg-um',
    'hag-um'
];

var RESOURCES = {
    'erg-uio': {
        grammar: 'ERG',
        lang: 'eng',
        server: 'lkb',
        location: 'UiO',
        url: 'http://erg.delph-in.net/rest/0.9/parse',
        inputs: ['Abrams knew that it rained.']
    },
    'erg-uw': {
        grammar: 'ERG',
        lang: 'eng',
        server: 'pydelphin',
        location: 'UW',
        url: 'http://chimpanzee.ling.washington.edu/bottlenose/erg/parse',
        inputs: ['Abrams knew that it rained.']
    },
    'ergtrunk-uw': {
        grammar: 'ERG r26803',
        lang: 'eng',
        server: 'pydelphin',
        location: 'UW',
        url: 'http://chimpanzee.ling.washington.edu/bottlenose/erg-trunk/parse',
        inputs: ['Abrams knew that it rained.']
    },
    'jacy-uw': {
        grammar: 'Jacy',
        lang: 'jpn',
        server: 'pydelphin',
        location: 'UW',
        url: 'http://chimpanzee.ling.washington.edu/bottlenose/jacy/parse',
        inputs: ['太郎 が 雨 が 降っ た こと を 知っ て い た ．']
    },
    'indra-uw': {
        grammar: 'Indra',
        lang: 'ind',
        server: 'pydelphin',
        location: 'UW',
        url: 'http://chimpanzee.ling.washington.edu/bottlenose/indra/parse',
        inputs: ['Adi tahu bahwa hujan sudah turun.']
    },
    'zhong-uw': {
        grammar: 'Zhong',
        lang: 'cmn',
        server: 'pydelphin',
        location: 'UW',
        url: 'http://chimpanzee.ling.washington.edu/bottlenose/zhong/parse',
        inputs: ['张三 知道 下 过 雨 。']
    }
    // currently offline
    // 'gg-um': {
    //     grammar: 'gg',
    //     lang: 'deu',
    //     server: 'pydelphin',
    //     location: 'UM',
    //     url: 'http://nedned.cis.unimelb.edu.au/bottlenose/gg/parse',
    //     inputs: ['Abrams wusste, dass es regnete.']
    // },
    // 'hag-um': {
    //     grammar: 'Hausa',
    //     lang: 'hau',
    //     server: 'pydelphin',
    //     location: 'UM',
    //     url: 'http://nedned.cis.unimelb.edu.au/bottlenose/hag/parse',
    //     inputs: ['Állàh yà gáafàrtà máalàm']
    // }
};
<|endoftext|>


<commit_before>// Given an array of integers, return indices of the two numbers such that they add up to a specific target.

// You may assume that each input would have exactly one solution.

// Example:
// Given nums = [2, 7, 11, 15], target = 9,

// Because nums[0] + nums[1] = 2 + 7 = 9,
// return [0, 1].

// set variable numLength as the nums array's length
// if numsLength is less than 2, return nums array
// create an object/hash called map to store each item in the array as the key and index as value
// create a for loop that runs as many times as the size of the array
  // if the target minus the current number is a hash key
  // or if the target minus the current number is equal to zero
    // return the key's value and the index in an array
  // if the current number is a key of the map is undefined
    // create a map key as they current number and value as the index

var twoSum = function(nums, target) {
    var numLength=nums.length;
    if(numLength<2){
        return nums;
    }
    var map={};
    for(var i = 0; i < numLength; i++){
         if(map[target - nums[i]] || map[target-nums[i]] === 0){
            return [map[target-nums[i]], i];
        }
        if(map[nums[i]]===undefined){
            map[nums[i]]=i;
        }
    }
};
<commit_msg>edit solution<commit_after>// Given an array of integers, return indices of the two numbers such that they add up to a specific target.

// You may assume that each input would have exactly one solution.

// Example:
// Given nums = [2, 7, 11, 15], target = 9,

// Because nums[0] + nums[1] = 2 + 7 = 9,
// return [0, 1].

// set variable numLength as the nums array's length
// if numsLength is less than 2, return nums array
// create an object/hash called map to store each item in the array as the key and index as value
// create a for loop that runs as many times as the size of the array
  // if the target minus the current number is a hash key
  // or if the target minus the current number is equal to zero
    // return the key's value and the index in an array
  // if the current number is a key of the map is undefined
    // create a map key as they current number and value as the index

var twoSum = function(nums, target) { //96ms runtime
    var numLength = nums.length;
    if( numLength<2 ){
        return nums;
    }
    var map = {};
    for(var i = 0; i < numLength; i++){
         if( map[target - nums[i]] || map[target-nums[i]] === 0 ){
            return [map [ target-nums[i] ], i];
        }
        if( map[nums[i]] === undefined ){
            map[ nums[i] ] = i;
        }
    }
};
<|endoftext|>