<commit_before>var canpost = mw.config.exists('canpost');
var ownpage = mw.config.exists('commentadmin') || mw.config.get('wgNamespaceNumber') === 2 && mw.config.get('wgTitle').replace('/$', '') === mw.user.id();

var replyBox = null;

function createThread(post) {
  var thread = new Thread();
  var object = thread.object;
  thread.init(post);

  if (canpost) {
    thread.addButton('reply', mw.msg('flowthread-ui-reply'), function() {
      thread.reply();
    });
  }

  // User not signed in do not have right to vote
  if (mw.user.getId() !== 0) {
    var likeNum = post.like ? '(' + post.like + ')' : '';
    thread.addButton('like', mw.msg('flowthread-ui-like') + likeNum, function() {
      if (object.find('.comment-like').attr('liked') !== undefined) {
        thread.dislike();
      } else {
        thread.like();
      }
    });
    thread.addButton('report', mw.msg('flowthread-ui-report'), function() {
      if (object.find('.comment-report').attr('reported') !== undefined) {
        thread.dislike();
      } else {
        thread.report();
      }
    });
  }

  // commentadmin-restricted and poster himself can delete comment
  if (ownpage || (post.userid && post.userid === mw.user.getId())) {
    thread.addButton('delete', mw.msg('flowthread-ui-delete'), function() {
      thread.delete();
    });
  }

  if (ownpage) {
    thread.addButton('pin', mw.msg('flowthread-ui-pin'), function() {
      if (object.find('.comment-pin').attr('pinned') !== undefined) {
        thread.unpin();
        object.find('.comment-pin').removeAttr('pinned').text(mw.msg('flowthread-ui-pin'));
      } else {
        thread.pin();
        object.find('.comment-pin').attr('pinned', '').text(mw.msg('flowthread-ui-unpin'));
      }
    });
  }

  if (post.myatt === 1) {
    object.find('.comment-like').attr('liked', '');
  } else if (post.myatt === 2) {
    object.find('.comment-report').attr('reported', '');
  }

  return thread;
}

Thread.prototype.reply = function() {
  if (replyBox) {
    replyBox.remove();
  }
  replyBox = createReplyBox(this.post.id);
  this.appendChild({
    object: replyBox
  });
}

Thread.sendComment = function(postid, text, wikitext) {
  var api = new mw.Api();
  var req = {
    action: 'flowthread',
    type: 'post',
    pageid: mw.config.get('wgArticleId'),
    postid: postid,
    content: text,
    wikitext: wikitext
  };
  api.get(req).done(reloadComments).fail(function(error, obj) {
    if (obj.error)
      showMsgDialog(obj.error.info);
    else if (error === 'http')
      showMsgDialog(mw.msg('flowthread-ui-networkerror'));
    else
      showMsgDialog(error);
  });
}

