<commit_before>import React, { Component } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import PropTypes from 'prop-types';
import { styled } from '@storybook/theming';

const Context = React.createContext();

class Provider extends Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
  };

  state = {
    grid: false,
    value: 'transparent',
  };

  setValue = value => this.setState({ value });

  setGrid = grid => this.setState({ grid });

  render() {
    const { setValue, setGrid } = this;
    const { children } = this.props;
    const { value, grid } = this.state;

    return (
      <Context.Provider value={{ value, setValue, grid, setGrid }}>{children}</Context.Provider>
    );
  }
}

const { Consumer } = Context;

function createGridStyles(cellSize) {
  const cellSizeDoubled = cellSize * 2;
  const cellSizeSquared = cellSize ** 2;

  const gridSVGEncoded = encodeURIComponent(
    renderToStaticMarkup(
      <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
        <defs>
          <pattern id="smallGrid" width={cellSize} height={cellSize} patternUnits="userSpaceOnUse">
            <path
              d={`M ${cellSize} 0 L 0 0 0 ${cellSize}`}
              fill="none"
              stroke="gray"
              strokeWidth="0.5"
            />
          </pattern>
          <pattern
            id="grid"
            width={cellSizeSquared}
            height={cellSizeSquared}
            patternUnits="userSpaceOnUse"
          >
            <rect width={cellSizeSquared} height={cellSizeSquared} fill="url(#smallGrid)" />
            <path
              d={`M ${cellSizeSquared} 0 L 0 0 0 ${cellSizeSquared}`}
              fill="none"
              stroke="gray"
              strokeWidth="1"
            />
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill="url(#grid)" />
      </svg>
    )
  );

  return {
    backgroundImage: `url("data:image/svg+xml,${gridSVGEncoded}")`,
    backgroundSize: `${cellSizeSquared}px ${cellSizeSquared}px, ${cellSizeSquared}px ${cellSizeSquared}px, ${cellSizeDoubled}px ${cellSizeDoubled}px, ${cellSizeDoubled}px ${cellSizeDoubled}px`,
    backgroundPosition: '-2px -2px',
    mixBlendMode: 'difference',
  };
}

const Grid = styled.div(
  {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
  },
  ({ theme }) => createGridStyles(theme.background.gridCellSize)
);

const Background = styled.div(
  {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
    transition: 'background .1s linear',
    iframe: {
      width: '100%',
      height: '100%',
      position: 'absolute',
      top: 0,
      left: 0,
      border: '0 none',
    },
  },
  ({ theme }) => ({ background: theme.background.content })
);

export { Grid, Background, Consumer as BackgroundConsumer, Provider as BackgroundProvider };
<commit_msg>Fix unstretched preview background wrapper<commit_after>import React, { Component } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import PropTypes from 'prop-types';
import { styled } from '@storybook/theming';

const Context = React.createContext();

class Provider extends Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
  };

  state = {
    grid: false,
    value: 'transparent',
  };

  setValue = value => this.setState({ value });

  setGrid = grid => this.setState({ grid });

  render() {
    const { setValue, setGrid } = this;
    const { children } = this.props;
    const { value, grid } = this.state;

    return (
      <Context.Provider value={{ value, setValue, grid, setGrid }}>{children}</Context.Provider>
    );
  }
}

const { Consumer } = Context;

function createGridStyles(cellSize) {
  const cellSizeDoubled = cellSize * 2;
  const cellSizeSquared = cellSize ** 2;

  const gridSVGEncoded = encodeURIComponent(
    renderToStaticMarkup(
      <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
        <defs>
          <pattern id="smallGrid" width={cellSize} height={cellSize} patternUnits="userSpaceOnUse">
            <path
              d={`M ${cellSize} 0 L 0 0 0 ${cellSize}`}
              fill="none"
              stroke="gray"
              strokeWidth="0.5"
            />
          </pattern>
          <pattern
            id="grid"
            width={cellSizeSquared}
            height={cellSizeSquared}
            patternUnits="userSpaceOnUse"
          >
            <rect width={cellSizeSquared} height={cellSizeSquared} fill="url(#smallGrid)" />
            <path
              d={`M ${cellSizeSquared} 0 L 0 0 0 ${cellSizeSquared}`}
              fill="none"
              stroke="gray"
              strokeWidth="1"
            />
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill="url(#grid)" />
      </svg>
    )
  );

  return {
    backgroundImage: `url("data:image/svg+xml,${gridSVGEncoded}")`,
    backgroundSize: `${cellSizeSquared}px ${cellSizeSquared}px, ${cellSizeSquared}px ${cellSizeSquared}px, ${cellSizeDoubled}px ${cellSizeDoubled}px, ${cellSizeDoubled}px ${cellSizeDoubled}px`,
    backgroundPosition: '-2px -2px',
    mixBlendMode: 'difference',
  };
}

const Grid = styled.div(
  {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
  },
  ({ theme }) => createGridStyles(theme.background.gridCellSize)
);

const Background = styled.div(
  {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    minHeight: '100%',
    transition: 'background .1s linear',
    iframe: {
      width: '100%',
      height: '100%',
      position: 'absolute',
      top: 0,
      left: 0,
      border: '0 none',
    },
  },
  ({ theme }) => ({ background: theme.background.content })
);

export { Grid, Background, Consumer as BackgroundConsumer, Provider as BackgroundProvider };
<|endoftext|>


