diff --git a/app/assets/images/MMCCicon_add.png b/app/assets/images/MMCCicon_add.png
new file mode 100644
index 00000000..fdb4045f
Binary files /dev/null and b/app/assets/images/MMCCicon_add.png differ
diff --git a/app/assets/images/MMCCicon_commons.png b/app/assets/images/MMCCicon_commons.png
new file mode 100644
index 00000000..1eed3c5b
Binary files /dev/null and b/app/assets/images/MMCCicon_commons.png differ
diff --git a/app/assets/images/MMCCicon_help.png b/app/assets/images/MMCCicon_help.png
new file mode 100644
index 00000000..16cd1894
Binary files /dev/null and b/app/assets/images/MMCCicon_help.png differ
diff --git a/app/assets/images/MMCCicon_info.png b/app/assets/images/MMCCicon_info.png
new file mode 100644
index 00000000..4594cba0
Binary files /dev/null and b/app/assets/images/MMCCicon_info.png differ
diff --git a/app/assets/images/MMCCicon_invite.png b/app/assets/images/MMCCicon_invite.png
new file mode 100644
index 00000000..347ddc02
Binary files /dev/null and b/app/assets/images/MMCCicon_invite.png differ
diff --git a/app/assets/images/MMCCicon_logout.png b/app/assets/images/MMCCicon_logout.png
new file mode 100644
index 00000000..5f22796f
Binary files /dev/null and b/app/assets/images/MMCCicon_logout.png differ
diff --git a/app/assets/images/MMCCicon_map.png b/app/assets/images/MMCCicon_map.png
new file mode 100644
index 00000000..e1a61d89
Binary files /dev/null and b/app/assets/images/MMCCicon_map.png differ
diff --git a/app/assets/images/MMCCicon_mapper.png b/app/assets/images/MMCCicon_mapper.png
new file mode 100644
index 00000000..0e9c3207
Binary files /dev/null and b/app/assets/images/MMCCicon_mapper.png differ
diff --git a/app/assets/images/MMCCicon_pop-out.png b/app/assets/images/MMCCicon_pop-out.png
new file mode 100644
index 00000000..ca3ecd45
Binary files /dev/null and b/app/assets/images/MMCCicon_pop-out.png differ
diff --git a/app/assets/images/MMCCicon_private.png b/app/assets/images/MMCCicon_private.png
new file mode 100644
index 00000000..50e98e18
Binary files /dev/null and b/app/assets/images/MMCCicon_private.png differ
diff --git a/app/assets/images/MMCCicon_public.png b/app/assets/images/MMCCicon_public.png
new file mode 100644
index 00000000..37a6fd07
Binary files /dev/null and b/app/assets/images/MMCCicon_public.png differ
diff --git a/app/assets/images/MMCCicon_settings.png b/app/assets/images/MMCCicon_settings.png
new file mode 100644
index 00000000..ae56c5a9
Binary files /dev/null and b/app/assets/images/MMCCicon_settings.png differ
diff --git a/app/assets/images/MMCCicon_synapse.png b/app/assets/images/MMCCicon_synapse.png
new file mode 100644
index 00000000..9fea87f0
Binary files /dev/null and b/app/assets/images/MMCCicon_synapse.png differ
diff --git a/app/assets/images/MMCCicon_topic.png b/app/assets/images/MMCCicon_topic.png
new file mode 100644
index 00000000..90457c0b
Binary files /dev/null and b/app/assets/images/MMCCicon_topic.png differ
diff --git a/app/assets/images/account_icon.png b/app/assets/images/account_icon.png
new file mode 100644
index 00000000..403c656d
Binary files /dev/null and b/app/assets/images/account_icon.png differ
diff --git a/app/assets/images/argument.png b/app/assets/images/argument.png
index 4221eed3..e306ee65 100644
Binary files a/app/assets/images/argument.png and b/app/assets/images/argument.png differ
diff --git a/app/assets/images/decision.png b/app/assets/images/decision.png
index c416a00d..0fda323e 100644
Binary files a/app/assets/images/decision.png and b/app/assets/images/decision.png differ
diff --git a/app/assets/images/example.png b/app/assets/images/example.png
index 986ce049..29a9393a 100644
Binary files a/app/assets/images/example.png and b/app/assets/images/example.png differ
diff --git a/app/assets/images/experience.png b/app/assets/images/experience.png
index 1a7f5569..0e70033a 100644
Binary files a/app/assets/images/experience.png and b/app/assets/images/experience.png differ
diff --git a/app/assets/images/futuredev.png b/app/assets/images/futuredev.png
index b5c66609..ad58519a 100644
Binary files a/app/assets/images/futuredev.png and b/app/assets/images/futuredev.png differ
diff --git a/app/assets/images/idea.png b/app/assets/images/idea.png
index 775f9a09..25378e79 100644
Binary files a/app/assets/images/idea.png and b/app/assets/images/idea.png differ
diff --git a/app/assets/images/implication.png b/app/assets/images/implication.png
index 328bfcc8..4d7e0120 100644
Binary files a/app/assets/images/implication.png and b/app/assets/images/implication.png differ
diff --git a/app/assets/images/insight.png b/app/assets/images/insight.png
index 6fe668fe..01c675ee 100644
Binary files a/app/assets/images/insight.png and b/app/assets/images/insight.png differ
diff --git a/app/assets/images/intention.png b/app/assets/images/intention.png
index 46e55607..3d734ed5 100644
Binary files a/app/assets/images/intention.png and b/app/assets/images/intention.png differ
diff --git a/app/assets/images/knowledge.png b/app/assets/images/knowledge.png
index 238118ad..ece21567 100644
Binary files a/app/assets/images/knowledge.png and b/app/assets/images/knowledge.png differ
diff --git a/app/assets/images/location.png b/app/assets/images/location.png
index 00aa12fa..00447228 100644
Binary files a/app/assets/images/location.png and b/app/assets/images/location.png differ
diff --git a/app/assets/images/menu_icon_32.png b/app/assets/images/menu_icon_32.png
new file mode 100644
index 00000000..811f4af3
Binary files /dev/null and b/app/assets/images/menu_icon_32.png differ
diff --git a/app/assets/images/moviemap.png b/app/assets/images/moviemap.png
index 554f4ac6..615e32fe 100644
Binary files a/app/assets/images/moviemap.png and b/app/assets/images/moviemap.png differ
diff --git a/app/assets/images/my_maps_icon.png b/app/assets/images/my_maps_icon.png
new file mode 100644
index 00000000..7cfbc33c
Binary files /dev/null and b/app/assets/images/my_maps_icon.png differ
diff --git a/app/assets/images/opinion.png b/app/assets/images/opinion.png
index 9cb9c921..3e418b65 100644
Binary files a/app/assets/images/opinion.png and b/app/assets/images/opinion.png differ
diff --git a/app/assets/images/pro.png b/app/assets/images/pro.png
index 44af61c9..a93acb84 100644
Binary files a/app/assets/images/pro.png and b/app/assets/images/pro.png differ
diff --git a/app/assets/images/problem.png b/app/assets/images/problem.png
index 06f6f188..199cfbb0 100644
Binary files a/app/assets/images/problem.png and b/app/assets/images/problem.png differ
diff --git a/app/assets/images/question.png b/app/assets/images/question.png
index 10a2b2fb..7caa86d4 100644
Binary files a/app/assets/images/question.png and b/app/assets/images/question.png differ
diff --git a/app/assets/images/resource.png b/app/assets/images/resource.png
index 12fc36bc..79a7818b 100644
Binary files a/app/assets/images/resource.png and b/app/assets/images/resource.png differ
diff --git a/app/assets/images/role.png b/app/assets/images/role.png
index 6ee08b0b..3d6147c4 100644
Binary files a/app/assets/images/role.png and b/app/assets/images/role.png differ
diff --git a/app/assets/images/search_icon_32x32.png b/app/assets/images/search_icon_32x32.png
new file mode 100644
index 00000000..00a6dc34
Binary files /dev/null and b/app/assets/images/search_icon_32x32.png differ
diff --git a/app/assets/images/task.png b/app/assets/images/task.png
index 11e5a7ae..c9d8f081 100644
Binary files a/app/assets/images/task.png and b/app/assets/images/task.png differ
diff --git a/app/assets/images/wildcard.png b/app/assets/images/wildcard.png
index 64dceb8c..d72c4994 100644
Binary files a/app/assets/images/wildcard.png and b/app/assets/images/wildcard.png differ
diff --git a/app/assets/javascripts/Jit/graphsettings-event-handlers.js b/app/assets/javascripts/Jit/graphsettings-event-handlers.js
index 47eb2c49..54af42c8 100644
--- a/app/assets/javascripts/Jit/graphsettings-event-handlers.js
+++ b/app/assets/javascripts/Jit/graphsettings-event-handlers.js
@@ -1,13 +1,12 @@
function selectEdgeOnClickHandler(adj, e) {
if (Mconsole.busy) return;
- //editing overrides everything else
- if (e.altKey) {
- //in select-edit-delete-nodes-and-edges.js
- editEdge(adj, e);
+ if (synapseWasDoubleClicked()) {
+ synapseDoubleClickHandler(adj, e);
return;
}
+
var edgeIsSelected = MetamapsModel.selectedEdges.indexOf(adj);
if (edgeIsSelected == -1) edgeIsSelected = false;
else if (edgeIsSelected != -1) edgeIsSelected = true;
@@ -30,18 +29,48 @@ function selectEdgeOnClickHandler(adj, e) {
Mconsole.plot();
}//selectEdgeOnClickHandler
+function synapseDoubleClickHandler(adj, e) {
+ editEdge(adj, e);
+}
+
+/*
+ * Returns a boolean saying if the synapse was double clicked in our understanding of the word
+ */
+function synapseWasDoubleClicked() {
+ //grab the timestamp of the click
+ var storedTime = MetamapsModel.lastSynapseClick;
+ var now = Date.now(); //not compatible with IE8 FYI
+ MetamapsModel.lastSynapseClick = now;
+
+ if (now - storedTime < MetamapsModel.DOUBLE_CLICK_TOLERANCE) {
+ return true;
+ } else {
+ return false;
+ }
+}//synapseWasDoubleClicked;
+
function nodeDoubleClickHandler(node, e) {
- keepFromCommons(node);
+ openNodeShowcard(node);
}
function enterKeyHandler() {
- var selectedNodesCopy = MetamapsModel.selectedNodes.slice(0);
- var len = selectedNodesCopy.length;
- for (var i = 0; i < len; i += 1) {
- n = selectedNodesCopy[i];
- keepFromCommons(n);
- }//for
- Mconsole.plot();
+
+ // if the metacode spinner is open, create topic when enter is pressed
+ if ( $('.new_topic').css('display') != 'none' ) {
+ $('.new_topic').submit();
+ }
+ // if the metacode spinner is open, create topic when enter is pressed
+ else if ( $('.new_synapse').css('display') != 'none' ) {
+ $('.new_synapse').submit();
+ }
+
+ //var selectedNodesCopy = MetamapsModel.selectedNodes.slice(0);
+ //var len = selectedNodesCopy.length;
+ //for (var i = 0; i < len; i += 1) {
+ // n = selectedNodesCopy[i];
+ // keepFromCommons(n);
+ //}//for
+ //Mconsole.plot();
}//enterKeyHandler
function escKeyHandler() {
@@ -53,36 +82,16 @@ function escKeyHandler() {
* Make a node "in the commons" (with a green circle) lose its
* green circle so it stays on the console/map/...
*/
-function keepFromCommons(node) {
+function keepFromCommons(id) {
if (userid == null) {
return;
}
- //greenCircle being true denotes it's actually "in the commons" still
- if (node.getData('greenCircle') == false) {
- return;
- }
-
- //this line adds it to the console if you close seek
- node.setData('greenCircle', false);
-
- //this is just aesthetic
- deselectNode(node);
-
- //this adds the node to the map, if it's a map
- if (window.mapid) {
- $.post('/mappings',
- {
- topic: {id: node.id},
- map: {id: window.mapid},
- xloc: node.pos.x,
- yloc: node.pos.y
- },
- function(data, textStatus, jqXHR) {
- console.log(data);
- node.setData('mappingid', data.id);
- });
- }
+ $('#topic_addSynapse').val("false");
+ $('#topic_x').val(0);
+ $('#topic_y').val(0);
+ $('#topic_grabTopic').val(id);
+ $('.new_topic').submit();
}//doubleClickNodeHandler
/*
@@ -143,14 +152,20 @@ function canvasDoubleClickHandler(canvasLoc,e) {
$('#new_topic').css('left', e.clientX + "px");
$('#new_topic').css('top', e.clientY + "px");
$('#topic_x').val(canvasLoc.x);
- $('#topic_y').val(canvasLoc.y);
- $('#topic_name').autocomplete('enable');
+ $('#topic_y').val(canvasLoc.y);
$('#new_topic').fadeIn('fast');
addMetacode();
$('#topic_name').focus();
} else {
$('#new_topic').fadeOut('fast');
$('#new_synapse').fadeOut('fast');
+ // reset the draw synapse positions to false
+ MetamapsModel.synapseStartCoord = false;
+ MetamapsModel.synapseEndCoord = false;
+ // set all node dimensions back to normal
+ Mconsole.graph.eachNode(function (n) {
+ n.setData('dim', 25, 'current');
+ });
tempInit = false;
tempNode = null;
tempNode2 = null;
@@ -250,13 +265,25 @@ function onDragMoveTopicHandler(node, eventInfo, e) {
if (tempInit == false) {
tempNode = node;
tempInit = true;
+ // set the draw synapse start position
+ MetamapsModel.synapseStartCoord = {
+ x: node.pos.getc().x,
+ y: node.pos.getc().y
+ };
}
//
temp = eventInfo.getNode();
if (temp != false && temp.id != node.id) { // this means a Node has been returned
tempNode2 = temp;
+
+ // set the draw synapse end position
+ MetamapsModel.synapseEndCoord = {
+ x: temp.pos.getc().x,
+ y: temp.pos.getc().y
+ };
+
Mconsole.plot();
- renderMidArrow({ x: tempNode.pos.getc().x, y: tempNode.pos.getc().y }, { x: temp.pos.getc().x, y: temp.pos.getc().y }, 13, false, Mconsole.canvas);
+
// before making the highlighted one bigger, make sure all the others are regular size
Mconsole.graph.eachNode(function (n) {
n.setData('dim', 25, 'current');
@@ -279,8 +306,12 @@ function onDragMoveTopicHandler(node, eventInfo, e) {
$('#new_synapse').css('top',myY + "px");
$('#topic_x').val(eventInfo.getPos().x);
$('#topic_y').val(eventInfo.getPos().y);
+ // set the draw synapse end position
+ MetamapsModel.synapseEndCoord = {
+ x: eventInfo.getPos().x,
+ y: eventInfo.getPos().y
+ };
Mconsole.plot();
- renderMidArrow({ x: tempNode.pos.getc().x, y: tempNode.pos.getc().y }, { x: pos.x, y: pos.y }, 13, false, Mconsole.canvas);
Mconsole.fx.plotNode(tempNode, Mconsole.canvas);
}
}
diff --git a/app/assets/javascripts/Jit/graphsettings-model.js b/app/assets/javascripts/Jit/graphsettings-model.js
index ea62de64..1939e738 100644
--- a/app/assets/javascripts/Jit/graphsettings-model.js
+++ b/app/assets/javascripts/Jit/graphsettings-model.js
@@ -31,7 +31,12 @@ MetamapsModel.edgeHoveringOver = false;
MetamapsModel.boxStartCoordinates = false;
MetamapsModel.boxEndCoordinates = false;
+//coordinates for drawing edge that's not created yet
+MetamapsModel.synapseStartCoord = false;
+MetamapsModel.synapseEndCoord = false;
+
//double clicking of nodes or canvas
+MetamapsModel.lastSynapseClick = 0;
MetamapsModel.lastNodeClick = 0;
MetamapsModel.lastCanvasClick = 0;
MetamapsModel.DOUBLE_CLICK_TOLERANCE = 300;
diff --git a/app/assets/javascripts/Jit/graphsettings.js b/app/assets/javascripts/Jit/graphsettings.js
index 75cdeb69..9ff758c8 100644
--- a/app/assets/javascripts/Jit/graphsettings.js
+++ b/app/assets/javascripts/Jit/graphsettings.js
@@ -13,7 +13,6 @@ function graphSettings(type, embed) {
//by scrolling and DnD
Navigation: {
enable: true,
- type: 'HTML',
//Enable panning events only if we're dragging the empty
//canvas (and not a node).
panning: 'avoid nodes',
@@ -39,8 +38,11 @@ function graphSettings(type, embed) {
},
//Native canvas text styling
Label: {
- type: 'HTML', //Native or HTML
+ type: 'Native', //Native or HTML
size: 20,
+ family: 'LatoLight',
+ textBaseline: 'hanging',
+ color:'#000'
//style: 'bold'
},
//Add Tips
@@ -52,7 +54,6 @@ function graphSettings(type, embed) {
Events: {
enable: true,
enableForEdges: true,
- type: 'HTML',
onMouseMove: function(node, eventInfo, e) {
onMouseMoveHandler(node, eventInfo, e);
},
@@ -123,6 +124,17 @@ function graphSettings(type, embed) {
}
canvasDoubleClickHandler(eventInfo.getPos(), e);
}//if
+ },
+ onRightClick: function (node, eventInfo, e) {
+ if (node && !node.nodeFrom) {
+ // open right click menu
+ }
+ else if (node && node.nodeFrom) { // the variable 'node' is actually an edge/adjacency
+ // open right click menu
+ }
+ else {
+ // right click on open canvas, options here?
+ }
}
},
//Number of iterations for the FD algorithm
@@ -131,13 +143,13 @@ function graphSettings(type, embed) {
levelDistance: 200,
// Add text to the labels. This method is only triggered
// on label creation and only for DOM labels (not native canvas ones).
- onCreateLabel: function (domElement, node) {
- onCreateLabelHandler(type, domElement, node);
- },
+ //onCreateLabel: function (domElement, node) {
+ // onCreateLabelHandler(type, domElement, node);
+ //},
// Change node styles when DOM labels are placed or moved.
- onPlaceLabel: function (domElement, node) {
- onPlaceLabelHandler(domElement, node);
- }
+ //onPlaceLabel: function (domElement, node) {
+ // onPlaceLabelHandler(domElement, node);
+ //}
};
if (embed) {
@@ -191,7 +203,7 @@ function hideCards() {
}
// defining code to draw edges with arrows pointing in one direction
-var renderMidArrow = function(from, to, dim, swap, canvas){
+var renderMidArrow = function(from, to, dim, swap, canvas, placement, newSynapse){
var ctx = canvas.getCtx();
// invert edge direction
if (swap) {
@@ -204,7 +216,10 @@ var renderMidArrow = function(from, to, dim, swap, canvas){
// scale it
vect.$scale(dim / vect.norm());
// compute the midpoint of the edge line
- var midPoint = new $jit.Complex((to.x + from.x) / 2, (to.y + from.y) / 2);
+ var newX = (to.x - from.x) * placement + from.x;
+ var newY = (to.y - from.y) * placement + from.y;
+ var midPoint = new $jit.Complex(newX, newY);
+
// move midpoint by half the "length" of the arrow so the arrow is centered on the midpoint
var arrowPoint = new $jit.Complex((vect.x / 0.7) + midPoint.x, (vect.y / 0.7) + midPoint.y);
// compute the tail intersection point with the edge line
@@ -213,8 +228,12 @@ var renderMidArrow = function(from, to, dim, swap, canvas){
var normal = new $jit.Complex(-vect.y / 2, vect.x / 2);
var v1 = intermediatePoint.add(normal);
var v2 = intermediatePoint.$add(normal.$scale(-1));
-
- //ctx.strokeStyle = "#222222";
+
+ if (newSynapse) {
+ ctx.strokeStyle = "#222222";
+ ctx.lineWidth = 2;
+ ctx.globalAlpha = 0.4;
+ }
ctx.beginPath();
ctx.moveTo(from.x, from.y);
ctx.lineTo(to.x, to.y);
@@ -225,38 +244,6 @@ var renderMidArrow = function(from, to, dim, swap, canvas){
ctx.lineTo(v2.x, v2.y);
ctx.stroke();
};
-// defining code to draw edges with arrows pointing in both directions
-var renderMidArrows = function(from, to, dim, swap, canvas){
- var ctx = canvas.getCtx();
- // invert edge direction
- if (swap) {
- var tmp = from;
- from = to;
- to = tmp;
- }
- // vect represents a line from tip to tail of the arrow
- var vect = new $jit.Complex(to.x - from.x, to.y - from.y);
- // scale it
- vect.$scale(dim / vect.norm());
- // compute the midpoint of the edge line
- var midPoint = new $jit.Complex((to.x + from.x) / 2, (to.y + from.y) / 2);
- // move midpoint by half the "length" of the arrow so the arrow is centered on the midpoint
- var arrowPoint = new $jit.Complex((vect.x / 0.7) + midPoint.x, (vect.y / 0.7) + midPoint.y);
- // compute the tail intersection point with the edge line
- var intermediatePoint = new $jit.Complex(arrowPoint.x - vect.x,
-arrowPoint.y - vect.y);
- // vector perpendicular to vect
- var normal = new $jit.Complex(-vect.y / 2, vect.x / 2);
- var v1 = intermediatePoint.add(normal);
- var v2 = intermediatePoint.$add(normal.$scale(-1));
-
- //ctx.strokeStyle = "#222222";
- ctx.beginPath();
- ctx.moveTo(v1.x, v1.y);
- ctx.lineTo(arrowPoint.x, arrowPoint.y);
- ctx.lineTo(v2.x, v2.y);
- ctx.stroke();
-};
// defining custom node type
var nodeSettings = {
@@ -309,13 +296,14 @@ var nodeSettings = {
edgeHelper.line.render({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, canvas);
}
else if (directionCat == "both") {
- renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, true, canvas);
- renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, false, canvas);
+ renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, true, canvas, 0.7);
+ renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, false, canvas, 0.7);
}
else if (directionCat == "from-to") {
var direction = adj.data.$direction;
var inv = (direction && direction.length > 1 && direction[0] != adj.nodeFrom.id);
- renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, inv, canvas);
+ renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, inv, canvas, 0.7);
+ renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, inv, canvas, 0.3);
}
}//renderEdgeArrow
@@ -549,7 +537,6 @@ function onDragEndTopicHandler(node, eventInfo, e, allowRealtime) {
$('#topic_addSynapse').val("false");
$('#synapse_topic1id').val(tempNode.id);
$('#synapse_topic2id').val(tempNode2.id);
- $('#synapse_desc').autocomplete('enable');
$('#new_synapse').fadeIn('fast');
$('#synapse_desc').focus();
tempNode = null;
diff --git a/app/assets/javascripts/Jit/jit2.0.0.js b/app/assets/javascripts/Jit/jit2.0.0.js
index 61520b7a..6f08f42c 100644
--- a/app/assets/javascripts/Jit/jit2.0.0.js
+++ b/app/assets/javascripts/Jit/jit2.0.0.js
@@ -7040,6 +7040,19 @@ Graph.Plot = {
!animating && opt.onAfterPlotLine(adj);
}
});
+
+ //START METAMAPS CODE
+ if (MetamapsModel.synapseStartCoord) {
+ ctx.save();
+ var X = MetamapsModel.synapseStartCoord.x;
+ var Y = MetamapsModel.synapseStartCoord.y;
+ var X2 = MetamapsModel.synapseEndCoord.x;
+ var Y2 = MetamapsModel.synapseEndCoord.y;
+ renderMidArrow({ x: X, y: Y }, { x: X2, y: Y2 }, 13, false, canvas, 0.5, true);
+ ctx.restore();
+ }
+ //END METAMAPS CODE
+
ctx.save();
if(node.drawn) {
!animating && opt.onBeforePlotNode(node);
@@ -7213,8 +7226,32 @@ Graph.Label.Native = new Class({
ctx.font = node.getLabelData('style') + ' ' + node.getLabelData('size') + 'px ' + node.getLabelData('family');
ctx.textAlign = node.getLabelData('textAlign');
- ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color');
+ // ORIGINAL CODE ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color');
ctx.textBaseline = node.getLabelData('textBaseline');
+
+ //START METAMAPS CODE
+ //render background
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
+ var margin = 5;
+ var height = 16 + margin; //font size + margin
+ var CURVE = height / 2; //offset for curvy corners
+ var width = ctx.measureText(node.name).width + 2 * margin - 2 * CURVE;
+ var labelX = (pos.x - width/2) - margin + CURVE/2;
+ var labelY = pos.y + node.getData("height"); // - height + margin;
+ ctx.fillRect(labelX, labelY, width, height);
+
+ //curvy corners woo - circles in place of last CURVE pixels of rect
+ ctx.beginPath();
+ ctx.arc(labelX, labelY + CURVE, CURVE, 0.5 * Math.PI, 1.5 * Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+ ctx.beginPath();
+ ctx.arc(labelX + width, labelY + CURVE, CURVE, 1.5 * Math.PI, 0.5 * Math.PI, false);
+ ctx.closePath();
+ ctx.fill();
+
+ ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color');
+ // END METAMAPS CODE
this.renderLabel(canvas, node, controller);
},
@@ -7235,7 +7272,10 @@ Graph.Label.Native = new Class({
renderLabel: function(canvas, node, controller) {
var ctx = canvas.getCtx();
var pos = node.pos.getc(true);
- ctx.fillText(node.name, pos.x, pos.y + node.getData("height") / 2);
+ //ctx.fillText(node.name, pos.x, pos.y + node.getData("height") / 2);
+ // START METAMAPS CODE
+ ctx.fillText(node.name, pos.x, pos.y + node.getData("height"));
+ // END METAMAPS CODE
},
hideLabel: $.empty,
diff --git a/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js b/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js
index ac122288..eabc3025 100644
--- a/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js
+++ b/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js
@@ -230,7 +230,6 @@ function updateEdgeDisplay(edge, dir, dirCat) {
}
function best_in_place_perms(edge) {
- console.log(edge);
var output =
'{{value}}
{{type}}
',
+ remote: {
+ url: '/topics/autocomplete_topic?term=%QUERY'
+ },
+ engine: Hogan
+ }
+ ]);
+ $('#topic_name').bind('typeahead:selected', function (event, datum, dataset) {
+ $('#topic_grabTopic').val(datum.id);
$('.new_topic').submit();
- }
- });
+ event.preventDefault();
+ event.stopPropagation();
+ });
- $('.new_topic').bind('submit', function(event, data){
+ $('.new_topic, .new_synapse').bind('submit', function(event, data){
event.preventDefault();
- });
+ });
+
+ // this is for the search box
+ $('.sidebarSearchField').typeahead([
+ {
+ name: 'topics',
+ template: $('.topicTemplate').html(),
+ remote: {
+ url: '/search/topics?term=%QUERY'
+ },
+ engine: Hogan,
+ header: ''
+ },
+ {
+ name: 'maps',
+ template: $('.mapTemplate').html(),
+ remote: {
+ url: '/search/maps?term=%QUERY'
+ },
+ engine: Hogan,
+ header: ''
+ },
+ {
+ name: 'mappers',
+ template: $('.mapperTemplate').html(),
+ remote: {
+ url: '/search/mappers?term=%QUERY'
+ },
+ engine: Hogan,
+ header: ''
+ }
+ ]);
+
+
$(".scroll").mCustomScrollbar();
@@ -52,49 +97,131 @@ var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null,
//$('.nodemargin').css('padding-top',$('.focus').css('height'));
// controls the sliding hover of the menus at the top
- var sliding1 = false;
+ var sliding1 = false;
var lT;
- $(".logo").hover(
- function () {
- $('.menuflag').hide();
- clearTimeout(lT);
- if (! sliding1) {
- sliding1 = true;
- var listLength = $('.logo .menu li').length * 28;
- $('.footer .menu').animate({
- height: listLength + 'px'
- }, 300, function() {
- sliding1 = false;
- });
- }
- },
- function () {
- lT = setTimeout(function() {
+
+ var closeMenu = function() {
+ lT = setTimeout(function() {
if (! sliding1) {
- sliding1 = true;
- $('.footer .menu').animate({
- height: '0px'
- }, 300, function() {
- sliding1 = false;
- menuIsOpen = false;
+ sliding1 = true;
+ // $('.footer .menu').animate({
+ // height: '0px'
+ // }, 300, function() {
+ // sliding1 = false;
+ // menuIsOpen = false;
+ // });
+ $('.footer').css('border-top-right-radius','5px');
+ $('.logo').animate({
+ 'background-position-x':'-10px'
+ }, 300);
+ $('.footer .menu').fadeOut(300, function() {
+ sliding1 = false;
+ menuIsOpen = false;
});
}
},800);
- }
- );
+ }
+
+ var openMenu = function() {
+ //closeAccount();
+ //closeSearch();
+ $('.menuflag').hide();
+ clearTimeout(lT);
+ if (! sliding1) {
+ sliding1 = true;
+
+ // $('.footer .menu').animate({
+ // height: listLength + 'px'
+ // }, 300, function() {
+ // sliding1 = false;
+ // });
+ $('.footer').css('border-top-right-radius','0');
+ $('.logo').animate({
+ 'background-position-x':'-7px'
+ }, 300);
+ $('.footer .menu').fadeIn(300, function() {
+ sliding1 = false;
+ });
+ }
+ }
+ // bind the hover events
+ $(".logo").hover(openMenu, closeMenu);
- var menuIsOpen = false;
+ // when on touch screen, make touching on the logo do what hovering does on desktop
$("#mainTitle a").bind('touchend', function(evt) {
if (!menuIsOpen) {
- menuIsOpen = true;
- var listLength = $('.logo .menu li').length * 28;
- $('.footer .menu').animate({
- height: listLength + 'px'
- }, 300);
+ openMenu();
evt.preventDefault();
- evt.stopPropogation();
+ evt.stopPropagation();
}
- });
+ });
+
+
+ // start account section
+ $('.sidebarAccountIcon').click(function(e) {
+ if (!accountIsOpen) openAccount();
+ else if (accountIsOpen) closeAccount();
+ e.stopPropagation();
+ });
+ $('.sidebarAccountBox').click(function(e) {
+ e.stopPropagation();
+ });
+
+ function openAccount() {
+ //closeMenu();
+ //closeSearch();
+ if (!accountIsOpen) {
+ $('.sidebarAccountBox').fadeIn(300, function() {
+ //$('.sidebarSearchField').css({padding:'5px 10px', width:'180px'}).focus();
+ accountIsOpen = true;
+ });
+ }
+ }
+ function closeAccount() {
+ if (accountIsOpen) {
+ $('.sidebarAccountBox').fadeOut(300, function() {
+ accountIsOpen = false;
+ });
+ }
+ }
+ // end account section
+
+ // start search section
+ $('.sidebarSearchIcon').click(function(e) {
+ if (!searchIsOpen) openSearch();
+ else if (searchIsOpen) closeSearch();
+ e.stopPropagation();
+ });
+ $('.sidebarSearch .twitter-typeahead').click(function(e) {
+ e.stopPropagation();
+ });
+
+ function openSearch() {
+ hideCards();
+ $('.sidebarSearch .twitter-typeahead, .sidebarSearch .tt-hint, .sidebarSearchField').animate({
+ width: '200px'
+ }, 300, function() {
+ $('.sidebarSearchField, .sidebarSearch .tt-hint').css({padding:'5px 10px', width:'180px'});
+ $('.sidebarSearchField').focus();
+ searchIsOpen = true;
+ });
+ }
+ function closeSearch() {
+ if (searchIsOpen) {
+ $('.sidebarSearchField, .sidebarSearch .tt-hint').css({padding:'5px 0', width:'200px'});
+ $('.sidebarSearch .twitter-typeahead, .sidebarSearch .tt-hint, .sidebarSearchField').animate({
+ width: '0'
+ }, 300, function() {
+ searchIsOpen = false;
+ });
+ }
+ }
+ // end search section
+
+ $('body').click(function() {
+ closeSearch();
+ closeAccount();
+ });
addHoverForSettings();
@@ -119,6 +246,15 @@ var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null,
event.preventDefault();
saveLayoutAll();
});
+
+ // bind keyboard handlers
+ $('body').bind('keyup', function(e) {
+ switch(e.which) {
+ case 13: enterKeyHandler(); break;
+ case 27: escKeyHandler(); break;
+ default: break; //console.log(e.which);
+ }
+ });
}); // end document.ready
@@ -244,7 +380,7 @@ function addMetacode() {
yRadius:40,
xPos: 150,
yPos: 40,
- speed:0.15,
+ speed:0.3,
mouseWheel:true,
bringToFront: true
});
@@ -305,24 +441,17 @@ function MconsoleReset() {
var mX = Mconsole.canvas.scaleOffsetX;
var mY = Mconsole.canvas.scaleOffsetY;
Mconsole.canvas.scale((1/mX),(1/mY));
-
}
-function hideLabels() {
- if (Mconsole.labels.labelsHidden) {
- Mconsole.labels.hideLabels();
- $('.hidelabels').html('Hide Labels');
- }
- else if (!Mconsole.labels.labelsHidden) {
- Mconsole.labels.hideLabels(true);
- $('.hidelabels').html('Show Labels');
- }
-}
+function openNodeShowcard(node) {
+ //populate the card that's about to show with the right topics data
+ populateShowCard(node);
-$('*').keypress(function(e) {
- switch(e.which) {
- case 13: enterKeyHandler(); break;
- case 27: escKeyHandler(); break;
- default: //alert(e.which); break;
- }
-});
+ // positions the card in the right place
+ $('#showcard').css('top', '250px');
+ $('#showcard').css('left', '100px');
+
+ $('.showcard.topic_' + node.id).fadeIn('fast');
+ //node.setData('dim', 1, 'current');
+ MetamapsModel.showcardInUse = node.id;
+}
diff --git a/app/assets/javascripts/autocomplete-rails-uncompressed.js b/app/assets/javascripts/autocomplete-rails-uncompressed.js
deleted file mode 100644
index 37b61fea..00000000
--- a/app/assets/javascripts/autocomplete-rails-uncompressed.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
-* Unobtrusive autocomplete
-*
-* To use it, you just have to include the HTML attribute autocomplete
-* with the autocomplete URL as the value
-*
-* Example:
-*
-*
-* Optionally, you can use a jQuery selector to specify a field that can
-* be updated with the element id whenever you find a matching value
-*
-* Example:
-*
-*/
-
-(function(jQuery)
-{
- var self = null;
- jQuery.fn.railsAutocomplete = function() {
- return this.live('focus',function() {
- if (!this.railsAutoCompleter) {
- this.railsAutoCompleter = new jQuery.railsAutocomplete(this);
- }
- });
- };
-
- jQuery.railsAutocomplete = function (e) {
- _e = e;
- this.init(_e);
- };
-
- jQuery.railsAutocomplete.fn = jQuery.railsAutocomplete.prototype = {
- railsAutocomplete: '0.0.1'
- };
-
- jQuery.railsAutocomplete.fn.extend = jQuery.railsAutocomplete.extend = jQuery.extend;
- jQuery.railsAutocomplete.fn.extend({
- init: function(e) {
- e.delimiter = jQuery(e).attr('data-delimiter') || null;
- function split( val ) {
- return val.split( e.delimiter );
- }
- function extractLast( term ) {
- return split( term ).pop().replace(/^\s+/,"");
- }
-
- jQuery(e).autocomplete({
- source: function( request, response ) {
- jQuery.getJSON( jQuery(e).attr('data-autocomplete'), {
- term: extractLast( request.term )
- }, function() {
- if(arguments[0].length == 0) {
- arguments[0] = []
- //arguments[0][0] = { id: "", label: "no existing match" }
- }
- jQuery(arguments[0]).each(function(i, el) {
- var obj = {};
- obj[el.id] = el;
- jQuery(e).data(obj);
- });
- response.apply(null, arguments);
- });
- },
- change: function( event, ui ) {
- if(jQuery(jQuery(this).attr('data-id-element')).val() == "") {
- return;
- }
- jQuery(jQuery(this).attr('data-id-element')).val(ui.item ? ui.item.id : "");
- var update_elements = jQuery.parseJSON(jQuery(this).attr("data-update-elements"));
- var data = ui.item ? jQuery(this).data(ui.item.id.toString()) : {};
- if(update_elements && jQuery(update_elements['id']).val() == "") {
- return;
- }
- for (var key in update_elements) {
- jQuery(update_elements[key]).val(ui.item ? data[key] : "");
- }
- },
- search: function() {
- // custom minLength
- var term = extractLast( this.value );
- if ( term.length < 2 ) {
- return false;
- }
- },
- focus: function() {
- // prevent value inserted on focus
- return false;
- },
- select: function( event, ui ) {
- var terms = split( this.value );
- // remove the current input
- terms.pop();
- // add the selected item
- terms.push( ui.item.value );
- // add placeholder to get the comma-and-space at the end
- if (e.delimiter != null) {
- terms.push( "" );
- this.value = terms.join( e.delimiter );
- } else {
- this.value = terms.join("");
- if (jQuery(this).attr('data-id-element')) {
- jQuery(jQuery(this).attr('data-id-element')).val(ui.item.id);
- }
- if (jQuery(this).attr('data-update-elements')) {
- var data = jQuery(this).data(ui.item.id.toString());
- var update_elements = jQuery.parseJSON(jQuery(this).attr("data-update-elements"));
- for (var key in update_elements) {
- jQuery(update_elements[key]).val(data[key]);
- }
- }
- }
- var remember_string = this.value;
- jQuery(this).bind('keyup.clearId', function(){
- if(jQuery(this).val().trim() != remember_string.trim()){
- jQuery(jQuery(this).attr('data-id-element')).val("");
- jQuery(this).unbind('keyup.clearId');
- }
- });
- jQuery(e).trigger('railsAutocomplete.select', ui);
- return false;
- }
- });
- }
- });
-
- jQuery(document).ready(function(){
- jQuery('input[data-autocomplete]').railsAutocomplete();
- });
-})(jQuery);
diff --git a/app/assets/javascripts/carousel/cloud-carousel.1.0.5.js b/app/assets/javascripts/carousel/cloud-carousel.1.0.5.js
index 2bae6528..7820a5f5 100644
--- a/app/assets/javascripts/carousel/cloud-carousel.1.0.5.js
+++ b/app/assets/javascripts/carousel/cloud-carousel.1.0.5.js
@@ -7,6 +7,40 @@
//
// Please retain this copyright header in all versions of the software
//////////////////////////////////////////////////////////////////////////////////
+var matched, browser;
+
+jQuery.uaMatch = function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
+ /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
+ /(msie) ([\w.]+)/.exec( ua ) ||
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
+ [];
+
+ return {
+ browser: match[ 1 ] || "",
+ version: match[ 2 ] || "0"
+ };
+};
+
+matched = jQuery.uaMatch( navigator.userAgent );
+browser = {};
+
+if ( matched.browser ) {
+ browser[ matched.browser ] = true;
+ browser.version = matched.version;
+}
+
+// Chrome is Webkit, but Webkit is also Safari.
+if ( browser.chrome ) {
+ browser.webkit = true;
+} else if ( browser.webkit ) {
+ browser.safari = true;
+}
+
+jQuery.browser = browser;
(function($) {
@@ -206,6 +240,8 @@
if ( items[this.frontIndex] === undefined ) { return; } // Images might not have loaded yet.
// METAMAPS CODE
$('#topic_metacode').val($(items[this.frontIndex].image).attr('title'));
+ $('img.cloudcarousel').css({"background":"none", "width":"","height":""});
+ $(items[this.frontIndex].image).css({"width":"45px","height":"45px"});
// NOT METAMAPS CODE
$(options.titleBox).html( $(items[this.frontIndex].image).attr('title'));
$(options.altBox).html( $(items[this.frontIndex].image).attr('alt'));
@@ -285,11 +321,11 @@
if (item.imageOK)
{
var img = item.image;
- w = img.width = item.orgWidth * scale;
+ img.style.zIndex = "" + (scale * 100)>>0; // >>0 = Math.foor(). Firefox doesn't like fractional decimals in z-index.
+ w = img.width = item.orgWidth * scale;
h = img.height = item.orgHeight * scale;
img.style.left = x + px ;
img.style.top = y + px;
- img.style.zIndex = "" + (scale * 100)>>0; // >>0 = Math.foor(). Firefox doesn't like fractional decimals in z-index.
if (item.reflection !== null)
{
reflHeight = options.reflHeight * scale;
diff --git a/app/assets/javascripts/hogan-2.0.0.js b/app/assets/javascripts/hogan-2.0.0.js
new file mode 100644
index 00000000..43a67074
--- /dev/null
+++ b/app/assets/javascripts/hogan-2.0.0.js
@@ -0,0 +1,576 @@
+/*
+ * Copyright 2011 Twitter, Inc.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+var Hogan = {};
+
+(function (Hogan, useArrayBuffer) {
+ Hogan.Template = function (renderFunc, text, compiler, options) {
+ this.r = renderFunc || this.r;
+ this.c = compiler;
+ this.options = options;
+ this.text = text || '';
+ this.buf = (useArrayBuffer) ? [] : '';
+ }
+
+ Hogan.Template.prototype = {
+ // render: replaced by generated code.
+ r: function (context, partials, indent) { return ''; },
+
+ // variable escaping
+ v: hoganEscape,
+
+ // triple stache
+ t: coerceToString,
+
+ render: function render(context, partials, indent) {
+ return this.ri([context], partials || {}, indent);
+ },
+
+ // render internal -- a hook for overrides that catches partials too
+ ri: function (context, partials, indent) {
+ return this.r(context, partials, indent);
+ },
+
+ // tries to find a partial in the curent scope and render it
+ rp: function(name, context, partials, indent) {
+ var partial = partials[name];
+
+ if (!partial) {
+ return '';
+ }
+
+ if (this.c && typeof partial == 'string') {
+ partial = this.c.compile(partial, this.options);
+ }
+
+ return partial.ri(context, partials, indent);
+ },
+
+ // render a section
+ rs: function(context, partials, section) {
+ var tail = context[context.length - 1];
+
+ if (!isArray(tail)) {
+ section(context, partials, this);
+ return;
+ }
+
+ for (var i = 0; i < tail.length; i++) {
+ context.push(tail[i]);
+ section(context, partials, this);
+ context.pop();
+ }
+ },
+
+ // maybe start a section
+ s: function(val, ctx, partials, inverted, start, end, tags) {
+ var pass;
+
+ if (isArray(val) && val.length === 0) {
+ return false;
+ }
+
+ if (typeof val == 'function') {
+ val = this.ls(val, ctx, partials, inverted, start, end, tags);
+ }
+
+ pass = (val === '') || !!val;
+
+ if (!inverted && pass && ctx) {
+ ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);
+ }
+
+ return pass;
+ },
+
+ // find values with dotted names
+ d: function(key, ctx, partials, returnFound) {
+ var names = key.split('.'),
+ val = this.f(names[0], ctx, partials, returnFound),
+ cx = null;
+
+ if (key === '.' && isArray(ctx[ctx.length - 2])) {
+ return ctx[ctx.length - 1];
+ }
+
+ for (var i = 1; i < names.length; i++) {
+ if (val && typeof val == 'object' && names[i] in val) {
+ cx = val;
+ val = val[names[i]];
+ } else {
+ val = '';
+ }
+ }
+
+ if (returnFound && !val) {
+ return false;
+ }
+
+ if (!returnFound && typeof val == 'function') {
+ ctx.push(cx);
+ val = this.lv(val, ctx, partials);
+ ctx.pop();
+ }
+
+ return val;
+ },
+
+ // find values with normal names
+ f: function(key, ctx, partials, returnFound) {
+ var val = false,
+ v = null,
+ found = false;
+
+ for (var i = ctx.length - 1; i >= 0; i--) {
+ v = ctx[i];
+ if (v && typeof v == 'object' && key in v) {
+ val = v[key];
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ return (returnFound) ? false : "";
+ }
+
+ if (!returnFound && typeof val == 'function') {
+ val = this.lv(val, ctx, partials);
+ }
+
+ return val;
+ },
+
+ // higher order templates
+ ho: function(val, cx, partials, text, tags) {
+ var compiler = this.c;
+ var options = this.options;
+ options.delimiters = tags;
+ var text = val.call(cx, text);
+ text = (text == null) ? String(text) : text.toString();
+ this.b(compiler.compile(text, options).render(cx, partials));
+ return false;
+ },
+
+ // template result buffering
+ b: (useArrayBuffer) ? function(s) { this.buf.push(s); } :
+ function(s) { this.buf += s; },
+ fl: (useArrayBuffer) ? function() { var r = this.buf.join(''); this.buf = []; return r; } :
+ function() { var r = this.buf; this.buf = ''; return r; },
+
+ // lambda replace section
+ ls: function(val, ctx, partials, inverted, start, end, tags) {
+ var cx = ctx[ctx.length - 1],
+ t = null;
+
+ if (!inverted && this.c && val.length > 0) {
+ return this.ho(val, cx, partials, this.text.substring(start, end), tags);
+ }
+
+ t = val.call(cx);
+
+ if (typeof t == 'function') {
+ if (inverted) {
+ return true;
+ } else if (this.c) {
+ return this.ho(t, cx, partials, this.text.substring(start, end), tags);
+ }
+ }
+
+ return t;
+ },
+
+ // lambda replace variable
+ lv: function(val, ctx, partials) {
+ var cx = ctx[ctx.length - 1];
+ var result = val.call(cx);
+
+ if (typeof result == 'function') {
+ result = coerceToString(result.call(cx));
+ if (this.c && ~result.indexOf("{\u007B")) {
+ return this.c.compile(result, this.options).render(cx, partials);
+ }
+ }
+
+ return coerceToString(result);
+ }
+
+ };
+
+ var rAmp = /&/g,
+ rLt = //g,
+ rApos =/\'/g,
+ rQuot = /\"/g,
+ hChars =/[&<>\"\']/;
+
+
+ function coerceToString(val) {
+ return String((val === null || val === undefined) ? '' : val);
+ }
+
+ function hoganEscape(str) {
+ str = coerceToString(str);
+ return hChars.test(str) ?
+ str
+ .replace(rAmp,'&')
+ .replace(rLt,'<')
+ .replace(rGt,'>')
+ .replace(rApos,''')
+ .replace(rQuot, '"') :
+ str;
+ }
+
+ var isArray = Array.isArray || function(a) {
+ return Object.prototype.toString.call(a) === '[object Array]';
+ };
+
+})(typeof exports !== 'undefined' ? exports : Hogan);
+
+
+
+
+(function (Hogan) {
+ // Setup regex assignments
+ // remove whitespace according to Mustache spec
+ var rIsWhitespace = /\S/,
+ rQuot = /\"/g,
+ rNewline = /\n/g,
+ rCr = /\r/g,
+ rSlash = /\\/g,
+ tagTypes = {
+ '#': 1, '^': 2, '/': 3, '!': 4, '>': 5,
+ '<': 6, '=': 7, '_v': 8, '{': 9, '&': 10
+ };
+
+ Hogan.scan = function scan(text, delimiters) {
+ var len = text.length,
+ IN_TEXT = 0,
+ IN_TAG_TYPE = 1,
+ IN_TAG = 2,
+ state = IN_TEXT,
+ tagType = null,
+ tag = null,
+ buf = '',
+ tokens = [],
+ seenTag = false,
+ i = 0,
+ lineStart = 0,
+ otag = '{{',
+ ctag = '}}';
+
+ function addBuf() {
+ if (buf.length > 0) {
+ tokens.push(new String(buf));
+ buf = '';
+ }
+ }
+
+ function lineIsWhitespace() {
+ var isAllWhitespace = true;
+ for (var j = lineStart; j < tokens.length; j++) {
+ isAllWhitespace =
+ (tokens[j].tag && tagTypes[tokens[j].tag] < tagTypes['_v']) ||
+ (!tokens[j].tag && tokens[j].match(rIsWhitespace) === null);
+ if (!isAllWhitespace) {
+ return false;
+ }
+ }
+
+ return isAllWhitespace;
+ }
+
+ function filterLine(haveSeenTag, noNewLine) {
+ addBuf();
+
+ if (haveSeenTag && lineIsWhitespace()) {
+ for (var j = lineStart, next; j < tokens.length; j++) {
+ if (!tokens[j].tag) {
+ if ((next = tokens[j+1]) && next.tag == '>') {
+ // set indent to token value
+ next.indent = tokens[j].toString()
+ }
+ tokens.splice(j, 1);
+ }
+ }
+ } else if (!noNewLine) {
+ tokens.push({tag:'\n'});
+ }
+
+ seenTag = false;
+ lineStart = tokens.length;
+ }
+
+ function changeDelimiters(text, index) {
+ var close = '=' + ctag,
+ closeIndex = text.indexOf(close, index),
+ delimiters = trim(
+ text.substring(text.indexOf('=', index) + 1, closeIndex)
+ ).split(' ');
+
+ otag = delimiters[0];
+ ctag = delimiters[1];
+
+ return closeIndex + close.length - 1;
+ }
+
+ if (delimiters) {
+ delimiters = delimiters.split(' ');
+ otag = delimiters[0];
+ ctag = delimiters[1];
+ }
+
+ for (i = 0; i < len; i++) {
+ if (state == IN_TEXT) {
+ if (tagChange(otag, text, i)) {
+ --i;
+ addBuf();
+ state = IN_TAG_TYPE;
+ } else {
+ if (text.charAt(i) == '\n') {
+ filterLine(seenTag);
+ } else {
+ buf += text.charAt(i);
+ }
+ }
+ } else if (state == IN_TAG_TYPE) {
+ i += otag.length - 1;
+ tag = tagTypes[text.charAt(i + 1)];
+ tagType = tag ? text.charAt(i + 1) : '_v';
+ if (tagType == '=') {
+ i = changeDelimiters(text, i);
+ state = IN_TEXT;
+ } else {
+ if (tag) {
+ i++;
+ }
+ state = IN_TAG;
+ }
+ seenTag = i;
+ } else {
+ if (tagChange(ctag, text, i)) {
+ tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag,
+ i: (tagType == '/') ? seenTag - ctag.length : i + otag.length});
+ buf = '';
+ i += ctag.length - 1;
+ state = IN_TEXT;
+ if (tagType == '{') {
+ if (ctag == '}}') {
+ i++;
+ } else {
+ cleanTripleStache(tokens[tokens.length - 1]);
+ }
+ }
+ } else {
+ buf += text.charAt(i);
+ }
+ }
+ }
+
+ filterLine(seenTag, true);
+
+ return tokens;
+ }
+
+ function cleanTripleStache(token) {
+ if (token.n.substr(token.n.length - 1) === '}') {
+ token.n = token.n.substring(0, token.n.length - 1);
+ }
+ }
+
+ function trim(s) {
+ if (s.trim) {
+ return s.trim();
+ }
+
+ return s.replace(/^\s*|\s*$/g, '');
+ }
+
+ function tagChange(tag, text, index) {
+ if (text.charAt(index) != tag.charAt(0)) {
+ return false;
+ }
+
+ for (var i = 1, l = tag.length; i < l; i++) {
+ if (text.charAt(index + i) != tag.charAt(i)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ function buildTree(tokens, kind, stack, customTags) {
+ var instructions = [],
+ opener = null,
+ token = null;
+
+ while (tokens.length > 0) {
+ token = tokens.shift();
+ if (token.tag == '#' || token.tag == '^' || isOpener(token, customTags)) {
+ stack.push(token);
+ token.nodes = buildTree(tokens, token.tag, stack, customTags);
+ instructions.push(token);
+ } else if (token.tag == '/') {
+ if (stack.length === 0) {
+ throw new Error('Closing tag without opener: /' + token.n);
+ }
+ opener = stack.pop();
+ if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) {
+ throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n);
+ }
+ opener.end = token.i;
+ return instructions;
+ } else {
+ instructions.push(token);
+ }
+ }
+
+ if (stack.length > 0) {
+ throw new Error('missing closing tag: ' + stack.pop().n);
+ }
+
+ return instructions;
+ }
+
+ function isOpener(token, tags) {
+ for (var i = 0, l = tags.length; i < l; i++) {
+ if (tags[i].o == token.n) {
+ token.tag = '#';
+ return true;
+ }
+ }
+ }
+
+ function isCloser(close, open, tags) {
+ for (var i = 0, l = tags.length; i < l; i++) {
+ if (tags[i].c == close && tags[i].o == open) {
+ return true;
+ }
+ }
+ }
+
+ Hogan.generate = function (tree, text, options) {
+ var code = 'var _=this;_.b(i=i||"");' + walk(tree) + 'return _.fl();';
+ if (options.asString) {
+ return 'function(c,p,i){' + code + ';}';
+ }
+
+ return new Hogan.Template(new Function('c', 'p', 'i', code), text, Hogan, options);
+ }
+
+ function esc(s) {
+ return s.replace(rSlash, '\\\\')
+ .replace(rQuot, '\\\"')
+ .replace(rNewline, '\\n')
+ .replace(rCr, '\\r');
+ }
+
+ function chooseMethod(s) {
+ return (~s.indexOf('.')) ? 'd' : 'f';
+ }
+
+ function walk(tree) {
+ var code = '';
+ for (var i = 0, l = tree.length; i < l; i++) {
+ var tag = tree[i].tag;
+ if (tag == '#') {
+ code += section(tree[i].nodes, tree[i].n, chooseMethod(tree[i].n),
+ tree[i].i, tree[i].end, tree[i].otag + " " + tree[i].ctag);
+ } else if (tag == '^') {
+ code += invertedSection(tree[i].nodes, tree[i].n,
+ chooseMethod(tree[i].n));
+ } else if (tag == '<' || tag == '>') {
+ code += partial(tree[i]);
+ } else if (tag == '{' || tag == '&') {
+ code += tripleStache(tree[i].n, chooseMethod(tree[i].n));
+ } else if (tag == '\n') {
+ code += text('"\\n"' + (tree.length-1 == i ? '' : ' + i'));
+ } else if (tag == '_v') {
+ code += variable(tree[i].n, chooseMethod(tree[i].n));
+ } else if (tag === undefined) {
+ code += text('"' + esc(tree[i]) + '"');
+ }
+ }
+ return code;
+ }
+
+ function section(nodes, id, method, start, end, tags) {
+ return 'if(_.s(_.' + method + '("' + esc(id) + '",c,p,1),' +
+ 'c,p,0,' + start + ',' + end + ',"' + tags + '")){' +
+ '_.rs(c,p,' +
+ 'function(c,p,_){' +
+ walk(nodes) +
+ '});c.pop();}';
+ }
+
+ function invertedSection(nodes, id, method) {
+ return 'if(!_.s(_.' + method + '("' + esc(id) + '",c,p,1),c,p,1,0,0,"")){' +
+ walk(nodes) +
+ '};';
+ }
+
+ function partial(tok) {
+ return '_.b(_.rp("' + esc(tok.n) + '",c,p,"' + (tok.indent || '') + '"));';
+ }
+
+ function tripleStache(id, method) {
+ return '_.b(_.t(_.' + method + '("' + esc(id) + '",c,p,0)));';
+ }
+
+ function variable(id, method) {
+ return '_.b(_.v(_.' + method + '("' + esc(id) + '",c,p,0)));';
+ }
+
+ function text(id) {
+ return '_.b(' + id + ');';
+ }
+
+ Hogan.parse = function(tokens, text, options) {
+ options = options || {};
+ return buildTree(tokens, '', [], options.sectionTags || []);
+ },
+
+ Hogan.cache = {};
+
+ Hogan.compile = function(text, options) {
+ // options
+ //
+ // asString: false (default)
+ //
+ // sectionTags: [{o: '_foo', c: 'foo'}]
+ // An array of object with o and c fields that indicate names for custom
+ // section tags. The example above allows parsing of {{_foo}}{{/foo}}.
+ //
+ // delimiters: A string that overrides the default delimiters.
+ // Example: "<% %>"
+ //
+ options = options || {};
+
+ var key = text + '||' + !!options.asString;
+
+ var t = this.cache[key];
+
+ if (t) {
+ return t;
+ }
+
+ t = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options);
+ return this.cache[key] = t;
+ };
+})(typeof exports !== 'undefined' ? exports : Hogan);
+
diff --git a/app/assets/javascripts/realtime.js.coffee b/app/assets/javascripts/realtime.js.coffee
index 53238fab..9efcd6b1 100644
--- a/app/assets/javascripts/realtime.js.coffee
+++ b/app/assets/javascripts/realtime.js.coffee
@@ -1,6 +1,6 @@
window.app.realtime =
connect : () ->
- window.app.socket = io.connect('http://metamaps.cc:5001');
- window.app.socket.on 'connect', () ->
- subscribeToRooms()
- console.log('socket connected')
\ No newline at end of file
+ #window.app.socket = io.connect('http://localhost:5001');
+ #window.app.socket.on 'connect', () ->
+ #subscribeToRooms()
+ #console.log('socket connected')
\ No newline at end of file
diff --git a/app/assets/javascripts/typeahead.min.js b/app/assets/javascripts/typeahead.min.js
new file mode 100644
index 00000000..c085f8a8
--- /dev/null
+++ b/app/assets/javascripts/typeahead.min.js
@@ -0,0 +1,7 @@
+/*!
+ * typeahead.js 0.9.3
+ * https://github.com/twitter/typeahead
+ * Copyright 2013 Twitter, Inc. and other contributors; Licensed MIT
+ */
+
+!function(a){var b="0.9.3",c={isMsie:function(){var a=/(msie) ([\w.]+)/i.exec(navigator.userAgent);return a?parseInt(a[2],10):!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},bind:a.proxy,bindAll:function(b){var c;for(var d in b)a.isFunction(c=b[d])&&(b[d]=a.proxy(c,b))},indexOf:function(a,b){for(var c=0;c=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},tokenizeQuery:function(b){return a.trim(b).toLowerCase().split(/[\s]+/)},tokenizeText:function(b){return a.trim(b).toLowerCase().split(/[\s\-_]+/)},getProtocol:function(){return location.protocol},noop:function(){}},d=function(){var a=/\s+/;return{on:function(b,c){var d;if(!c)return this;for(this._callbacks=this._callbacks||{},b=b.split(a);d=b.shift();)this._callbacks[d]=this._callbacks[d]||[],this._callbacks[d].push(c);return this},trigger:function(b,c){var d,e;if(!this._callbacks)return this;for(b=b.split(a);d=b.shift();)if(e=this._callbacks[d])for(var f=0;fa;a++)(b=f.key(a)).match(this.keyMatcher)&&c.push(b.replace(this.keyMatcher,""));for(a=c.length;a--;)this.remove(c[a]);return this},isExpired:function(a){var d=e(f.getItem(this._ttlKey(a)));return c.isNumber(d)&&b()>d?!0:!1}}:{get:c.noop,set:c.noop,remove:c.noop,clear:c.noop,isExpired:c.noop},c.mixin(a.prototype,g),a}(),g=function(){function a(a){c.bindAll(this),a=a||{},this.sizeLimit=a.sizeLimit||10,this.cache={},this.cachedKeysByAge=[]}return c.mixin(a.prototype,{get:function(a){return this.cache[a]},set:function(a,b){var c;this.cachedKeysByAge.length===this.sizeLimit&&(c=this.cachedKeysByAge.shift(),delete this.cache[c]),this.cache[a]=b,this.cachedKeysByAge.push(a)}}),a}(),h=function(){function b(a){c.bindAll(this),a=c.isString(a)?{url:a}:a,i=i||new g,h=c.isNumber(a.maxParallelRequests)?a.maxParallelRequests:h||6,this.url=a.url,this.wildcard=a.wildcard||"%QUERY",this.filter=a.filter,this.replace=a.replace,this.ajaxSettings={type:"get",cache:a.cache,timeout:a.timeout,dataType:a.dataType||"json",beforeSend:a.beforeSend},this._get=(/^throttle$/i.test(a.rateLimitFn)?c.throttle:c.debounce)(this._get,a.rateLimitWait||300)}function d(){j++}function e(){j--}function f(){return h>j}var h,i,j=0,k={};return c.mixin(b.prototype,{_get:function(a,b){function c(c){var e=d.filter?d.filter(c):c;b&&b(e),i.set(a,c)}var d=this;f()?this._sendRequest(a).done(c):this.onDeckRequestArgs=[].slice.call(arguments,0)},_sendRequest:function(b){function c(){e(),k[b]=null,f.onDeckRequestArgs&&(f._get.apply(f,f.onDeckRequestArgs),f.onDeckRequestArgs=null)}var f=this,g=k[b];return g||(d(),g=k[b]=a.ajax(b,this.ajaxSettings).always(c)),g},get:function(a,b){var d,e,f=this,g=encodeURIComponent(a||"");return b=b||c.noop,d=this.replace?this.replace(this.url,g):this.url.replace(this.wildcard,g),(e=i.get(d))?c.defer(function(){b(f.filter?f.filter(e):e)}):this._get(d,b),!!e}}),b}(),i=function(){function d(b){c.bindAll(this),c.isString(b.template)&&!b.engine&&a.error("no template engine specified"),b.local||b.prefetch||b.remote||a.error("one of local, prefetch, or remote is required"),this.name=b.name||c.getUniqueId(),this.limit=b.limit||5,this.minLength=b.minLength||1,this.header=b.header,this.footer=b.footer,this.valueKey=b.valueKey||"value",this.template=e(b.template,b.engine,this.valueKey),this.local=b.local,this.prefetch=b.prefetch,this.remote=b.remote,this.itemHash={},this.adjacencyList={},this.storage=b.name?new f(b.name):null}function e(a,b,d){var e,f;return c.isFunction(a)?e=a:c.isString(a)?(f=b.compile(a),e=c.bind(f.render,f)):e=function(a){return""+a[d]+"
"},e}var g={thumbprint:"thumbprint",protocol:"protocol",itemHash:"itemHash",adjacencyList:"adjacencyList"};return c.mixin(d.prototype,{_processLocalData:function(a){this._mergeProcessedData(this._processData(a))},_loadPrefetchData:function(d){function e(a){var b=d.filter?d.filter(a):a,e=m._processData(b),f=e.itemHash,h=e.adjacencyList;m.storage&&(m.storage.set(g.itemHash,f,d.ttl),m.storage.set(g.adjacencyList,h,d.ttl),m.storage.set(g.thumbprint,n,d.ttl),m.storage.set(g.protocol,c.getProtocol(),d.ttl)),m._mergeProcessedData(e)}var f,h,i,j,k,l,m=this,n=b+(d.thumbprint||"");return this.storage&&(f=this.storage.get(g.thumbprint),h=this.storage.get(g.protocol),i=this.storage.get(g.itemHash),j=this.storage.get(g.adjacencyList)),k=f!==n||h!==c.getProtocol(),d=c.isString(d)?{url:d}:d,d.ttl=c.isNumber(d.ttl)?d.ttl:864e5,i&&j&&!k?(this._mergeProcessedData({itemHash:i,adjacencyList:j}),l=a.Deferred().resolve()):l=a.getJSON(d.url).done(e),l},_transformDatum:function(a){var b=c.isString(a)?a:a[this.valueKey],d=a.tokens||c.tokenizeText(b),e={value:b,tokens:d};return c.isString(a)?(e.datum={},e.datum[this.valueKey]=a):e.datum=a,e.tokens=c.filter(e.tokens,function(a){return!c.isBlankString(a)}),e.tokens=c.map(e.tokens,function(a){return a.toLowerCase()}),e},_processData:function(a){var b=this,d={},e={};return c.each(a,function(a,f){var g=b._transformDatum(f),h=c.getUniqueId(g.value);d[h]=g,c.each(g.tokens,function(a,b){var d=b.charAt(0),f=e[d]||(e[d]=[h]);!~c.indexOf(f,h)&&f.push(h)})}),{itemHash:d,adjacencyList:e}},_mergeProcessedData:function(a){var b=this;c.mixin(this.itemHash,a.itemHash),c.each(a.adjacencyList,function(a,c){var d=b.adjacencyList[a];b.adjacencyList[a]=d?d.concat(c):c})},_getLocalSuggestions:function(a){var b,d=this,e=[],f=[],g=[];return c.each(a,function(a,b){var d=b.charAt(0);!~c.indexOf(e,d)&&e.push(d)}),c.each(e,function(a,c){var e=d.adjacencyList[c];return e?(f.push(e),(!b||e.length").css({position:"absolute",left:"-9999px",visibility:"hidden",whiteSpace:"nowrap",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function f(a,b){return a=(a||"").replace(/^\s*/g,"").replace(/\s{2,}/g," "),b=(b||"").replace(/^\s*/g,"").replace(/\s{2,}/g," "),a===b}return c.mixin(b.prototype,d,{_handleFocus:function(){this.trigger("focused")},_handleBlur:function(){this.trigger("blured")},_handleSpecialKeyEvent:function(a){var b=this.specialKeyCodeMap[a.which||a.keyCode];b&&this.trigger(b+"Keyed",a)},_compareQueryToInputValue:function(){var a=this.getInputValue(),b=f(this.query,a),c=b?this.query.length!==a.length:!1;c?this.trigger("whitespaceChanged",{value:this.query}):b||this.trigger("queryChanged",{value:this.query=a})},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$hint=this.$input=this.$overflowHelper=null},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(a){this.query=a},getInputValue:function(){return this.$input.val()},setInputValue:function(a,b){this.$input.val(a),!b&&this._compareQueryToInputValue()},getHintValue:function(){return this.$hint.val()},setHintValue:function(a){this.$hint.val(a)},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},isOverflow:function(){return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>this.$input.width()},isCursorAtEnd:function(){var a,b=this.$input.val().length,d=this.$input[0].selectionStart;return c.isNumber(d)?d===b:document.selection?(a=document.selection.createRange(),a.moveStart("character",-b),b===a.text.length):!0}}),b}(),k=function(){function b(b){c.bindAll(this),this.isOpen=!1,this.isEmpty=!0,this.isMouseOverDropdown=!1,this.$menu=a(b.menu).on("mouseenter.tt",this._handleMouseenter).on("mouseleave.tt",this._handleMouseleave).on("click.tt",".tt-suggestion",this._handleSelection).on("mouseover.tt",".tt-suggestion",this._handleMouseover)}function e(a){return a.data("suggestion")}var f={suggestionsList:''},g={suggestionsList:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"}};return c.mixin(b.prototype,d,{_handleMouseenter:function(){this.isMouseOverDropdown=!0},_handleMouseleave:function(){this.isMouseOverDropdown=!1},_handleMouseover:function(b){var c=a(b.currentTarget);this._getSuggestions().removeClass("tt-is-under-cursor"),c.addClass("tt-is-under-cursor")},_handleSelection:function(b){var c=a(b.currentTarget);this.trigger("suggestionSelected",e(c))},_show:function(){this.$menu.css("display","block")},_hide:function(){this.$menu.hide()},_moveCursor:function(a){var b,c,d,f;if(this.isVisible()){if(b=this._getSuggestions(),c=b.filter(".tt-is-under-cursor"),c.removeClass("tt-is-under-cursor"),d=b.index(c)+a,d=(d+1)%(b.length+1)-1,-1===d)return this.trigger("cursorRemoved"),void 0;-1>d&&(d=b.length-1),f=b.eq(d).addClass("tt-is-under-cursor"),this._ensureVisibility(f),this.trigger("cursorMoved",e(f))}},_getSuggestions:function(){return this.$menu.find(".tt-suggestions > .tt-suggestion")},_ensureVisibility:function(a){var b=this.$menu.height()+parseInt(this.$menu.css("paddingTop"),10)+parseInt(this.$menu.css("paddingBottom"),10),c=this.$menu.scrollTop(),d=a.position().top,e=d+a.outerHeight(!0);0>d?this.$menu.scrollTop(c+d):e>b&&this.$menu.scrollTop(c+(e-b))},destroy:function(){this.$menu.off(".tt"),this.$menu=null},isVisible:function(){return this.isOpen&&!this.isEmpty},closeUnlessMouseIsOverDropdown:function(){this.isMouseOverDropdown||this.close()},close:function(){this.isOpen&&(this.isOpen=!1,this.isMouseOverDropdown=!1,this._hide(),this.$menu.find(".tt-suggestions > .tt-suggestion").removeClass("tt-is-under-cursor"),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,!this.isEmpty&&this._show(),this.trigger("opened"))},setLanguageDirection:function(a){var b={left:"0",right:"auto"},c={left:"auto",right:" 0"};"ltr"===a?this.$menu.css(b):this.$menu.css(c)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getSuggestionUnderCursor:function(){var a=this._getSuggestions().filter(".tt-is-under-cursor").first();return a.length>0?e(a):null},getFirstSuggestion:function(){var a=this._getSuggestions().first();return a.length>0?e(a):null},renderSuggestions:function(b,d){var e,h,i,j,k,l="tt-dataset-"+b.name,m='%body
',n=this.$menu.find("."+l);0===n.length&&(h=a(f.suggestionsList).css(g.suggestionsList),n=a("").addClass(l).append(b.header).append(h).append(b.footer).appendTo(this.$menu)),d.length>0?(this.isEmpty=!1,this.isOpen&&this._show(),i=document.createElement("div"),j=document.createDocumentFragment(),c.each(d,function(c,d){d.dataset=b.name,e=b.template(d.datum),i.innerHTML=m.replace("%body",e),k=a(i.firstChild).css(g.suggestion).data("suggestion",d),k.children().each(function(){a(this).css(g.suggestionChild)}),j.appendChild(k[0])}),n.show().find(".tt-suggestions").html(j)):this.clearSuggestions(b.name),this.trigger("suggestionsRendered")},clearSuggestions:function(a){var b=a?this.$menu.find(".tt-dataset-"+a):this.$menu.find('[class^="tt-dataset-"]'),c=b.find(".tt-suggestions");b.hide(),c.empty(),0===this._getSuggestions().length&&(this.isEmpty=!0,this._hide())}}),b}(),l=function(){function b(a){var b,d,f;c.bindAll(this),this.$node=e(a.input),this.datasets=a.datasets,this.dir=null,this.eventBus=a.eventBus,b=this.$node.find(".tt-dropdown-menu"),d=this.$node.find(".tt-query"),f=this.$node.find(".tt-hint"),this.dropdownView=new k({menu:b}).on("suggestionSelected",this._handleSelection).on("cursorMoved",this._clearHint).on("cursorMoved",this._setInputValueToSuggestionUnderCursor).on("cursorRemoved",this._setInputValueToQuery).on("cursorRemoved",this._updateHint).on("suggestionsRendered",this._updateHint).on("opened",this._updateHint).on("closed",this._clearHint).on("opened closed",this._propagateEvent),this.inputView=new j({input:d,hint:f}).on("focused",this._openDropdown).on("blured",this._closeDropdown).on("blured",this._setInputValueToQuery).on("enterKeyed tabKeyed",this._handleSelection).on("queryChanged",this._clearHint).on("queryChanged",this._clearSuggestions).on("queryChanged",this._getSuggestions).on("whitespaceChanged",this._updateHint).on("queryChanged whitespaceChanged",this._openDropdown).on("queryChanged whitespaceChanged",this._setLanguageDirection).on("escKeyed",this._closeDropdown).on("escKeyed",this._setInputValueToQuery).on("tabKeyed upKeyed downKeyed",this._managePreventDefault).on("upKeyed downKeyed",this._moveDropdownCursor).on("upKeyed downKeyed",this._openDropdown).on("tabKeyed leftKeyed rightKeyed",this._autocomplete)}function e(b){var c=a(g.wrapper),d=a(g.dropdown),e=a(b),f=a(g.hint);c=c.css(h.wrapper),d=d.css(h.dropdown),f.css(h.hint).css({backgroundAttachment:e.css("background-attachment"),backgroundClip:e.css("background-clip"),backgroundColor:e.css("background-color"),backgroundImage:e.css("background-image"),backgroundOrigin:e.css("background-origin"),backgroundPosition:e.css("background-position"),backgroundRepeat:e.css("background-repeat"),backgroundSize:e.css("background-size")}),e.data("ttAttrs",{dir:e.attr("dir"),autocomplete:e.attr("autocomplete"),spellcheck:e.attr("spellcheck"),style:e.attr("style")}),e.addClass("tt-query").attr({autocomplete:"off",spellcheck:!1}).css(h.query);try{!e.attr("dir")&&e.attr("dir","auto")}catch(i){}return e.wrap(c).parent().prepend(f).append(d)}function f(a){var b=a.find(".tt-query");c.each(b.data("ttAttrs"),function(a,d){c.isUndefined(d)?b.removeAttr(a):b.attr(a,d)}),b.detach().removeData("ttAttrs").removeClass("tt-query").insertAfter(a),a.remove()}var g={wrapper:'',hint:'',dropdown:''},h={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none"},query:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"}};return c.isMsie()&&c.mixin(h.query,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),c.isMsie()&&c.isMsie()<=7&&(c.mixin(h.wrapper,{display:"inline",zoom:"1"}),c.mixin(h.query,{marginTop:"-1px"})),c.mixin(b.prototype,d,{_managePreventDefault:function(a){var b,c,d=a.data,e=!1;switch(a.type){case"tabKeyed":b=this.inputView.getHintValue(),c=this.inputView.getInputValue(),e=b&&b!==c;break;case"upKeyed":case"downKeyed":e=!d.shiftKey&&!d.ctrlKey&&!d.metaKey}e&&d.preventDefault()},_setLanguageDirection:function(){var a=this.inputView.getLanguageDirection();a!==this.dir&&(this.dir=a,this.$node.css("direction",a),this.dropdownView.setLanguageDirection(a))},_updateHint:function(){var a,b,d,e,f,g=this.dropdownView.getFirstSuggestion(),h=g?g.value:null,i=this.dropdownView.isVisible(),j=this.inputView.isOverflow();h&&i&&!j&&(a=this.inputView.getInputValue(),b=a.replace(/\s{2,}/g," ").replace(/^\s+/g,""),d=c.escapeRegExChars(b),e=new RegExp("^(?:"+d+")(.*$)","i"),f=e.exec(h),this.inputView.setHintValue(a+(f?f[1]:"")))},_clearHint:function(){this.inputView.setHintValue("")},_clearSuggestions:function(){this.dropdownView.clearSuggestions()},_setInputValueToQuery:function(){this.inputView.setInputValue(this.inputView.getQuery())},_setInputValueToSuggestionUnderCursor:function(a){var b=a.data;this.inputView.setInputValue(b.value,!0)},_openDropdown:function(){this.dropdownView.open()},_closeDropdown:function(a){this.dropdownView["blured"===a.type?"closeUnlessMouseIsOverDropdown":"close"]()},_moveDropdownCursor:function(a){var b=a.data;b.shiftKey||b.ctrlKey||b.metaKey||this.dropdownView["upKeyed"===a.type?"moveCursorUp":"moveCursorDown"]()},_handleSelection:function(a){var b="suggestionSelected"===a.type,d=b?a.data:this.dropdownView.getSuggestionUnderCursor();d&&(this.inputView.setInputValue(d.value),b?this.inputView.focus():a.data.preventDefault(),b&&c.isMsie()?c.defer(this.dropdownView.close):this.dropdownView.close(),this.eventBus.trigger("selected",d.datum,d.dataset))},_getSuggestions:function(){var a=this,b=this.inputView.getQuery();c.isBlankString(b)||c.each(this.datasets,function(c,d){d.getSuggestions(b,function(c){b===a.inputView.getQuery()&&a.dropdownView.renderSuggestions(d,c)})})},_autocomplete:function(a){var b,c,d,e,f;("rightKeyed"!==a.type&&"leftKeyed"!==a.type||(b=this.inputView.isCursorAtEnd(),c="ltr"===this.inputView.getLanguageDirection()?"leftKeyed"===a.type:"rightKeyed"===a.type,b&&!c))&&(d=this.inputView.getQuery(),e=this.inputView.getHintValue(),""!==e&&d!==e&&(f=this.dropdownView.getFirstSuggestion(),this.inputView.setInputValue(f.value),this.eventBus.trigger("autocompleted",f.datum,f.dataset)))},_propagateEvent:function(a){this.eventBus.trigger(a.type)},destroy:function(){this.inputView.destroy(),this.dropdownView.destroy(),f(this.$node),this.$node=null},setQuery:function(a){this.inputView.setQuery(a),this.inputView.setInputValue(a),this._clearHint(),this._clearSuggestions(),this._getSuggestions()}}),b}();!function(){var b,d={},f="ttView";b={initialize:function(b){function g(){var b,d=a(this),g=new e({el:d});b=c.map(h,function(a){return a.initialize()}),d.data(f,new l({input:d,eventBus:g=new e({el:d}),datasets:h})),a.when.apply(a,b).always(function(){c.defer(function(){g.trigger("initialized")})})}var h;return b=c.isArray(b)?b:[b],0===b.length&&a.error("no datasets provided"),h=c.map(b,function(a){var b=d[a.name]?d[a.name]:new i(a);return a.name&&(d[a.name]=b),b}),this.each(g)},destroy:function(){function b(){var b=a(this),c=b.data(f);c&&(c.destroy(),b.removeData(f))}return this.each(b)},setQuery:function(b){function c(){var c=a(this).data(f);c&&c.setQuery(b)}return this.each(c)}},jQuery.fn.typeahead=function(a){return b[a]?b[a].apply(this,[].slice.call(arguments,1)):b.initialize.apply(this,arguments)}}()}(window.jQuery);
\ No newline at end of file
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index b23aa5ff..7aa738c2 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -59,7 +59,7 @@ html {
body {
background:#031924 url(background2-for-repeating.jpg) repeat 0 0;
- font-family: 'katarine-web', sans-serif;
+ font-family: 'LatoLight', helvetica, sans-serif;
background-attachment:fixed;
color:#FFF;
}
@@ -88,6 +88,43 @@ a {
text-decoration:none;
}
+button.button, a.button, input[type="submit"] {
+border: none;
+-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
+box-shadow: 0 1px 2px rgba(0,0,0,.2);
+border: none;
+border-bottom-left-radius: 0;
+border-top-left-radius: 0;
+height: 30px;
+outline: none;
+padding: 0 0;
+width: 60px;
+-webkit-box-shadow: none;
+box-shadow: none;
+background: #69a3a4;
+background: -webkit-linear-gradient(top,#69a3a4,#69a3aF);
+background: linear-gradient(top,#4387fd,#4683ea);
+filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#4387fd,endColorstr=#4683ea,GradientType=1);
+vertical-align: top;
+color: #fff!important;
+margin: 0px;
+cursor: default!important;
+display: inline-block;
+font-weight: bold;
+line-height: 29px;
+min-width: 54px;
+text-align: center;
+text-decoration: none!important;
+-webkit-border-radius: 2px;
+border-radius: 2px;
+-webkit-user-select: none;
+}
+
+button.button:hover, a.button:hover, input[type="submit"]:hover {
+-webkit-box-shadow: 0 1px 0 rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.2);
+box-shadow: 0 1px 0 rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.2);
+}
+
/*
* Utility
*/
@@ -109,6 +146,10 @@ a {
* Layout stuffs
*/
+#barometer_tab {
+ display:none;
+}
+
#error_explanation {
background: #612127;
padding: 30px;
@@ -123,7 +164,6 @@ a {
}
.profile {
- overflow-y:scroll;
height:100%;
margin-bottom:50px;
}
@@ -210,12 +250,28 @@ a {
position: absolute;
}
-.anypage #topic_name {
- width:200px;
- position:absolute;
+#new_topic .twitter-typeahead {
+ position:absolute !important;
top:40px;
left:50px;
- z-index:9999;
+ z-index:9999;
+ width:202px;
+ height: 37px;
+ font-family: 'katarine-web';
+}
+
+.anypage #topic_name, .anypage .tt-hint {
+ width:190px;
+background: rgba(0,0,0,0.8);
+height: 25px;
+margin: 0;
+padding: 5px 5px;
+border: 1px solid black;
+outline: none;
+font-size: 25px;
+line-height: 35px;
+color: rgba(255,255,255,0.7);
+font-family: 'katarine-web';
}
#metacodeImg {
@@ -235,13 +291,21 @@ label, select, input, textarea {
}
label {
- margin-top:5px;
+ margin-top:10px;
+ margin-bottom:4px;
}
input[type="submit"] {
margin-top:5px;
}
+#user_remember_me {
+ margin-top:11px;
+}
+#user_remember_me, label[for="user_remember_me"] {
+ float:left;
+}
+
.contentarea p,
.contentarea ul,
.contentarea ol,
@@ -340,118 +404,410 @@ box-shadow: 6px 6px 8px rgba(0,0,0,0.4);
margin:0 0;
}
+
+/* bottom right corner stuffs */
+
+.wrapper div.index {
+ position: fixed;
+ bottom: 9px;
+ right: 0px;
+ z-index: 9999;
+ width: auto;
+ background: rgba(0,0,0,0.7);
+ padding: 1px 10px 0px 10px;
+ font-family: "vinyl",sans-serif;
+ font-style:italic;
+ height: 35px;
+ font-size: 30px;
+ line-height: 38px;
+ border:1px solid #000;
+ border-right:none;
+ border-bottom-left-radius:5px;
+ border-top-left-radius:5px;
+}
+.wrapper div.index .openCheatsheet {
+ position:absolute;
+ top:0;
+ left:-45px;
+ background: rgba(0,0,0,0.7) url('MMCCicon_help.png') no-repeat center center;
+ background-size: 32px 32px;
+ border:1px solid #000;
+ border-radius:5px;
+ height:36px;
+ width:36px;
+ cursor:pointer;
+}
+.wrapper div.index span {
+ float:left;
+}
+.wrapper div.index span.mapName {
+ text-transform:uppercase;
+ margin-right:9px;
+}
+.wrapper div.index span.mapInfo {
+ width: 24px;
+ height: 24px;
+ line-height: 24px;
+ text-align: center;
+ margin-top: 5px;
+ font-size: 27px;
+ background: url('MMCCicon_info.png') no-repeat center center;
+ background-size:24px 24px;
+ cursor:pointer;
+}
+
.wrapper h1.index {
position: fixed;
bottom: 9px;
right: 0;
z-index: 9999;
width: auto;
- background: url('black_bg.png');
+ background: rgba(0,0,0,0.7);
padding: 1px 10px 0px 20px;
- border-bottom-left-radius: 5px;
- border-top-left-radius: 5px;
text-transform:uppercase;
font-style:italic;
height: 35px;
font-size: 30px;
line-height: 38px;
border:1px solid #000;
+ border-right:none;
+ border-bottom-left-radius:5px;
+ border-top-left-radius:5px;
}
-.nodemargin {
- padding-top:120px;
+/* account */
+
+.sidebarAccount {
+position:absolute;
+top:5px;
+right:5px;
+z-index:200;
+width: 35px;
+height:35px;
}
-.focus {
- position:fixed;
- top:0;
- left:0;
- width:90%;
- z-index:2;
- display: block;
- min-width:533px;
- margin: 50px 50px 25px 50px;
- background: url('bg.png'); border-radius: 20px;
- color:#000;
- border:1px solid #000;
+.sidebarAccountIcon {
+position:absolute;
+width: 35px;
+height: 35px;
+background: #69a3a4 url('MMCCicon_mapper.png') no-repeat center center;
+background-size: 28px 28px;
+cursor:pointer;
+}
+.sidebarAccountBox {
+ position:absolute;
+ display:none;
+ height:auto;
+ background: rgba(0,0,0,0.7);
+ top: 36px;
+ right:0;
+ padding: 10px;
+ border: 1px solid black;
+ min-width:120px;
+ font-family: 'LatoLight', helvetica, sans-serif;
+}
+.sidebarAccountBox.loggedin {
+ width:auto;
+}
+.sidebarAccountBox.loggedout {
+ width:200px;
}
-.focus h1 {
- margin-top:0;
+.sidebarAccountBox h3 {
+ font-family: 'vinyl', helvetica, sans-serif;
+ text-transform:uppercase;
+ font-style:italic;
}
-
-.focusleft,
-.focusmiddle,
-.focusright {
+.sidebarAccountBox ul {
+ list-style:none;
+}
+.sidebarAccountBox li.accountIcon {
+padding: 6px 0 6px 25px;
+background-size: 18px 18px;
+background-repeat: no-repeat;
+background-position: 0px 6px;
+font-size: 18px;
+line-height: 20px;
+}
+li.accountMaps {
+ background-image: url('MMCCicon_map.png');
+}
+li.accountSettings {
+ background-image: url('MMCCicon_settings.png');
+}
+li.accountInvite{
+ background-image: url('MMCCicon_invite.png');
+}
+li.accountLogout {
+ background-image: url('MMCCicon_logout.png');
+}
+li.accountIcon a {
display:block;
+}
+
+.sidebarAccountBox a {
+ color:white;
+}
+
+.sidebarAccountBox input[type="email"], .sidebarAccountBox input[type="password"] {
+width: 200px;
+height: 32px;
+font-size: 15px;
+direction: ltr;
+-webkit-appearance: none;
+appearance: none;
+display: inline-block;
+margin: 0;
+padding: 0 8px;
+background: #fff;
+border: 1px solid #d9d9d9;
+border-top: 1px solid #c0c0c0;
+-webkit-box-sizing: border-box;
+-moz-box-sizing: border-box;
+box-sizing: border-box;
+-webkit-border-radius: 1px;
+-moz-border-radius: 1px;
+border-radius: 1px;
+font: -webkit-small-control;
+color: initial;
+letter-spacing: normal;
+word-spacing: normal;
+text-transform: none;
+text-indent: 0px;
+text-shadow: none;
+display: inline-block;
+text-align: start;
+}
+
+.sidebarAccountBox .links a {
+ display:block;
+ margin-top:5px;
+}
+
+/* search */
+
+.sidebarSearch {
+position:absolute;
+top:5px;
+left:5px;
+height: 35px;
+z-index:200;
+}
+
+.sidebarSearchIcon {
+float:left;
+width: 35px;
+height: 35px;
+background: #cf8e88 url('search_icon_32x32.png') no-repeat center center;
+background-size: 25px 25px;
+cursor:pointer;
+}
+
+.sidebarSearch .twitter-typeahead {
float:left;
}
-.focusleft {
- width:20%;
- min-width:70px;
- text-align:center;
+.sidebarSearchField, .sidebarSearch .tt-hint {
+ height:25px;
+ padding:5px 0;
+ width:0px;
+ margin: 0;
+ border: 0;
+ outline: none;
+ font-size: 25px;
+ line-height:35px;
+ background:rgba(0,0,0,0.7);
+ color: rgba(255,255,255,0.6);
+ font-family: 'katarine-web';
}
-.focusmiddle {
- display:block;
- width:49%;
- min-height:115px;
- border-right:2px solid #000;
- border-left:2px solid #000;
+.sidebarSearch .tt-dropdown-menu {
+left:-35px !important;
+background: rgba(0,0,0,0.7);
+min-width: 440px;
+border: 1px solid black;
}
-.focusright {
- width:30%;
- min-width:150px;
-}
-
-.focus .focusleft p {
- font-weight:normal;
- font-size:16px;
+.sidebarSearch .tt-dropdown-menu h3 {
+ font-family:'vinyl',helvetica,sans-serif;
+ text-transform:uppercase;
+ font-style:italic;
+ font-size:20px;
line-height:20px;
- padding:10px 0 5px 0;
+ margin: 10px 0 3px 10px;
}
-.focus .focusright p {
- font-weight:normal;
+.sidebarSearch .tt-suggestions {
+ font-family:'LatoLight', helvetica, sans-serif;
+}
+
+.sidebarSearch .tt-suggestion {
+background: rgba(0,0,0,0.5);
+border: 1px solid black;
+}
+
+.sidebarSearch .tt-is-under-cursor {
+ background:black;
+}
+
+.sidebarSearch .tt-suggestion .icon {
+ float:left;
+ width:36px;
+ height:36px;
+ margin-right:5px;
+}
+.sidebarSearch .tt-dataset-mappers .tt-suggestion .icon {
+ width:28px;
+ height:28px;
+ padding:4px;
+}
+
+.sidebarSearch .resultText {
+ width: 280px;
+ display: block;
+ float: left;
+}
+
+.sidebarSearch .resultTitle {
+ font-weight:bold;
+ font-size:20px;
+ line-height:22px;
+ width:100%;
+ padding-top:8px;
+}
+.sidebarSearch .resultDesc {
+ font-style:italic;
font-size:16px;
- line-height:20px;
- padding:10px 0 5px 10px;
+ line-height:16px;
+ width:100%;
+ padding: 6px 0;
}
-.focus .icon {
- margin:0 auto;
+.sidebarSearch .tip {
+ display:none;
}
-.focus .title {
- font-size:22px;
- line-height:25px;
- border-bottom:2px solid #000;
- padding:10px;
+.sidebarSearch div.autoOptions {
+ width: 117px;
+ float: left;
+ position:relative;
+ display:none;
}
-
-.focus .desc {
- padding:10px;
- height:75px;
- font-family:Arial, Helvetica, sans-serif;
-}
-
-.focus .desc h3 {
- font-style:normal;
-}
-
-.focus .location {
- padding-left:10px;
-}
-
-.focus .link {
- padding:0 0 0 10px;
+.sidebarSearch .tt-is-under-cursor .autoOptions {
display:block;
- width:90%;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
+}
+
+.sidebarSearch .autoOptions button, .sidebarSearch .autoOptions a, .sidebarSearch .autoOptions div {
+ position: absolute;
+ padding: 0;
+ margin: 0;
+ border: none;
+ outline: none;
+}
+
+.sidebarSearch button.addToMap {
+ width: 20px;
+ height: 20px;
+ background: url(/assets/MMCCicon_add.png) no-repeat center center;
+ background-size: 15px 15px;
+ top: 10px;
+ left: 0px;
+}
+
+.sidebarSearch a.goTo {
+width: 20px;
+height: 20px;
+background: url(/assets/MMCCicon_pop-out.png) no-repeat center center;
+background-size: 15px 15px;
+top: 11px;
+left: 22px;
+}
+
+.sidebarSearch div.mapCount {
+width: 20px;
+height: 20px;
+background: url(/assets/MMCCicon_map.png) no-repeat 0px center;
+background-size: 14px 14px;
+top: 0px;
+left: 50px;
+padding-left: 18px;
+font-size: 12px;
+line-height: 20px;
+}
+
+.sidebarSearch div.topicCount {
+width: 20px;
+height: 20px;
+background: url(/assets/MMCCicon_topic.png) no-repeat 0px center;
+background-size: 14px 14px;
+top: 0px;
+left: 50px;
+padding-left: 18px;
+font-size: 12px;
+line-height: 20px;
+}
+
+.sidebarSearch div.synapseCount {
+width: 20px;
+height: 20px;
+background: url(/assets/MMCCicon_synapse.png) no-repeat 0px center;
+background-size: 14px 14px;
+top: 0px;
+left: 83px;
+padding-left: 15px;
+font-size: 12px;
+line-height: 20px;
+}
+
+.sidebarSearch div.topicOriginatorIcon {
+ width: 20px;
+ height: 20px;
+ background: url(/assets/MMCCicon_mapper.png) no-repeat center center;
+ background-size: 16px 16px;
+ top: 21px;
+ left: 52px;
+}
+
+.sidebarSearch div.mapContributorsIcon {
+ width: 20px;
+ height: 20px;
+ background: url(/assets/MMCCicon_mapper.png) no-repeat 0px center;
+ background-size: 16px 16px;
+ top: 21px;
+ left: 50px;
+ padding-left: 18px;
+ font-size: 12px;
+ line-height: 20px;
+}
+
+.sidebarSearch div.topicPermission, .sidebarSearch div.mapPermission {
+width: 20px;
+height: 20px;
+background-size: 20px 20px !important;
+top: 20px;
+left: 84px;
+}
+.sidebarSearch div.topicPermission.commons, .sidebarSearch div.mapPermission.commons {
+ background: url(/assets/MMCCicon_commons.png) no-repeat center center;
+}
+.sidebarSearch div.topicPermission.public, .sidebarSearch div.mapPermission.public {
+ background: url(/assets/MMCCicon_public.png) no-repeat center center;
+}
+.sidebarSearch div.topicPermission.private, .sidebarSearch div.mapPermission.private {
+ background: url(/assets/MMCCicon_private.png) no-repeat center center;
+}
+
+.sidebarSearch .tt-dataset-mappers a.goTo {
+ top:7px;
+}
+.sidebarSearch .tt-dataset-mappers div.mapCount {
+ top:8px;
+}
+
+/* end search */
+
+.nodemargin {
+ padding-top:120px;
}
.divider {
@@ -468,177 +824,21 @@ box-shadow: 6px 6px 8px rgba(0,0,0,0.4);
}
#cards {
- height:100%;
- overflow-y:scroll;
+ height:100%;
}
#cards p.empty {
margin-left:50px;
}
-/* --- styling the sideOptions section ---*/
-.sideOption {
- position:fixed;
- left:0px;
- display:block;
- height:32px;
- background: #FFF;
- padding:0 0 0 15px;
- border-bottom-right-radius:10px;
- border-top-right-radius:10px;
- color:#000;
- border:1px solid #000;
- overflow:hidden;
- cursor:pointer;
- box-shadow: 6px 6px 8px rgba(0,0,0,0.4);
-}
-
-#sideOptionFind {
- top:25%;
- width:45px;
-}
-
-#sideOptionAnalyze {
- top:35%;
- width:64px;
-}
-
-#sideOptionOrganize {
- top:45%;
- width:75px;
- display:none;
-}
-
-.closeSideOption {
- position:fixed;
- left:4px;
- display:none;
- margin-top: -22px;
- cursor: pointer;
- background: #000;
- padding: 0 4px;
- border-radius: 8px;
-}
-#closeFind {
- top:25%;
-}
-
-#closeAnalyze {
- top:35%;
-}
-
-#closeOrganize {
- top:45%;
-}
-
-#findWhere {
- position:fixed;
- top:25%;
- left:90px;
- display:none;
- margin-top:-20px;
-}
-
-.findWhereField, #findWhere input, #findWhere p {
- float:left;
-}
-
-.findWhereField.inCommons {
- color:#67be5f;
-}
-
-.sideOption select,
-.sideOption span {
- float:left;
- margin-top:10px;
-}
-
-.sideOption .spacer {
- margin:10px 10px 0;
-}
-
-.sideOption .find_key {
- margin-right:8px;
-}
-
-.find_topic_by_name {
- display: block;
-}
-
-.find_topic_by_name input, .find_map_by_name input, .find_mapper_by_name input {
- margin:10px 0 0 0;
- width: 270px;
- border-radius: 10px;
- height: 20px;
- padding: 0 10px;
- outline: none;
- }
-
-.find_mapper_by_name,
-.find_map_by_name {
- display:none;
-}
-
-.find_topic_by_metacode {
- z-index:12;
- display:none;
- width:auto;
- color: #67AF9F;
-}
-
-.find_topic_by_metacode ul {
- display:block;
-}
-
-.find_topic_by_metacode ul li {
- clear:both;
- list-style-type:none;
- display:block;
- padding:3px;
-}
-
-.find_topic_by_metacode ul img {
- width:40px;
- height:40px;
- float:left;
-}
-
-.find_topic_by_metacode ul p {
- float:left;
- display: block;
- margin: 0;
- background: none;
- padding: 10px 4px 2px 4px;
-}
-
-.find_topic_by_metacode #filters-one {
- float:left;
-}
-
-.find_topic_by_metacode #filters-two {
- float:left;
-}
-
-.find_topic_by_metacode #filters-three {
- float:left;
-}
-
-.find_topic_by_metacode li.toggledOff {
- opacity: 0.4;
-}
-
-#get_topics_form {
- display:none;
-}
-
/* --- styling the logo button ---*/
-.footer {
+/*.footer {
width: 188px;
display: block;
position: fixed;
bottom: 9px;
height: 38px;
- background: url('black_bg.png');
+ background: rgba(0,0,0,0.5);
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
z-index: 15000;
@@ -655,12 +855,29 @@ box-shadow: 6px 6px 8px rgba(0,0,0,0.4);
padding: 3px 8px;
margin: -0.75em 0 0;
}
+*/
+.footer {
+ display: block;
+ position: fixed;
+ bottom: 9px;
+ height: 35px;
+ z-index: 15000;
+ border:1px solid #000;
+ border-bottom-right-radius:5px;
+ border-top-right-radius:5px;
+}
+
+.logo {
+ z-index:12;
+ display:block;
+ width: 136px;
+background: rgba(0,0,0,0.7) url(menu_icon_32.png) no-repeat -10px 8px;
+padding: 5px 0px 1px 15px;
+background-size: 22px 20px;
+}
#mainTitle {
- float: left;
- /*background: url('black_bg.png') repeat 0 0;*/
padding: 0 5px;
- border-radius: 10px;
}
#mainTitle a {
@@ -669,37 +886,33 @@ box-shadow: 6px 6px 8px rgba(0,0,0,0.4);
font-style: italic;
text-transform:uppercase;
font-weight: 400;
-}
-
-#beta {
- float:left;
- margin-left: 2px;
+ font-size:30px;
+ line-height:30px;
}
.footer .menu {
- display:block;
+ display:none;
position:absolute;
border:none;
- bottom:42px;
- left:10px;
- height:0px;
+ bottom:36px;
+ left:-1px;
+ height:142px;
z-index:12;
- width:118px;
+ width:151px;
color: #67AF9F;
white-space: nowrap;
text-align: center;
font-size: 16px;
overflow: hidden;
- padding: 0 8px;
+ padding: 0;
margin: 0;
- background: white;
- border-radius: 6px;
+ /*border-radius: 6px;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
box-shadow: 0 2px rgba(0, 0, 0, 0.05), 0 -2px rgba(0, 0, 0, 0.05) inset;
-webkit-box-shadow: 0 2px rgba(0, 0, 0, 0.05), 0 -2px rgba(0, 0, 0, 0.05) inset;
- -moz-box-shadow: 0 2px rgba(0, 0, 0, 0.05), 0 -2px rgba(0, 0, 0, 0.05) inset;
- background: url('black_bg.png') repeat 0 0;
+ -moz-box-shadow: 0 2px rgba(0, 0, 0, 0.05), 0 -2px rgba(0, 0, 0, 0.05) inset;*/
+ background: rgba(0,0,0,0.7);/*url('black_bg.png'); */
border-left:1px solid #000;
border-right:1px solid #000;
}
@@ -710,21 +923,65 @@ box-shadow: 6px 6px 8px rgba(0,0,0,0.4);
float:none;
list-style-type:none;
display:block;
- padding:3px;
+ padding:0;
text-align:center;
- border-top:1px solid #999;
}
-.footer ul li.first {
- border:none;
+
+li.meta .button {
+ background: #89aa7b;
+ margin:7px;
}
-.footer ul li a:hover {
- color:#9E2;
+
+li.beta {
+ margin: 4px 0 0 !important;
+border-top: 1px solid black;
+border-bottom: 1px solid black;
+position: relative;
+height: 30px;
}
-.footer ul li a {
- color: #FFF;
+.inBeta {
+ background: rgba(0,0,0,0.6);
+display: inline-block;
+color: white;
+height: 30px;
+padding: 0 5px;
+font-family: 'LatoLight';
+font-size: 30px;
+position: absolute;
+top: 0;
+left: 0;
+line-height: 30px;
+}
+
+li.beta button {
+position: absolute;
+top: 0;
+right: 0;
+width: 84px;
+border-radius: 0;
+font-size: 12px;
+margin: 0;
+}
+
+li.tutorial, li.exploreMaps {
+ height:30px;
+ line-height:30px;
+ font-size:20px;
+}
+
+li.tutorial a, li.exploreMaps a {
display:block;
}
+li.exploreMaps {
+ border-top:1px solid white;
+}
+
+.footer ul li a {
+ color: #FFF;
+}
+
+
.menuflag {
position: absolute;
@@ -748,7 +1005,6 @@ font-size: 21px;
}
.home_bg {
- overflow-y:scroll;
display:block;
height:100%;
}
@@ -806,3 +1062,7 @@ background: url('home_bg2.png') no-repeat center -46px;
#edit_synapse label.left {
margin-right: 0.5em;
}
+
+.templates {
+ display:none;
+}
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 2a7b3ceb..9b5009da 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,9 +1,25 @@
class ApplicationController < ActionController::Base
protect_from_forgery
+ # this is for global login
+ include ContentHelper
+
helper_method :user
helper_method :authenticated?
+ after_filter :store_location
+
+ def store_location
+ # store last url - this is needed for post-login redirect to whatever the user last visited.
+ if (!request.fullpath.match("/users/") && !request.xhr?) # don't store ajax calls
+ session[:previous_url] = request.fullpath
+ end
+ end
+
+ def after_sign_in_path_for(resource)
+ session[:previous_url] || root_path
+ end
+
private
def require_no_user
diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb
index 7cb2f870..8c40fd51 100644
--- a/app/controllers/main_controller.rb
+++ b/app/controllers/main_controller.rb
@@ -1,10 +1,13 @@
class MainController < ApplicationController
include TopicsHelper
+ include MapsHelper
+ include UsersHelper
before_filter :require_user, only: [:invite]
respond_to :html, :js, :json
+ # home page
def home
@maps = Map.visibleToUser(@current, nil).sort! { |a,b| b.created_at <=> a.created_at }
@maps = @maps.slice(0,5)
@@ -12,46 +15,12 @@ class MainController < ApplicationController
respond_with(@maps)
end
- def console
-
- end
-
- def search
- @current = current_user
- @topics = Array.new()
- @synapses = Array.new()
- if params[:topics_by_name] != ""
- like_keyword = "%"+params[:topics_by_name]+"%"
- like_keyword.downcase! #convert to lowercase for better comparison
- @topics = Topic.where("LOWER(name) LIKE ?", like_keyword)
- end
- if params[:topics_by_user_id] != ""
- @user = User.find(params[:topics_by_user_id])
- @topics = @topics | Topic.visibleToUser(@current, @user)
- end
- if params[:topics_by_map_id] != ""
- @map = Map.find(params[:topics_by_map_id])
- @topics = @topics | @map.topics.delete_if{|topic| not topic.authorize_to_view(@current)}
- end
-
- @topics.each do |t|
- t.synapses.each do |s|
- @synapses = @synapses.push(s) if not @synapses.include? s
- end
- end
-
- @topics.sort! { |a,b| a.name.downcase <=> b.name.downcase }
-
- respond_to do |format|
- format.js { respond_with(@topics,@synapses) }
- end
- end
-
-
+ # /request
def requestinvite
end
+ # /invite
def invite
@user = current_user
@@ -60,5 +29,112 @@ class MainController < ApplicationController
end
end
+ ### SEARCHING ###
+
+ # get /search/topics?term=SOMETERM
+ def searchtopics
+ @current = current_user
+
+ term = params[:term]
+
+ if term && !term.empty? && term.downcase[0..3] != "map:" && term.downcase[0..6] != "mapper:" && term.downcase != "topic:"
+
+ #remove "topic:" if appended at beginning
+ term = term[6..-1] if term.downcase[0..5] == "topic:"
+
+ #check whether there's a filter by metacode as part of the query
+ filterByMetacode = false
+ Metacode.all.each do |m|
+ lOne = m.name.length+1
+ lTwo = m.name.length
+
+ if term.downcase[0..lTwo] == m.name.downcase + ":"
+ term = term[lOne..-1]
+ filterByMetacode = m
+ end
+ end
+
+ if filterByMetacode
+ if term == ""
+ @topics = []
+ else
+ search = '%' + term.downcase + '%'
+ @topics = Topic.where('LOWER("name") like ? OR LOWER("desc") like ? OR LOWER("link") like ?', search, search, search).
+ where('metacode_id = ?', filterByMetacode.id).limit(10).order('"name"').visibleToUser(@current,nil)
+ end
+ else
+ search = '%' + term.downcase + '%'
+ @topics = Topic.where('LOWER("name") like ? OR LOWER("desc") like ? OR LOWER("link") like ?', search, search, search).
+ limit(10).order('"name"').visibleToUser(@current,nil)
+ end
+ else
+ @topics = []
+ end
+ render json: autocomplete_array_json(@topics)
+ #if params[:topics_by_user_id] != ""
+ # @user = User.find(params[:topics_by_user_id])
+ # @topics = @topics | Topic.visibleToUser(@current, @user)
+ #end
+ #if params[:topics_by_map_id] != ""
+ # @map = Map.find(params[:topics_by_map_id])
+ # @topics = @topics | @map.topics.delete_if{|topic| not topic.authorize_to_view(@current)}
+ #end
+ #@topics.sort! { |a,b| a.name.downcase <=> b.name.downcase }
+ end
+
+ # get /search/maps?term=SOMETERM
+ def searchmaps
+ @current = current_user
+
+ term = params[:term]
+ if term && !term.empty? && term.downcase[0..5] != "topic:" && term.downcase[0..6] != "mapper:" && term.downcase != "map:"
+
+ #remove "map:" if appended at beginning
+ term = term[4..-1] if term.downcase[0..3] == "map:"
+
+ search = '%' + term.downcase + '%'
+ @maps = Map.where('LOWER("name") like ? OR LOWER("desc") like ?', search, search).
+ limit(10).order('"name"').visibleToUser(@current,nil)
+ else
+ @maps = []
+ end
+ render json: autocomplete_map_array_json(@maps)
+ #if params[:topics_by_user_id] != ""
+ # @user = User.find(params[:topics_by_user_id])
+ # @topics = @topics | Topic.visibleToUser(@current, @user)
+ #end
+ #if params[:topics_by_map_id] != ""
+ # @map = Map.find(params[:topics_by_map_id])
+ # @topics = @topics | @map.topics.delete_if{|topic| not topic.authorize_to_view(@current)}
+ #end
+ #@topics.sort! { |a,b| a.name.downcase <=> b.name.downcase }
+ end
+
+ # get /search/mappers?term=SOMETERM
+ def searchmappers
+ @current = current_user
+
+ term = params[:term]
+ if term && !term.empty? && term.downcase[0..3] != "map:" && term.downcase[0..5] != "topic:" && term.downcase != "mapper:"
+
+ #remove "mapper:" if appended at beginning
+ term = term[7..-1] if term.downcase[0..6] == "mapper:"
+
+ @mappers = User.where('LOWER("name") like ?', '%' + term.downcase + '%').
+ limit(10).order('"name"')
+ else
+ @mappers = []
+ end
+ render json: autocomplete_user_array_json(@mappers)
+ #if params[:topics_by_user_id] != ""
+ # @user = User.find(params[:topics_by_user_id])
+ # @topics = @topics | Topic.visibleToUser(@current, @user)
+ #end
+ #if params[:topics_by_map_id] != ""
+ # @map = Map.find(params[:topics_by_map_id])
+ # @topics = @topics | @map.topics.delete_if{|topic| not topic.authorize_to_view(@current)}
+ #end
+ #@topics.sort! { |a,b| a.name.downcase <=> b.name.downcase }
+ end
end
diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb
index ec337ac7..9b89c0bc 100644
--- a/app/controllers/topics_controller.rb
+++ b/app/controllers/topics_controller.rb
@@ -1,10 +1,24 @@
class TopicsController < ApplicationController
+ include TopicsHelper
+
before_filter :require_user, only: [:new, :create, :edit, :update, :removefrommap, :destroy]
respond_to :html, :js, :json
- autocomplete :topic, :name, :full => true, :extra_data => [:user_id], :display_value => :topic_autocomplete_method
+ #autocomplete :topic, :name, :full => true, :extra_data => [:user_id], :display_value => :topic_autocomplete_method
+ # GET /topics/autocomplete_topic
+ def autocomplete_topic
+ @current = current_user
+ term = params[:term]
+ if term && !term.empty?
+ t = Topic.where('LOWER("name") like ?', term.downcase + '%').
+ limit(10).order('"name"').visibleToUser(@current,nil)
+ else
+ t = []
+ end
+ render json: autocomplete_array_json(t)
+ end
# GET topics
# or GET /users/:user_id/topics
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 56723d72..13af08f8 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -14,19 +14,6 @@ class UsersController < ApplicationController
respond_with(@user)
end
- # GET /user/:id
- def show
- @user = User.find(params[:id])
- @topics = Topic.visibleToUser(@current, @user).sort! { |a,b| b.created_at <=> a.created_at }
- @topics = @topics.slice(0,3)
- @synapses = Synapse.visibleToUser(@current, @user).sort! { |a,b| b.created_at <=> a.created_at }
- @synapses = @synapses.slice(0,3)
- @maps = Map.visibleToUser(@current, @user).sort! { |a,b| b.created_at <=> a.created_at }
- @maps = @maps.slice(0,3)
-
- respond_with(@user, @topics, @synapses, @maps)
- end
-
# PUT /user
def update
@user = current_user
diff --git a/app/helpers/content_helper.rb b/app/helpers/content_helper.rb
new file mode 100644
index 00000000..4a8820f0
--- /dev/null
+++ b/app/helpers/content_helper.rb
@@ -0,0 +1,13 @@
+module ContentHelper
+ def resource_name
+ :user
+ end
+
+ def resource
+ @resource ||= User.new
+ end
+
+ def devise_mapping
+ @devise_mapping ||= Devise.mappings[:user]
+ end
+end
diff --git a/app/helpers/maps_helper.rb b/app/helpers/maps_helper.rb
index 88ee3d5c..99a3a752 100644
--- a/app/helpers/maps_helper.rb
+++ b/app/helpers/maps_helper.rb
@@ -1,2 +1,32 @@
module MapsHelper
+
+ ## this one is for building our custom JSON autocomplete format for typeahead
+ def autocomplete_map_array_json(maps)
+ temp = []
+ maps.each do |m|
+ map = {}
+ map['id'] = m.id
+ map['label'] = m.name
+ map['value'] = m.name
+ map['description'] = m.desc.truncate(30)
+ map['permission'] = m.permission
+ map['topicCount'] = m.topics.count
+ map['synapseCount'] = m.synapses.count
+ map['contributorCount'] = m.contributors.count
+
+ contributorList = ''
+ if m.contributors.count > 0
+ contributorList += ''
+ m.contributors.each do |c|
+ contributorList += '- ' + c.name + '
'
+ end
+ contributorList += '
'
+ end
+ map['contributorList'] = contributorList
+
+ temp.push map
+ end
+ return temp
+ end
+
end
diff --git a/app/helpers/topics_helper.rb b/app/helpers/topics_helper.rb
index 9d7593b6..1c0b1f1f 100644
--- a/app/helpers/topics_helper.rb
+++ b/app/helpers/topics_helper.rb
@@ -1,5 +1,26 @@
module TopicsHelper
+ ## this one is for building our custom JSON autocomplete format for typeahead
+ def autocomplete_array_json(topics)
+ temp = []
+ topics.each do |t|
+ topic = {}
+ topic['id'] = t.id
+ topic['label'] = t.name
+ topic['value'] = t.name
+ topic['description'] = t.desc.truncate(35) # make this return matched results
+ topic['type'] = t.metacode.name
+ topic['typeImageURL'] = '/assets/' + t.metacode.icon
+ topic['permission'] = t.permission
+ topic['mapCount'] = t.maps.count
+ topic['synapseCount'] = t.synapses.count
+ topic['originator'] = t.user.name
+
+ temp.push topic
+ end
+ return temp
+ end
+
#find all nodes in any given nodes network
def network(node, array, count)
# recurse starting with a node to find all connected nodes and return an array of topics that constitutes the starting nodes network
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index 2310a240..03bdb2dd 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -1,2 +1,18 @@
module UsersHelper
+
+ ## this one is for building our custom JSON autocomplete format for typeahead
+ def autocomplete_user_array_json(users)
+ temp = []
+ users.each do |u|
+ user = {}
+ user['id'] = u.id
+ user['label'] = u.name
+ user['value'] = u.name
+ user['mapCount'] = u.maps.count
+
+ temp.push user
+ end
+ return temp
+ end
+
end
diff --git a/app/models/map.rb b/app/models/map.rb
index 5eb088f9..f204a370 100644
--- a/app/models/map.rb
+++ b/app/models/map.rb
@@ -21,6 +21,17 @@ def mk_permission
"pr"
end
end
+
+ #return an array of the contributors to the map
+ def contributors
+ contributors = []
+
+ self.mappings.each do |m|
+ contributors.push(m.user) if !contributors.include?(m.user)
+ end
+
+ return contributors
+ end
###### JSON ######
diff --git a/app/models/topic.rb b/app/models/topic.rb
index 63758248..1c826bcc 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -18,7 +18,7 @@ has_many :maps, :through => :mappings
def relatives
topics1 + topics2
- end
+ end
belongs_to :metacode
diff --git a/app/views/layouts/_account.html.erb b/app/views/layouts/_account.html.erb
new file mode 100644
index 00000000..661e016e
--- /dev/null
+++ b/app/views/layouts/_account.html.erb
@@ -0,0 +1,40 @@
+<%#
+ # @file
+ # The inner HTML of the account box that comes up in the bottom left
+ #%>
+
+<% if authenticated? %>
+ <% account = current_user %>
+
+
+ - <%= link_to "My Maps", user_maps_url(user) %>
+ - <%= link_to "Settings", edit_user_url(account) %>
+ - <%= link_to "Share Invite", invite_path %>
+ - <%= link_to "Logout", "/sign_out", id: "Logout" %>
+
+<% else %>
+
+ <%= form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { class: "loginAnywhere" }) do |f| %>
+
+ <%= f.label :email %>
+ <%= f.email_field :email, :autofocus => true %>
+
+
+ <%= f.label :password %>
+ <%= f.password_field :password %>
+
+ <% if devise_mapping.rememberable? -%>
+ <%= f.check_box :remember_me %> <%= f.label :remember_me %>
+ <% end -%>
+
+ <%= f.submit "Sign in" %>
+
+
+ <% end %>
+
+ <%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
+ <%= link_to "Forgot your password?", new_password_path(resource_name) %>
+ <% end -%>
+
Request Invite
+
+<% end %>
diff --git a/app/views/layouts/_searchtemplates.html.erb b/app/views/layouts/_searchtemplates.html.erb
new file mode 100644
index 00000000..8c1ac4b1
--- /dev/null
+++ b/app/views/layouts/_searchtemplates.html.erb
@@ -0,0 +1,88 @@
+<%#
+ # @file
+ # templates for the upper right autocomplete results
+ #%>
+
+
+
+
+

+
{{type}}
+
+
{{value}}
+
{{description}}
+
+
+
+ <% if controller_name == 'maps' && action_name == 'show' && @map.authorize_to_edit(@current) %>
+
+
add to map
+ <% end %>
+
+ open in new tab
+
+
+ appears on maps
+ {{mapCount}}
+
+
+ # of synapses
+ {{synapseCount}}
+
+
+ {{originator}}
+
+
+ permission: {{permission}}
+
+
+
+
+
+
+

+
+
{{value}}
+
{{description}}
+
+
+
+ open in new tab
+
+
+ has topics
+ {{topicCount}}
+
+
+ has synapses
+ {{synapseCount}}
+
+
+ {{contributorList}}
+ {{contributorCount}}
+
+
+ permission: {{permission}}
+
+
+
+
+
+
+

+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 9dc6750a..5a9f0156 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -47,43 +47,50 @@
<%= content_tag :div, class: authenticated? ? "main authenticated" : "main unauthenticated" do %>
+
+
<%= yield %>
<% end %>
<%= render :partial => 'layouts/ga' if Rails.env.production? %>
+
+ <% if authenticated? %>
+
+
+
+
+ <% end %>