function reloadComments(offset) {
  offset = offset || 0;
  var api = new mw.Api();
  api.get({
    action: 'flowthread',
    type: 'list',
    pageid: mw.config.get('wgArticleId'),
    offset: offset
  }).done(function(data) {
    $('.comment-container-top').html('
' + mw.msg('flowthread-ui-popular') + '
').attr('disabled', '');
    $('.comment-container').html('');
    var canpostbak = canpost;
    canpost = false; // No reply for topped comments
    data.flowthread.pinned.forEach(function(item) {
      var obj = createThread(item);
      obj.markAsPinned();
      obj.object.find('.comment-pin').attr('pinned', '').text(mw.msg('flowthread-ui-unpin'));
      $('.comment-container-top').removeAttr('disabled').append(obj.object);
    });
    data.flowthread.popular.forEach(function(item) {
      var obj = createThread(item);
      obj.markAsPopular();
      $('.comment-container-top').removeAttr('disabled').append(obj.object);
    });
    canpost = canpostbak;
    data.flowthread.posts.forEach(function(item) {
      if (item.parentid === '') {
        $('.comment-container').append(createThread(item).object);
      } else {
        Thread.fromId(item.parentid).appendChild(createThread(item));
      }
    });
    pager.current = Math.floor(offset / 10);
    pager.count = Math.ceil(data.flowthread.count / 10);
    pager.repaint();
  });
}

function setFollowUp(postid, follow) {
  var obj = $('[comment-id=' + postid + '] > .comment-post');
  obj.after(follow);
}

function createReplyBox(parentid) {
  var replyBox = new ReplyBox();

  replyBox.onSubmit = function() {
    var text = replyBox.getValue().trim();
    if (!text) {
      showMsgDialog(mw.msg('flowthread-ui-nocontent'));
      return;
    }
    replyBox.setValue('');
    Thread.sendComment(parentid, text, replyBox.isInWikitextMode());
  };
  return replyBox.object;
}

/* Paginator support */
function Paginator() {
  this.object = $('

');
  this.current = 0;
  this.count = 1;
}

Paginator.prototype.add = function(page) {
  var item = $('' + (page + 1) + '');
  if (page === this.current) {
    item.attr('current', '');
  }
  item.click(function() {
    reloadComments(page * 10);
  });
  this.object.append(item);
}

Paginator.prototype.addEllipse = function() {
  this.object.append('...')
}

Paginator.prototype.repaint = function() {
  this.object.html('');
  if (this.count <= 1) {
    this.object.hide();
  } else {
    this.object.show();
  }
  var pageStart = Math.max(this.current - 2, 0);
  var pageEnd = Math.min(this.current + 4, this.count - 1);
  if (pageStart !== 0) {
    this.add(0);
  }
  if (pageStart > 1) {
    this.addEllipse();
  }
  for (var i = pageStart; i <= pageEnd; i++) {
    this.add(i);
  }
  if (this.count - pageEnd > 2) {
    this.addEllipse();
  }
  if (this.count - pageEnd !== 1) {
    this.add(this.count - 1);
  }
}

var pager = new Paginator();

$('#bodyContent').after('

', '

', pager.object, function() {
  if (canpost) return createReplyBox('');
  var noticeContainer = $('
').addClass('comment-bannotice');
  noticeContainer.html(config.CantPostNotice);
  return noticeContainer;
}());
reloadComments();<commit_msg>Bugfix<commit_after>var canpost = mw.config.exists('canpost');
var ownpage = mw.config.exists('commentadmin') || mw.config.get('wgNamespaceNumber') === 2 && mw.config.get('wgTitle').replace('/$', '') === mw.user.id();

var replyBox = null;

function createThread(post) {
  var thread = new Thread();
  var object = thread.object;
  thread.init(post);

  if (canpost) {
    thread.addButton('reply', mw.msg('flowthread-ui-reply'), function() {
      thread.reply();
    });
  }

  // User not signed in do not have right to vote
  if (mw.user.getId() !== 0) {
    var likeNum = post.like ? '(' + post.like + ')' : '';
    thread.addButton('like', mw.msg('flowthread-ui-like') + likeNum, function() {
      if (object.find('.comment-like').first().attr('liked') !== undefined) {
        thread.dislike();
      } else {
        thread.like();
      }
    });
    thread.addButton('report', mw.msg('flowthread-ui-report'), function() {
      if (object.find('.comment-report').first().attr('reported') !== undefined) {
        thread.dislike();
      } else {
        thread.report();
      }
    });
  }

  // commentadmin-restricted and poster himself can delete comment
  if (ownpage || (post.userid && post.userid === mw.user.getId())) {
    thread.addButton('delete', mw.msg('flowthread-ui-delete'), function() {
      thread.delete();
    });
  }

  if (ownpage) {
    thread.addButton('pin', mw.msg('flowthread-ui-pin'), function() {
      if (object.find('.comment-pin').first().attr('pinned') !== undefined) {
        thread.unpin();
        object.find('.comment-pin').first().removeAttr('pinned').text(mw.msg('flowthread-ui-pin'));
      } else {
        thread.pin();
        object.find('.comment-pin').first().attr('pinned', '').text(mw.msg('flowthread-ui-unpin'));
      }
    });
  }

  if (post.myatt === 1) {
    object.find('.comment-like').attr('liked', '');
  } else if (post.myatt === 2) {
    object.find('.comment-report').attr('reported', '');
  }

  return thread;
}

Thread.prototype.reply = function() {
  if (replyBox) {
    replyBox.remove();
  }
  replyBox = createReplyBox(this.post.id);
  this.appendChild({
    object: replyBox
  });
}

Thread.sendComment = function(postid, text, wikitext) {
  var api = new mw.Api();
  var req = {
    action: 'flowthread',
    type: 'post',
    pageid: mw.config.get('wgArticleId'),
    postid: postid,
    content: text,
    wikitext: wikitext
  };
  api.get(req).done(reloadComments).fail(function(error, obj) {
    if (obj.error)
      showMsgDialog(obj.error.info);
    else if (error === 'http')
      showMsgDialog(mw.msg('flowthread-ui-networkerror'));
    else
      showMsgDialog(error);
  });
}

function reloadComments(offset) {
  offset = offset || 0;
  var api = new mw.Api();
  api.get({
    action: 'flowthread',
    type: 'list',
    pageid: mw.config.get('wgArticleId'),
    offset: offset
  }).done(function(data) {
    $('.comment-container-top').html('
' + mw.msg('flowthread-ui-popular') + '
').attr('disabled', '');
    $('.comment-container').html('');
    var canpostbak = canpost;
    canpost = false; // No reply for topped comments
    data.flowthread.pinned.forEach(function(item) {
      var obj = createThread(item);
      obj.markAsPinned();
      obj.object.find('.comment-pin').attr('pinned', '').text(mw.msg('flowthread-ui-unpin'));
      $('.comment-container-top').removeAttr('disabled').append(obj.object);
    });
    data.flowthread.popular.forEach(function(item) {
      var obj = createThread(item);
      obj.markAsPopular();
      $('.comment-container-top').removeAttr('disabled').append(obj.object);
    });
    canpost = canpostbak;
    data.flowthread.posts.forEach(function(item) {
      if (item.parentid === '') {
        $('.comment-container').append(createThread(item).object);
      } else {
        Thread.fromId(item.parentid).appendChild(createThread(item));
      }
    });
    pager.current = Math.floor(offset / 10);
    pager.count = Math.ceil(data.flowthread.count / 10);
    pager.repaint();
  });
}

function setFollowUp(postid, follow) {
  var obj = $('[comment-id=' + postid + '] > .comment-post');
  obj.after(follow);
}

function createReplyBox(parentid) {
  var replyBox = new ReplyBox();

  replyBox.onSubmit = function() {
    var text = replyBox.getValue().trim();
    if (!text) {
      showMsgDialog(mw.msg('flowthread-ui-nocontent'));
      return;
    }
    replyBox.setValue('');
    Thread.sendComment(parentid, text, replyBox.isInWikitextMode());
  };
  return replyBox.object;
}

/* Paginator support */
function Paginator() {
  this.object = $('

');
  this.current = 0;
  this.count = 1;
}

Paginator.prototype.add = function(page) {
  var item = $('' + (page + 1) + '');
  if (page === this.current) {
    item.attr('current', '');
  }
  item.click(function() {
    reloadComments(page * 10);
  });
  this.object.append(item);
}

Paginator.prototype.addEllipse = function() {
  this.object.append('...')
}

Paginator.prototype.repaint = function() {
  this.object.html('');
  if (this.count <= 1) {
    this.object.hide();
  } else {
    this.object.show();
  }
  var pageStart = Math.max(this.current - 2, 0);
  var pageEnd = Math.min(this.current + 4, this.count - 1);
  if (pageStart !== 0) {
    this.add(0);
  }
  if (pageStart > 1) {
    this.addEllipse();
  }
  for (var i = pageStart; i <= pageEnd; i++) {
    this.add(i);
  }
  if (this.count - pageEnd > 2) {
    this.addEllipse();
  }
  if (this.count - pageEnd !== 1) {
    this.add(this.count - 1);
  }
}

var pager = new Paginator();

$('#bodyContent').after('

', '

', pager.object, function() {
  if (canpost) return createReplyBox('');
  var noticeContainer = $('
').addClass('comment-bannotice');
  noticeContainer.html(config.CantPostNotice);
  return noticeContainer;
}());
reloadComments();<|endoftext|>


<commit_before>var width = 960,
    height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-80)
    .linkDistance(200)
    .friction(0.9)
    .size([width, height]);

var forceSvg = d3.select("div#chord_chart").append("svg")
    .attr("width", width)
    .attr("height", height);

var node_drag = d3.behavior.drag()
    .on("dragstart", dragstart)
    .on("drag", dragmove)
    .on("dragend", dragend);
    function dragstart(d, i) {
        force.stop() // stops the force auto positioning before you start dragging
    }
    function dragmove(d, i) {
        d.px += d3.event.dx;
        d.py += d3.event.dy;
        d.x += d3.event.dx;
        d.y += d3.event.dy;
    }
    function dragend(d, i) {
        d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
        force.resume();
        for (var i = 0; i < 20; ++i) force.tick();
        force.stop();

    }
    function releasenode(d) {
        d.fixed = false; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
        //force.resume();
    };

d3.csv("cooccurrenceMatrixData.csv", function(data){

  selectedList = ['pm','school','mandarin','up','chinese','strike','new'];
  data1 = $.map(data, function(element){
    return ($.inArray(element.word1,selectedList)>-1?element:null);
  });
  data = $.map(data1, function(element){
    return ($.inArray(element.word2,selectedList)>-1?element:null);
  });

  graphDict = {};
  graphDict['nodes'] = [];
  graphDict['links'] = [];
  entrylist = [];
  for (i=0; i<data.length; i++){
    if ($.inArray(data[i].word1, entrylist) < 0){
      dict = {};
      dict['name'] = data[i].word1
      dict['group'] = 0
      graphDict['nodes'].push(dict)
      entrylist.push(data[i].word1);
    };
    if ($.inArray(data[i].word2, entrylist) < 0){
      dict = {};
      dict['name'] = data[i].word2
      dict['group'] = 0
      graphDict['nodes'].push(dict)
      entrylist.push(data[i].word2);
    };
    dict = {};
    dict['source'] = entrylist.indexOf(data[i].word1);
    dict['target'] = entrylist.indexOf(data[i].word2);
    dict['value'] = +data[i].size
    graphDict['links'].push(dict);
    drawGraph(graph);

  };

  function drawGraph(graph){
    force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

    var graphMin = d3.min(graph.links, function(d){ return d.size; });
    var graphMax = d3.max(graph.links, function(d){ return d.size; });

    var fill = d3.scale.ordinal()
        .domain([graphMin, graphMax])
        .range(["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4",
          "#41ae76","#238b45","#006d2c","#00441b"]);

    var div = d3.select('div#chord_chart').append('div')
            .attr('class', 'tooltip')
            .style('opacity', 0);

    var link = forceSvg.selectAll(".link")
        .data(graph.links)
      .enter().append("line")
        .attr("class", "link")
        .style('stroke-width', 1)
        .style('stroke', function(d){ return fill(d.value); });
        //.style("stroke-width", function(d) { return Math.sqrt(d.value); });

    var node = forceSvg.selectAll(".node")
        .data(graph.nodes)
      .enter().append("circle")
        .attr("class", "node")
        .attr("r", 5)
        .style("fill", function(d) { return color(d.group); })
        .on('dblclick', releasenode)
        .on('click', connectedNodes)
        .call(node_drag);
        //.call(force.drag);

    node
        .on('mouseover', function(d,i,j){
            d3.select(this).transition().duration(600)
              .attr('r', 8).style('opacity', 1);
            div.transition()
              .duration(500)
              .style('opacity', 1);
            div.html(d.name)
              .style('left', '300px')
              .style('top', '10px');
              //.style('left', (d3.event.pageX) + 10 + "px")
              //.style('top', (d3.event.pageY) + 2 + "px")
              //.style('color', line_color(used_data[j].term));
        })
        .on('mouseout', function(d){
            d3.select(this).transition().duration(600)
              .attr('r', 5).style('opacity', 1);
            div.transition()
              .duration(500)
              .style('opacity', 0);
        });

    node.append("title")
        .text(function(d) { return d.name; });

    force.on("tick", function() {
      link.attr("x1", function(d) { return d.source.x; })
          .attr("y1", function(d) { return d.source.y; })
          .attr("x2", function(d) { return d.target.x; })
          .attr("y2", function(d) { return d.target.y; });

      node.attr("cx", function(d) { return d.x; })
          .attr("cy", function(d) { return d.y; });
    });

    var k = 0;
    while ((force.alpha() > 1e-2) && (k < 150)) {
        force.tick(),
        k = k + 1;
    }

    //Toggle stores whether the highlighting is on
  var toggle = 0;

  //Create an array logging what is connected to what
  var linkedByIndex = {};
  for (i = 0; i < graph.nodes.length; i++) {
      linkedByIndex[i + "," + i] = 1;
  };
  graph.links.forEach(function (d) {
      linkedByIndex[d.source.index + "," + d.target.index] = 1;
  });

  //This function looks up whether a pair are neighbours
  function neighboring(a, b) {
      return linkedByIndex[a.index + "," + b.index];
  }

  function connectedNodes() {

    if (toggle == 0) {
        //Reduce the opacity of all but the neighbouring nodes
        d = d3.select(this).node().__data__;
        node.style("opacity", function (o) {
            return neighboring(d, o) | neighboring(o, d) ? 1 : 0.1;
        });

        link.style("opacity", function (o) {
            return d.index==o.source.index | d.index==o.target.index ? 1 : 0.1;
        });

        //Reduce the op

        toggle = 1;
    } else {
        //Put them back to opacity=1
        node.style("opacity", 1);
        link.style("opacity", 1);
        toggle = 0;
    }

  }
  }

});

/*
d3.json("newsGraph.json", function(error, graph) {
  testGraph = JSON.parse(JSON.stringify(graph))

  selectedList = ['up','police','china','labor','union'];
  selectedData1 = $.map(testGraph.nodes, function(element){
      return ($.inArray(element.name,selectedList)>-1?element:null);
    });

  selectedData2 = $.map(testGraph.links, function(element){
      return ($.inArray(element['name1'],selectedList)>-1?element:null);
    });

  selectedData3 = $.map(selectedData2, function(element){
      return ($.inArray(element.name2,selectedList)>-1?element:null);
    });

  new_graph = {};
  new_graph['nodes'] = graph.nodes;
  new_graph['links'] = selectedData3;

  //drawGraph(graph, selectedData1, selectedData3);
  drawGraph(graph);

});
*/

<commit_msg>update data<commit_after>var width = 960,
    height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-80)
    .linkDistance(200)
    .friction(0.9)
    .size([width, height]);

var forceSvg = d3.select("div#chord_chart").append("svg")
    .attr("width", width)
    .attr("height", height);

var node_drag = d3.behavior.drag()
    .on("dragstart", dragstart)
    .on("drag", dragmove)
    .on("dragend", dragend);
    function dragstart(d, i) {
        force.stop() // stops the force auto positioning before you start dragging
    }
    function dragmove(d, i) {
        d.px += d3.event.dx;
        d.py += d3.event.dy;
        d.x += d3.event.dx;
        d.y += d3.event.dy;
    }
    function dragend(d, i) {
        d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
        force.resume();
        for (var i = 0; i < 20; ++i) force.tick();
        force.stop();

    }
    function releasenode(d) {
        d.fixed = false; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
        //force.resume();
    };

d3.csv("cooccurrenceMatrixData.csv", function(data){

  selectedList = ['pm','school','mandarin','up','chinese','strike','new'];
  data1 = $.map(data, function(element){
    return ($.inArray(element.word1,selectedList)>-1?element:null);
  });
  data = $.map(data1, function(element){
    return ($.inArray(element.word2,selectedList)>-1?element:null);
  });

  graphDict = {};
  graphDict['nodes'] = [];
  graphDict['links'] = [];
  entrylist = [];
  for (i=0; i<data.length; i++){
    if ($.inArray(data[i].word1, entrylist) < 0){
      dict = {};
      dict['name'] = data[i].word1
      dict['group'] = 0
      graphDict['nodes'].push(dict)
      entrylist.push(data[i].word1);
    };
    if ($.inArray(data[i].word2, entrylist) < 0){
      dict = {};
      dict['name'] = data[i].word2
      dict['group'] = 0
      graphDict['nodes'].push(dict)
      entrylist.push(data[i].word2);
    };
    dict = {};
    dict['source'] = entrylist.indexOf(data[i].word1);
    dict['target'] = entrylist.indexOf(data[i].word2);
    dict['value'] = +data[i].size
    graphDict['links'].push(dict);

  };
  drawGraph(graphDict);

  function drawGraph(graph){
    force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

    var graphMin = d3.min(graph.links, function(d){ return d.size; });
    var graphMax = d3.max(graph.links, function(d){ return d.size; });

    var fill = d3.scale.ordinal()
        .domain([graphMin, graphMax])
        .range(["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4",
          "#41ae76","#238b45","#006d2c","#00441b"]);

    var div = d3.select('div#chord_chart').append('div')
            .attr('class', 'tooltip')
            .style('opacity', 0);

    var link = forceSvg.selectAll(".link")
        .data(graph.links)
      .enter().append("line")
        .attr("class", "link")
        .style('stroke-width', 1)
        .style('stroke', function(d){ return fill(d.value); });
        //.style("stroke-width", function(d) { return Math.sqrt(d.value); });

    var node = forceSvg.selectAll(".node")
        .data(graph.nodes)
      .enter().append("circle")
        .attr("class", "node")
        .attr("r", 5)
        .style("fill", function(d) { return color(d.group); })
        .on('dblclick', releasenode)
        .on('click', connectedNodes)
        .call(node_drag);
        //.call(force.drag);

    node
        .on('mouseover', function(d,i,j){
            d3.select(this).transition().duration(600)
              .attr('r', 8).style('opacity', 1);
            div.transition()
              .duration(500)
              .style('opacity', 1);
            div.html(d.name)
              .style('left', '300px')
              .style('top', '10px');
              //.style('left', (d3.event.pageX) + 10 + "px")
              //.style('top', (d3.event.pageY) + 2 + "px")
              //.style('color', line_color(used_data[j].term));
        })
        .on('mouseout', function(d){
            d3.select(this).transition().duration(600)
              .attr('r', 5).style('opacity', 1);
            div.transition()
              .duration(500)
              .style('opacity', 0);
        });

    node.append("title")
        .text(function(d) { return d.name; });

    force.on("tick", function() {
      link.attr("x1", function(d) { return d.source.x; })
          .attr("y1", function(d) { return d.source.y; })
          .attr("x2", function(d) { return d.target.x; })
          .attr("y2", function(d) { return d.target.y; });

      node.attr("cx", function(d) { return d.x; })
          .attr("cy", function(d) { return d.y; });
    });

    var k = 0;
    while ((force.alpha() > 1e-2) && (k < 150)) {
        force.tick(),
        k = k + 1;
    }

    //Toggle stores whether the highlighting is on
  var toggle = 0;

  //Create an array logging what is connected to what
  var linkedByIndex = {};
  for (i = 0; i < graph.nodes.length; i++) {
      linkedByIndex[i + "," + i] = 1;
  };
  graph.links.forEach(function (d) {
      linkedByIndex[d.source.index + "," + d.target.index] = 1;
  });

  //This function looks up whether a pair are neighbours
  function neighboring(a, b) {
      return linkedByIndex[a.index + "," + b.index];
  }

  function connectedNodes() {

    if (toggle == 0) {
        //Reduce the opacity of all but the neighbouring nodes
        d = d3.select(this).node().__data__;
        node.style("opacity", function (o) {
            return neighboring(d, o) | neighboring(o, d) ? 1 : 0.1;
        });

        link.style("opacity", function (o) {
            return d.index==o.source.index | d.index==o.target.index ? 1 : 0.1;
        });

        //Reduce the op

        toggle = 1;
    } else {
        //Put them back to opacity=1
        node.style("opacity", 1);
        link.style("opacity", 1);
        toggle = 0;
    }

  }
  }

});

/*
d3.json("newsGraph.json", function(error, graph) {
  testGraph = JSON.parse(JSON.stringify(graph))

  selectedList = ['up','police','china','labor','union'];
  selectedData1 = $.map(testGraph.nodes, function(element){
      return ($.inArray(element.name,selectedList)>-1?element:null);
    });

  selectedData2 = $.map(testGraph.links, function(element){
      return ($.inArray(element['name1'],selectedList)>-1?element:null);
    });

  selectedData3 = $.map(selectedData2, function(element){
      return ($.inArray(element.name2,selectedList)>-1?element:null);
    });

  new_graph = {};
  new_graph['nodes'] = graph.nodes;
  new_graph['links'] = selectedData3;

  //drawGraph(graph, selectedData1, selectedData3);
  drawGraph(graph);

});
*/

<|endoftext|>


<commit_before>function doAll(){
	var text = $("#inputText").val();
	var output="";
	$(".multioutput").remove();

	//reverse()
	output = reverse(text);
	$("#multioutput").append("

Reverse

");
	$("#multioutput").append("
"+output+"
");

	//atbash()
	output = atbash(text);
	$("#multioutput").append("

Atbash

");
	$("#multioutput").append("
"+output+"
");

	//odd-even()
	output = extractAlternatingChars(text,0);
	$("#multioutput").append("

Odd

");
	$("#multioutput").append("
"+output+"
");
	output = extractAlternatingChars(text,1);
	$("#multioutput").append("

Even

");
	$("#multioutput").append("
"+output+"
");

	//caseSwitch()
	output = caseSwitch(text);
	$("#multioutput").append("

Case Switch

");
	$("#multioutput").append("
"+output+"
");

}

function copyVals(){
	var text = $("#inputText").val();
	$("#outputText").val(text.trim());
	$("#outputText").removeClass("btn-success btn-warning");
	$(".multioutput").removeClass("btn-success btn-warning");
}

function clickToCopy(text){
	$("#outputText").val(text);
	$("#outputText").removeClass("btn-success btn-warning");
	formValidate($("#outputText"),text);
}

function recordLog(){
}

function formValidate(obj,text){
	classstring="";
	var ret = validate(text,keywords);
	if(ret.length>0){
		if(ret[0][1]=="full"){
			classstring="btn-success";
		}
		else if(ret[0][1]=="pattern"){
			classstring="btn-warning";
		}
		else if(ret[0][1]=="partial"){
			classstring="btn-info";
		}
	}
	else{
		classstring="";
	}
	if(obj){
		$(obj).removeClass("btn-success btn-warning btn-info");
		if(typeof classstring !== 'undefined'){
			$(obj).addClass(classstring);
		}
	}
	else{
		return classstring;
	}
	return;
}

function formAtbash(){
	text = atbash($("#outputText").val());
	$("#outputText").val(text);
	formValidate($("#outputText"),text);
}

function formReverse(){
	text = reverse($("#outputText").val());
	$("#outputText").val(text);
	formValidate($("#outputText"),text);
}

function formOddEven(){
	var text = $("#outputText").val();
	$(".multioutput").remove();
	$("#outputText").removeClass("btn-success btn-warning");
	$("#multioutput").append("

Odd

");
	$("#multioutput").append("

Even

");

	ret = extractAlternatingChars(text,0);
	$("#multioutput #odd").append("
"+ret+"
");
	$("#multioutput #odd .multioutput:last-child").addClass(formValidate("",ret));
	$("#multioutput #odd .multioutput:last-child").attr("value",ret);
	$("#multioutput #odd .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

	ret = extractAlternatingChars(text,1);
	$("#multioutput #even").append("
"+ret+"
");
	$("#multioutput #even .multioutput:last-child").addClass(formValidate("",ret));
	$("#multioutput #even .multioutput:last-child").attr("value",ret);
	$("#multioutput #even .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");
}

function formRotN(){
	var text = $("#outputText").val();
	$(".multioutput").remove();
	for(i=1;i<=25;i++){
		ret = caesar(text,i,0);
		$("#multioutput").append("
"+ret+" rot:"+i+"
");
		$("#multioutput .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");
		$("#multioutput .multioutput:last-child").addClass(formValidate("",ret));
	}
	formValidate();
}

function formAffine(){
	var text = $("#outputText").val();
	$(".multioutput").remove();
	a = new Array(9,21,15,3,19,7,23,11,5,17,25);
	for(i=0;i<=a.length;i++){
		for(b=0;b<26;b++){
			ret = affine(text,a[i],b,0);
			$("#multioutput").append("
"+ret+" (Affine A/B:"+a[i]+"/"+b+")
");
			$("#multioutput .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");
			$("#multioutput .multioutput:last-child").addClass(formValidate("",ret));
		}
	}
	formValidate();
}

function formColumnar(type){
	var text = $("#outputText").val();
	var fac = factors(text);
	$(".multioutput").remove();
	$("#outputText").removeClass("btn-success btn-warning");
	$("#multioutput").append("

Top to Bottom: Left to Right

");
	$("#multioutput").append("

Top to Bottom: Right to Left

");
	$("#multioutput").append("

Bottom to Top: Left to Right

");
	$("#multioutput").append("

Bottom to Top: Right to Left

");
	$("#multioutput").append("

Right to Left: Top to Bottom

");
	$("#multioutput").append("

Right to Left: Bottom to Top

");
	$("#multioutput").append("

Left to Right: Top to Bottom

");
	$("#multioutput").append("

Left to Right: Bottom to Top

");

	for(i=0;i<fac.length;i++){
		ret = columnar_transposition(text,fac[i],0,type);
		$("#multioutput #column0").append("
"+ret+" (columns:"+fac[i]+")
");
		$("#multioutput #column0 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column0 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column0 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],1,type);
		$("#multioutput #column1").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column1 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column1 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column1 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],2,type);
		$("#multioutput #column2").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column2 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column2 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column2 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],3,type);
		$("#multioutput #column3").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column3 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column3 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column3 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],4,type);
		$("#multioutput #column4").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column4 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column4 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column4 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],5,type);
		$("#multioutput #column5").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column5 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column5 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column5 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],6,type);
		$("#multioutput #column6").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column6 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column6 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column6 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],7,type);
		$("#multioutput #column7").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column7 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column7 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column7 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

	}

}

function formLettersNum(flag){
	text = $("#outputText").val();
	text = numText(text,flag);
	$("#outputText").removeClass("btn-success btn-warning");
	$("#outputText").val(text);
	formValidate($("#outputText"),text);
}

function formCaseSwitch(){
	text = caseSwitch($("#outputText").val());
	$("#outputText").val(text);
	formValidate($("#outputText"),text);
}

function formGroup(n){
	text = $("#outputText").val();
	output = "";
	for(i=0;i<text.length;i++){
		output = output+ text.charAt(i);
		if((i+1)%n==0){
			output = output + " ";
		}
	}
	$("#outputText").val(output);
}
<commit_msg>Update formhelper.js<commit_after>function doAll(){
	var text = $("#inputText").val();
	var output="";
	$(".multioutput").remove();

	//reverse()
	output = reverse(text);
	$("#multioutput").append("

Reverse

");
	$("#multioutput").append("
"+output+"
");

	//atbash()
	output = atbash(text);
	$("#multioutput").append("

Atbash

");
	$("#multioutput").append("
"+output+"
");

	//odd-even()
	output = extractAlternatingChars(text,0);
	$("#multioutput").append("

Odd

");
	$("#multioutput").append("
"+output+"
");
	output = extractAlternatingChars(text,1);
	$("#multioutput").append("

Even

");
	$("#multioutput").append("
"+output+"
");

	//caseSwitch()
	output = caseSwitch(text);
	$("#multioutput").append("

Case Switch

");
	$("#multioutput").append("
"+output+"
");

}

function copyVals(){
	var text = $("#inputText").val();
	$("#outputText").val(text.trim());
	$("#outputText").removeClass("btn-success btn-warning");
	$(".multioutput").removeClass("btn-success btn-warning");
}

function clickToCopy(text){
	$("#outputText").val(text);
	$("#outputText").removeClass("btn-success btn-warning");
	formValidate($("#outputText"),text);
}

function recordLog(){
}

function formValidate(obj,text){
	classstring="";
	var ret = validate(text,keywords);
	if(ret.length>0){
		if(ret[0][1]=="full"){
			classstring="btn-success";
		}
		else if(ret[0][1]=="pattern"){
			classstring="btn-warning";
		}
		else if(ret[0][1]=="partial"){
			classstring="btn-info";
		}
	}
	else{
		classstring="";
	}
	if(obj){
		$(obj).removeClass("btn-success btn-warning btn-info");
		if(typeof classstring !== 'undefined'){
			$(obj).addClass(classstring);
		}
	}
	else{
		return classstring;
	}
	return;
}

function formAtbash(){
	text = atbash($("#outputText").val());
	$("#outputText").val(text);
	formValidate($("#outputText"),text);
}

function formReverse(){
	text = reverse($("#outputText").val());
	$("#outputText").val(text);
	formValidate($("#outputText"),text);
}

function formOddEven(){
	var text = $("#outputText").val();
	$(".multioutput").remove();
	$("#outputText").removeClass("btn-success btn-warning");
	$("#multioutput").append("

Odd

");
	$("#multioutput").append("

Even

");

	ret = extractAlternatingChars(text,0);
	$("#multioutput #odd").append("
"+ret+"
");
	$("#multioutput #odd .multioutput:last-child").addClass(formValidate("",ret));
	$("#multioutput #odd .multioutput:last-child").attr("value",ret);
	$("#multioutput #odd .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

	ret = extractAlternatingChars(text,1);
	$("#multioutput #even").append("
"+ret+"
");
	$("#multioutput #even .multioutput:last-child").addClass(formValidate("",ret));
	$("#multioutput #even .multioutput:last-child").attr("value",ret);
	$("#multioutput #even .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");
}

function formRotN(){
	var text = $("#outputText").val();
	$(".multioutput").remove();
	for(i=1;i<=25;i++){
		ret = caesar(text,i,0);
		$("#multioutput").append("
"+ret+" rot:"+i+"
");
		$("#multioutput .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");
		$("#multioutput .multioutput:last-child").addClass(formValidate("",ret));
	}
	formValidate();
}

function formAffine(){
	var text = $("#outputText").val();
	$(".multioutput").remove();
	a = new Array(9,21,15,3,19,7,23,11,5,17,25);
	for(i=0;i<=a.length;i++){
		for(b=0;b<26;b++){
			ret = affine(text,a[i],b,0);
			$("#multioutput").append("
"+ret+" (Affine A/B:"+a[i]+"/"+i+")
");
			$("#multioutput .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");
			$("#multioutput .multioutput:last-child").addClass(formValidate("",ret));
		}
	}
	formValidate();
}

function formColumnar(type){
	var text = $("#outputText").val();
	var fac = factors(text);
	$(".multioutput").remove();
	$("#outputText").removeClass("btn-success btn-warning");
	$("#multioutput").append("

Top to Bottom: Left to Right

");
	$("#multioutput").append("

Top to Bottom: Right to Left

");
	$("#multioutput").append("

Bottom to Top: Left to Right

");
	$("#multioutput").append("

Bottom to Top: Right to Left

");
	$("#multioutput").append("

Right to Left: Top to Bottom

");
	$("#multioutput").append("

Right to Left: Bottom to Top

");
	$("#multioutput").append("

Left to Right: Top to Bottom

");
	$("#multioutput").append("

Left to Right: Bottom to Top

");

	for(i=0;i<fac.length;i++){
		ret = columnar_transposition(text,fac[i],0,type);
		$("#multioutput #column0").append("
"+ret+" (columns:"+fac[i]+")
");
		$("#multioutput #column0 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column0 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column0 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],1,type);
		$("#multioutput #column1").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column1 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column1 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column1 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],2,type);
		$("#multioutput #column2").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column2 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column2 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column2 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],3,type);
		$("#multioutput #column3").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column3 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column3 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column3 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],4,type);
		$("#multioutput #column4").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column4 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column4 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column4 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],5,type);
		$("#multioutput #column5").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column5 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column5 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column5 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],6,type);
		$("#multioutput #column6").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column6 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column6 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column6 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

		ret = columnar_transposition(text,fac[i],7,type);
		$("#multioutput #column7").append("
"+ret+"(columns:"+fac[i]+")
");
		$("#multioutput #column7 .multioutput:last-child").addClass(formValidate("",ret));
		$("#multioutput #column7 .multioutput:last-child").attr("value",ret);
		$("#multioutput #column7 .multioutput:last-child").attr("ondblclick","clickToCopy(\""+ret+"\")");

	}

}

function formLettersNum(flag){
	text = $("#outputText").val();
	text = numText(text,flag);
	$("#outputText").removeClass("btn-success btn-warning");
	$("#outputText").val(text);
	formValidate($("#outputText"),text);
}

function formCaseSwitch(){
	text = caseSwitch($("#outputText").val());
	$("#outputText").val(text);
	formValidate($("#outputText"),text);
}

function formGroup(n){
	text = $("#outputText").val();
	output = "";
	for(i=0;i<text.length;i++){
		output = output+ text.charAt(i);
		if((i+1)%n==0){
			output = output + " ";
		}
	}
	$("#outputText").val(output);
}
<|endoftext|>


<commit_before>/*jshint worker: true*/
import Utils from './utils/utils';
import WorkerBroker from './utils/worker_broker'; // jshint ignore:line
import mergeObjects from './utils/merge';
import Tile from './tile';
import DataSource from './sources/data_source';
import FeatureSelection from './selection';
import {StyleParser} from './styles/style_parser';
import {StyleManager} from './styles/style_manager';
import {parseRules} from './styles/rule';
import Texture from './gl/texture';

export var SceneWorker = self;

// Worker functionality will only be defined in worker thread
if (Utils.isWorkerThread) {

Object.assign(self, {

    FeatureSelection,

    sources: {
        tiles: {},
        objects: {}
    },
    styles: {},
    rules: {},
    layers: {},
    tiles: {},
    objects: {},
    config: {},     // raw config (e.g. functions, etc. not expanded)

    // Initialize worker
    init (worker_id, num_workers, device_pixel_ratio) {
        self._worker_id = worker_id;
        self.num_workers = num_workers;
        Utils.device_pixel_ratio = device_pixel_ratio;
        FeatureSelection.setPrefix(self._worker_id);
        return worker_id;
    },

    // Starts a config refresh
    updateConfig ({ config, generation }) {
        config = JSON.parse(config);

        self.last_config = mergeObjects({}, self.config);
        self.config = mergeObjects({}, config);
        self.generation = generation;

        // Data block functions are not context wrapped like the rest of the style functions are
        // TODO: probably want a cleaner way to exclude these
        for (let layer in config.layers) {
            if (config.layers[layer]) {
                config.layers[layer].data = Utils.stringsToFunctions(config.layers[layer].data);
            }
        }

        // Create data sources
        config.sources = Utils.stringsToFunctions(config.sources); // parse new sources
        self.sources.tiles = {}; // clear previous sources
        for (let name in config.sources) {
            let source;
            try {
                source = DataSource.create(Object.assign({}, config.sources[name], {name}));
            }
            catch(e) {
                continue;
            }

            if (!source) {
                continue;
            }

            if (source.tiled) {
                self.sources.tiles[name] = source;
            }
            else {
                // Distribute object sources across workers
                if (source.id % self.num_workers === self._worker_id) {
                    // Load source if not cached
                    self.sources.objects[name] = source;
                    if (!self.objects[source.name]) {
                        self.objects[source.name] = {};
                        source.load(self.objects[source.name]);
                    }
                }
            }
        }

        // Clear tile cache if data source config changed
        if (!self.config.sources ||
            !self.last_config.sources ||
            Object.keys(self.config.sources).some(s => {
                return JSON.stringify(self.config.sources[s]) !== JSON.stringify(self.last_config.sources[s]);
            })) {
            self.tiles = {};
        }

        // Expand styles
        config = Utils.stringsToFunctions(config, StyleParser.wrapFunction);
        self.styles = StyleManager.build(config.styles, { generation: self.generation });

        // Parse each top-level layer as a separate rule tree
        self.layers = config.layers;
        self.rules = parseRules(self.layers);

        // Sync tetxure info from main thread
        self.syncing_textures = self.syncTextures(config.textures);

        // Return promise for when config refresh finishes
        self.configuring = self.syncing_textures.then(() => {
            Utils.log('debug', `updated config`);
        });
    },

    // Returns a promise that fulfills when config refresh is finished
    awaitConfiguration () {
        return self.configuring;
    },

    // Build a tile: load from tile source if building for first time, otherwise rebuild with existing data
    buildTile ({ tile }) {
        // Tile cached?
        if (self.tiles[tile.key] != null) {
            // Already loading?
            if (self.tiles[tile.key].loading === true) {
                return;
            }
        }

        // Update tile cache
        tile = self.tiles[tile.key] = Object.assign(self.tiles[tile.key] || {}, tile);

        // Update config (styles, etc.), then build tile
        return self.awaitConfiguration().then(() => {
            // First time building the tile
            if (tile.loaded !== true) {

                return new Promise((resolve, reject) => {

                    tile.loading = true;
                    tile.loaded = false;
                    tile.error = null;

                    self.loadTileSourceData(tile).then(() => {
                        // Warn and continue on data source error
                        if (tile.source_data.error) {
                            Utils.log('warn', `tile load error(s) for ${tile.key}: ${tile.source_data.error}`);
                        }

                        tile.loading = false;
                        tile.loaded = true;
                        Tile.buildGeometry(tile, self.layers, self.rules, self.styles).then(keys => {
                            resolve({ tile: Tile.slice(tile, keys) });
                        });
                    }).catch((error) => {
                        tile.loading = false;
                        tile.loaded = false;
                        tile.error = error.toString();
                        Utils.log('error', `tile load error for ${tile.key}: ${tile.error} at: ${error.stack}`);

                        resolve({ tile: Tile.slice(tile) });
                    });
                });
            }
            // Tile already loaded, just rebuild
            else {
                Utils.log('trace', `used worker cache for tile ${tile.key}`);

                // Build geometry
                return Tile.buildGeometry(tile, self.layers, self.rules, self.styles).then(keys => {
                    return { tile: Tile.slice(tile, keys) };
                });
            }
        });
    },

    // Load this tile's data source
    loadTileSourceData (tile) {
        return self.sources.tiles[tile.source].load(tile);
    },

    // Remove tile
    removeTile (key) {
        var tile = self.tiles[key];

        if (tile != null) {
            // Cancel if loading
            if (tile.loading === true) {
                Utils.log('trace', `cancel tile load for ${key}`);
                tile.loading = false;
            }

            Tile.cancel(tile);

            // Remove from cache
            FeatureSelection.clearTile(key);
            delete self.tiles[key];
            Utils.log('trace', `remove tile from cache for ${key}`);
        }
    },

    // Get a feature from the selection map
    getFeatureSelection ({ id, key } = {}) {
        var selection = FeatureSelection.map[key];

        return {
            id: id,
            feature: (selection && selection.feature)
        };
    },

    // Resets the feature selection state
    resetFeatureSelection () {
        FeatureSelection.reset();
    },

    // Selection map size for this worker
    getFeatureSelectionMapSize () {
        return FeatureSelection.getMapSize();
    },

    // Texture info needs to be synced from main thread, e.g. width/height, which we only know after the texture loads
    syncTextures (tex_config) {
        let textures = [];
        if (tex_config) {
            textures.push(...Object.keys(tex_config));
        }

        Utils.log('trace', 'sync textures to worker:', textures);
        if (textures.length > 0) {
            return Texture.syncTexturesToWorker(textures);
        }
        return Promise.resolve();
    },

    // Sync device pixel ratio from main thread
    updateDevicePixelRatio (device_pixel_ratio) {
        Utils.device_pixel_ratio = device_pixel_ratio;
    },

    // Profiling helpers
    profile (name) {
        console.profile(`worker ${self._worker_id}: ${name}`);
    },

    profileEnd (name) {
        console.profileEnd(`worker ${self._worker_id}: ${name}`);
    }

});

WorkerBroker.addTarget('self', self);

}
<commit_msg>throw error if trying to build tile for a non-existent data source<commit_after>/*jshint worker: true*/
import Utils from './utils/utils';
import WorkerBroker from './utils/worker_broker'; // jshint ignore:line
import mergeObjects from './utils/merge';
import Tile from './tile';
import DataSource from './sources/data_source';
import FeatureSelection from './selection';
import {StyleParser} from './styles/style_parser';
import {StyleManager} from './styles/style_manager';
import {parseRules} from './styles/rule';
import Texture from './gl/texture';

export var SceneWorker = self;

// Worker functionality will only be defined in worker thread
if (Utils.isWorkerThread) {

Object.assign(self, {

    FeatureSelection,

    sources: {
        tiles: {},
        objects: {}
    },
    styles: {},
    rules: {},
    layers: {},
    tiles: {},
    objects: {},
    config: {},     // raw config (e.g. functions, etc. not expanded)

    // Initialize worker
    init (worker_id, num_workers, device_pixel_ratio) {
        self._worker_id = worker_id;
        self.num_workers = num_workers;
        Utils.device_pixel_ratio = device_pixel_ratio;
        FeatureSelection.setPrefix(self._worker_id);
        return worker_id;
    },

    // Starts a config refresh
    updateConfig ({ config, generation }) {
        config = JSON.parse(config);

        self.last_config = mergeObjects({}, self.config);
        self.config = mergeObjects({}, config);
        self.generation = generation;

        // Data block functions are not context wrapped like the rest of the style functions are
        // TODO: probably want a cleaner way to exclude these
        for (let layer in config.layers) {
            if (config.layers[layer]) {
                config.layers[layer].data = Utils.stringsToFunctions(config.layers[layer].data);
            }
        }

        // Create data sources
        config.sources = Utils.stringsToFunctions(config.sources); // parse new sources
        self.sources.tiles = {}; // clear previous sources
        for (let name in config.sources) {
            let source;
            try {
                source = DataSource.create(Object.assign({}, config.sources[name], {name}));
            }
            catch(e) {
                continue;
            }

            if (!source) {
                continue;
            }

            if (source.tiled) {
                self.sources.tiles[name] = source;
            }
            else {
                // Distribute object sources across workers
                if (source.id % self.num_workers === self._worker_id) {
                    // Load source if not cached
                    self.sources.objects[name] = source;
                    if (!self.objects[source.name]) {
                        self.objects[source.name] = {};
                        source.load(self.objects[source.name]);
                    }
                }
            }
        }

        // Clear tile cache if data source config changed
        if (!self.config.sources ||
            !self.last_config.sources ||
            Object.keys(self.config.sources).some(s => {
                return JSON.stringify(self.config.sources[s]) !== JSON.stringify(self.last_config.sources[s]);
            })) {
            self.tiles = {};
        }

        // Expand styles
        config = Utils.stringsToFunctions(config, StyleParser.wrapFunction);
        self.styles = StyleManager.build(config.styles, { generation: self.generation });

        // Parse each top-level layer as a separate rule tree
        self.layers = config.layers;
        self.rules = parseRules(self.layers);

        // Sync tetxure info from main thread
        self.syncing_textures = self.syncTextures(config.textures);

        // Return promise for when config refresh finishes
        self.configuring = self.syncing_textures.then(() => {
            Utils.log('debug', `updated config`);
        });
    },

    // Returns a promise that fulfills when config refresh is finished
    awaitConfiguration () {
        return self.configuring;
    },

    // Build a tile: load from tile source if building for first time, otherwise rebuild with existing data
    buildTile ({ tile }) {
        // Tile cached?
        if (self.tiles[tile.key] != null) {
            // Already loading?
            if (self.tiles[tile.key].loading === true) {
                return;
            }
        }

        // Update tile cache
        tile = self.tiles[tile.key] = Object.assign(self.tiles[tile.key] || {}, tile);

        // Update config (styles, etc.), then build tile
        return self.awaitConfiguration().then(() => {
            // First time building the tile
            if (tile.loaded !== true) {

                return new Promise((resolve, reject) => {

                    tile.loading = true;
                    tile.loaded = false;
                    tile.error = null;

                    self.loadTileSourceData(tile).then(() => {
                        // Warn and continue on data source error
                        if (tile.source_data.error) {
                            Utils.log('warn', `tile load error(s) for ${tile.key}: ${tile.source_data.error}`);
                        }

                        tile.loading = false;
                        tile.loaded = true;
                        Tile.buildGeometry(tile, self.layers, self.rules, self.styles).then(keys => {
                            resolve({ tile: Tile.slice(tile, keys) });
                        });
                    }).catch((error) => {
                        tile.loading = false;
                        tile.loaded = false;
                        tile.error = error.toString();
                        Utils.log('error', `tile load error for ${tile.key}: ${tile.error} at: ${error.stack}`);

                        resolve({ tile: Tile.slice(tile) });
                    });
                });
            }
            // Tile already loaded, just rebuild
            else {
                Utils.log('trace', `used worker cache for tile ${tile.key}`);

                // Build geometry
                return Tile.buildGeometry(tile, self.layers, self.rules, self.styles).then(keys => {
                    return { tile: Tile.slice(tile, keys) };
                });
            }
        });
    },

    // Load this tile's data source
    loadTileSourceData (tile) {
        if (self.sources.tiles[tile.source]) {
            return self.sources.tiles[tile.source].load(tile);
        }
        else {
            tile.source_data = { error: `Data source '${tile.source}' not found` };
            return Promise.resolve(tile);
        }
    },

    // Remove tile
    removeTile (key) {
        var tile = self.tiles[key];

        if (tile != null) {
            // Cancel if loading
            if (tile.loading === true) {
                Utils.log('trace', `cancel tile load for ${key}`);
                tile.loading = false;
            }

            Tile.cancel(tile);

            // Remove from cache
            FeatureSelection.clearTile(key);
            delete self.tiles[key];
            Utils.log('trace', `remove tile from cache for ${key}`);
        }
    },

    // Get a feature from the selection map
    getFeatureSelection ({ id, key } = {}) {
        var selection = FeatureSelection.map[key];

        return {
            id: id,
            feature: (selection && selection.feature)
        };
    },

    // Resets the feature selection state
    resetFeatureSelection () {
        FeatureSelection.reset();
    },

    // Selection map size for this worker
    getFeatureSelectionMapSize () {
        return FeatureSelection.getMapSize();
    },

    // Texture info needs to be synced from main thread, e.g. width/height, which we only know after the texture loads
    syncTextures (tex_config) {
        let textures = [];
        if (tex_config) {
            textures.push(...Object.keys(tex_config));
        }

        Utils.log('trace', 'sync textures to worker:', textures);
        if (textures.length > 0) {
            return Texture.syncTexturesToWorker(textures);
        }
        return Promise.resolve();
    },

    // Sync device pixel ratio from main thread
    updateDevicePixelRatio (device_pixel_ratio) {
        Utils.device_pixel_ratio = device_pixel_ratio;
    },

    // Profiling helpers
    profile (name) {
        console.profile(`worker ${self._worker_id}: ${name}`);
    },

    profileEnd (name) {
        console.profileEnd(`worker ${self._worker_id}: ${name}`);
    }

});

WorkerBroker.addTarget('self', self);

}
<|endoftext|>


<commit_before>'use strict';

let superagent = require('superagent');

/**
 * Class Poster
 *
 * Post messages to Slack
 */
class Poster
{
    /**
     * Construct an instance of a Poster
     *
     * @param Config
     */
    constructor (Config)
    {
        this.config = Config;
    }

    /**
     * Post a message to slack
     *
     * @param username
     * @param message
     * @param callback
     */
    send (username, message, callback)
    {
        superagent
            .post(config.get('slack.url'))
            .send({
                username: username,
                message: message
            })
            .end(function(error, res){
                if (callback) {
                    callback(error, res);
                }
            });
    }
}

module.exports = Poster;
<commit_msg>Bug fix for the Poster service<commit_after>'use strict';

let superagent = require('superagent');

/**
 * Class Poster
 *
 * Post messages to Slack
 */
class Poster
{
    /**
     * Construct an instance of a Poster
     *
     * @param Config
     */
    constructor (Config)
    {
        this.config = Config;
    }

    /**
     * Post a message to slack
     *
     * @param username
     * @param message
     * @param callback
     */
    send (username, message, callback)
    {
        superagent
            .post(this.config.get('slack.url'))
            .send({
                username: username,
                message: message
            })
            .end(function(error, res){
                if (callback) {
                    callback(error, res);
                }
            });
    }
}

module.exports = Poster;
<|endoftext|>


<commit_before>// server.js
// // BASE SETUP
// // =============================================================================
//
var mongoose   = require('mongoose');
mongoose.connect('mongodb://localhost/assidu_node')
//var Person     = require('./app/models/person');
var express    = require('express');        // call express
var app        = express();                 // define our app using express
var path = require('path');
var bodyParser = require('body-parser');
var routes = require('./routes');
//var routes = require('routes')(app);
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', routes);

app.get('*', function(req, res) {
    // load the single view file (angular will handle
    // the page changes on the front-end)
    res.sendFile(path.join(__dirname + '/testrig/index.html'));
});

var port = process.env.PORT || 8080;        // set our port
// START THE SERVER
// =============================================================================
app.listen(port, "0.0.0.0" );
console.log('server.js serving on ' + port);
<commit_msg>Minor tweak to comments<commit_after>// server.js
// // BASE SETUP
// // =============================================================================
//
var mongoose   = require('mongoose');
mongoose.connect('mongodb://localhost/assidu_node')
//var Person     = require('./app/models/person');
var express    = require('express');        // call express
var app        = express();                 // define our app using express
var path = require('path');
var bodyParser = require('body-parser');
var routes = require('./routes');
//var routes = require('routes')(app);
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', routes);

app.get('*', function(req, res) {
    //Load the main .html page and allow angular to do its
    //thing within that page
    res.sendFile(path.join(__dirname + '/testrig/index.html'));
});

var port = process.env.PORT || 8080;        // set our port
// START THE SERVER
// =============================================================================
app.listen(port, "0.0.0.0" );
console.log('server.js serving on ' + port);
<|endoftext|>


<commit_before>/*!
 * Start Bootstrap - Freelancer Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

// jQuery for page scrolling feature - requires jQuery Easing plugin
$(function() {
    $('.page-scroll a').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });
});

// Floating label headings for the contact form
$(function() {
    $("body").on("input propertychange", ".floating-label-form-group", function(e) {
        $(this).toggleClass("floating-label-form-group-with-value", !! $(e.target).val());
    }).on("focus", ".floating-label-form-group", function() {
        $(this).addClass("floating-label-form-group-with-focus");
    }).on("blur", ".floating-label-form-group", function() {
        $(this).removeClass("floating-label-form-group-with-focus");
    });
});

// Highlight the top nav as scrolling occurs
$('body').scrollspy({
    target: '.navbar-fixed-top'
})

// Closes the Responsive Menu on Menu Item Click
$('.navbar-collapse ul li a').click(function() {
    $('.navbar-toggle:visible').click();
});

$(document).ready(function () {
    $("#portfolio a[title].tooltip-info").each(function () {
        $(this).attr("title-tooltip", $(this).attr("title"));
        $(this).removeAttr("title");
    })

    $("#portfolio a.tooltip-info").click(function (e) {
        if ($(this).attr("href") == "#") {
            e.preventDefault();
        }
    });
})<commit_msg>Hide header and footer when embedded<commit_after>/*!
 * Start Bootstrap - Freelancer Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

// jQuery for page scrolling feature - requires jQuery Easing plugin
$(function() {
    $('.page-scroll a').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });
});

// Floating label headings for the contact form
$(function() {
    $("body").on("input propertychange", ".floating-label-form-group", function(e) {
        $(this).toggleClass("floating-label-form-group-with-value", !! $(e.target).val());
    }).on("focus", ".floating-label-form-group", function() {
        $(this).addClass("floating-label-form-group-with-focus");
    }).on("blur", ".floating-label-form-group", function() {
        $(this).removeClass("floating-label-form-group-with-focus");
    });
});

// Highlight the top nav as scrolling occurs
$('body').scrollspy({
    target: '.navbar-fixed-top'
})

// Closes the Responsive Menu on Menu Item Click
$('.navbar-collapse ul li a').click(function() {
    $('.navbar-toggle:visible').click();
});

$(document).ready(function () {
    $("#portfolio a[title].tooltip-info").each(function () {
        $(this).attr("title-tooltip", $(this).attr("title"));
        $(this).removeAttr("title");
    })

    $("#portfolio a.tooltip-info").click(function (e) {
        if ($(this).attr("href") == "#") {
            e.preventDefault();
        }
    });

    if (inIframe()) {
        $("nav").addClass("hide");
        $("header").addClass("hide");
        $("footer").addClass("hide");
    }
})

function inIframe() {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}<|endoftext|>


<commit_before>import tv4 from 'tv4';

tv4.addFormat('date-time', (data) => {
    if (typeof data === 'string') {
        data = new Date(data);
    }
    if ((data instanceof Date) && !isNaN(data.getTime())) {
        return null;
    }
    return "Invalid date";
});

function isObject(val) {
    return val !== null && val !== undefined && typeof val === 'object';
}

/**
 * Clone javascript objects.
 * @private
 *
 * @param {Object|Array} obj The object to clone.
 * @param {Function} callback An optional function which runs before inserting a property.
 * @return {Object|Array} The clone of the object.
 */
function clone(obj, callback) {
    callback = callback || function(scope, key, prop) { return prop; };
    if (Array.isArray(obj)) {
        return obj.map((entry, index) => {
            entry = callback(obj, index, entry);
            if (isObject(entry)) {
                return clone(entry, callback);
            }
            return entry;
        });
    } else if (obj instanceof Date) {
        return new Date(obj);
    }
    let res = {};
    Object.keys(obj).forEach((k) => {
        let val = callback(obj, k, obj[k]);
        if (isObject(val)) {
            res[k] = clone(val, callback);
        } else {
            res[k] = val;
        }
    });
    return res;
}
/**
 * Merge two objects in a new one.
 * @private
 *
 * @param {Object} obj1 The initial object.
 * @param {Object} obj2 The object to merge.
 * @return {Object} The merged object.
 */
function merge(obj1, obj2) {
    let res = clone(obj1);
    Object.keys(obj2).forEach((key) => {
        if (isObject(obj2[key])) {
            if (isObject(res[key])) {
                res[key] = merge(res[key], obj2[key]);
            } else {
                res[key] = obj2[key];
            }
        } else {
            res[key] = obj2[key];
        }
    });
    return res;
}
/**
 * Get data from an object.
 * @private
 *
 * @param {Object} scope The object to use.
 * @param {String} k The data key.
 * @param {Boolean} internal Should get value has private property.
 * @return {any} The value of the object for the given key.
 */
function get(scope, k, internal) {
    if (internal) {
        k = getSymbol(k);
    }
    return scope[k];
}
/**
 * Merge data to another object.
 * @private
 *
 * @param {Object} scope The object to update.
 * @param {Object} data The object to merge.
 * @param {Boolean} internal Should set value has private property.
 */
function set(scope, data, internal) {
    Object.keys(data).forEach((k) => {
        let ok = k;
        if (internal) {
            k = getSymbol(k);
        }
        if (scope[k] !== data[ok]) {
            scope[k] = data[ok];
        }
    });
}
/**
 * Create a private symbol.
 * @private
 *
 * @param {String} name The name of the property to privatize.
 * @return {Symbol|String}
 */
function getSymbol(name) {
    if (!getSymbol.cache[name]) {
        if (typeof Symbol !== 'undefined') {
            getSymbol.cache[name] = Symbol(name);
        } else {
            getSymbol.cache[name] = `__${name}`;
        }
    }
    return getSymbol.cache[name];
}

getSymbol.cache = {};
/**
 * Get all root properties merging definition.
 * @private
 *
 * @param {Object} schema The schema to analyze.
 * @param {Object} validator The validator instance.
 * @return {Object} A list of properties.
 */
function getProperties(schema, validator) {
    let root = !validator;
    if (root) {
        validator = tv4.freshApi();
        validator.addSchema('', schema);
    }
    if (schema.$ref) {
        schema = validator.getSchema(schema.$ref);
    }
    if (schema.properties) {
        return clone(schema.properties);
    } else if (root) {
        let res = {};
        let defs = schema['anyOf'] || schema['allOf'] || schema['oneOf'];
        if (defs) {
            defs.forEach((def) => {
                res = merge(res, getProperties(def, validator));
            });
        }
        return res;
    }
    return {};
}

const DEFAULT_OPTIONS = {
    validate: true,
    internal: false,
};

export class SchemaModel {
    /**
     * Merge two objects in a new one.
     *
     * @param {Object} obj1 The initial object.
     * @param {Object} obj2 The object to merge.
     * @return {Object} The merged object.
     */
    static merge(...args) {
        return merge(...args);
    }
    /**
     * Clone javascript objects.
     *
     * @param {Object|Array} obj The object to clone.
     * @param {Function} callback An optional function which runs before inserting a property.
     * @return {Object|Array} The clone of the object.
     */
    static clone(...args) {
        return clone(...args);
    }
    /**
     * Create a new schema class extending SchemaModel.
     *
     * @param {Object} schema The schema to use for the new model class.
     * @return {class} An extended SchemaModel.
     */
    static create(schema) {
        return class extends SchemaModel {
            static get schema() {
                return schema;
            }
        };
    }
    /**
     * The schema of the model.
     * @type {Object}
     * @memberof SchemaModel
     */
    static get schema() {
        throw new Error('Missing schema');
    }
    /**
     * The schema merged properties.
     * @type {Object}
     * @memberof SchemaModel
     */
    static get schemaProperties() {
        return getProperties(this.schema);
    }
    /**
     * Generate Model classes based on JSON Schema definition.
     * @class
     *
     * @param {Object} data The (optional) initial data to set.
     * @param {Object} options Optional options for data setting.
     */
    constructor(data, options) {
        if (data) {
            this.set(data, options);
        }
    }
    /**
     * Get a property value.
     *
     * @param {String} name The property name to retrieve.
     * @param {Object} options Optional options for data getting.
     * @return {any} The property value.
     */
    get(name, options) {
        options = merge(DEFAULT_OPTIONS, options || {});
        return get(this, name, options.internal);
    }
    /**
     * Set a bunch of properties.
     *
     * @param {Object} data The data to set.
     * @param {Object} options Optional options for data setting.
     */
    set(data, value, options) {
        if (typeof data === 'string') {
            return this.set({
                [data]: value,
            }, options);
        }
        options = merge(DEFAULT_OPTIONS, value || {});
        if (!options.internal && options.validate) {
            let dataToValidate = merge(this.toJSON(true), data);
            let res = this.validate(dataToValidate, options);
            /* istanbul ignore if */
            if (!res.valid) {
                if (res.error && res.error.message) {
                    throw new Error(res.error.message);
                } else if (res.missing.length) {
                    throw new Error(`Missing $ref schemas: ${res.missing.join(', ')}`);
                }
                throw new Error('Validation failed');
            } else {
                data = dataToValidate;
            }
        }
        set(this, data, options.internal);
    }
    /**
     * Validate a bunch of data or the model instance.
     *
     * @param {Object} data Optional data to validate (if empty, use model's data).
     * @return {Object} A validation result.
     */
    validate(data) {
        data = data || this.toJSON(true);
        let schema = this.constructor.schema;
        let res = tv4.validateResult(data, schema);
        /* istanbul ignore if  */
        if (res.valid && res.missing.length) {
            res.valid = false;
        }
        return res;
    }
    /**
     * Convert the model to a plain javascript object.
     *
     * @param {Boolean} stripUndefined Strip undefined values from model.
     * @return {Object} A representation of the model as plain object.
     */
    toJSON(stripUndefined) {
        let keys = Object.keys(this.constructor.schemaProperties);
        let res = {};
        keys.forEach((key) => {
            let val = this.get(key);
            if (!stripUndefined || val !== undefined) {
                res[key] = val;
            }
        });
        res = clone(res, (scope, key, prop) => {
            if (prop instanceof SchemaModel) {
                return prop.toJSON(stripUndefined);
            }
            return prop;
        });
        return res;
    }
}

SchemaModel.symbols = {};
<commit_msg>fix: set correct data<commit_after>import tv4 from 'tv4';

tv4.addFormat('date-time', (data) => {
    if (typeof data === 'string') {
        data = new Date(data);
    }
    if ((data instanceof Date) && !isNaN(data.getTime())) {
        return null;
    }
    return "Invalid date";
});

function isObject(val) {
    return val !== null && val !== undefined && typeof val === 'object';
}

/**
 * Clone javascript objects.
 * @private
 *
 * @param {Object|Array} obj The object to clone.
 * @param {Function} callback An optional function which runs before inserting a property.
 * @return {Object|Array} The clone of the object.
 */
function clone(obj, callback) {
    callback = callback || function(scope, key, prop) { return prop; };
    if (Array.isArray(obj)) {
        return obj.map((entry, index) => {
            entry = callback(obj, index, entry);
            if (isObject(entry)) {
                return clone(entry, callback);
            }
            return entry;
        });
    } else if (obj instanceof Date) {
        return new Date(obj);
    }
    let res = {};
    Object.keys(obj).forEach((k) => {
        let val = callback(obj, k, obj[k]);
        if (isObject(val)) {
            res[k] = clone(val, callback);
        } else {
            res[k] = val;
        }
    });
    return res;
}
/**
 * Merge two objects in a new one.
 * @private
 *
 * @param {Object} obj1 The initial object.
 * @param {Object} obj2 The object to merge.
 * @return {Object} The merged object.
 */
function merge(obj1, obj2) {
    let res = clone(obj1);
    Object.keys(obj2).forEach((key) => {
        if (isObject(obj2[key])) {
            if (isObject(res[key])) {
                res[key] = merge(res[key], obj2[key]);
            } else {
                res[key] = obj2[key];
            }
        } else {
            res[key] = obj2[key];
        }
    });
    return res;
}
/**
 * Get data from an object.
 * @private
 *
 * @param {Object} scope The object to use.
 * @param {String} k The data key.
 * @param {Boolean} internal Should get value has private property.
 * @return {any} The value of the object for the given key.
 */
function get(scope, k, internal) {
    if (internal) {
        k = getSymbol(k);
    }
    return scope[k];
}
/**
 * Merge data to another object.
 * @private
 *
 * @param {Object} scope The object to update.
 * @param {Object} data The object to merge.
 * @param {Boolean} internal Should set value has private property.
 */
function set(scope, data, internal) {
    Object.keys(data).forEach((k) => {
        let ok = k;
        if (internal) {
            k = getSymbol(k);
        }
        if (scope[k] !== data[ok]) {
            scope[k] = data[ok];
        }
    });
}
/**
 * Create a private symbol.
 * @private
 *
 * @param {String} name The name of the property to privatize.
 * @return {Symbol|String}
 */
function getSymbol(name) {
    if (!getSymbol.cache[name]) {
        if (typeof Symbol !== 'undefined') {
            getSymbol.cache[name] = Symbol(name);
        } else {
            getSymbol.cache[name] = `__${name}`;
        }
    }
    return getSymbol.cache[name];
}

getSymbol.cache = {};
/**
 * Get all root properties merging definition.
 * @private
 *
 * @param {Object} schema The schema to analyze.
 * @param {Object} validator The validator instance.
 * @return {Object} A list of properties.
 */
function getProperties(schema, validator) {
    let root = !validator;
    if (root) {
        validator = tv4.freshApi();
        validator.addSchema('', schema);
    }
    if (schema.$ref) {
        schema = validator.getSchema(schema.$ref);
    }
    if (schema.properties) {
        return clone(schema.properties);
    } else if (root) {
        let res = {};
        let defs = schema['anyOf'] || schema['allOf'] || schema['oneOf'];
        if (defs) {
            defs.forEach((def) => {
                res = merge(res, getProperties(def, validator));
            });
        }
        return res;
    }
    return {};
}

const DEFAULT_OPTIONS = {
    validate: true,
    internal: false,
};

export class SchemaModel {
    /**
     * Merge two objects in a new one.
     *
     * @param {Object} obj1 The initial object.
     * @param {Object} obj2 The object to merge.
     * @return {Object} The merged object.
     */
    static merge(...args) {
        return merge(...args);
    }
    /**
     * Clone javascript objects.
     *
     * @param {Object|Array} obj The object to clone.
     * @param {Function} callback An optional function which runs before inserting a property.
     * @return {Object|Array} The clone of the object.
     */
    static clone(...args) {
        return clone(...args);
    }
    /**
     * Create a new schema class extending SchemaModel.
     *
     * @param {Object} schema The schema to use for the new model class.
     * @return {class} An extended SchemaModel.
     */
    static create(schema) {
        return class extends SchemaModel {
            static get schema() {
                return schema;
            }
        };
    }
    /**
     * The schema of the model.
     * @type {Object}
     * @memberof SchemaModel
     */
    static get schema() {
        throw new Error('Missing schema');
    }
    /**
     * The schema merged properties.
     * @type {Object}
     * @memberof SchemaModel
     */
    static get schemaProperties() {
        return getProperties(this.schema);
    }
    /**
     * Generate Model classes based on JSON Schema definition.
     * @class
     *
     * @param {Object} data The (optional) initial data to set.
     * @param {Object} options Optional options for data setting.
     */
    constructor(data, options) {
        if (data) {
            this.set(data, options);
        }
    }
    /**
     * Get a property value.
     *
     * @param {String} name The property name to retrieve.
     * @param {Object} options Optional options for data getting.
     * @return {any} The property value.
     */
    get(name, options) {
        options = merge(DEFAULT_OPTIONS, options || {});
        return get(this, name, options.internal);
    }
    /**
     * Set a bunch of properties.
     *
     * @param {Object} data The data to set.
     * @param {Object} options Optional options for data setting.
     */
    set(data, value, options) {
        if (typeof data === 'string') {
            return this.set({
                [data]: value,
            }, options);
        }
        data = data || {};
        options = merge(DEFAULT_OPTIONS, value || {});
        if (!options.internal && options.validate) {
            let dataToValidate = merge(this.toJSON(true), data);
            let res = this.validate(dataToValidate, options);
            /* istanbul ignore if */
            if (!res.valid) {
                if (res.error && res.error.message) {
                    throw new Error(res.error.message);
                } else if (res.missing.length) {
                    throw new Error(`Missing $ref schemas: ${res.missing.join(', ')}`);
                }
                throw new Error('Validation failed');
            }
        }
        set(this, data, options.internal);
    }
    /**
     * Validate a bunch of data or the model instance.
     *
     * @param {Object} data Optional data to validate (if empty, use model's data).
     * @return {Object} A validation result.
     */
    validate(data) {
        data = data || this.toJSON(true);
        let schema = this.constructor.schema;
        let res = tv4.validateResult(data, schema);
        /* istanbul ignore if  */
        if (res.valid && res.missing.length) {
            res.valid = false;
        }
        return res;
    }
    /**
     * Convert the model to a plain javascript object.
     *
     * @param {Boolean} stripUndefined Strip undefined values from model.
     * @return {Object} A representation of the model as plain object.
     */
    toJSON(stripUndefined) {
        let keys = Object.keys(this.constructor.schemaProperties);
        let res = {};
        keys.forEach((key) => {
            let val = this.get(key);
            if (!stripUndefined || val !== undefined) {
                res[key] = val;
            }
        });
        res = clone(res, (scope, key, prop) => {
            if (prop instanceof SchemaModel) {
                return prop.toJSON(stripUndefined);
            }
            return prop;
        });
        return res;
    }
}

SchemaModel.symbols = {};
<|endoftext|>


<commit_before>if (typeof buster == "undefined") {
    var buster = {};
}

buster.util = (function () {
    var div = typeof document != "undefined" && document.createElement("div");

    return {
        isNode: function (obj) {
            if (!div) {
                return false;
            }

            try {
                div.appendChild(obj);
                div.removeChild(obj);
            } catch (e) {
                return false;
            }

            return true;
        },

        isElement: function (obj) {
            return obj && this.isNode(obj) && obj.nodeType === 1;
        }
    };
}());

if (typeof module != "undefined") {
    module.exports = buster.util;
}
<commit_msg>Add util.isArguments<commit_after>if (typeof buster == "undefined") {
    var buster = {};
}

buster.util = (function () {
    var toString = Object.prototype.toString;
    var div = typeof document != "undefined" && document.createElement("div");

    return {
        isNode: function (obj) {
            if (!div) {
                return false;
            }

            try {
                div.appendChild(obj);
                div.removeChild(obj);
            } catch (e) {
                return false;
            }

            return true;
        },

        isElement: function (obj) {
            return obj && this.isNode(obj) && obj.nodeType === 1;
        },

        isArguments: function (obj) {
            if (typeof obj != "object" || typeof obj.length != "number" ||
                toString.call(obj) == "[object Array]") {
                return false;
            }

            if (typeof obj.callee == "function") {
                return true;
            }

            try {
                obj[obj.length] = 6;
                delete obj[obj.length];
            } catch (e) {
                return true;
            }

            return false;
        }
    };
}());

if (typeof module != "undefined") {
    module.exports = buster.util;
}
<|endoftext|>


<commit_before>var http = require('http'),
    app = require('./lib/app.js'),
    config = require('./config.js'),
    api = require('./lib/api.js');

app.configure(config);

var server = http.createServer();

server.on('request', function(req, res) {
  if(!api.route(req, res)) {
    console.log('No route found', req.url);
    res.end();
  }
}).listen(config.port, config.host);
<commit_msg>Fix server.js<commit_after>var http = require('http'),

    api = require('./lib/api.js'),
    Cache = require('./lib/cache.js'),
    Package = require('./lib/package.js'),

    config = require('./config.js');

Cache.configure({
    cacheDirectory: config.cacheDirectory,
    cacheAge: config.cacheAge
  });
Package.configure({
  cache: Cache,
  externalUrl: config.externalUrl
});

var server = http.createServer();

server.on('request', function(req, res) {
  if(!api.route(req, res)) {
    console.log('No route found', req.url);
    res.end();
  }
}).listen(config.port, config.host);

console.log('npm_lazy at', config.host, 'port', config.port);
<|endoftext|>