<commit_before>define(['jquery', 'd3', 'underscore',
    'util/dock', 'util/eventemitter', 'util/hud', 'renderers/table'],
function ($, d3, _, Dock, EventEmitter, HUD, Table) {

    var defaults = {
        dock: true
    };

    var NODE_SIZE  = {
        GENE: 8,
        CLUSTER: 16
    };
    var color = d3.scale.category10();

    var Network = function (options) {
        var self = this;
        options = options ? _.clone(options) : {};
        _.defaults(options, defaults);
        var $el = $(options.element);
        var _idSequence = 1;
        var _autoUpdate = true;
        var CLUSTER_Y = $el.height() * 5 / 6;

        this.addNode = function (node) {
            if (node.id) {
                node.id = parseInt(node.id);
                var existing = findNode(node.id);
                if (!existing) {
                    nodes.push(node);
                    _idSequence = d3.max(_idSequence, node.id + 1);
                }
            } else {
                node.id = _idSequence++;
                nodes.push(node);
            }
            if (_autoUpdate) update();
            return node.id;
        }

        this.removeNode = function (id) {
            var i = 0;
            var n = findNode(id);
            while (i < links.length) {
                if ((links[i]['source'] == n) ||
                    (links[i]['target'] == n))
                    links.splice(i,1);
                else i++;
            }
            nodes.splice(findNodeIndex(id),1);
            update();
            return this;
        }

        this.setData  = function (data) {
            this.setNodes(data.nodes);
            this.setEdges(data.edges);
            return this;
        }

        this.setNodes = function (nodesArg) {
            force.nodes(nodesArg);
            nodes = force.nodes();
            _idSequence = d3.max(nodes, function (n) { return n.id }) + 1;
            return this;
        }

        this.setEdges = function (edgesArg) {
            force.links(edgesArg);
            links = force.links();
            return this;
        }

        this.addEdge = function (edge) {
            edge.source = this.findNode(edge.source);
            edge.target = this.findNode(edge.target);
            links.push(edge);
            if (_autoUpdate) update();
            return this;
        }

        this.addLink = function (source, target, params) {
            var edge = {
                source: this.findNode(source),
                target: this.findNode(target),
            };
            if (edge.source == null || edge.target == null) {
                console.log("Cannot find edge for ", source, target);
            }
            for (var p in params) {
                edge[p] = params[p];
            }
            links.push(edge);
            if (_autoUpdate) update();
            return this;
        }

        this.highlight = function (name) {
            d3.select("#" + name)
                .style("stroke", "yellow")
                .style("stroke-width", 3)
                .style("stroke-location", "outside")
            return this;
        }

        this.display = function () { update(); return this; }

        this.findNode = function (key, type) {
            type = (type || 'id');
            for (var i in nodes) {if (nodes[i][type] === key) return nodes[i]};
        }

        this.find = function (key, type) {
            type = (type || 'id');
            var result = [];
            for (var i in nodes) {
                if (nodes[i][type] === key) result.push(nodes[i]);
            }
            return result;
        }

        function findNodeIndex(id) {
            for (var i in nodes) { if (nodes[i].id === id) return i };
        }

        var w = $el.width(),
            h = $el.height();

        var vis = this.vis = d3.select($el[0]).append("svg:svg")
            .attr("width", w)
            .attr("height", h);

        var dock;
        if (options.dock) { dock = new Dock(vis) };

        // This order matters (nodes painted on top of links)
        var linkG = vis.append("g").attr("id", "networkLinks");
        var nodeG = vis.append("g").attr("id", "networkNodes");

        var force = d3.layout.force()
            .gravity(.05)
            .distance(100)
            .charge(-60)
            .size([w, h]);

        var nodes = force.nodes(),
            links = force.links();

        var svgNodes, svgLinks;
        function tick() {
            svgLinks.attr("x1", function (d) { return d.source.x; })
                    .attr("y1", function (d) {
                        return d.source.type == 'CLUSTER' ? CLUSTER_Y : d.source.y; })
                    .attr("x2", function (d) { return d.target.x; })
                    .attr("y2", function (d) {
                        return d.target.type == 'CLUSTER' ? CLUSTER_Y : d.target.y; });
            svgNodes.attr("cx", function (d) { return d.x; })
                    .attr("cy", function (d) {
                        return d.type == 'CLUSTER' ? CLUSTER_Y : d.y; });
        }

        function update() {
            svgLinks = linkG.selectAll("line.link").data(links);
            var linkEnter = svgLinks.enter()
                .append("line")
                .attr("class", "link")
                .style("stroke-width", function(d) { return d.weight; });
            svgLinks.exit().remove();

            svgNodes = nodeG.selectAll("circle.node").data(nodes);
            var nodeEnter = svgNodes.enter().append("circle")
                .attr("class", "node")
                .attr("id",     function (d) {
                    d.elementId = "node-" + d.id; return d.elementId;
                })
                .attr("r",      function (d) { return nodeSize(d); })
                .style("fill",  function (d) { return color(d.group); })
                .on("click",    function (d) {
                    d3.event.stopPropagation();
                    self.emit("click-node", [d, this]);
                })
                .on("dblclick", function (d) {
                    d3.event.stopPropagation();
                    self.emit("dblclick-node", [d, this]);
                });
            if (options.dock) {
                nodeEnter.call(dock.drag());
            } else {
                nodeEnter.call(force.drag);
            }
            svgNodes.exit().remove();

            force.on("tick", tick);
            force.start();
        }

        if (options.dock) {
            dock.on("dragstart.dock", function () { force.stop(); })
                .on("dragmove.dock",  function () { tick() })
                .on("dragend.dock",   function () { tick(); force.start(); })
                .on("dock", function (evt, d, element) {
                    element
                        .style("stroke", "yellow")
                        .style("stroke-width", 3)
                        .style("stroke-location", "outside")
                })
                .on("undock", function (evt, d, element) {
                    element
                        .style("stroke", null)
                        .style("stroke-width", null)
                        .style("stroke-location", null);
                });
        }

        function nodeSize(d) {
            var size = NODE_SIZE[d.type] || 8;
            return size;
        }

        var selected, originalFill,
            hud = new HUD({
                position: { bottom: 20, left: 20 },
                width: 300
            });
        self.clickNode = function (d, element) {
            if (selected) {
                selected.style["fill"] = originalFill;
            }
            if (selected == element) {
                hud.dismiss();
                selected = null;
                return;
            }
            selected = element;
            originalFill = selected.style["fill"];
            var fill = d3.hsl(originalFill);
            selected.style["fill"] = fill.brighter().toString();

            hud.empty().append(nodeInfo(d))
            hud.show();
            hud.on("dismiss", function () {
                if (selected != null) {
                    selected.style["fill"] = originalFill;
                    selected = null;
                }
            });
        }

        function nodeInfo(d) {
            var $table =
                $("<table id='nodeInfo' class='table table-condensed'>")
                .append($("<tbody>"));
            function row(key, val) {
                if (!val) return;
                $table.find("tbody").append($("<tr>")
                    .append($("<th>").text(key))
                    .append($("<td>").text(val))
                );
            }
            row("Name", d.name);
            row("KBase ID", d.kbid);
            row("Type", d.type);
            row("Entity ID", d.entityId);
            return $table;
        }

        self.merge = function (data) {
            if (nodes.length == 0 && links.length == 0) {
                self.setData(data).display();
                return this;
            }
            var origAutoUpdate = _autoUpdate;
            _autoUpdate = false;
            var nodeMap = {};
            if (data.nodes == null) data.nodes = [];
            if (data.edges == null) data.edges = [];
            for (var i = 0; i < data.nodes.length; i++) {
                var newNode = data.nodes[i];
                var oldNode = self.findNode(newNode.name, "name");
                var oldId = i;
                if (oldNode != null) {
                    nodeMap[oldId] = oldNode.id;
                    _.extend(oldNode, newNode);
                    oldNode.id = nodeMap[oldId];
                } else {
                    newNode.id = null;
                    var newId = self.addNode(newNode);
                    nodeMap[oldId] = newId;
                }
            }
            data.edges.forEach(function (e) {
                self.addLink(
                    nodeMap[e.source], nodeMap[e.target],
                    { weight: e.weight });
            });
            self.display();
            _autoUpdate = origAutoUpdate;
            return this;
        }
        self.reset = function () {
            nodes.length = 0; links.length = 0;
            if (dock) { dock.reset() }
            update();
            return self;
        }
        self.dockNodes = function (names) {
            var nodes = [];
            for (var i in names) {
                var node = self.findNode(names[i], 'name');
                if (node) nodes.push(node);
            }
            dock.set(nodes);
        }
        self.addDockAction = function (callback) {
            dock.addUpdateAction(callback);
        }
        self.dockHudContent = function (callback) {
            dock.hudContent(callback);
        }
        return self;
    };
    Network.getNeighbors = function (node) {
        var network = this;
        if (!node) return;
        var path = node.entityId
            ? 'node/' + node.entityId + '/neighbors'
            : 'network/random/' + node.name + '/neighbors';
        $.ajax({
            url: '/data/' + path,
            success: function (data) {
                network.merge(data);
            }
        });
    }
    $.extend(Network.prototype, EventEmitter);
    return Network;
});<commit_msg>Collapsing nodes! First double-click fetched remote nodes. Subsequent double clicks collapse/uncollapse neighborhoods.<commit_after>define(['jquery', 'd3', 'underscore',
    'util/dock', 'util/eventemitter', 'util/hud', 'renderers/table'],
function ($, d3, _, Dock, EventEmitter, HUD, Table) {

    var defaults = {
        dock: true
    };

    var NODE_SIZE  = {
        GENE: 8,
        CLUSTER: 16
    };
    var color = d3.scale.category10();

    var Network = function (options) {
        var self = this;
        options = options ? _.clone(options) : {};
        _.defaults(options, defaults);
        var $el = $(options.element);
        var _idSequence = 1;
        var _autoUpdate = true;
        var CLUSTER_Y = $el.height() * 5 / 6;

        self.addNode = function (node) {
            if (node.id) {
                node.id = parseInt(node.id);
                var existing = self.findNode(node.id);
                if (!existing) {
                    nodes.push(node);
                    _idSequence = d3.max(_idSequence, node.id + 1);
                }
            } else {
                node.id = _idSequence++;
                nodes.push(node);
            }
            if (_autoUpdate) update();
            return node.id;
        }

        self.removeNode = function (id) {
            var i = 0;
            var n = self.findNode(id);
            if (n == null) return;
            while (i < links.length) {
                if ((links[i].source == n) ||
                    (links[i].target == n))
                    links.splice(i,1);
                else i++;
            }
            nodes.splice(findNodeIndex(id),1);
            update();
            return this;
        }

        self.setData  = function (data) {
            this.setNodes(data.nodes);
            this.setEdges(data.edges);
            return this;
        }

        this.setNodes = function (nodesArg) {
            force.nodes(nodesArg);
            nodes = force.nodes();
            _idSequence = d3.max(nodes, function (n) { return n.id }) + 1;
            return this;
        }

        this.setEdges = function (edgesArg) {
            force.links(edgesArg);
            links = force.links();
            return this;
        }

        this.addEdge = function (edge) {
            edge.source = this.findNode(edge.source);
            edge.target = this.findNode(edge.target);
            links.push(edge);
            if (_autoUpdate) update();
            return this;
        }

        this.addLink = function (source, target, params) {
            var edge = {
                source: this.findNode(source),
                target: this.findNode(target),
            };
            if (edge.source == null || edge.target == null) {
                console.log("Cannot find edge for ", source, target);
            }
            for (var p in params) {
                edge[p] = params[p];
            }
            links.push(edge);
            if (_autoUpdate) update();
            return this;
        }

        this.highlight = function (name) {
            d3.select("#" + name)
                .style("stroke", "yellow")
                .style("stroke-width", 3)
                .style("stroke-location", "outside")
            return this;
        }

        this.display = function () { update(); return this; }

        this.findNode = function (key, type) {
            type = (type || 'id');
            for (var i in nodes) {if (nodes[i][type] === key) return nodes[i]};
        }

        this.find = function (key, type) {
            type = (type || 'id');
            var result = [];
            for (var i in nodes) {
                if (nodes[i][type] === key) result.push(nodes[i]);
            }
            return result;
        }

        function findNodeIndex(id) {
            for (var i in nodes) { if (nodes[i].id === id) return i };
        }

        var w = $el.width(),
            h = $el.height();

        var vis = this.vis = d3.select($el[0]).append("svg:svg")
            .attr("width", w)
            .attr("height", h);

        var dock;
        if (options.dock) { dock = new Dock(vis) };

        // This order matters (nodes painted on top of links)
        var linkG = vis.append("g").attr("id", "networkLinks");
        var nodeG = vis.append("g").attr("id", "networkNodes");

        var force = d3.layout.force()
            .gravity(.05)
            .distance(100)
            .charge(-60)
            .size([w, h]);

        var nodes = force.nodes(),
            links = force.links();

        var svgNodes, svgLinks;
        function tick() {
            svgLinks.attr("x1", function (d) { return d.source.x; })
                    .attr("y1", function (d) {
                        return d.source.type == 'CLUSTER' ? CLUSTER_Y : d.source.y; })
                    .attr("x2", function (d) { return d.target.x; })
                    .attr("y2", function (d) {
                        return d.target.type == 'CLUSTER' ? CLUSTER_Y : d.target.y; });
            svgNodes.attr("cx", function (d) { return d.x; })
                    .attr("cy", function (d) {
                        return d.type == 'CLUSTER' ? CLUSTER_Y : d.y; });
        }

        function update() {
            svgLinks = linkG.selectAll("line.link").data(links);
            var linkEnter = svgLinks.enter()
                .append("line")
                .attr("class", "link")
                .style("stroke-width", function(d) { return d.weight; });
            svgLinks.exit().remove();

            svgNodes = nodeG.selectAll("circle.node").data(nodes);
            var nodeEnter = svgNodes.enter().append("circle")
                .attr("class", "node")
                .attr("id",     function (d) {
                    d.elementId = "node-" + d.id; return d.elementId;
                })
                .attr("r",      function (d) { return nodeSize(d); })
                .style("fill",  function (d) { return color(d.group); })
                .on("click",    function (d) {
                    d3.event.stopPropagation();
                    self.emit("click-node", [d, this]);
                })
                .on("dblclick", function (d) {
                    d3.event.stopPropagation();
                    self.emit("dblclick-node", [d, this]);
                });
            if (options.dock) {
                nodeEnter.call(dock.drag());
            } else {
                nodeEnter.call(force.drag);
            }
            svgNodes.exit().remove();

            force.on("tick", tick);
            force.start();
        }

        if (options.dock) {
            dock.on("dragstart.dock", function () { force.stop(); })
                .on("dragmove.dock",  function () { tick() })
                .on("dragend.dock",   function () { tick(); force.start(); })
                .on("dock", function (evt, d, element) {
                    element
                        .style("stroke", "yellow")
                        .style("stroke-width", 3)
                        .style("stroke-location", "outside")
                })
                .on("undock", function (evt, d, element) {
                    element
                        .style("stroke", null)
                        .style("stroke-width", null)
                        .style("stroke-location", null);
                });
        }

        function nodeSize(d) {
            var size = NODE_SIZE[d.type] || 8;
            return size;
        }

        var selected, originalFill,
            hud = new HUD({
                position: { bottom: 20, left: 20 },
                width: 300
            });
        self.clickNode = function (d, element) {
            if (selected) {
                selected.style["fill"] = originalFill;
            }
            if (selected == element) {
                hud.dismiss();
                selected = null;
                return;
            }
            selected = element;
            originalFill = selected.style["fill"];
            var fill = d3.hsl(originalFill);
            selected.style["fill"] = fill.brighter().toString();

            hud.empty().append(nodeInfo(d))
            hud.show();
            hud.on("dismiss", function () {
                if (selected != null) {
                    selected.style["fill"] = originalFill;
                    selected = null;
                }
            });
        }

        function nodeInfo(d) {
            var $table =
                $("<table id='nodeInfo' class='table table-condensed'>")
                .append($("<tbody>"));
            function row(key, val) {
                if (!val) return;
                $table.find("tbody").append($("<tr>")
                    .append($("<th>").text(key))
                    .append($("<td>").text(val))
                );
            }
            row("Name", d.name);
            row("KBase ID", d.kbid);
            row("Type", d.type);
            row("Entity ID", d.entityId);
            return $table;
        }

        // Get neighbors for a given node.
        self.neighbors = function (node) {
            var neigh = [];
            links.forEach(function (link) {
                var n;
                if (link.source == node )
                    n = link.target;
                else if (link.target == node)
                    n = link.source;
                if (n != null && n !== node)
                    neigh.push([ n, link ]);
            });
            return neigh;
        }

        self.collapse = function (node) {
            var collapsed = node._collapsed = {};
            var neighbors = self.neighbors(node);

            // Create hash of primary neighbors
            var seen = {};
            for (var i = 0; i < neighbors.length; i++) {
                neighbor = neighbors[i];
                var n = neighbor[0];
                seen[n.id] = true;
            }
            for (var i = 0; i < neighbors.length; i++) {
                neighbor = neighbors[i];
                var n = neighbor[0];

                var cousins = self.neighbors(n);
                var cousinEdges = [];
                var j = 0;

                // Handle neighbors to the collapsing nodes that
                // link with each other. Filter out all seen nodes.
                while (j < cousins.length) {
                    if (seen[cousins[j][0].id]) {
                        var edge = _.clone(cousins[j][1]);
                        edge.source = edge.source.id;
                        edge.target = edge.target.id;
                        cousinEdges.push(edge);
                        cousins.splice(j, 1);
                    } else j++
                }
                // Collapse nodes if not implicated with other nodes.
                if (cousins.length <= 1) {
                    var edge = _.clone(neighbor[1]);
                    edge.source = edge.source.id;
                    edge.target = edge.target.id;
                    collapsed[n.id] = {
                        node: n,
                        edges: _.flatten([edge, cousinEdges])
                    };
                }
            }
            for (var id in collapsed) {
                self.removeNode(parseInt(id));
            }
            return this;
        }

        self.uncollapse = function (node) {
            if (!node._collapsed) return this;
            var origAutoUpdate = _autoUpdate;
            _autoUpdate = false;
            // First add the nodes
            for (var id in node._collapsed) {
                var d = node._collapsed[id];
                nodes.push(d.node);
            }

            // Then add the edges
            for (var id in node._collapsed) {
                var d = node._collapsed[id];
                d.edges.forEach(function (edge) {
                    self.addEdge(edge);
                });
                delete node._collapsed[id];
            }
            self.display();
            _autoUpdate = true;
            delete node._collapsed;
            return this;
        }

        self.merge = function (data) {
            if (nodes.length == 0 && links.length == 0) {
                self.setData(data).display();
                return this;
            }
            var origAutoUpdate = _autoUpdate;
            _autoUpdate = false;
            var nodeMap = {};
            if (data.nodes == null) data.nodes = [];
            if (data.edges == null) data.edges = [];
            for (var i = 0; i < data.nodes.length; i++) {
                var newNode = data.nodes[i];
                var oldNode = self.findNode(newNode.name, "name");
                var oldId = i;
                if (oldNode != null) {
                    nodeMap[oldId] = oldNode.id;
                    _.extend(oldNode, newNode);
                    oldNode.id = nodeMap[oldId];
                } else {
                    newNode.id = null;
                    var newId = self.addNode(newNode);
                    nodeMap[oldId] = newId;
                }
            }
            data.edges.forEach(function (e) {
                self.addLink(
                    nodeMap[e.source], nodeMap[e.target],
                    { weight: e.weight });
            });
            self.display();
            _autoUpdate = origAutoUpdate;
            return this;
        }
        self.reset = function () {
            nodes.length = 0; links.length = 0;
            if (dock) { dock.reset() }
            update();
            return self;
        }
        self.dockNodes = function (names) {
            var nodes = [];
            for (var i in names) {
                var node = self.findNode(names[i], 'name');
                if (node) nodes.push(node);
            }
            dock.set(nodes);
        }
        self.addDockAction = function (callback) {
            dock.addUpdateAction(callback);
        }
        self.dockHudContent = function (callback) {
            dock.hudContent(callback);
        }
        return self;
    };
    Network.getNeighbors = function (node) {
        var network = this;
        if (!node) return;
        var path = node.entityId
            ? 'node/' + node.entityId + '/neighbors'
            : 'network/random/' + node.name + '/neighbors';
        $.ajax({
            url: '/data/' + path,
            success: function (data) {
                network.merge(data);
            }
        });
    }
    $.extend(Network.prototype, EventEmitter);
    return Network;
});<|endoftext|>


<commit_before>var util = require('../../../shared/Util.js');
var statusVM = require('./StatusViewModel.js').getStatusViewModel();
var mapVM = require('./MapViewModel.js').getMapViewModel();
var sideMenuVM = require('./SideMenuViewModel.js').getSideMenuViewModel();
var urlArgs = require('./UrlArgs.js');
var eventToOpenID = urlArgs.id;
var eventToOpenType = urlArgs.type;
var programEvents = require('./ProgramEvents.js');

var mapControl;
var waitedSinceLastChange;

module.exports.getMapControl = function() {
  if (!mapControl) {
    programEvents.add(function(event) {
      if (event.event === 'updateMap') {
        clearTimeout(waitedSinceLastChange);
        waitedSinceLastChange = setTimeout(function() {
          mapControl.updateMap();
        }, 1400);
      }
    });

    mapControl = new MapControl();
  }
  return mapControl;
};

var MapControl = can.Control({
  init: function() {
    this.sideMenu = sideMenuVM;

    if (eventToOpenID && eventToOpenType) {
      programEvents.dispatch({ event: 'updateMap' });
    } else {
      this.loadMyLocation();
    }
  },
  '#loadMyLocation click': function(el, ev) {
    this.loadMyLocation();
    programEvents.dispatch({ event: 'updateMap' });
  }
});

MapControl.prototype.loadMyLocation = function() {
  if (navigator.geolocation) {
    var self = this;
    navigator.geolocation.getCurrentPosition(function (position) {
      mapVM.mapProp.attr('lat', util.roundNumber(position.coords.latitude));
      mapVM.mapProp.attr('lng', util.roundNumber(position.coords.longitude));

      self.centerToLatLng();
      programEvents.dispatch({ event: 'updateMap' });
    }, function(error) {
      console.log(error);
      programEvents.dispatch({ event: 'updateMap' });
    });
  } else {
    statusVM.setStatus(statusVM.CONST.GEO_ERROR);
  }
};

MapControl.prototype.addEventMarkers = function(events) {
  if (!events) {
    return;
  }
  for (var n = 0; n < events.length; n++) {
    var currentEvent = events[n];
    var identifier = currentEvent.type + currentEvent.id;

    if (mapVM.ids[identifier] !== 1) {
      mapVM.ids[identifier] = 1;
      mapVM.addEventMarker(currentEvent);
    }
  }
};

MapControl.prototype.getEventsByIDCall = function(param) {
  var self = this;
  getEventsAjaxDeferred('getEventsById', param).done(function(data) {
    self.processEventData(data);
  }).fail(function() {
    console.log('ERROR: getEventsByID call failed.');
  });
};

MapControl.prototype.getEventsCall = function(param) {
  var self = this;
  getEventsAjaxDeferred('eb/getEvents', param).done(function(data) {
    self.processEventData(data);
  }).fail(function() {
    console.log('ERROR: eventBrite getEvents call failed.');
  });

  getEventsAjaxDeferred('mu/getEvents', param).done(function(data) {
    self.processEventData(data);
  }).fail(function() {
    console.log('ERROR: meetUp getEvents call failed.');
  });
};

MapControl.prototype.processEventData = function(data) {
  if (data.searchResult) {
    if (data.center) {
      var center = new google.maps.LatLng(data.center.lat, data.center.lng);
      mapVM.map.setCenter(center);
    }

    if (data.date) {
      sideMenuVM.setDateToSelectedEvent(data.date.startDate, data.date.endDate);
    }

    this.addEventMarkers(data.searchResult);
    statusVM.setStatus(statusVM.CONST.NORMAL);
  } else {
    statusVM.setStatus(statusVM.CONST.NO_EVENTS);
  }
};

MapControl.prototype.updateMap = function() {
  if (this.isNeedUpdate()) {
    statusVM.setStatus(statusVM.CONST.WORKING);
    mapVM.latestLoc.lat = mapVM.mapProp.lat;
    mapVM.latestLoc.lng = mapVM.mapProp.lng;

    if (eventToOpenID && eventToOpenType) {
      this.getEventsByIDCall({
        id : eventToOpenID,
        radius : mapVM.mapProp.radius,
        sourceType : eventToOpenType
      });
    } else {
      this.getEventsCall({
        lat : mapVM.mapProp.lat,
        lng : mapVM.mapProp.lng,
        dateFrom : sideMenuVM.sideMenuProp.dateFrom,
        dateTo : sideMenuVM.sideMenuProp.dateTo,
        type : sideMenuVM.sideMenuProp.types,
        radius : mapVM.mapProp.radius
      });
    }
  }
};

MapControl.prototype.isNeedUpdate = function() {
  if (mapVM.dragging) {
    return false;
  }
  // Is it current working?
  if (statusVM.getStatus() === 1) {
    return false;
  }
  if (mapVM.mapProp.radius > 19) {
    statusVM.setStatus(statusVM.CONST.ZOOM_ERROR);
    return false;
  }
  if (!this.validateLatLng()) {
    return false;
  }

  return mapVM.distCheckPass || Math.abs(this.getScreenTravelDistance()) > mapVM.mapProp.radius / 1.5;
};

MapControl.prototype.getScreenTravelDistance = function() {
  return util.getDistanceFromLatLng(mapVM.mapProp.lat, mapVM.mapProp.lng, mapVM.latestLoc.lat, mapVM.latestLoc.lng);
};

MapControl.prototype.validateLatLng = function() {
  return util.isNumber(mapVM.mapProp.lat) && util.isNumber(mapVM.mapProp.lng);
};

MapControl.prototype.centerToLatLng = function() {
  mapVM.map.setCenter(new google.maps.LatLng(mapVM.mapProp.lat, mapVM.mapProp.lng));
};

var getEventsAjaxDeferred = function(url, data) {
  return $.ajax({
    type: 'GET',
    url: '/api/' + url,
    data: data,
    cache: false
  });
};
<commit_msg>Calling get events after get event by id<commit_after>var util = require('../../../shared/Util.js');
var statusVM = require('./StatusViewModel.js').getStatusViewModel();
var mapVM = require('./MapViewModel.js').getMapViewModel();
var sideMenuVM = require('./SideMenuViewModel.js').getSideMenuViewModel();
var urlArgs = require('./UrlArgs.js');
var eventToOpenID = urlArgs.id;
var eventToOpenType = urlArgs.type;
var programEvents = require('./ProgramEvents.js');

var mapControl;
var waitedSinceLastChange;

module.exports.getMapControl = function() {
  if (!mapControl) {
    programEvents.add(function(event) {
      if (event.event === 'updateMap') {
        clearTimeout(waitedSinceLastChange);
        waitedSinceLastChange = setTimeout(function() {
          mapControl.updateMap();
        }, 1400);
      }
    });

    mapControl = new MapControl();
  }
  return mapControl;
};

var MapControl = can.Control({
  init: function() {
    this.sideMenu = sideMenuVM;

    if (eventToOpenID && eventToOpenType) {
      programEvents.dispatch({ event: 'updateMap' });
    } else {
      this.loadMyLocation();
    }
  },
  '#loadMyLocation click': function(el, ev) {
    this.loadMyLocation();
    programEvents.dispatch({ event: 'updateMap' });
  }
});

MapControl.prototype.loadMyLocation = function() {
  if (navigator.geolocation) {
    var self = this;
    navigator.geolocation.getCurrentPosition(function (position) {
      mapVM.mapProp.attr('lat', util.roundNumber(position.coords.latitude));
      mapVM.mapProp.attr('lng', util.roundNumber(position.coords.longitude));

      self.centerToLatLng();
      programEvents.dispatch({ event: 'updateMap' });
    }, function(error) {
      console.log(error);
      programEvents.dispatch({ event: 'updateMap' });
    });
  } else {
    statusVM.setStatus(statusVM.CONST.GEO_ERROR);
  }
};

MapControl.prototype.addEventMarkers = function(events) {
  if (!events) {
    return;
  }
  for (var n = 0; n < events.length; n++) {
    var currentEvent = events[n];
    var identifier = currentEvent.type + currentEvent.id;

    if (mapVM.ids[identifier] !== 1) {
      mapVM.ids[identifier] = 1;
      mapVM.addEventMarker(currentEvent);
    }
  }
};

MapControl.prototype.getEventsByIDCall = function(param) {
  var self = this;
  getEventsAjaxDeferred('getEventsById', param).done(function(data) {
    self.processEventData(data);
    self.getEventsCall({
      lat : mapVM.mapProp.lat,
      lng : mapVM.mapProp.lng,
      dateFrom : sideMenuVM.sideMenuProp.dateFrom,
      dateTo : sideMenuVM.sideMenuProp.dateTo,
      type : sideMenuVM.sideMenuProp.types,
      radius : mapVM.mapProp.radius
    });
  }).fail(function() {
    console.log('ERROR: getEventsByID call failed.');
  });
};

MapControl.prototype.getEventsCall = function(param) {
  var self = this;
  getEventsAjaxDeferred('eb/getEvents', param).done(function(data) {
    self.processEventData(data);
  }).fail(function() {
    console.log('ERROR: eventBrite getEvents call failed.');
  });

  getEventsAjaxDeferred('mu/getEvents', param).done(function(data) {
    self.processEventData(data);
  }).fail(function() {
    console.log('ERROR: meetUp getEvents call failed.');
  });
};

MapControl.prototype.processEventData = function(data) {
  if (data.searchResult) {
    if (data.center) {
      var center = new google.maps.LatLng(data.center.lat, data.center.lng);
      mapVM.map.setCenter(center);
    }

    if (data.date) {
      sideMenuVM.setDateToSelectedEvent(data.date.startDate, data.date.endDate);
    }

    this.addEventMarkers(data.searchResult);
    statusVM.setStatus(statusVM.CONST.NORMAL);
  } else {
    statusVM.setStatus(statusVM.CONST.NO_EVENTS);
  }
};

MapControl.prototype.updateMap = function() {
  if (this.isNeedUpdate()) {
    statusVM.setStatus(statusVM.CONST.WORKING);
    mapVM.latestLoc.lat = mapVM.mapProp.lat;
    mapVM.latestLoc.lng = mapVM.mapProp.lng;

    if (eventToOpenID && eventToOpenType) {
      this.getEventsByIDCall({
        id : eventToOpenID,
        radius : mapVM.mapProp.radius,
        sourceType : eventToOpenType
      });
    } else {
      this.getEventsCall({
        lat : mapVM.mapProp.lat,
        lng : mapVM.mapProp.lng,
        dateFrom : sideMenuVM.sideMenuProp.dateFrom,
        dateTo : sideMenuVM.sideMenuProp.dateTo,
        type : sideMenuVM.sideMenuProp.types,
        radius : mapVM.mapProp.radius
      });
    }
  }
};

MapControl.prototype.isNeedUpdate = function() {
  if (mapVM.dragging) {
    return false;
  }
  // Is it current working?
  if (statusVM.getStatus() === 1) {
    return false;
  }
  if (mapVM.mapProp.radius > 19) {
    statusVM.setStatus(statusVM.CONST.ZOOM_ERROR);
    return false;
  }
  if (!this.validateLatLng()) {
    return false;
  }

  return mapVM.distCheckPass || Math.abs(this.getScreenTravelDistance()) > mapVM.mapProp.radius / 1.5;
};

MapControl.prototype.getScreenTravelDistance = function() {
  return util.getDistanceFromLatLng(mapVM.mapProp.lat, mapVM.mapProp.lng, mapVM.latestLoc.lat, mapVM.latestLoc.lng);
};

MapControl.prototype.validateLatLng = function() {
  return util.isNumber(mapVM.mapProp.lat) && util.isNumber(mapVM.mapProp.lng);
};

MapControl.prototype.centerToLatLng = function() {
  mapVM.map.setCenter(new google.maps.LatLng(mapVM.mapProp.lat, mapVM.mapProp.lng));
};

var getEventsAjaxDeferred = function(url, data) {
  return $.ajax({
    type: 'GET',
    url: '/api/' + url,
    data: data,
    cache: false
  });
};
<|endoftext|>


<commit_before>var $ = require('../../../bower_components/jquery/jquery.min.js');
var util = require('./Util.js');
var statusObservable = require('./StatusObservable.js');
require('../../../bower_components/jquery-mousewheel/jquery.mousewheel.js');

var map;
var ids = [];
var markers = [];
var lastClickMarker = null;
var lastOpen;
var latestLoc = {lat: null, lng: null};
var distCheckPass = null;
var eventToOpenID = null;
var dragging = false;
var needUpdate = true;
var MAX_NUMBER = 9007199254740992;
var socket = null;
var defaultLoc = {lat: 40.72616, lng: -73.99973};

var MapControl = can.Control({
    init: function(element, options) {
        setupSocket();
        initializeMainElements(this.element);

        if(navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (position) {
                var lat = util.roundNumber(position.coords.latitude);
                var lng = util.roundNumber(position.coords.longitude);

                $('#lat').val(lat);
                $('#lng').val(lng);

                initializeMap(lat, lng);
            }, function err() {
                initializeMap(defaultLoc.lat, defaultLoc.lng);
            });
        } else {
            initializeMap(defaultLoc.lat, defaultLoc.lng);
        }
    },
    ".type change": function(el, ev) {
        typeChanged();
        clearMap();
        callUpdateMap(true);
    },
    ".datePicker change": function(el, ev) {
        clearMap();
        callUpdateMap(true);
    }
});
exports.MapControl = MapControl;

var initializeMainElements = function(element) {
    element.html(can.view('indexTemplate', {}));
    eventToOpenID = util.getURLArgument.id;

    $("#dateFrom").datepicker({
        defaultDate : "",
        changeMonth : true,
        changeYear : true,
        numberOfMonths : 1,
        onSelect : function(selectedDate) {
            $("#dateTo").datepicker("option", "minDate", selectedDate);
            $(this).trigger("change");
        }
    });
    $("#dateTo").datepicker({
        defaultDate : "+1w",
        changeMonth : true,
        changeYear : true,
        numberOfMonths : 1,
        onSelect : function(selectedDate) {
            $("#dateFrom").datepicker("option", "maxDate", selectedDate);
            $(this).trigger("change");
        }
    });

    var today = new Date();
    $("#dateFrom").val(util.getPrettyDate(today));
    $("#dateTo").datepicker("option", "minDate", today);

    var todayPlusOne = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);
    $("#dateTo").val(util.getPrettyDate(todayPlusOne));
    $("#dateFrom").datepicker("option", "maxDate", todayPlusOne);

    $("#menuBox").mCustomScrollbar();
    typeChanged();
}

var initializeMap = function (lat, lng) {
    var point = new google.maps.LatLng(lat, lng);

    map = new google.maps.Map(document.getElementById('mapBox'), {
        zoom : 15,
        center : point,
        mapTypeId : google.maps.MapTypeId.ROADMAP
    });

    google.maps.event.addListenerOnce(map, 'idle', function() {
        var ne = map.getBounds().getNorthEast();
        var sw = map.getBounds().getSouthWest();

        $('#radius').val(util.getDistanceFromLatLng(ne.lat(), ne.lng(), sw.lat(), sw.lng()) / 4);
        $('#lat').val(util.roundNumber(map.getCenter().lat()));
        $('#lng').val(util.roundNumber(map.getCenter().lng()));

        updateMap();
    });

    google.maps.event.addListener(map, 'dragstart', function() {
        dragging = true;
    });

    google.maps.event.addListener(map, 'dragend', function() {
        $('#lat').val(util.roundNumber(map.getCenter().lat()));
        $('#lng').val(util.roundNumber(map.getCenter().lng()));
        dragging = false;
        callUpdateMap(false);
    });

    google.maps.event.addListener(map, 'zoom_changed', function() {
        var ne = map.getBounds().getNorthEast();
        var sw = map.getBounds().getSouthWest();

        $('#radius').val(util.getDistanceFromLatLng(ne.lat(), ne.lng(), sw.lat(), sw.lng()));

        callUpdateMap(true);
    });
}

function setupSocket() {
    socket = io.connect('http://serenedi.com/');

    socket.on('getEventsResult', function(data) {
        var m = 1;
        var n = 0;

        if(data.message != null) {

            if(typeof(data.center) != 'undefined' || data.center != null){
                map.setCenter(new google.maps.LatLng(data.center.lat, data.center.lng));
            }

            if(typeof(data.date) != 'undefined' || data.date != null) {
                $("#dateFrom").datepicker("option", "maxDate", data.date.endDate);
                $('#dateFrom').val(data.date.startDate);
                $("#dateTo").datepicker("option", "minDate", data.date.startDate);
                $('#dateTo').val(data.date.endDate);
            }

           while(m < data.message.events.length) {

               if(n >= ids.length) {
                   ids[n] = MAX_NUMBER;
               }

               if(data.message.events[m].event.id < ids[n]) {
                   if(ids[n] == MAX_NUMBER) {
                       ids.pop();
                   }

                   ids.push(data.message.events[m].event.id);
                   addMarkers(data.message.events[m].event);

                   m++;
               } else if (data.message.events[m].event.id > ids[n]) {
                   n++;
               } else {
                   n++;
                   m++;
               }
           }

           ids.sort();
        } else {
           statusObservable.status.attr('value', 2);
        }
        statusObservable.status.attr('value', 0);
    });
}

var callUpdateMap = function (flag) {
    distCheckPass = flag;
    needUpdate = true;
}

var updateMap = function() {
    var distanceCheck = distCheckPass
                || ((latestLoc.lat == null && latestLoc.lng == null)
                || Math.abs(util.getDistanceFromLatLng($('#lat').val(), $('#lng').val(), latestLoc.lat, latestLoc.lng)) > $('#radius').val() / 1.5);
    var radiusCheck = $('#radius').val() < 20;

    if(needUpdate && !dragging && distanceCheck && radiusCheck && statusObservable.status.attr('value') != 1) {
        statusObservable.status.attr('value', 1);
        needUpdate = false;
        latestLoc.lat = $('#lat').val();
        latestLoc.lng = $('#lng').val();

        if (eventToOpenID == null || eventToOpenID == 'undefined') {
            socket.emit('getEventsCall', {
                message: { lat : $('#lat').val(),
                           lng : $('#lng').val(),
                           dateFrom : $('#dateFrom').val(),
                           dateTo : $('#dateTo').val(),
                           type : $('#categories').val(),
                           radius : $('#radius').val() }
            });
        } else {
            socket.emit('getEventsByIDCall', {
                message: { id : eventToOpenID,
                           radius : $('#radius').val()}
            });
        }
     }

     if(!radiusCheck) {
        statusObservable.status.attr('value', 3);
     }

     setTimeout(updateMap, 1000);
}

var clearMap = function () {
    closeLastOpen();

    for(n = 0; n < markers.length; n++) {
        markers[n].setMap(null);
    }

    markers = [];
    ids = [];
}

var closeLastOpen = function () {
    if (lastOpen != null) {
       lastOpen.close();
    }
    if (lastClickMarker != null) {
       lastClickMarker.setAnimation(null);
    }
    lastOpen = null;
    lastClickMarker = null;
}

var addMarkers = function (event) {
    var point = new google.maps.LatLng(event.venue.latitude, event.venue.longitude);

    var marker = new google.maps.Marker({
        position: point,
        map : map,
        title : event.title,
        animation : google.maps.Animation.DROP,
        clickable : true
    });

   marker.info = new google.maps.InfoWindow({content: '' + event.title + '
'});
   markers.push(marker);

   google.maps.event.addListener(
       marker,
       'click',
       function() {
           closeLastOpen();

    //TODO USE CSS FOR THE LOVE OF MOTHER TERESA
           var content = '
';
           content += '
';
           content += '
' + marker.getTitle() + '
';
           content += '
URL: 	' + event.url + '
http://www.serenedi.com/?id=' + event.id + '' + '
';
           content += '
Start: 	' + event.start_date.split(' ')[0] + '
';
           if (event.end_date != null) {
               content += '
End: 	' + event.end_date.split(' ')[0] + '
';
           }
           if (event.venue.address != null || event.venue.address != '') {
               content += '
Address: 	' + event.venue.address + ' ' + event.venue.address_2 + '
';
               content += '
	' + event.venue.city + ', ' + event.venue.region + ' ' + event.venue.postalcode + '
';
           }
           content += '
Category: 	' + event.category + '
';
           content += '

';
           content += '

 <fb:comments href="www.serenedi.com/?id=' + event.id + '" num_posts="2" width="400"> </script>

';
           content += '

';

           var info = new google.maps.InfoWindow();
           info.setContent(content);

           google.maps.event.addListenerOnce(info, 'closeclick', function() {
               marker.setAnimation(null);
           });

           info.open(map, marker);

           marker.setAnimation(google.maps.Animation.BOUNCE);

           lastClickMarker = marker;
           lastOpen = info;

           setTimeout(function() {
               try {
                   FB.XFBML.parse();
               } catch (ex) {
               }
           } , 100);
        });

    if (event.id == eventToOpenID) {
        google.maps.event.trigger(marker, 'click');
    }
}

var flagCheck = function(element) {
    if ($(element).prop('checked')) {
        return "1";
    } else {
        return "0";
    }
}

var typeChanged = function() {
    var result = flagCheck('#typeConfFlag');

    result += flagCheck('#typeConvFlag');
    result += flagCheck('#typeEntFlag');
    result += flagCheck('#typeFairFlag');
    result += flagCheck('#typeFoodFlag');
    result += flagCheck('#typeFundFlag');
    result += flagCheck('#typeMeetFlag');
    result += flagCheck('#typeMusicFlag');
    result += flagCheck('#typePerfFlag');
    result += flagCheck('#typeRecFlag');
    result += flagCheck('#typeReligFlag');
    result += flagCheck('#typeReunFlag');
    result += flagCheck('#typeSalesFlag');
    result += flagCheck('#typeSemiFlag');
    result += flagCheck('#typeSociFlag');
    result += flagCheck('#typeSportsFlag');
    result += flagCheck('#typeTradeFlag');
    result += flagCheck('#typeTravelFlag');
    result += flagCheck('#typeOtherFlag');

    $('#categories').val(result);
}
<commit_msg>Indentation fix...  Still looks wrong...  :P<commit_after>var $ = require('../../../bower_components/jquery/jquery.min.js');
var util = require('./Util.js');
var statusObservable = require('./StatusObservable.js');
require('../../../bower_components/jquery-mousewheel/jquery.mousewheel.js');

var map;
var ids = [];
var markers = [];
var lastClickMarker = null;
var lastOpen;
var latestLoc = {lat: null, lng: null};
var distCheckPass = null;
var eventToOpenID = null;
var dragging = false;
var needUpdate = true;
var MAX_NUMBER = 9007199254740992;
var socket = null;
var defaultLoc = {lat: 40.72616, lng: -73.99973};

var MapControl = can.Control({
    init: function(element, options) {
        setupSocket();
        initializeMainElements(this.element);

        if(navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (position) {
                var lat = util.roundNumber(position.coords.latitude);
                var lng = util.roundNumber(position.coords.longitude);

                $('#lat').val(lat);
                $('#lng').val(lng);

                initializeMap(lat, lng);
            }, function err() {
                initializeMap(defaultLoc.lat, defaultLoc.lng);
            });
        } else {
            initializeMap(defaultLoc.lat, defaultLoc.lng);
        }
    },
    ".type change": function(el, ev) {
        typeChanged();
        clearMap();
        callUpdateMap(true);
    },
    ".datePicker change": function(el, ev) {
        clearMap();
        callUpdateMap(true);
    }
});
exports.MapControl = MapControl;

var initializeMainElements = function(element) {
    element.html(can.view('indexTemplate', {}));
    eventToOpenID = util.getURLArgument.id;

    $("#dateFrom").datepicker({
        defaultDate : "",
        changeMonth : true,
        changeYear : true,
        numberOfMonths : 1,
        onSelect : function(selectedDate) {
            $("#dateTo").datepicker("option", "minDate", selectedDate);
            $(this).trigger("change");
        }
    });
    $("#dateTo").datepicker({
        defaultDate : "+1w",
        changeMonth : true,
        changeYear : true,
        numberOfMonths : 1,
        onSelect : function(selectedDate) {
            $("#dateFrom").datepicker("option", "maxDate", selectedDate);
            $(this).trigger("change");
        }
    });

    var today = new Date();
    $("#dateFrom").val(util.getPrettyDate(today));
    $("#dateTo").datepicker("option", "minDate", today);

    var todayPlusOne = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);
    $("#dateTo").val(util.getPrettyDate(todayPlusOne));
    $("#dateFrom").datepicker("option", "maxDate", todayPlusOne);

    $("#menuBox").mCustomScrollbar();
    typeChanged();
}

var initializeMap = function (lat, lng) {
    var point = new google.maps.LatLng(lat, lng);

    map = new google.maps.Map(document.getElementById('mapBox'), {
        zoom : 15,
        center : point,
        mapTypeId : google.maps.MapTypeId.ROADMAP
    });

    google.maps.event.addListenerOnce(map, 'idle', function() {
        var ne = map.getBounds().getNorthEast();
        var sw = map.getBounds().getSouthWest();

        $('#radius').val(util.getDistanceFromLatLng(ne.lat(), ne.lng(), sw.lat(), sw.lng()) / 4);
        $('#lat').val(util.roundNumber(map.getCenter().lat()));
        $('#lng').val(util.roundNumber(map.getCenter().lng()));

        updateMap();
    });

    google.maps.event.addListener(map, 'dragstart', function() {
        dragging = true;
    });

    google.maps.event.addListener(map, 'dragend', function() {
        $('#lat').val(util.roundNumber(map.getCenter().lat()));
        $('#lng').val(util.roundNumber(map.getCenter().lng()));
        dragging = false;
        callUpdateMap(false);
    });

    google.maps.event.addListener(map, 'zoom_changed', function() {
        var ne = map.getBounds().getNorthEast();
        var sw = map.getBounds().getSouthWest();

        $('#radius').val(util.getDistanceFromLatLng(ne.lat(), ne.lng(), sw.lat(), sw.lng()));

        callUpdateMap(true);
    });
}

function setupSocket() {
    socket = io.connect('http://serenedi.com/');

    socket.on('getEventsResult', function(data) {
        var m = 1;
        var n = 0;

        if(data.message != null) {

            if(typeof(data.center) != 'undefined' || data.center != null){
                map.setCenter(new google.maps.LatLng(data.center.lat, data.center.lng));
            }

            if(typeof(data.date) != 'undefined' || data.date != null) {
                $("#dateFrom").datepicker("option", "maxDate", data.date.endDate);
                $('#dateFrom').val(data.date.startDate);
                $("#dateTo").datepicker("option", "minDate", data.date.startDate);
                $('#dateTo').val(data.date.endDate);
            }

            while(m < data.message.events.length) {

             if(n >= ids.length) {
                 ids[n] = MAX_NUMBER;
             }

             if(data.message.events[m].event.id < ids[n]) {
                 if(ids[n] == MAX_NUMBER) {
                     ids.pop();
                 }

                 ids.push(data.message.events[m].event.id);
                 addMarkers(data.message.events[m].event);

                 m++;
             } else if (data.message.events[m].event.id > ids[n]) {
                 n++;
             } else {
                 n++;
                 m++;
             }
         }

         ids.sort();
     } else {
         statusObservable.status.attr('value', 2);
     }
     statusObservable.status.attr('value', 0);
 });
}

var callUpdateMap = function (flag) {
    distCheckPass = flag;
    needUpdate = true;
}

var updateMap = function() {
    var distanceCheck = distCheckPass
    || ((latestLoc.lat == null && latestLoc.lng == null)
        || Math.abs(util.getDistanceFromLatLng($('#lat').val(), $('#lng').val(), latestLoc.lat, latestLoc.lng)) > $('#radius').val() / 1.5);
    var radiusCheck = $('#radius').val() < 20;

    if(needUpdate && !dragging && distanceCheck && radiusCheck && statusObservable.status.attr('value') != 1) {
        statusObservable.status.attr('value', 1);
        needUpdate = false;
        latestLoc.lat = $('#lat').val();
        latestLoc.lng = $('#lng').val();

        if (eventToOpenID == null || eventToOpenID == 'undefined') {
            socket.emit('getEventsCall', {
                message: { lat : $('#lat').val(),
                                lng : $('#lng').val(),
                                dateFrom : $('#dateFrom').val(),
                                dateTo : $('#dateTo').val(),
                                type : $('#categories').val(),
                                radius : $('#radius').val() }
            });
        } else {
            socket.emit('getEventsByIDCall', {
                message: { id : eventToOpenID,
                 radius : $('#radius').val()}
             });
        }
    }

    if(!radiusCheck) {
        statusObservable.status.attr('value', 3);
    }

    setTimeout(updateMap, 1000);
}

var clearMap = function () {
    closeLastOpen();

    for(n = 0; n < markers.length; n++) {
        markers[n].setMap(null);
    }

    markers = [];
    ids = [];
}

var closeLastOpen = function () {
    if (lastOpen != null) {
        lastOpen.close();
    }
    if (lastClickMarker != null) {
        lastClickMarker.setAnimation(null);
    }
    lastOpen = null;
    lastClickMarker = null;
}

var addMarkers = function (event) {
    var point = new google.maps.LatLng(event.venue.latitude, event.venue.longitude);

    var marker = new google.maps.Marker({
        position: point,
        map : map,
        title : event.title,
        animation : google.maps.Animation.DROP,
        clickable : true
    });

    marker.info = new google.maps.InfoWindow({content: '' + event.title + '
'});
    markers.push(marker);

    google.maps.event.addListener(
     marker,
     'click',
     function() {
         closeLastOpen();

            //TODO USE CSS FOR THE LOVE OF MOTHER TERESA
            var content = '
';
            content += '
';
            content += '
' + marker.getTitle() + '
';
            content += '
URL: 	' + event.url + '
http://www.serenedi.com/?id=' + event.id + '' + '
';
            content += '
Start: 	' + event.start_date.split(' ')[0] + '
';
            if (event.end_date != null) {
                content += '
End: 	' + event.end_date.split(' ')[0] + '
';
            }
            if (event.venue.address != null || event.venue.address != '') {
             content += '
Address: 	' + event.venue.address + ' ' + event.venue.address_2 + '
';
             content += '
	' + event.venue.city + ', ' + event.venue.region + ' ' + event.venue.postalcode + '
';
            }
            content += '
Category: 	' + event.category + '
';
            content += '

';
            content += '

 <fb:comments href="www.serenedi.com/?id=' + event.id + '" num_posts="2" width="400"> </script>

';
            content += '

';

            var info = new google.maps.InfoWindow();
            info.setContent(content);

            google.maps.event.addListenerOnce(info, 'closeclick', function() {
                marker.setAnimation(null);
            });

            info.open(map, marker);

            marker.setAnimation(google.maps.Animation.BOUNCE);

            lastClickMarker = marker;
            lastOpen = info;

            setTimeout(function() {
                try {
                    FB.XFBML.parse();
                } catch (ex) {
                }
            } , 100);
     });

    if (event.id == eventToOpenID) {
        google.maps.event.trigger(marker, 'click');
    }
}

var flagCheck = function(element) {
    if ($(element).prop('checked')) {
        return "1";
    } else {
        return "0";
    }
}

var typeChanged = function() {
    var result = flagCheck('#typeConfFlag');

    result += flagCheck('#typeConvFlag');
    result += flagCheck('#typeEntFlag');
    result += flagCheck('#typeFairFlag');
    result += flagCheck('#typeFoodFlag');
    result += flagCheck('#typeFundFlag');
    result += flagCheck('#typeMeetFlag');
    result += flagCheck('#typeMusicFlag');
    result += flagCheck('#typePerfFlag');
    result += flagCheck('#typeRecFlag');
    result += flagCheck('#typeReligFlag');
    result += flagCheck('#typeReunFlag');
    result += flagCheck('#typeSalesFlag');
    result += flagCheck('#typeSemiFlag');
    result += flagCheck('#typeSociFlag');
    result += flagCheck('#typeSportsFlag');
    result += flagCheck('#typeTradeFlag');
    result += flagCheck('#typeTravelFlag');
    result += flagCheck('#typeOtherFlag');

    $('#categories').val(result);
}
<|endoftext|>


<commit_before>var $ = require('../../../bower_components/jquery/jquery.min.js');
var util = require('./Util.js');
var statusObservable = require('./StatusObservable.js');

var map;
var ids = [];
var markers = [];
var lastClickMarker = null;
var lastOpen;
var latestLoc = {lat: null, lng: null};
var distCheckPass = null;
var eventToOpenID = null;
var dragging = false;
var needUpdate = true;
var MAX_NUMBER = 9007199254740992;
var socket = null;
var defaultLoc = {lat: 40.72616, lng: -73.99973};
var waitedSinceLastChange = true;

var MapControl = can.Control({
  init: function(element, options) {
    setupSocket();
    initializeMainElements(this.element);

    initializeMap();
    loadMyLocation();
    updateMap();
  },
  ".type change": function(el, ev) {
    typeChanged();
    clearMap();
    callUpdateMap(true);
  },
  ".datePicker change": function(el, ev) {
    clearMap();
    callUpdateMap(true);
  },
  ".location change": function(el, ev) {
    if(validateLatLng()) {
      callUpdateMap(true);
      reCenter();
    }
  },
  "#loadMyLocation click": function(el, ev) {
    loadMyLocation();
  }
});
exports.MapControl = MapControl;

var loadMyLocation = function() {
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function (position) {
      var lat = util.roundNumber(position.coords.latitude);
      var lng = util.roundNumber(position.coords.longitude);

      $('#lat').val(lat);
      $('#lng').val(lng);

      reCenter();
      callUpdateMap(true);
    });
  } else {
    $('#lat').val(defaultLoc.lat);
    $('#lng').val(defaultLoc.lng);

    reCenter();
    callUpdateMap(true);
  }
};

var initializeMainElements = function(element) {
  element.html(can.view('mapTemplate', {}));
  eventToOpenID = util.getURLArgument.id;

  $("#dateFrom").datepicker({
    defaultDate : "",
    changeMonth : true,
    changeYear : true,
    numberOfMonths : 1,
    onSelect : function(selectedDate) {
      $("#dateTo").datepicker("option", "minDate", selectedDate);
      $(this).trigger("change");
    }
  });
  $("#dateTo").datepicker({
    defaultDate : "+1w",
    changeMonth : true,
    changeYear : true,
    numberOfMonths : 1,
    onSelect : function(selectedDate) {
      $("#dateFrom").datepicker("option", "maxDate", selectedDate);
      $(this).trigger("change");
    }
  });

  var today = new Date();
  $("#dateFrom").val(util.getPrettyDate(today));
  $("#dateTo").datepicker("option", "minDate", today);

  var todayPlusOne = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);
  $("#dateTo").val(util.getPrettyDate(todayPlusOne));
  $("#dateFrom").datepicker("option", "maxDate", todayPlusOne);
  $("#sideMenu").mCustomScrollbar();

  $('#loadMyLocation').popover();
};

var initializeMap = function () {
  map = new google.maps.Map(document.getElementById('mapBox'), {
    zoom : 15,
    center : new google.maps.LatLng(defaultLoc.lat, defaultLoc.lng),
    mapTypeId : google.maps.MapTypeId.ROADMAP,
    disableDefaultUI: true,
    mapTypeControl: true
  });

  google.maps.event.addListenerOnce(map, 'idle', function() {
    var ne = map.getBounds().getNorthEast();
    var sw = map.getBounds().getSouthWest();

    $('#radius').val(util.getDistanceFromLatLng(ne.lat(), ne.lng(), sw.lat(), sw.lng()) / 3);
    $('#lat').val(util.roundNumber(map.getCenter().lat()));
    $('#lng').val(util.roundNumber(map.getCenter().lng()));
  });

  google.maps.event.addListener(map, 'dragstart', function() {
    dragging = true;
  });

  google.maps.event.addListener(map, 'dragend', function() {
    $('#lat').val(util.roundNumber(map.getCenter().lat()));
    $('#lng').val(util.roundNumber(map.getCenter().lng()));
    dragging = false;
    callUpdateMap(false);
  });

  google.maps.event.addListener(map, 'zoom_changed', function() {
    var ne = map.getBounds().getNorthEast();
    var sw = map.getBounds().getSouthWest();

    $('#radius').val(util.getDistanceFromLatLng(ne.lat(), ne.lng(), sw.lat(), sw.lng()));

    callUpdateMap(true);
  });
};

var setupSocket = function() {
  var socketOptions = {
    "transports" : [ "jsonp-polling" ],
    "try multiple transports" : false,
    "reconnect" : true,
    "connect timeout" : 5000,
    "reconnection limit attempts": 15
  };

  socket = io.connect('http://serenedi.com/', socketOptions);

  socket.on('getEventsResult', function(data) {
    var m = 1;
    var n = 0;

    if(data.message != null) {

      if(typeof(data.center) != 'undefined' || data.center != null){
        map.setCenter(new google.maps.LatLng(data.center.lat, data.center.lng));
      }

      if(typeof(data.date) != 'undefined' || data.date != null) {
        $("#dateFrom").datepicker("option", "maxDate", data.date.endDate);
        $('#dateFrom').val(data.date.startDate);
        $("#dateTo").datepicker("option", "minDate", data.date.startDate);
        $('#dateTo').val(data.date.endDate);
      }

      while(m < data.message.events.length) {

        if(n >= ids.length) {
          ids[n] = MAX_NUMBER;
        }

        if(data.message.events[m].event.id < ids[n]) {
          if(ids[n] == MAX_NUMBER) {
            ids.pop();
          }

          ids.push(data.message.events[m].event.id);
          addMarkers(data.message.events[m].event);

          m++;
        } else if (data.message.events[m].event.id > ids[n]) {
          n++;
        } else {
          n++;
          m++;
        }
      }

      ids.sort();
      statusObservable.status.attr('value', 0);
    } else {
      statusObservable.status.attr('value', 2);
    }
  });
};

var callUpdateMap = function (flag) {
  distCheckPass = flag;
  needUpdate = true;

  waitedSinceLastChange = false;
  setTimeout(function() {waitedSinceLastChange = true;}, 400);
};

var updateMap = function() {
  var distanceCheck = distCheckPass
  || ((latestLoc.lat == null && latestLoc.lng == null)
    || Math.abs(util.getDistanceFromLatLng($('#lat').val(), $('#lng').val(), latestLoc.lat, latestLoc.lng)) > $('#radius').val() / 1.5);
  var radiusCheck = $('#radius').val() < 20;

  if(needUpdate && !dragging && distanceCheck && radiusCheck && statusObservable.status.attr('value') != 1 && waitedSinceLastChange) {
    statusObservable.status.attr('value', 1);
    needUpdate = false;
    latestLoc.lat = $('#lat').val();
    latestLoc.lng = $('#lng').val();

    if (eventToOpenID == null || eventToOpenID == 'undefined') {
      socket.emit('getEventsCall', {
        message: { lat : $('#lat').val(),
        lng : $('#lng').val(),
        dateFrom : $('#dateFrom').val(),
        dateTo : $('#dateTo').val(),
        type : $('#categories').val(),
        radius : $('#radius').val() }
      });
    } else {
      socket.emit('getEventsByIDCall', {
        message: { id : eventToOpenID,
          radius : $('#radius').val()}
        });
    }
  }

  if(!radiusCheck) {
    statusObservable.status.attr('value', 3);
  }

  setTimeout(updateMap, 1500);
};

var clearMap = function () {
  closeLastOpen();

  for(n = 0; n < markers.length; n++) {
    markers[n].setMap(null);
  }

  markers = [];
  ids = [];
};

var closeLastOpen = function () {
  if (lastOpen != null) {
    lastOpen.close();
  }
  if (lastClickMarker != null) {
    lastClickMarker.setAnimation(null);
  }
  lastOpen = null;
  lastClickMarker = null;
};

var addMarkers = function (event) {
  var point = new google.maps.LatLng(event.venue.latitude, event.venue.longitude);

  var marker = new google.maps.Marker({
    position: point,
    map : map,
    title : event.title,
    animation : google.maps.Animation.DROP,
    clickable : true
  });

  marker.info = new google.maps.InfoWindow({content: '' + event.title + '
'});
  markers.push(marker);

  google.maps.event.addListener(
    marker,
    'click',
    function() {
      closeLastOpen();

      var info = new google.maps.InfoWindow({
        content: can.view.render("infoPopUpTemplate",
        {
          title: marker.getTitle(),
          url: {eventbrite: event.url, serenedi: 'http://www.serenedi.com/?id=' + event.id},
          start: event.start_date.split(' ')[0],
          end: event.end_date.split(' ')[0],
          showAddr: event.venue.address != null || event.venue.address != '',
          addr: event.venue.address + ' ' + event.venue.address_2,
          city: event.venue.city,
          region: event.venue.region,
          zip: event.venue.postalcode,
          category: event.category
        })
      });

      google.maps.event.addListenerOnce(info, 'closeclick', function() {
        marker.setAnimation(null);
      });

      info.open(map, marker);

      marker.setAnimation(google.maps.Animation.BOUNCE);

      lastClickMarker = marker;
      lastOpen = info;

      setTimeout(function() {
        try {
          FB.XFBML.parse();
        } catch (ex) {
        }
      } , 100);
    }
  );

  if (event.id == eventToOpenID) {
    google.maps.event.trigger(marker, 'click');
  }
};

var flagCheck = function(element) {
  if ($(element).prop('checked')) {
    return "1";
  } else {
    return "0";
  }
};

var typeChanged = function() {
  var result = flagCheck('#typeConfFlag');

  result += flagCheck('#typeConvFlag');
  result += flagCheck('#typeEntFlag');
  result += flagCheck('#typeFairFlag');
  result += flagCheck('#typeFoodFlag');
  result += flagCheck('#typeFundFlag');
  result += flagCheck('#typeMeetFlag');
  result += flagCheck('#typeMusicFlag');
  result += flagCheck('#typePerfFlag');
  result += flagCheck('#typeRecFlag');
  result += flagCheck('#typeReligFlag');
  result += flagCheck('#typeReunFlag');
  result += flagCheck('#typeSalesFlag');
  result += flagCheck('#typeSemiFlag');
  result += flagCheck('#typeSociFlag');
  result += flagCheck('#typeSportsFlag');
  result += flagCheck('#typeTradeFlag');
  result += flagCheck('#typeTravelFlag');
  result += flagCheck('#typeOtherFlag');

  $('#categories').val(result);
};

var validateLatLng = function() {
  return util.isNumber($("#lat").val()) && util.isNumber($("#lng").val());
};

var reCenter = function() {
  map.setCenter(new google.maps.LatLng($("#lat").val(), $("#lng").val()));
};<commit_msg>Refractoring MapControl.js based on JS Hint<commit_after>var $ = require('../../../bower_components/jquery/jquery.min.js');
var util = require('./Util.js');
var statusObservable = require('./StatusObservable.js');

var map;
var ids = [];
var markers = [];
var lastClickMarker = null;
var lastOpen;
var latestLoc = {lat: null, lng: null};
var distCheckPass = null;
var eventToOpenID = null;
var dragging = false;
var needUpdate = true;
var MAX_NUMBER = 9007199254740992;
var socket = null;
var defaultLoc = {lat: 40.72616, lng: -73.99973};
var waitedSinceLastChange = true;

var MapControl = can.Control({
  init: function(element, options) {
    setupSocket();
    initializeMainElements(this.element);

    initializeMap();
    loadMyLocation();
    updateMap();
  },
  ".type change": function(el, ev) {
    typeChanged();
    clearMap();
    callUpdateMap(true);
  },
  ".datePicker change": function(el, ev) {
    clearMap();
    callUpdateMap(true);
  },
  ".location change": function(el, ev) {
    if(validateLatLng()) {
      callUpdateMap(true);
      reCenter();
    }
  },
  "#loadMyLocation click": function(el, ev) {
    loadMyLocation();
  }
});
exports.MapControl = MapControl;

var loadMyLocation = function() {
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function (position) {
      var lat = util.roundNumber(position.coords.latitude);
      var lng = util.roundNumber(position.coords.longitude);

      $('#lat').val(lat);
      $('#lng').val(lng);

      reCenter();
      callUpdateMap(true);
    });
  } else {
    $('#lat').val(defaultLoc.lat);
    $('#lng').val(defaultLoc.lng);

    reCenter();
    callUpdateMap(true);
  }
};

var initializeMainElements = function(element) {
  element.html(can.view('mapTemplate', {}));
  eventToOpenID = util.getURLArgument.id;

  $("#dateFrom").datepicker({
    defaultDate : "",
    changeMonth : true,
    changeYear : true,
    numberOfMonths : 1,
    onSelect : function(selectedDate) {
      $("#dateTo").datepicker("option", "minDate", selectedDate);
      $(this).trigger("change");
    }
  });
  $("#dateTo").datepicker({
    defaultDate : "+1w",
    changeMonth : true,
    changeYear : true,
    numberOfMonths : 1,
    onSelect : function(selectedDate) {
      $("#dateFrom").datepicker("option", "maxDate", selectedDate);
      $(this).trigger("change");
    }
  });

  var today = new Date();
  $("#dateFrom").val(util.getPrettyDate(today));
  $("#dateTo").datepicker("option", "minDate", today);

  var todayPlusOne = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);
  $("#dateTo").val(util.getPrettyDate(todayPlusOne));
  $("#dateFrom").datepicker("option", "maxDate", todayPlusOne);
  $("#sideMenu").mCustomScrollbar();

  $('#loadMyLocation').popover();
};

var initializeMap = function () {
  map = new google.maps.Map(document.getElementById('mapBox'), {
    zoom : 15,
    center : new google.maps.LatLng(defaultLoc.lat, defaultLoc.lng),
    mapTypeId : google.maps.MapTypeId.ROADMAP,
    disableDefaultUI: true,
    mapTypeControl: true
  });

  google.maps.event.addListenerOnce(map, 'idle', function() {
    var ne = map.getBounds().getNorthEast();
    var sw = map.getBounds().getSouthWest();

    $('#radius').val(util.getDistanceFromLatLng(ne.lat(), ne.lng(), sw.lat(), sw.lng()) / 3);
    $('#lat').val(util.roundNumber(map.getCenter().lat()));
    $('#lng').val(util.roundNumber(map.getCenter().lng()));
  });

  google.maps.event.addListener(map, 'dragstart', function() {
    dragging = true;
  });

  google.maps.event.addListener(map, 'dragend', function() {
    $('#lat').val(util.roundNumber(map.getCenter().lat()));
    $('#lng').val(util.roundNumber(map.getCenter().lng()));
    dragging = false;
    callUpdateMap(false);
  });

  google.maps.event.addListener(map, 'zoom_changed', function() {
    var ne = map.getBounds().getNorthEast();
    var sw = map.getBounds().getSouthWest();

    $('#radius').val(util.getDistanceFromLatLng(ne.lat(), ne.lng(), sw.lat(), sw.lng()));

    callUpdateMap(true);
  });
};

var setupSocket = function() {
  var socketOptions = {
    "transports" : [ "jsonp-polling" ],
    "try multiple transports" : false,
    "reconnect" : true,
    "connect timeout" : 5000,
    "reconnection limit attempts": 15
  };

  socket = io.connect('http://serenedi.com/', socketOptions);

  socket.on('getEventsResult', function(data) {
    var m = 1;
    var n = 0;

    if(data.message !== null) {
      if(data.center){
        map.setCenter(new google.maps.LatLng(data.center.lat, data.center.lng));
      }

      if(data.date) {
        $("#dateFrom").datepicker("option", "maxDate", data.date.endDate);
        $('#dateFrom').val(data.date.startDate);
        $("#dateTo").datepicker("option", "minDate", data.date.startDate);
        $('#dateTo').val(data.date.endDate);
      }

      while(m < data.message.events.length) {

        if(n >= ids.length) {
          ids[n] = MAX_NUMBER;
        }

        if(data.message.events[m].event.id < ids[n]) {
          if(ids[n] == MAX_NUMBER) {
            ids.pop();
          }

          ids.push(data.message.events[m].event.id);
          addMarkers(data.message.events[m].event);

          m++;
        } else if (data.message.events[m].event.id > ids[n]) {
          n++;
        } else {
          n++;
          m++;
        }
      }

      ids.sort();
      statusObservable.status.attr('value', 0);
    } else {
      statusObservable.status.attr('value', 2);
    }
  });
};

var callUpdateMap = function (flag) {
  distCheckPass = flag;
  needUpdate = true;

  waitedSinceLastChange = false;
  setTimeout(function() {waitedSinceLastChange = true;}, 400);
};

var updateMap = function() {
  var distanceCheck = distCheckPass ||
    ((latestLoc.lat && latestLoc.lng) || Math.abs(util.getDistanceFromLatLng($('#lat').val(), $('#lng').val(), latestLoc.lat, latestLoc.lng)) > $('#radius').val() / 1.5);
  var radiusCheck = $('#radius').val() < 20;

  if(needUpdate && !dragging && distanceCheck && radiusCheck && statusObservable.status.attr('value') !== 1 && waitedSinceLastChange) {
    statusObservable.status.attr('value', 1);
    needUpdate = false;
    latestLoc.lat = $('#lat').val();
    latestLoc.lng = $('#lng').val();

    if (eventToOpenID) {
      socket.emit('getEventsByIDCall', {
        message: { id : eventToOpenID,
          radius : $('#radius').val()}
        });
    } else {
      socket.emit('getEventsCall', {
        message: { lat : $('#lat').val(),
        lng : $('#lng').val(),
        dateFrom : $('#dateFrom').val(),
        dateTo : $('#dateTo').val(),
        type : $('#categories').val(),
        radius : $('#radius').val() }
      });
    }
  }

  if(!radiusCheck) {
    statusObservable.status.attr('value', 3);
  }

  setTimeout(updateMap, 1500);
};

var clearMap = function () {
  closeLastOpen();

  for(n = 0; n < markers.length; n++) {
    markers[n].setMap(null);
  }

  markers = [];
  ids = [];
};

var closeLastOpen = function () {
  if (lastOpen) {
    lastOpen.close();
  }
  if (lastClickMarker) {
    lastClickMarker.setAnimation(null);
  }
  lastOpen = null;
  lastClickMarker = null;
};

var addMarkers = function (event) {
  var point = new google.maps.LatLng(event.venue.latitude, event.venue.longitude);

  var marker = new google.maps.Marker({
    position: point,
    map : map,
    title : event.title,
    animation : google.maps.Animation.DROP,
    clickable : true
  });

  marker.info = new google.maps.InfoWindow({content: '' + event.title + '
'});
  markers.push(marker);

  google.maps.event.addListener(
    marker,
    'click',
    function() {
      closeLastOpen();

      var info = new google.maps.InfoWindow({
        content: can.view.render("infoPopUpTemplate",
        {
          title: marker.getTitle(),
          url: {eventbrite: event.url, serenedi: 'http://www.serenedi.com/?id=' + event.id},
          start: event.start_date.split(' ')[0],
          end: event.end_date.split(' ')[0],
          showAddr: event.venue.address !== null || event.venue.address !== "",
          addr: event.venue.address + ' ' + event.venue.address_2,
          city: event.venue.city,
          region: event.venue.region,
          zip: event.venue.postalcode,
          category: event.category
        })
      });

      google.maps.event.addListenerOnce(info, 'closeclick', function() {
        marker.setAnimation(null);
      });

      info.open(map, marker);

      marker.setAnimation(google.maps.Animation.BOUNCE);

      lastClickMarker = marker;
      lastOpen = info;

      setTimeout(function() {
        try {
          FB.XFBML.parse();
        } catch (ex) {
        }
      } , 100);
    }
  );

  if (event.id == eventToOpenID) {
    google.maps.event.trigger(marker, 'click');
  }
};

var flagCheck = function(element) {
  if ($(element).prop('checked')) {
    return "1";
  } else {
    return "0";
  }
};

var typeChanged = function() {
  var result = flagCheck('#typeConfFlag');

  result += flagCheck('#typeConvFlag');
  result += flagCheck('#typeEntFlag');
  result += flagCheck('#typeFairFlag');
  result += flagCheck('#typeFoodFlag');
  result += flagCheck('#typeFundFlag');
  result += flagCheck('#typeMeetFlag');
  result += flagCheck('#typeMusicFlag');
  result += flagCheck('#typePerfFlag');
  result += flagCheck('#typeRecFlag');
  result += flagCheck('#typeReligFlag');
  result += flagCheck('#typeReunFlag');
  result += flagCheck('#typeSalesFlag');
  result += flagCheck('#typeSemiFlag');
  result += flagCheck('#typeSociFlag');
  result += flagCheck('#typeSportsFlag');
  result += flagCheck('#typeTradeFlag');
  result += flagCheck('#typeTravelFlag');
  result += flagCheck('#typeOtherFlag');

  $('#categories').val(result);
};

var validateLatLng = function() {
  return util.isNumber($("#lat").val()) && util.isNumber($("#lng").val());
};

var reCenter = function() {
  map.setCenter(new google.maps.LatLng($("#lat").val(), $("#lng").val()));
};<|endoftext|>


<commit_before>function visualiserApp(luigi) {
    var templates = {};

    function loadTemplates() {
        $("script[type='text/template']").each(function(i, element) {
            var name = $(element).attr("name");
            var content = $(element).text();
            templates[name] = content;
        });
    }

    function renderTemplate(templateName, dataObject) {
        return $("<div>").html(Mustache.render(templates[templateName], dataObject));
    }

    function formatTime(dateObject) {
        return dateObject.getHours() + ":" + dateObject.getMinutes() + ":" + dateObject.getSeconds();
    }

    function taskToDisplayTask(task) {
        var taskIdParts = /([A-Za-z]*)\((.*)\)/.exec(task.taskId);
        var taskName = taskIdParts[1];
        var taskParams = taskIdParts[2];
        var displayTime = new Date(Math.floor(task.start_time*1000)).toLocaleTimeString();
        return {
            taskId: task.taskId,
            taskName: taskName,
            taskParams: taskParams,
            displayTime: displayTime,
            trackingUrl: task.trackingUrl,
            status: task.status,
            graph: (task.status == "PENDING" || task.status == "RUNNING")
        };
    }

    function indexByProperty(tasks, fieldName) {
        indexedTasks = {};
        $.each(tasks, function(i, task) {
            if (!indexedTasks.hasOwnProperty(task[fieldName])) {
                indexedTasks[task[fieldName]] = [];
            }
            indexedTasks[task[fieldName]].push(task);
        });
        return indexedTasks;
    }

    function entryList(object) {
        var list = [];
        $.each(object, function(key, value) {
            list.push({key: key, value:value});
        });
        return list;
    }

    function renderTasks(tasks) {
        var displayTasks = $.map(tasks, taskToDisplayTask);
        displayTasks.sort(function(a,b) { return a.taskId.localeCompare(b.taskId); });
        var tasksByFamily = entryList(indexByProperty(displayTasks, "taskName"));
        tasksByFamily.sort(function(a,b) { return a.key.localeCompare(b.key); });
        return renderTemplate("rowTemplate", {tasks: tasksByFamily});
    }

    function switchTab(tabId) {
        $(".tabButton").parent().removeClass("active");
        $(".tab-pane").removeClass("active");
        $("#"+tabId).addClass("active");
        $(".tabButton[data-tab="+tabId+"]").parent().addClass("active");
    }

    function showErrorTrace(error) {
        $("#errorModal").empty().append(renderTemplate("errorTemplate", error));
        $("#errorModal").modal({});
    }

    function processHashChange() {
        var hash = location.hash;
        if (hash) {
            var taskId = hash.substr(1);
            $("#graphContainer").hide();
            if (taskId != "g") {
                luigi.getDependencyGraph(taskId, function(dependencyGraph) {
                    $("#dependencyTitle").text(taskId);
                    $("#graphPlaceholder svg").empty();
                    $("#graphPlaceholder").get(0).graph.updateData(dependencyGraph);
                    $("#graphContainer").show();
                    bindGraphEvents();
                });
            }
            switchTab("dependencyGraph");
        } else {
            switchTab("taskList");
        }
    }

    function bindGraphEvents() {
        $(".graph-node-a").click(function(event) {
            var taskId = $(this).attr("data-task-id");
            var status = $(this).attr("data-task-status");
            if (status=="FAILED") {
                event.preventDefault();
                luigi.getErrorTrace(taskId, function(error) {
                   showErrorTrace(error);
                });
            }
        });
    }

    function bindListEvents() {
        $("[data-action=expandTaskRows]").click(function(event) {
            event.preventDefault();
            var icon = $(this).find("span");
            if (icon.hasClass("icon-plus")) {
                icon.removeClass("icon-plus");
                icon.addClass("icon-minus");
            } else {
                icon.removeClass("icon-minus");
                icon.addClass("icon-plus");
            }
            var taskRows = $(this).closest(".taskFamily").find(".taskRows").slideToggle("fast");
        });
        $(window).on('hashchange', processHashChange);
        $("a[href=#list]").click(function() { location.hash=""; });
        $("#loadTaskForm").submit(function(event) {
            event.preventDefault();
            location.hash = $(this).find("input").val();
        });
        $(".error-trace-button").click(function() {
            luigi.getErrorTrace($(this).attr("data-task-id"), function(error) {
               showErrorTrace(error);
            });
        });
    }

    $(document).ready(function() {
        loadTemplates();

        luigi.getFailedTaskList(function(failedTasks) {
            luigi.getUpstreamFailedTaskList(function(upstreamFailedTasks) {
            	luigi.getRunningTaskList(function(runningTasks) {
                luigi.getPendingTaskList(function(pendingTasks) {
                	$("#failedTasks").append(renderTasks(failedTasks));
                	$("#upstreamFailedTasks").append(renderTasks(upstreamFailedTasks));
                	$("#runningTasks").append(renderTasks(runningTasks));
                  $("#pendingTasks").append(renderTasks(pendingTasks));
                	bindListEvents();
             	  });
              });
            });
        });

        var graph = new Graph.DependencyGraph($("#graphPlaceholder")[0]);
        $("#graphPlaceholder")[0].graph = graph;
        processHashChange();
    });
}
<commit_msg>Changed ordering of tasks in the task list to be most recently submitted first (within each grouped list of tasks)<commit_after>function visualiserApp(luigi) {
    var templates = {};

    function loadTemplates() {
        $("script[type='text/template']").each(function(i, element) {
            var name = $(element).attr("name");
            var content = $(element).text();
            templates[name] = content;
        });
    }

    function renderTemplate(templateName, dataObject) {
        return $("<div>").html(Mustache.render(templates[templateName], dataObject));
    }

    function formatTime(dateObject) {
        return dateObject.getHours() + ":" + dateObject.getMinutes() + ":" + dateObject.getSeconds();
    }

    function taskToDisplayTask(task) {
        var taskIdParts = /([A-Za-z]*)\((.*)\)/.exec(task.taskId);
        var taskName = taskIdParts[1];
        var taskParams = taskIdParts[2];
        var displayTime = new Date(Math.floor(task.start_time*1000)).toLocaleTimeString();
        return {
            taskId: task.taskId,
            taskName: taskName,
            taskParams: taskParams,
            displayTime: displayTime,
            displayTimestamp : task.start_time,
            trackingUrl: task.trackingUrl,
            status: task.status,
            graph: (task.status == "PENDING" || task.status == "RUNNING")
        };
    }

    function indexByProperty(tasks, fieldName) {
        indexedTasks = {};
        $.each(tasks, function(i, task) {
            if (!indexedTasks.hasOwnProperty(task[fieldName])) {
                indexedTasks[task[fieldName]] = [];
            }
            indexedTasks[task[fieldName]].push(task);
        });
        return indexedTasks;
    }

    function entryList(object) {
        var list = [];
        $.each(object, function(key, value) {
            list.push({key: key, value:value});
        });
        return list;
    }

    function renderTasks(tasks) {
        var displayTasks = $.map(tasks, taskToDisplayTask);
        displayTasks.sort(function(a,b) { return b.displayTimestamp - a.displayTimestamp; });
        var tasksByFamily = entryList(indexByProperty(displayTasks, "taskName"));
        tasksByFamily.sort(function(a,b) { return a.key.localeCompare(b.key); });
        return renderTemplate("rowTemplate", {tasks: tasksByFamily});
    }

    function switchTab(tabId) {
        $(".tabButton").parent().removeClass("active");
        $(".tab-pane").removeClass("active");
        $("#"+tabId).addClass("active");
        $(".tabButton[data-tab="+tabId+"]").parent().addClass("active");
    }

    function showErrorTrace(error) {
        $("#errorModal").empty().append(renderTemplate("errorTemplate", error));
        $("#errorModal").modal({});
    }

    function processHashChange() {
        var hash = location.hash;
        if (hash) {
            var taskId = hash.substr(1);
            $("#graphContainer").hide();
            if (taskId != "g") {
                luigi.getDependencyGraph(taskId, function(dependencyGraph) {
                    $("#dependencyTitle").text(taskId);
                    $("#graphPlaceholder svg").empty();
                    $("#graphPlaceholder").get(0).graph.updateData(dependencyGraph);
                    $("#graphContainer").show();
                    bindGraphEvents();
                });
            }
            switchTab("dependencyGraph");
        } else {
            switchTab("taskList");
        }
    }

    function bindGraphEvents() {
        $(".graph-node-a").click(function(event) {
            var taskId = $(this).attr("data-task-id");
            var status = $(this).attr("data-task-status");
            if (status=="FAILED") {
                event.preventDefault();
                luigi.getErrorTrace(taskId, function(error) {
                   showErrorTrace(error);
                });
            }
        });
    }

    function bindListEvents() {
        $("[data-action=expandTaskRows]").click(function(event) {
            event.preventDefault();
            var icon = $(this).find("span");
            if (icon.hasClass("icon-plus")) {
                icon.removeClass("icon-plus");
                icon.addClass("icon-minus");
            } else {
                icon.removeClass("icon-minus");
                icon.addClass("icon-plus");
            }
            var taskRows = $(this).closest(".taskFamily").find(".taskRows").slideToggle("fast");
        });
        $(window).on('hashchange', processHashChange);
        $("a[href=#list]").click(function() { location.hash=""; });
        $("#loadTaskForm").submit(function(event) {
            event.preventDefault();
            location.hash = $(this).find("input").val();
        });
        $(".error-trace-button").click(function() {
            luigi.getErrorTrace($(this).attr("data-task-id"), function(error) {
               showErrorTrace(error);
            });
        });
    }

    $(document).ready(function() {
        loadTemplates();

        luigi.getFailedTaskList(function(failedTasks) {
            luigi.getUpstreamFailedTaskList(function(upstreamFailedTasks) {
            	luigi.getRunningTaskList(function(runningTasks) {
                luigi.getPendingTaskList(function(pendingTasks) {
                	$("#failedTasks").append(renderTasks(failedTasks));
                	$("#upstreamFailedTasks").append(renderTasks(upstreamFailedTasks));
                	$("#runningTasks").append(renderTasks(runningTasks));
                  $("#pendingTasks").append(renderTasks(pendingTasks));
                	bindListEvents();
             	  });
              });
            });
        });

        var graph = new Graph.DependencyGraph($("#graphPlaceholder")[0]);
        $("#graphPlaceholder")[0].graph = graph;
        processHashChange();
    });
}
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.render('contact', { title: 'Contact' });
});

module.exports = router;
<commit_msg>Nodemailer Setup<commit_after>var express = require('express');
var router = express.Router();
var nodemailer = require('nodemailer');

router.get('/', function(req, res, next) {
  res.render('contact', { title: 'Contact' });
});

router.post('/send',function(req, res, next){
  var transporter = nodemailer.createTransport({
    service: 'Gmail',
    auth: {
      user: 'educostachaves@gmail.com',
      pass: 'mypass'
    }
  });

  var mailOptions = {
    from: 'Jonh Doe <johndoe@outlook.com>',
    to: 'educostachaves@gmail.com',
    subject: 'Website Submission',
    text: 'Name: '+req.body.name+' Email: '+req.body.email+' Message'+req.body.message,
    html: '
You got a new submission

Name: '+req.body.name+'

Email: '+req.body.email+'

Message'+req.body.message+'

'
  };

  transporter.sendMail(mailOptions, function(error, info){
    if(error){
      console.log(error);
      res.redirect('/');
    } else {
      console.log('Message Sent: '+info.response);
      res.redirect('/');
    }
  });
});

module.exports = router;
<|endoftext|>