<commit_before>var Vis = require('vis');
var remote = require('remote');
var dialog = remote.require('dialog');
var fs = require('fs');

var network;
var inc = 0;

$(document).ready(function () {
    $('#submit-btn').click(function () {
        if (network.body.data.nodes.get().length == 0) {
            createAlert("You have not added any nodes to the graph.");
            return;
        }
        if (network.body.data.edges.get().length == 0) {
            createAlert("You have not added any edges to the graph.");
            return;
        }
        var rootNode = findRootNode(network.body.data.nodes.get());
        if (!rootNode) {
            rootNode = network.body.data.nodes.get()[0];
            rootNode.root = true;
            $("#algo-panel").prepend(alertUserThatNoRoot());
        }
        var obj = getBFSPath(rootNode);
        obj.path = markAllNodesAsUnvisited(obj.path);
        var pathClone = deepCopyPath(obj.path);
        bfsRootAnimation(obj.path);
        rootCodeLineAnimation();
        setTimeout(function () {
            bfsNodesAnimation(obj.path, obj.iter);
        }, 3000);
        setTimeout(function () {
            bfsNodesCodeLineAnimation(pathClone, obj.iter);
        }, 3000);
    });
});

// create a network
var container = $('#tree-simple')[0];

var options = {
    autoResize: true,
    manipulation: {
        enabled: true,
        initiallyActive: true,
        addNode: function (nodeData, callback) {
            if (network.body.nodes === {}) {
                inc = 1;
            }
            else {
                inc++;
            }
            nodeData.root = false;
            nodeData.label = inc;
            nodeData.color = '#009688';
            nodeData.font = {
                color: '#fff'
            };
            nodeData.visited = false;
            nodeData.adjacencyList = [];
            nodeData.predecessor = null;
            callback(nodeData);
        },
        editNode: function (nodeData, callback) {
            editNode(nodeData, callback);
        },
        addEdge: function (edgeData, callback) {
            var fromNode = network.body.data.nodes.get().filter(function (x) {
                    return x.id === edgeData.from;
                }
            );
            var toNode = network.body.data.nodes.get().filter(function (x) {
                    return x.id === edgeData.to;
                }
            );
            fromNode[0].adjacencyList.push(toNode[0]);
            if ($('#directed-chechbox').prop('checked')){
                edgeData.arrows = {};
                edgeData.arrows.to = true;
            }
            if (edgeData.from === edgeData.to) {
                var r = confirm('Do you want to connect the node to itself?');
                if (r === true) {
                    callback(edgeData);
                }
            }
            else {
                callback(edgeData);
            }
        },
        editEdge: {
            editWithoutDrag: function (data, callback) {
                editEdgeWithoutDrag(data, callback);
            }
        }
    },
    interaction: {
        navigationButtons: true
    },
    physics: {
        enabled: false
    }
};

network = new Vis.Network(container, [], options);

function bfsRootAnimation(path) {
    var root = findRootNode(path);
    for (var index = 1; index < 3; index++) {
        (function (ind) {
            setTimeout(function () {
                if (ind === 1) {
                    root.visited = true;
                    root.color = '#3f51b5';
                    network = rebuildNetwork(path);
                }
                else {
                    appendToQueue(root.label);
                }
            }, (1000 * ind));
        })(index);
    }
}

// TODO: add code for line animation here instead of keeping 2 different functions
function bfsNodesAnimation(path, iter) {
    var queue = [path[0]];
    for (var index = 0; index < iter; index++) {
        (function (ind) {
            setTimeout(function () {
                var u = queue.shift();
                removeFromQueue();
                if (u && u.adjacencyList && u.adjacencyList.length > 0) {
                    var adjacencyList = u.adjacencyList;
                    for (var index1 = 0; index1 < adjacencyList.length; index1++) {
                        (function (ind1) {
                            setTimeout(function () {
                                if (!adjacencyList[ind1].visited) {
                                    adjacencyList[ind1].visited = true;
                                    adjacencyList[ind1].color = '#3f51b5';
                                    adjacencyList[ind1].predecessor = u;
                                    network = rebuildNetwork(path);
                                    queue.push(adjacencyList[ind1]);
                                    appendToQueue(adjacencyList[ind1].label);
                                }
                            }, (8000 * ind + ind1 * (parseFloat(7800) / adjacencyList.length)));
                        })(index1);
                    }
                }
            }, ((8000 * ind)));
        })(index);
    }
}

function rootCodeLineAnimation() {
    for (var index1 = 0; index1 < 3; index1++) {
        (function (ind1) {
            setTimeout(function () {
                unHighlightCodeLine(ind1 - 1);
                highlightCodeLine(ind1);
            }, (1000 * ind1));
        })(index1);
    }
}

// function bfsNodesCodeLineAnimation(clonePath, iter) {
//     clonePath[0].visited = true;
//     var queue1 = [];
//     queue1.push(clonePath[0]);
//     for (var indexCode = 0; indexCode < iter; indexCode++) {
//         (function (indCode) {
//             setTimeout(function () {
//                 console.log("hit");
//                 var u1 = queue1.shift();
//                 unHighlightAllCodeLines();
//                 highlightMultipleCodeLines([3, 4]);
//                 if (u1 && u1.adjacencyList && u1.adjacencyList.length > 0) {
//                     var adjacencyList1 = u1.adjacencyList;
//                     for (var indexCode1 = 0; indexCode1 < adjacencyList1.length; indexCode1++) {
//                         (function (indCode1) {
//                             setTimeout(function () {
//                                 unHighlightAllCodeLines();
//                                 highlightMultipleCodeLines([3, 5]);
//                                 if (adjacencyList1[indCode1].visited === false) {
//                                     for (var indexCode2 = 0; indexCode2 < 3; indexCode2++) {
//                                         (function (indCode2) {
//                                             setTimeout(function () {
//                                                 unHighlightAllCodeLines();
//                                                 highlightMultipleCodeLines([3, 5, 6]);
//                                                 var d = new Date();
//                                                 console.log(d.getTime());
//                                                 if (indCode2 == 0) {
//                                                     unHighlightAllCodeLines();
//                                                     highlightMultipleCodeLines([3, 5, 6, 7]);
//                                                     adjacencyList1[indCode1].visited = true;
//                                                     adjacencyList1[indCode1].color = '#3f51b5';
//                                                 }
//                                                 else if (indCode2 == 1) {
//                                                     adjacencyList1[indCode1].predecessor = u1;
//                                                     unHighlightAllCodeLines();
//                                                     highlightMultipleCodeLines([3, 5, 6,8]);
//                                                 }
//                                                 else if (indCode2 == 2) {
//                                                     unHighlightAllCodeLines();
//                                                     highlightMultipleCodeLines([3, 5, 6, 9]);
//                                                     queue1.push(adjacencyList1[indCode1]);
//                                                 }
//                                             }, (8000 * indCode + indCode1 * (parseFloat(7900) / adjacencyList1.length) + indCode2 * (parseFloat(7800) / adjacencyList1.length / 3)));
//                                         })(indexCode2);
//                                     }
//                                 }
//                             }, (8000 * indCode + indCode1 * (parseFloat(7900) / adjacencyList1.length)));
//                         })(indexCode1);
//                     }
//                 }
//             }, 8000 * indCode);
//         })(indexCode);
//     }
// }

function getBFSPath(root) {
    var queue = [root];
    var numberOfQueueIterations = 0;
    var path = [root];
    queue.push(root);
    while (queue.length > 0) {
        var u = queue.shift();
        var adjacencyList = u.adjacencyList;
        for (var i = 0; i < adjacencyList.length; i++) {
            if (!adjacencyList[i].visited) {
                adjacencyList[i].visited = true;
                adjacencyList[i].predecessor = u;
                queue.push(adjacencyList[i]);
                path.push(adjacencyList[i]);
            }
        }
        numberOfQueueIterations++;
    }
    return {path: path, iter: numberOfQueueIterations};
}

function highlightCodeLine(number) {
    $('#line-' + number).css('color', 'red');
}

function unHighlightCodeLine(number) {
    $('#line-' + number).css('color', '#3f51b5');
}

function unHighlightAllCodeLines() {
    for (var i = 0; i < 10; i++) {
        unHighlightCodeLine(i);
    }
}

function highlightMultipleCodeLines(array) {
    for (var i = 0; i < array.length; i++) {
        highlightCodeLine(array[i]);
    }
}

function appendToQueue(text) {
    var th = '' + text + '	';
    $('#queue-row').append(th);
}

function removeFromQueue() {
    $('#queue-row').find('th:first').remove();
}

function markAllNodesAsUnvisited(path) {
    for (var i = 0; i < path.length; i++) {
        path[i].visited = false;
    }
    return path;
}

function createAlert(alertText) {
     var alert = "
 <button type='button' class='close' data-dismiss='alert'> x </button> Oh snap! " + alertText + '
';
     $('#algo-panel').prepend(alert);
}

function alertUserThatNoRoot() {
    var alert = "
 \
    <button type='button' class='close' data-dismiss='alert'>x</button> \
    Heads up! You have not selected any \
    root node, so the first node will be automatically set as root. \

";
    return alert;
}

function rebuildNetwork(nodes) {
    var data = {
        nodes: nodes,
        edges: network.body.data.edges
    };

    network.destroy();
    network = new Vis.Network(container, data, options);
    return network;
}

function editEdgeWithoutDrag(data, callback) {
    $('#edge-label-text').removeClass('is-empty');
    $('#edge-label').val(data.label);
    $('#edge-saveButton').click(saveEdgeData.bind(this, data, callback));
    $('#edge-cancelButton').click(cancelEdgeEdit.bind(this,callback));
    $('#close-x').click(cancelEdgeEdit.bind(this,callback));
    $('#edge-popUp').css('display', 'block');
}

function clearEdgePopUp() {
    $('#edge-saveButton').click(null);
    $('#edge-cancelButton').click(null);
    $('#close-x').click(null);
    $('#edge-popUp').css('display', 'none');
}

function cancelEdgeEdit(callback) {
    clearEdgePopUp();
    callback(null);
}

function saveEdgeData(data, callback) {
    if (typeof data.to === 'object')
        data.to = data.to.id;
    if (typeof data.from === 'object')
        data.from = data.from.id;
    data.label = $('#edge-label').val();
    clearEdgePopUp();
    callback(data);
}

function editNode(data, callback) {
    var nodeInData = network.body.data.nodes.get().filter(function (x) {
        return x.id === data.id;
    });
    data.adjacencyList = nodeInData[0].adjacencyList;
    if (data.root) {
        $('#node-root-checkbox').prop('checked', true);
    }
    else {
        $('#node-root-checkbox').prop('checked', false);
    }
    $('#node-label-text').removeClass('is-empty');
    $('#node-label').val(data.label);
    $('#node-saveButton').click(saveNodeData.bind(this, data, callback));
    $('#node-cancelButton').click(cancelNodeEdit.bind(this, callback));
    $('#close-x1').click(cancelNodeEdit.bind(this, callback));
    $('#node-popUp').css('display', 'block');
}

function clearNodePopUp() {
    $('#node-saveButton').click(null);
    $('#node-cancelButton').click(null);
    $('#close-x1').click(null);
    $('#node-popUp').css('display', 'none');
}

function cancelNodeEdit(callback) {
    clearNodePopUp();
    callback(null);
}

function saveNodeData(data, callback) {
    data.label = parseInt($('#node-label').val());
    data.root = $('#node-root-checkbox').prop('checked');
    clearNodePopUp();
    callback(data);
}

function findRootNode(path) {
    for (var i = 0; i < path.length; i++) {
        if (path[i].root) {
            return path[i];
        }
    }
}

function deepCopyPath(path) {
    var returnArray = [];
    for (var i = 0; i < path.length; i++) {
        var node = new Node();
        node.label = path[i].label;
        node.adjacencyList = [];
        for (var j = 0; j < path[i].adjacencyList.length; j++) {
            var nodeTemp = new Node();
            nodeTemp.label = path[i].adjacencyList[j].label;
            nodeTemp.visited = path[i].adjacencyList[j].visited;
            nodeTemp.color = path[i].adjacencyList[j].color;
            nodeTemp.root = path[i].adjacencyList[j].root;
            nodeTemp.font = path[i].adjacencyList[j].font;
            node.adjacencyList.push(nodeTemp);
        }
        node.visited = false;
        node.root = path[i].root;
        node.color = path[i].color;
        node.font = path[i].font;
        returnArray.push(node);
    }
    return returnArray;
}
<commit_msg>added the code line animation into the loop for the nodes<commit_after>var Vis = require('vis');
var remote = require('remote');
var dialog = remote.require('dialog');
var fs = require('fs');

var network;
var inc = 0;

$(document).ready(function () {
    $('#submit-btn').click(function () {
        if (network.body.data.nodes.get().length == 0) {
            createAlert("You have not added any nodes to the graph.");
            return;
        }
        if (network.body.data.edges.get().length == 0) {
            createAlert("You have not added any edges to the graph.");
            return;
        }
        var rootNode = findRootNode(network.body.data.nodes.get());
        if (!rootNode) {
            rootNode = network.body.data.nodes.get()[0];
            rootNode.root = true;
            $("#algo-panel").prepend(alertUserThatNoRoot());
        }
        var obj = getBFSPath(rootNode);
        obj.path = markAllNodesAsUnvisited(obj.path);
        var pathClone = deepCopyPath(obj.path);
        bfsRootAnimation(obj.path);
        rootCodeLineAnimation();
        setTimeout(function () {
            bfsNodesAnimation(obj.path, obj.iter);
        }, 3000);
    });
});

// create a network
var container = $('#tree-simple')[0];

var options = {
    autoResize: true,
    manipulation: {
        enabled: true,
        initiallyActive: true,
        addNode: function (nodeData, callback) {
            if (network.body.nodes === {}) {
                inc = 1;
            }
            else {
                inc++;
            }
            nodeData.root = false;
            nodeData.label = inc;
            nodeData.color = '#009688';
            nodeData.font = {
                color: '#fff'
            };
            nodeData.visited = false;
            nodeData.adjacencyList = [];
            nodeData.predecessor = null;
            callback(nodeData);
        },
        editNode: function (nodeData, callback) {
            editNode(nodeData, callback);
        },
        addEdge: function (edgeData, callback) {
            var fromNode = network.body.data.nodes.get().filter(function (x) {
                    return x.id === edgeData.from;
                }
            );
            var toNode = network.body.data.nodes.get().filter(function (x) {
                    return x.id === edgeData.to;
                }
            );
            fromNode[0].adjacencyList.push(toNode[0]);
            if ($('#directed-chechbox').prop('checked')){
                edgeData.arrows = {};
                edgeData.arrows.to = true;
            }
            if (edgeData.from === edgeData.to) {
                var r = confirm('Do you want to connect the node to itself?');
                if (r === true) {
                    callback(edgeData);
                }
            }
            else {
                callback(edgeData);
            }
        },
        editEdge: {
            editWithoutDrag: function (data, callback) {
                editEdgeWithoutDrag(data, callback);
            }
        }
    },
    interaction: {
        navigationButtons: true
    },
    physics: {
        enabled: false
    }
};

network = new Vis.Network(container, [], options);

function bfsRootAnimation(path) {
    var root = findRootNode(path);
    for (var index = 1; index < 3; index++) {
        (function (ind) {
            setTimeout(function () {
                if (ind === 1) {
                    root.visited = true;
                    root.color = '#3f51b5';
                    network = rebuildNetwork(path);
                }
                else {
                    appendToQueue(root.label);
                }
            }, (1000 * ind));
        })(index);
    }
}

// TODO: add code for line animation here instead of keeping 2 different functions
function bfsNodesAnimation(path, iter) {
    var queue = [path[0]];
    highlightCodeLine(3);
    for (var index = 0; index < iter; index++) {
        (function (ind) {
            setTimeout(function () {
                var u = queue.shift();
                highlightCodeLine(4);
                removeFromQueue();
                if (u && u.adjacencyList && u.adjacencyList.length > 0) {
                    var adjacencyList = u.adjacencyList;
                    for (var index1 = 0; index1 < adjacencyList.length; index1++) {
                        (function (ind1) {
                            setTimeout(function () {
                                unHighlightCodeLine(4);
                                unHighlightCodeLine(9);
                                highlightCodeLine(5);
                                if (!adjacencyList[ind1].visited) {
                                    for (var index2 = 0; index2 < 3; index2++) {
                                        (function (ind2) {
                                            setTimeout(function() {
                                                highlightCodeLine(6);
                                                if (ind2 == 0) {
                                                    adjacencyList[ind1].predecessor = u;
                                                    highlightCodeLine(7);
                                                }
                                                else if (ind2 == 1) {
                                                    adjacencyList[ind1].visited = true;
                                                    adjacencyList[ind1].color = '#3f51b5';
                                                    network = rebuildNetwork(path);
                                                    unHighlightCodeLine(7);
                                                    highlightCodeLine(8)
                                                }
                                                else {
                                                    queue.push(adjacencyList[ind1]);
                                                    appendToQueue(adjacencyList[ind1].label);
                                                    unHighlightCodeLine(8);
                                                    highlightCodeLine(9);
                                                }
                                            }, 8000 * ind + ind1 * (parseFloat(7800) * adjacencyList.length) + ind2 * (parseFloat(7800) / adjacencyList.length) / 3);
                                        })(index2);
                                    }
                                }
                            }, (8000 * ind + ind1 * (parseFloat(7800) / adjacencyList.length)));
                        })(index1);
                    }
                }
            }, ((8000 * ind)));
        })(index);
    }
}

function rootCodeLineAnimation() {
    for (var index1 = 0; index1 < 3; index1++) {
        (function (ind1) {
            setTimeout(function () {
                unHighlightCodeLine(ind1 - 1);
                highlightCodeLine(ind1);
            }, (1000 * ind1));
        })(index1);
    }
}

// function bfsNodesCodeLineAnimation(clonePath, iter) {
//     clonePath[0].visited = true;
//     var queue1 = [];
//     queue1.push(clonePath[0]);
//     for (var indexCode = 0; indexCode < iter; indexCode++) {
//         (function (indCode) {
//             setTimeout(function () {
//                 console.log("hit");
//                 var u1 = queue1.shift();
//                 unHighlightAllCodeLines();
//                 highlightMultipleCodeLines([3, 4]);
//                 if (u1 && u1.adjacencyList && u1.adjacencyList.length > 0) {
//                     var adjacencyList1 = u1.adjacencyList;
//                     for (var indexCode1 = 0; indexCode1 < adjacencyList1.length; indexCode1++) {
//                         (function (indCode1) {
//                             set
//                                 unHighlightAllCodeLines();
//                                 highlightMultipleCodeLines([3, 5]);
//                                 if (adjacencyList1[indCode1].visited === false) {
//                                     for (var indexCode2 = 0; indexCode2 < 3; indexCode2++) {
//                                         (function (indCode2) {
//                                             setTimeout(function () {
//                                                 unHighlightAllCodeLines();
//                                                 highlightMultipleCodeLines([3, 5, 6]);
//                                                 var d = new Date();
//                                                 console.log(d.getTime());
//                                                 if (indCode2 == 0) {
//                                                     unHighlightAllCodeLines();
//                                                     highlightMultipleCodeLines([3, 5, 6, 7]);
//                                                     adjacencyList1[indCode1].visited = true;
//                                                     adjacencyList1[indCode1].color = '#3f51b5';
//                                                 }
//                                                 else if (indCode2 == 1) {
//                                                     adjacencyList1[indCode1].predecessor = u1;
//                                                     unHighlightAllCodeLines();
//                                                     highlightMultipleCodeLines([3, 5, 6,8]);
//                                                 }
//                                                 else if (indCode2 == 2) {
//                                                     unHighlightAllCodeLines();
//                                                     highlightMultipleCodeLines([3, 5, 6, 9]);
//                                                     queue1.push(adjacencyList1[indCode1]);
//                                                 }
//                                             }, (8000 * indCode + indCode1 * (parseFloat(7900) / adjacencyList1.length) + indCode2 * (parseFloat(7800) / adjacencyList1.length / 3)));
//                                         })(indexCode2);
//                                     }
//                                 }
//                             }, (8000 * indCode + indCode1 * (parseFloat(7900) / adjacencyList1.length)));
//                         })(indexCode1);
//                     }
//                 }
//             }, 8000 * indCode);
//         })(indexCode);
//     }
// }

function getBFSPath(root) {
    var queue = [root];
    var numberOfQueueIterations = 0;
    var path = [root];
    queue.push(root);
    while (queue.length > 0) {
        var u = queue.shift();
        var adjacencyList = u.adjacencyList;
        for (var i = 0; i < adjacencyList.length; i++) {
            if (!adjacencyList[i].visited) {
                adjacencyList[i].visited = true;
                adjacencyList[i].predecessor = u;
                queue.push(adjacencyList[i]);
                path.push(adjacencyList[i]);
            }
        }
        numberOfQueueIterations++;
    }
    return {path: path, iter: numberOfQueueIterations};
}

function highlightCodeLine(number) {
    $('#line-' + number).css('color', 'red');
}

function unHighlightCodeLine(number) {
    $('#line-' + number).css('color', '#3f51b5');
}

function unHighlightAllCodeLines() {
    for (var i = 0; i < 10; i++) {
        unHighlightCodeLine(i);
    }
}

function highlightMultipleCodeLines(array) {
    for (var i = 0; i < array.length; i++) {
        highlightCodeLine(array[i]);
    }
}

function appendToQueue(text) {
    var th = '' + text + '	';
    $('#queue-row').append(th);
}

function removeFromQueue() {
    $('#queue-row').find('th:first').remove();
}

function markAllNodesAsUnvisited(path) {
    for (var i = 0; i < path.length; i++) {
        path[i].visited = false;
    }
    return path;
}

function createAlert(alertText) {
     var alert = "
 <button type='button' class='close' data-dismiss='alert'> x </button> Oh snap! " + alertText + '
';
     $('#algo-panel').prepend(alert);
}

function alertUserThatNoRoot() {
    var alert = "
 \
    <button type='button' class='close' data-dismiss='alert'>x</button> \
    Heads up! You have not selected any \
    root node, so the first node will be automatically set as root. \

";
    return alert;
}

function rebuildNetwork(nodes) {
    var data = {
        nodes: nodes,
        edges: network.body.data.edges
    };

    network.destroy();
    network = new Vis.Network(container, data, options);
    return network;
}

function editEdgeWithoutDrag(data, callback) {
    $('#edge-label-text').removeClass('is-empty');
    $('#edge-label').val(data.label);
    $('#edge-saveButton').click(saveEdgeData.bind(this, data, callback));
    $('#edge-cancelButton').click(cancelEdgeEdit.bind(this,callback));
    $('#close-x').click(cancelEdgeEdit.bind(this,callback));
    $('#edge-popUp').css('display', 'block');
}

function clearEdgePopUp() {
    $('#edge-saveButton').click(null);
    $('#edge-cancelButton').click(null);
    $('#close-x').click(null);
    $('#edge-popUp').css('display', 'none');
}

function cancelEdgeEdit(callback) {
    clearEdgePopUp();
    callback(null);
}

function saveEdgeData(data, callback) {
    if (typeof data.to === 'object')
        data.to = data.to.id;
    if (typeof data.from === 'object')
        data.from = data.from.id;
    data.label = $('#edge-label').val();
    clearEdgePopUp();
    callback(data);
}

function editNode(data, callback) {
    var nodeInData = network.body.data.nodes.get().filter(function (x) {
        return x.id === data.id;
    });
    data.adjacencyList = nodeInData[0].adjacencyList;
    if (data.root) {
        $('#node-root-checkbox').prop('checked', true);
    }
    else {
        $('#node-root-checkbox').prop('checked', false);
    }
    $('#node-label-text').removeClass('is-empty');
    $('#node-label').val(data.label);
    $('#node-saveButton').click(saveNodeData.bind(this, data, callback));
    $('#node-cancelButton').click(cancelNodeEdit.bind(this, callback));
    $('#close-x1').click(cancelNodeEdit.bind(this, callback));
    $('#node-popUp').css('display', 'block');
}

function clearNodePopUp() {
    $('#node-saveButton').click(null);
    $('#node-cancelButton').click(null);
    $('#close-x1').click(null);
    $('#node-popUp').css('display', 'none');
}

function cancelNodeEdit(callback) {
    clearNodePopUp();
    callback(null);
}

function saveNodeData(data, callback) {
    data.label = parseInt($('#node-label').val());
    data.root = $('#node-root-checkbox').prop('checked');
    clearNodePopUp();
    callback(data);
}

function findRootNode(path) {
    for (var i = 0; i < path.length; i++) {
        if (path[i].root) {
            return path[i];
        }
    }
}

function deepCopyPath(path) {
    var returnArray = [];
    for (var i = 0; i < path.length; i++) {
        var node = new Node();
        node.label = path[i].label;
        node.adjacencyList = [];
        for (var j = 0; j < path[i].adjacencyList.length; j++) {
            var nodeTemp = new Node();
            nodeTemp.label = path[i].adjacencyList[j].label;
            nodeTemp.visited = path[i].adjacencyList[j].visited;
            nodeTemp.color = path[i].adjacencyList[j].color;
            nodeTemp.root = path[i].adjacencyList[j].root;
            nodeTemp.font = path[i].adjacencyList[j].font;
            node.adjacencyList.push(nodeTemp);
        }
        node.visited = false;
        node.root = path[i].root;
        node.color = path[i].color;
        node.font = path[i].font;
        returnArray.push(node);
    }
    return returnArray;
}
<|endoftext|>


<commit_before>/*
 * CMS.js v1.0.0
 * Copyright 2015 Chris Diana
 * www.cdmedia.github.io/cms.js
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */
'use strict';

var CMS = {

  settings: {
    siteName: 'CMS.js',
    siteTagline: 'Your site tagline',
    siteEmail: 'your_email@example.com',
    siteAuthor: 'Your Name',
    siteUrl: '',
    siteNavItems: [
      { name: 'Github', href: '#', newWindow: false },
      { name: 'About' }
    ],
    pagination: 3,
    postsFolder: 'posts',
    postSnippetLength: 120,
    pagesFolder: 'pages',
    fadeSpeed: 300,
    mainContainer: $(document.getElementsByClassName('cms_main')),
    footerContainer: $(document.getElementsByClassName('cms_footer')),
    footerText: '© ' + new Date().getFullYear() + ' All Rights Reserved.',
    parseSeperator: '---',
    postsOnFrontpage: true,
    pageAsFrontpage: '',
    postsOnUrl: '',
    loader: '
Loading...
',
    get siteAttributes() {
      return [
        { attr: 'title', value: CMS.settings.siteName },
        { attr: '.cms_sitename', value: CMS.settings.siteName },
        { attr: '.cms_tagline', value: CMS.settings.siteTagline },
        { attr: '.cms_footer_text', value: CMS.settings.footerText }
      ];
    },
    mode: 'Github',
    githubUserSettings: {
      username: 'yourusername',
      repo: 'yourrepo',
    },
    githubSettings: {
      branch: 'gh-pages',
      host: 'https://api.github.com'
    }
  },

  posts: [],
  pages: [],
  loaded: {},

  extend: function (target, opts, callback) {
    var next;
    if (typeof opts === 'undefined') {
      opts = target;
      target = CMS;
    }
    for (next in opts) {
      if (Object.prototype.hasOwnProperty.call(opts, next)) {
        target[next] = opts[next];
      }
    }
    callback(); // check user config options
    return target;
  },

  render: function (url) {
    CMS.settings.mainContainer.html('').fadeOut(CMS.settings.fadeSpeed);
    CMS.settings.footerContainer.hide();

    var type = url.split('/')[0];

    var map = {

      // Main view / Frontpage
      '' : function () {
          CMS.renderPosts();
      },

      // Post view / single view
      '#post' : function () {
        var id = url.split('#post/')[1].trim();
        CMS.renderPost(id);
      },

      // Page view
      '#page' : function () {
        var title = url.split('#page/')[1].trim();
        CMS.renderPage(title);
      }

    };

    if (map[type]) {
      map[type]();
    } else {
      // Error view
      var errorMsg = 'Error loading page.';
      CMS.renderError(errorMsg);
    }
  },

  renderPage: function (title) {
    CMS.pages.sort(function (a, b) { return CMS.settings.sortDateOrder ? b.date - a.date : a.date - b.date; });
    CMS.pages.forEach(function (page) {
      if (page.title == title) {

        var tpl = $(document.getElementById('page-template')).html(),
          $tpl = $(tpl);

        $tpl.find('.page-title').html(page.title);
        $tpl.find('.page-content').html(page.contentData);

        CMS.settings.mainContainer.html($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
      }
    });
    CMS.renderFooter();
  },

  renderPost: function (id) {
    CMS.posts.forEach(function (post) {
      if (post.id == id) {

        var tpl = $(document.getElementById('post-template')).html(),
          $tpl = $(tpl);

        $tpl.find('.post-title').html(post.title);
        $tpl.find('.post-date').html((post.date.getUTCMonth() + 1) + '/' + post.date.getUTCDate() + '/' +  post.date.getUTCFullYear());
        $tpl.find('.post-content').html(post.contentData);

        CMS.settings.mainContainer.html($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
      }
    });
    CMS.renderFooter();
  },

  renderPosts: function () {
    CMS.posts.sort(function (a, b) { return CMS.settings.sortDateOrder ? b.date - a.date : a.date - b.date; });
    CMS.posts.forEach(function (post) {
      var tpl = $(document.getElementById('post-template')).html(),
        $tpl = $(tpl);

      var title = '' + post.title + '',
        date = (post.date.getUTCMonth() + 1) + '/' + post.date.getUTCDate() + '/' +  post.date.getUTCFullYear(),
        snippet = post.contentData.split('.')[0] + '.';

      var postLink = $tpl.find('.post-title'),
        postDate = $tpl.find('.post-date'),
        postSnippet = $tpl.find('.post-content');

      postLink.on('click', function (e) {
        e.preventDefault();
        window.location.hash = 'post/' + post.id;
      });

      postLink.html(title);
      postSnippet.html(snippet);
      postDate.html(date);
      CMS.settings.mainContainer.append($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
    });
    CMS.renderFooter();
  },

  renderFooter: function () {
    // Delay footer loading while waiting on ajax requests
    setTimeout(function () {
      CMS.settings.footerContainer.fadeIn(CMS.settings.fadeSpeed);
    }, 800);
  },

  renderError: function (msg) {
    var tpl = $(document.getElementById('error-template')).html(),
      $tpl = $(tpl);

    $tpl.find('.error_text').html(msg);

    CMS.settings.mainContainer.html('').fadeOut(CMS.settings.fadeSpeed, function () {
      CMS.settings.mainContainer.html($tpl).fadeIn(CMS.settings.fadeSpeed);
    });
  },

  contentLoaded: function (type) {

    CMS.loaded[type] = true;

    if (CMS.loaded.page && CMS.loaded.post) {

      // Set navigation
      this.setNavigation();

      // Manually trigger on initial load
      $(window).trigger('hashchange');
    }
  },

  parseContent: function (content, type, file, counter, numFiles) {

    var data = content.split(CMS.settings.parseSeperator),
      contentObj = {},
      id = counter,
      date = file.date;

    contentObj.id = id;
    contentObj.date = date;

    // Get content info
    var infoData = data[1].split(/[\n\r]+/);

    $.each(infoData, function (k, v) {
      if (v.length) {
        v.replace(/^\s+|\s+$/g, '').trim();
        var i = v.split(':');
        var val = v.slice(v.indexOf(':')+1);
        k = i[0];

        val = (k == 'date' ? (new Date(val)) : val);

        contentObj[k] = (val.trim ? val.trim() : val);
      }
    });

    // Drop data we don't need
    data.splice(0, 2);

    // Put everything back together if broken
    var contentData = data.join();
    contentObj.contentData = marked(contentData);

    switch(type) {
      case 'post':
        CMS.posts.push(contentObj);
        break;
      case 'page':
        CMS.pages.push(contentObj);
        break;
    }

    // Execute after all content is loaded
    if (counter === numFiles) {
      CMS.contentLoaded(type);
    }
  },

  getContent: function (type, file, counter, numFiles) {

    var urlFolder = '',
      url;

    switch(type) {
      case 'post':
        urlFolder = CMS.settings.postsFolder;
        break;
      case 'page':
        urlFolder = CMS.settings.pagesFolder;
        break;
    }

    if (CMS.settings.mode == 'Github') {
      url = file.link;
    } else {
      url = file.name.indexOf(urlFolder) > -1 ? file.name : urlFolder + '/' + file.name;
    }

    $.ajax({
      type: 'GET',
      url: url,
      dataType: 'html',
      success: function (content) {
        CMS.parseContent(content, type, file, counter, numFiles);
      },
      error: function () {
        var errorMsg = 'Error loading ' + type + ' content';
        CMS.renderError(errorMsg);
      }
    });
  },

  getFiles: function (type) {

    var folder = '',
      url = '';

    switch(type) {
      case 'post':
        folder = CMS.settings.postsFolder;
        break;
      case 'page':
        folder = CMS.settings.pagesFolder;
        break;
    }

    if (CMS.settings.mode == 'Github') {
      var gus = CMS.settings.githubUserSettings,
        gs = CMS.settings.githubSettings;
      url = gs.host + '/repos/' + gus.username + '/' + gus.repo + '/contents/' + folder + '?ref=' + gs.branch;
    } else {
      url = folder;
    }

    $.ajax({
      url: url,
      success: function (data) {

        var files = [],
          linkFiles,
          dateParser = /\d{4}-\d{2}(?:-\d{2})?/; // can parse both 2016-01 and 2016-01-01

        if (CMS.settings.mode == 'Github') {
          linkFiles = data;
        } else {
          linkFiles = $(data).find('a');
        }

        $(linkFiles).each(function (k, f) {

          var filename,
            downloadLink;

          if (CMS.settings.mode == 'Github') {
            filename = f.name;
            downloadLink = f.download_url;
          } else {
            filename = $(f).attr('href');
          }

          if (filename.split('.').pop() === 'md') {
            var file = {};
            file.date = new Date(dateParser.test(filename) && dateParser.exec(filename)[0]);
            file.name = filename;
            if (downloadLink) {
              file.link = downloadLink;
            }
            files.push(file);
          }

        });

        var counter = 0,
          numFiles = files.length;

        if (numFiles > 0) {
          for (var file of files) {
            counter++;
            CMS.getContent(type, file, counter, numFiles);
          }
        } else {
          var errorMsg = 'Error loading ' + type + 's in directory. Make sure ' +
            'there are Markdown ' + type + 's in the ' + type + 's folder.';
          CMS.renderError(errorMsg);
        }
      },
      error: function () {
        var errorMsg;
        if (CMS.settings.mode == 'Github') {
          errorMsg = 'Error loading ' + type + 's directory. Make sure ' +
            'your Github settings are correctly set in your config.js file.';
        } else {
          errorMsg = 'Error loading the ' + type + 's directory. Make sure ' +
            'the ' + type + 's directory is set correctly in config and  ' +
            'the ' + type + 's directory indexing feature is enabled.';
        }
        CMS.renderError(errorMsg);
      }
    });
  },

  setNavigation: function () {

    var navBuilder = ['
'];
    CMS.settings.siteNavItems.forEach(function (navItem) {
      if (navItem.hasOwnProperty('href')) {
        navBuilder.push('
', navItem.name, '
');
      } else {
        CMS.pages.forEach(function (page) {
          if (navItem.name == page.title) {
            navBuilder.push('
', navItem.name, '
');
          }
        });
      }
    });
    navBuilder.push('
');
    var nav = navBuilder.join('');

    $(document.getElementsByClassName('cms_nav')).html(nav);

    // Set onclicks for nav links
    $.each($(document.getElementsByClassName('cms_nav_link')), function (k, link) {
      var title = $(this).attr('id');
      $(this).on('click', function (e) {
        e.preventDefault();
        window.location.hash = 'page/' + title;
      });
    });
  },

  setSiteAttributes: function () {
    CMS.settings.siteAttributes.forEach(function (attribute) {

      var value;

      // Set brand
      if (attribute.attr == '.cms_sitename' && attribute.value.match(/\.(jpeg|jpg|gif|png)$/)) {
        value = '';
      } else {
        value = attribute.value;
      }
      $(attribute.attr).html(value).hide().fadeIn(CMS.settings.fadeSpeed);
    });
  },

  generateSite: function () {

    this.setSiteAttributes();

    var types = ['post', 'page'];

    types.forEach(function (type) {
      CMS.getFiles(type);
    });

    // Check for hash changes
    $(window).on('hashchange', function () {
      CMS.render(window.location.hash);
    });
  },

  init: function (options) {
    if (!(options instanceof Array)) {
      return this.extend(this.settings, options, function () {
        CMS.generateSite();
      });
    }
  }

};
<commit_msg>fix for cdmedia issue #65 async load of pages results in incorrect display of navigation bar as setNavigation() is called prematurelly. if last page is first to load, couter === numFiles<commit_after>/*
 * CMS.js v1.0.0
 * Copyright 2015 Chris Diana
 * www.cdmedia.github.io/cms.js
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */
'use strict';

var CMS = {

  settings: {
    siteName: 'CMS.js',
    siteTagline: 'Your site tagline',
    siteEmail: 'your_email@example.com',
    siteAuthor: 'Your Name',
    siteUrl: '',
    siteNavItems: [
      { name: 'Github', href: '#', newWindow: false },
      { name: 'About' }
    ],
    pagination: 3,
    postsFolder: 'posts',
    postSnippetLength: 120,
    pagesFolder: 'pages',
    fadeSpeed: 300,
    mainContainer: $(document.getElementsByClassName('cms_main')),
    footerContainer: $(document.getElementsByClassName('cms_footer')),
    footerText: '© ' + new Date().getFullYear() + ' All Rights Reserved.',
    parseSeperator: '---',
    postsOnFrontpage: true,
    pageAsFrontpage: '',
    postsOnUrl: '',
    loader: '
Loading...
',
    get siteAttributes() {
      return [
        { attr: 'title', value: CMS.settings.siteName },
        { attr: '.cms_sitename', value: CMS.settings.siteName },
        { attr: '.cms_tagline', value: CMS.settings.siteTagline },
        { attr: '.cms_footer_text', value: CMS.settings.footerText }
      ];
    },
    mode: 'Github',
    githubUserSettings: {
      username: 'yourusername',
      repo: 'yourrepo',
    },
    githubSettings: {
      branch: 'gh-pages',
      host: 'https://api.github.com'
    }
  },

  posts: [],
  pages: [],
  loaded: {},

  extend: function (target, opts, callback) {
    var next;
    if (typeof opts === 'undefined') {
      opts = target;
      target = CMS;
    }
    for (next in opts) {
      if (Object.prototype.hasOwnProperty.call(opts, next)) {
        target[next] = opts[next];
      }
    }
    callback(); // check user config options
    return target;
  },

  render: function (url) {
    CMS.settings.mainContainer.html('').fadeOut(CMS.settings.fadeSpeed);
    CMS.settings.footerContainer.hide();

    var type = url.split('/')[0];

    var map = {

      // Main view / Frontpage
      '' : function () {
          CMS.renderPosts();
      },

      // Post view / single view
      '#post' : function () {
        var id = url.split('#post/')[1].trim();
        CMS.renderPost(id);
      },

      // Page view
      '#page' : function () {
        var title = url.split('#page/')[1].trim();
        CMS.renderPage(title);
      }

    };

    if (map[type]) {
      map[type]();
    } else {
      // Error view
      var errorMsg = 'Error loading page.';
      CMS.renderError(errorMsg);
    }
  },

  renderPage: function (title) {
    CMS.pages.sort(function (a, b) { return CMS.settings.sortDateOrder ? b.date - a.date : a.date - b.date; });
    CMS.pages.forEach(function (page) {
      if (page.title == title) {

        var tpl = $(document.getElementById('page-template')).html(),
          $tpl = $(tpl);

        $tpl.find('.page-title').html(page.title);
        $tpl.find('.page-content').html(page.contentData);

        CMS.settings.mainContainer.html($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
      }
    });
    CMS.renderFooter();
  },

  renderPost: function (id) {
    CMS.posts.forEach(function (post) {
      if (post.id == id) {

        var tpl = $(document.getElementById('post-template')).html(),
          $tpl = $(tpl);

        $tpl.find('.post-title').html(post.title);
        $tpl.find('.post-date').html((post.date.getUTCMonth() + 1) + '/' + post.date.getUTCDate() + '/' +  post.date.getUTCFullYear());
        $tpl.find('.post-content').html(post.contentData);

        CMS.settings.mainContainer.html($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
      }
    });
    CMS.renderFooter();
  },

  renderPosts: function () {
    CMS.posts.sort(function (a, b) { return CMS.settings.sortDateOrder ? b.date - a.date : a.date - b.date; });
    CMS.posts.forEach(function (post) {
      var tpl = $(document.getElementById('post-template')).html(),
        $tpl = $(tpl);

      var title = '' + post.title + '',
        date = (post.date.getUTCMonth() + 1) + '/' + post.date.getUTCDate() + '/' +  post.date.getUTCFullYear(),
        snippet = post.contentData.split('.')[0] + '.';

      var postLink = $tpl.find('.post-title'),
        postDate = $tpl.find('.post-date'),
        postSnippet = $tpl.find('.post-content');

      postLink.on('click', function (e) {
        e.preventDefault();
        window.location.hash = 'post/' + post.id;
      });

      postLink.html(title);
      postSnippet.html(snippet);
      postDate.html(date);
      CMS.settings.mainContainer.append($tpl).hide().fadeIn(CMS.settings.fadeSpeed);
    });
    CMS.renderFooter();
  },

  renderFooter: function () {
    // Delay footer loading while waiting on ajax requests
    setTimeout(function () {
      CMS.settings.footerContainer.fadeIn(CMS.settings.fadeSpeed);
    }, 800);
  },

  renderError: function (msg) {
    var tpl = $(document.getElementById('error-template')).html(),
      $tpl = $(tpl);

    $tpl.find('.error_text').html(msg);

    CMS.settings.mainContainer.html('').fadeOut(CMS.settings.fadeSpeed, function () {
      CMS.settings.mainContainer.html($tpl).fadeIn(CMS.settings.fadeSpeed);
    });
  },

  contentLoaded: function (type) {

    CMS.loaded[type] = true;

    if (CMS.loaded.page && CMS.loaded.post) {

      // Set navigation
      this.setNavigation();

      // Manually trigger on initial load
      $(window).trigger('hashchange');
    }
  },

  parseContent: function (content, type, file, counter, numFiles) {

    var data = content.split(CMS.settings.parseSeperator),
      contentObj = {},
      id = counter,
      date = file.date;

    contentObj.id = id;
    contentObj.date = date;

    // Get content info
    var infoData = data[1].split(/[\n\r]+/);

    $.each(infoData, function (k, v) {
      if (v.length) {
        v.replace(/^\s+|\s+$/g, '').trim();
        var i = v.split(':');
        var val = v.slice(v.indexOf(':')+1);
        k = i[0];

        val = (k == 'date' ? (new Date(val)) : val);

        contentObj[k] = (val.trim ? val.trim() : val);
      }
    });

    // Drop data we don't need
    data.splice(0, 2);

    // Put everything back together if broken
    var contentData = data.join();
    contentObj.contentData = marked(contentData);

    switch(type) {
      case 'post':
        CMS.posts.push(contentObj);
        break;
      case 'page':
        CMS.pages.push(contentObj);
        break;
    }

    // Execute after all content is loaded
    if (CMS[type + 's'].length === numFiles) {
      CMS.contentLoaded(type);
    }
  },

  getContent: function (type, file, counter, numFiles) {

    var urlFolder = '',
      url;

    switch(type) {
      case 'post':
        urlFolder = CMS.settings.postsFolder;
        break;
      case 'page':
        urlFolder = CMS.settings.pagesFolder;
        break;
    }

    if (CMS.settings.mode == 'Github') {
      url = file.link;
    } else {
      url = file.name.indexOf(urlFolder) > -1 ? file.name : urlFolder + '/' + file.name;
    }

    $.ajax({
      type: 'GET',
      url: url,
      dataType: 'html',
      success: function (content) {
        CMS.parseContent(content, type, file, counter, numFiles);
      },
      error: function () {
        var errorMsg = 'Error loading ' + type + ' content';
        CMS.renderError(errorMsg);
      }
    });
  },

  getFiles: function (type) {

    var folder = '',
      url = '';

    switch(type) {
      case 'post':
        folder = CMS.settings.postsFolder;
        break;
      case 'page':
        folder = CMS.settings.pagesFolder;
        break;
    }

    if (CMS.settings.mode == 'Github') {
      var gus = CMS.settings.githubUserSettings,
        gs = CMS.settings.githubSettings;
      url = gs.host + '/repos/' + gus.username + '/' + gus.repo + '/contents/' + folder + '?ref=' + gs.branch;
    } else {
      url = folder;
    }

    $.ajax({
      url: url,
      success: function (data) {

        var files = [],
          linkFiles,
          dateParser = /\d{4}-\d{2}(?:-\d{2})?/; // can parse both 2016-01 and 2016-01-01

        if (CMS.settings.mode == 'Github') {
          linkFiles = data;
        } else {
          linkFiles = $(data).find('a');
        }

        $(linkFiles).each(function (k, f) {

          var filename,
            downloadLink;

          if (CMS.settings.mode == 'Github') {
            filename = f.name;
            downloadLink = f.download_url;
          } else {
            filename = $(f).attr('href');
          }

          if (filename.split('.').pop() === 'md') {
            var file = {};
            file.date = new Date(dateParser.test(filename) && dateParser.exec(filename)[0]);
            file.name = filename;
            if (downloadLink) {
              file.link = downloadLink;
            }
            files.push(file);
          }

        });

        var counter = 0,
          numFiles = files.length;

        if (numFiles > 0) {
          for (var file of files) {
            counter++;
            CMS.getContent(type, file, counter, numFiles);
          }
        } else {
          var errorMsg = 'Error loading ' + type + 's in directory. Make sure ' +
            'there are Markdown ' + type + 's in the ' + type + 's folder.';
          CMS.renderError(errorMsg);
        }
      },
      error: function () {
        var errorMsg;
        if (CMS.settings.mode == 'Github') {
          errorMsg = 'Error loading ' + type + 's directory. Make sure ' +
            'your Github settings are correctly set in your config.js file.';
        } else {
          errorMsg = 'Error loading the ' + type + 's directory. Make sure ' +
            'the ' + type + 's directory is set correctly in config and  ' +
            'the ' + type + 's directory indexing feature is enabled.';
        }
        CMS.renderError(errorMsg);
      }
    });
  },

  setNavigation: function () {

    var navBuilder = ['
'];
    CMS.settings.siteNavItems.forEach(function (navItem) {
      if (navItem.hasOwnProperty('href')) {
        navBuilder.push('
', navItem.name, '
');
      } else {
        CMS.pages.forEach(function (page) {
          if (navItem.name == page.title) {
            navBuilder.push('
', navItem.name, '
');
          }
        });
      }
    });
    navBuilder.push('
');
    var nav = navBuilder.join('');

    $(document.getElementsByClassName('cms_nav')).html(nav);

    // Set onclicks for nav links
    $.each($(document.getElementsByClassName('cms_nav_link')), function (k, link) {
      var title = $(this).attr('id');
      $(this).on('click', function (e) {
        e.preventDefault();
        window.location.hash = 'page/' + title;
      });
    });
  },

  setSiteAttributes: function () {
    CMS.settings.siteAttributes.forEach(function (attribute) {

      var value;

      // Set brand
      if (attribute.attr == '.cms_sitename' && attribute.value.match(/\.(jpeg|jpg|gif|png)$/)) {
        value = '';
      } else {
        value = attribute.value;
      }
      $(attribute.attr).html(value).hide().fadeIn(CMS.settings.fadeSpeed);
    });
  },

  generateSite: function () {

    this.setSiteAttributes();

    var types = ['post', 'page'];

    types.forEach(function (type) {
      CMS.getFiles(type);
    });

    // Check for hash changes
    $(window).on('hashchange', function () {
      CMS.render(window.location.hash);
    });
  },

  init: function (options) {
    if (!(options instanceof Array)) {
      return this.extend(this.settings, options, function () {
        CMS.generateSite();
      });
    }
  }

};
<|endoftext|>


<commit_before>/**
 * @private
 * @flow
 */

import EventEmitter from 'events';
import * as util from 'silk-sysutils';

/**
 * Silk volume module
 *
 * @module silk-volume
 * @example
 * const volume = require('silk-volume').default;
 * volume.level = 50;
 * volume.mute = false;
 */
class Volume extends EventEmitter {
  _level: number;
  _mute: boolean;

  constructor() {
    super();
    this._level = util.getintprop('persist.silk.volume.level', 0);
    this._mute = util.getboolprop('persist.silk.volume.mute', false);
  }

  /**
   * Gets the current volume level (0..100).  Note that the value returned is
   * unaffected by the active mute setting.
   *
   * @memberof silk-volume
   * @instance
   */
  get level(): number {
    return this._level;
  }

  /**
   * Sets the current volume level (0..100)
   *
   * @memberof silk-volume
   * @instance
   */
  set level(newlevel: number): void {
    if (newlevel < 0 || newlevel > 100) {
      throw new Error('Invalid volume level', newlevel);
    }
    this._level = newlevel;
    util.setprop('persist.silk.volume.level', newlevel);

    /**
     * Emitted when the volume level changes
     *
     * @event level
     * @param {number} Level volume level
     * @memberof silk-volume
     * @instance
     */
    this._throwyEmit('level', newlevel);
  }

  /**
   * Gets the current volume mute
   *
   * @memberof silk-volume
   * @instance
   */
  get mute(): boolean {
    return this._mute;
  }

  /**
   * Sets the current volume mute
   *
   * @memberof silk-volume
   * @instance
   */
  set mute(newmute: boolean): void {
    this._mute = newmute;
    util.setprop('persist.silk.volume.mute', newmute);

    /**
     * Emitted when the volume mute changes
     *
     * @event mute
     * @param {bool} Mute enabled or disabled
     * @memberof silk-volume
     * @instance
     */
    this._throwyEmit('mute', newmute);
  }

  /**
   * Emit an event, and re-throw any exceptions to the process once the current
   * call stack is unwound.
   *
   * @private
   */
  // Legitimate use of 'any' here based on the fact that Flow's library
  // definition for EventEmitter uses it.
  // eslint-disable-next-line flowtype/no-weak-types
  _throwyEmit(eventName: string, ...args: any): void {
    try {
      this.emit(eventName, ...args);
    } catch (err) {
      process.nextTick(() => {
        util.processthrow(err.stack || err);
      });
    }
  }
}

let volume = new Volume();
export default volume;
<commit_msg>silk-volume: match args type to that of EventEmitter.emit()<commit_after>/**
 * @private
 * @flow
 */

import EventEmitter from 'events';
import * as util from 'silk-sysutils';

/**
 * Silk volume module
 *
 * @module silk-volume
 * @example
 * const volume = require('silk-volume').default;
 * volume.level = 50;
 * volume.mute = false;
 */
class Volume extends EventEmitter {
  _level: number;
  _mute: boolean;

  constructor() {
    super();
    this._level = util.getintprop('persist.silk.volume.level', 0);
    this._mute = util.getboolprop('persist.silk.volume.mute', false);
  }

  /**
   * Gets the current volume level (0..100).  Note that the value returned is
   * unaffected by the active mute setting.
   *
   * @memberof silk-volume
   * @instance
   */
  get level(): number {
    return this._level;
  }

  /**
   * Sets the current volume level (0..100)
   *
   * @memberof silk-volume
   * @instance
   */
  set level(newlevel: number): void {
    if (newlevel < 0 || newlevel > 100) {
      throw new Error('Invalid volume level', newlevel);
    }
    this._level = newlevel;
    util.setprop('persist.silk.volume.level', newlevel);

    /**
     * Emitted when the volume level changes
     *
     * @event level
     * @param {number} Level volume level
     * @memberof silk-volume
     * @instance
     */
    this._throwyEmit('level', newlevel);
  }

  /**
   * Gets the current volume mute
   *
   * @memberof silk-volume
   * @instance
   */
  get mute(): boolean {
    return this._mute;
  }

  /**
   * Sets the current volume mute
   *
   * @memberof silk-volume
   * @instance
   */
  set mute(newmute: boolean): void {
    this._mute = newmute;
    util.setprop('persist.silk.volume.mute', newmute);

    /**
     * Emitted when the volume mute changes
     *
     * @event mute
     * @param {bool} Mute enabled or disabled
     * @memberof silk-volume
     * @instance
     */
    this._throwyEmit('mute', newmute);
  }

  /**
   * Emit an event, and re-throw any exceptions to the process once the current
   * call stack is unwound.
   *
   * @private
   */
  // Legitimate use of 'any' here based on the fact that Flow's library
  // definition for EventEmitter uses it.
  // eslint-disable-next-line flowtype/no-weak-types
  _throwyEmit(eventName: string, ...args: Array<any>): void {
    try {
      this.emit(eventName, ...args);
    } catch (err) {
      process.nextTick(() => {
        util.processthrow(err.stack || err);
      });
    }
  }
}

let volume = new Volume();
export default volume;
<|endoftext|>


<commit_before>var map = L.map('map');
map.addLayer(new L.Google('ROADMAP'));

otp.metadata.then(function(data) {
  map.setView([data.centerLatitude, data.centerLongitude], 12);
});

var progress = new Ractive({
  el: '#search',
  append: true,
  template: ' {{#loading}}loading{{/loading}}'
})
progress.setLoading = function(loading) {
  this.set('loading', loading);
}

var search = new Ractive({
  el: '#search',
  template: '#searchTemplate',
});
search.layer = L.layerGroup([]).addTo(map);

search.on({
  clearSearch: function(event) {
    this.layer.clearLayers();
  },
});

(function() {
  var self = search;
  var input = document.getElementById("query");
  var searchBox = new google.maps.places.SearchBox(input);

  google.maps.event.addListener(searchBox, 'places_changed', function() {
    search.fire('clearSearch');
    var places = searchBox.getPlaces();
    var first = true;
    places.forEach(function(place) {
      var latlng = g2lLatLng(place.geometry.location);
      var marker = L.marker(latlng);
      var popup = new Popup(marker);
      marker.addTo(self.layer);
      if(first) {
        marker.openPopup();
        map.setView(latlng, 14);
      }
    });
  });

  map.on('moveend', function() {
    var bounds = l2gBounds(map.getBounds());
    searchBox.setBounds(bounds);
  });
})();

var Popup = (function() {
  var _class = Ractive.extend({
    template: '#popupTemplate',
    init: function() {
      var self = this;

      function setSomething(a, b) {
        return function(event) {
          var targets = router.get('targets');
          search.fire('clearSearch');
          var latlng = this.get('latlng');

          var marker;
          if(targets[a]) {
            marker = targets[a];
            marker.setLatLng(latlng);
            marker.unbindPopup();
          }
          else {
            marker = L.marker(latlng);
          }

          var popup = new Popup(marker);

          if(!targets[a]) {
            marker.addTo(map);
            targets[a] = marker;
          }

          geocoder.fromLatLng(self.get('latlng')).then(function(data) {
            var address = data[0].formatted_address;
            router.set('targets.'+a+'Address', address);
          });

          if(targets[b]) {
            if(targets[b].getLatLng() == latlng) { // handle setting start as destination
              map.removeLayer(targets[b]);
              targets[b] = null;
            }
          }
          router.update('targets');
          map.closePopup();
        }
      }

      this.on({
        setStart: setSomething('from', 'to'),
        setEnd: setSomething('to', 'from')
      });

      geocoder.fromLatLng(self.get('latlng')).then(function(data) {
        var address = data[0].formatted_address;
        self.set('address', address);
      });
    },
    open: function() {
      map.openPopup(this.el, this.get('latlng'));
    },
    bindTo: function(marker) {
      marker.bindPopup(this.el);
    }
  });
  return function(pos) {
    var latlng = pos;
    if(pos.constructor == L.Marker) {
      latlng = pos.getLatLng();
    }
    var popup = new _class({
      el: document.createElement('div'),
      data: {
        latlng: latlng
      }
    });
    if(pos.constructor == L.Marker) {
      popup.bindTo(pos);
    }
    return popup;
  }
})();

map.on('contextmenu', function(event) {
  var popup = new Popup(event.latlng);
  popup.open();
});

var itinerary = new Ractive({
  el: '#itinerary',
  template: '#itineraryTemplate',
  debug: true,
  data: {
    f: formatDuration,
    formatDirection: function(dir) {
      return dir.toLowerCase().replace('_', ' ');
    },
    isTransit: function(mode) {
      return mode == 'JEEP' || mode == 'BUS' || mode == 'RAIL';
    },
  }
});
itinerary.on({
  showSteps: function(event) {
    var path = event.keypath+'.showSteps';
    this.set(path, !this.get(path));
  },
  hover: function(event, index) {
    var leg = this.get('current').legs[index];
    if(event.hover) {
      if(leg.polyline == undefined) {
        leg.polyline = L.polyline(leg.points, {
          color: 'yellow',
          weight: 7
        });
      }
      leg.polyline.addTo(router.layer);
    }
    else {
      map.removeLayer(leg.polyline);
    }
  }
})

var router = new Ractive({
  el: '#routes',
  template: '#routerTemplate',
  debug: true,
  data: {
    f: formatDuration,
    targets: {
      mode: 'TRANSIT,WALK'
    }
  }
});
router.layer = L.layerGroup([]).addTo(map);
router.reset = function() {
  this.layer.clearLayers();
  this.routeLine = L.multiPolyline([]).addTo(this.layer);
}
router.getPoints = function(index) {
  var results = this.get('results');
  var lines = [];
  results[index].legs.forEach(function(leg) {
    lines.push(leg.points);
  });
  return lines;
}
router.showRoute = function(index) {
  this.routeLine.setLatLngs(this.getPoints(index));
  this.unhighlightRoute(index);
  map.fitBounds(this.routeLine.getBounds(), { padding: [10, 10] });
}
router.highlightRoute = function(index) {
  var route = this.get('results')[index];
  if(route.polyline == undefined) {
    route.polyline = L.multiPolyline(this.getPoints(index), {
      color: 'red'
    });
  }
  route.polyline.addTo(this.layer);
}
router.unhighlightRoute = function(index) {
  var polyline = this.get('results')[index].polyline;
  if(this.layer.hasLayer(polyline)) {
    this.layer.removeLayer(polyline);
  }
}

router.observe('selected', function(val) {
  if(val == undefined || val < 0) return;
  var results = this.get('results');
  itinerary.set('current', results[val]);
  this.showRoute(val);
});

router.observe('targets', function(targets) {
  if(!targets.from || !targets.to) return;
  var self = this;
  progress.setLoading(true);
  otp.route(
    targets.from.getLatLng(),
    targets.to.getLatLng(),
    targets.mode
  )
  .then(function(data) {
    self.reset();
    if(data.plan) {
      var results = data.plan.itineraries;
      results.forEach(function(itinerary) {
        itinerary.legs.forEach(function(leg) {
          leg.points = decodePoints(leg.legGeometry.points);
          if(leg.mode == 'BUS' && leg.routeId.indexOf('PUJ') >= 0) {
            leg.mode = 'JEEP';
          }

          leg.fare = calculateFare(leg);
        });
      });
      self.set('results', results);
      self.set('selected', -1);
      self.set('selected', 0);
    }
    else {
      self.set('results', null);
      itinerary.set('current', null);
    }
  })
  .fin(function() {
    progress.setLoading(false);
  });
});

router.on({
  select: function(event, index) {
    this.set('selected', index);
  },
  swap: function(event) {
    var targets = this.get('targets');
    var tmp = targets.from;
    targets.from = targets.to;
    targets.to = tmp;
    tmp = targets.fromAddress;
    targets.fromAddress = targets.toAddress;
    targets.toAddress = tmp;
    this.update('targets');
  },
  hover: function(event, index) {
    if(index != this.get('selected')) {
      if(event.hover) {
        this.highlightRoute(index);
      }
      else {
        this.unhighlightRoute(index);
      }
    }
  }
});
<commit_msg>Fix undefined error when switching routes<commit_after>var map = L.map('map');
map.addLayer(new L.Google('ROADMAP'));

otp.metadata.then(function(data) {
  map.setView([data.centerLatitude, data.centerLongitude], 12);
});

var progress = new Ractive({
  el: '#search',
  append: true,
  template: ' {{#loading}}loading{{/loading}}'
})
progress.setLoading = function(loading) {
  this.set('loading', loading);
}

var search = new Ractive({
  el: '#search',
  template: '#searchTemplate',
});
search.layer = L.layerGroup([]).addTo(map);

search.on({
  clearSearch: function(event) {
    this.layer.clearLayers();
  },
});

(function() {
  var self = search;
  var input = document.getElementById("query");
  var searchBox = new google.maps.places.SearchBox(input);

  google.maps.event.addListener(searchBox, 'places_changed', function() {
    search.fire('clearSearch');
    var places = searchBox.getPlaces();
    var first = true;
    places.forEach(function(place) {
      var latlng = g2lLatLng(place.geometry.location);
      var marker = L.marker(latlng);
      var popup = new Popup(marker);
      marker.addTo(self.layer);
      if(first) {
        marker.openPopup();
        map.setView(latlng, 14);
      }
    });
  });

  map.on('moveend', function() {
    var bounds = l2gBounds(map.getBounds());
    searchBox.setBounds(bounds);
  });
})();

var Popup = (function() {
  var _class = Ractive.extend({
    template: '#popupTemplate',
    init: function() {
      var self = this;

      function setSomething(a, b) {
        return function(event) {
          var targets = router.get('targets');
          search.fire('clearSearch');
          var latlng = this.get('latlng');

          var marker;
          if(targets[a]) {
            marker = targets[a];
            marker.setLatLng(latlng);
            marker.unbindPopup();
          }
          else {
            marker = L.marker(latlng);
          }

          var popup = new Popup(marker);

          if(!targets[a]) {
            marker.addTo(map);
            targets[a] = marker;
          }

          geocoder.fromLatLng(self.get('latlng')).then(function(data) {
            var address = data[0].formatted_address;
            router.set('targets.'+a+'Address', address);
          });

          if(targets[b]) {
            if(targets[b].getLatLng() == latlng) { // handle setting start as destination
              map.removeLayer(targets[b]);
              targets[b] = null;
            }
          }
          router.update('targets');
          map.closePopup();
        }
      }

      this.on({
        setStart: setSomething('from', 'to'),
        setEnd: setSomething('to', 'from')
      });

      geocoder.fromLatLng(self.get('latlng')).then(function(data) {
        var address = data[0].formatted_address;
        self.set('address', address);
      });
    },
    open: function() {
      map.openPopup(this.el, this.get('latlng'));
    },
    bindTo: function(marker) {
      marker.bindPopup(this.el);
    }
  });
  return function(pos) {
    var latlng = pos;
    if(pos.constructor == L.Marker) {
      latlng = pos.getLatLng();
    }
    var popup = new _class({
      el: document.createElement('div'),
      data: {
        latlng: latlng
      }
    });
    if(pos.constructor == L.Marker) {
      popup.bindTo(pos);
    }
    return popup;
  }
})();

map.on('contextmenu', function(event) {
  var popup = new Popup(event.latlng);
  popup.open();
});

var itinerary = new Ractive({
  el: '#itinerary',
  template: '#itineraryTemplate',
  debug: true,
  data: {
    f: formatDuration,
    formatDirection: function(dir) {
      if(dir == undefined) return '';
      return dir.toLowerCase().replace('_', ' ');
    },
    isTransit: function(mode) {
      return mode == 'JEEP' || mode == 'BUS' || mode == 'RAIL';
    },
  }
});
itinerary.on({
  showSteps: function(event) {
    var path = event.keypath+'.showSteps';
    this.set(path, !this.get(path));
  },
  hover: function(event, index) {
    var leg = this.get('current').legs[index];
    if(event.hover) {
      if(leg.polyline == undefined) {
        leg.polyline = L.polyline(leg.points, {
          color: 'yellow',
          weight: 7
        });
      }
      leg.polyline.addTo(router.layer);
    }
    else {
      map.removeLayer(leg.polyline);
    }
  }
})

var router = new Ractive({
  el: '#routes',
  template: '#routerTemplate',
  debug: true,
  data: {
    f: formatDuration,
    targets: {
      mode: 'TRANSIT,WALK'
    }
  }
});
router.layer = L.layerGroup([]).addTo(map);
router.reset = function() {
  this.layer.clearLayers();
  this.routeLine = L.multiPolyline([]).addTo(this.layer);
}
router.getPoints = function(index) {
  var results = this.get('results');
  var lines = [];
  results[index].legs.forEach(function(leg) {
    lines.push(leg.points);
  });
  return lines;
}
router.showRoute = function(index) {
  this.routeLine.setLatLngs(this.getPoints(index));
  this.unhighlightRoute(index);
  map.fitBounds(this.routeLine.getBounds(), { padding: [10, 10] });
}
router.highlightRoute = function(index) {
  var route = this.get('results')[index];
  if(route.polyline == undefined) {
    route.polyline = L.multiPolyline(this.getPoints(index), {
      color: 'red'
    });
  }
  route.polyline.addTo(this.layer);
}
router.unhighlightRoute = function(index) {
  var polyline = this.get('results')[index].polyline;
  if(this.layer.hasLayer(polyline)) {
    this.layer.removeLayer(polyline);
  }
}

router.observe('selected', function(val) {
  if(val == undefined || val < 0) return;
  var results = this.get('results');
  itinerary.set('current', results[val]);
  this.showRoute(val);
});

router.observe('targets', function(targets) {
  if(!targets.from || !targets.to) return;
  var self = this;
  progress.setLoading(true);
  otp.route(
    targets.from.getLatLng(),
    targets.to.getLatLng(),
    targets.mode
  )
  .then(function(data) {
    self.reset();
    if(data.plan) {
      var results = data.plan.itineraries;
      results.forEach(function(itinerary) {
        itinerary.legs.forEach(function(leg) {
          leg.points = decodePoints(leg.legGeometry.points);
          if(leg.mode == 'BUS' && leg.routeId.indexOf('PUJ') >= 0) {
            leg.mode = 'JEEP';
          }

          leg.fare = calculateFare(leg);
        });
      });
      self.set('results', results);
      self.set('selected', -1);
      self.set('selected', 0);
    }
    else {
      self.set('results', null);
      itinerary.set('current', null);
    }
  })
  .fin(function() {
    progress.setLoading(false);
  });
});

router.on({
  select: function(event, index) {
    this.set('selected', index);
  },
  swap: function(event) {
    var targets = this.get('targets');
    var tmp = targets.from;
    targets.from = targets.to;
    targets.to = tmp;
    tmp = targets.fromAddress;
    targets.fromAddress = targets.toAddress;
    targets.toAddress = tmp;
    this.update('targets');
  },
  hover: function(event, index) {
    if(index != this.get('selected')) {
      if(event.hover) {
        this.highlightRoute(index);
      }
      else {
        this.unhighlightRoute(index);
      }
    }
  }
});
<|endoftext|>


<commit_before>// Copyright (c) 2016 CanalTP
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

var map = {

    DrawSectionOption: {
        DRAWSTART: 2, // 10
        DRAWEND: 1, // 01
        DRAWBOTH: 3, // 11
        DRAWNEITHER: 0 // 00
    },
    _should_draw_section_start: function(option) {
        return (option & 2);
    },
    _should_draw_section_end: function(option) {
        return (option & 1);
    },
    STARTTEXT : 'Start',
    ENDTEXT : 'End',
    makeFeatures: {
        region: function(context, json) {
            if (json.shape) {
                var geoJsonShape = wkt2geojson(json.shape);
                return map._makePolygon(context, 'region', geoJsonShape, json);
            }
            return [];
        },
        section: function(context, json, draw_section_option) {
            var color = json.display_informations;
            switch (json.type) {
            case 'street_network':
                switch (json.mode) {
                case 'bike': color = map.bikeColor; break;
                case 'car': color = map.carColor; break;
                case 'walking': color = map.walkingColor; break;
                }
                break;
            case 'transfer':
                switch (json.transfer_type) {
                case 'guaranteed': color = map.carColor; break;
                case 'extension': color = map.bikeColor; break;
                case 'walking': color = map.walkingColor; break;
                }
                break;
            }
            if (draw_section_option === undefined) {
                draw_section_option = map.DrawSectionOption.DRAWBOTH;
            }
            return map._makeString(context, 'section', json, color)
                .concat(map._makeStopTimesMarker(context, json, color, draw_section_option));
        },
        line: function(context, json) {
            return map._makeString(context, 'line', json, json);
        },
        journey: function(context, json) {
            if (! ('sections' in json)) { return []; }
            var bind = function(s, i, array) {
                var draw_section_option = map.DrawSectionOption.DRAWNEITHER;
                if ( i === 0) { draw_section_option |= map.DrawSectionOption.DRAWSTART; }
                if ( i === (array.length -1) ) { draw_section_option |= map.DrawSectionOption.DRAWEND; }
                return map.makeFeatures.section(context, s, draw_section_option);
            };
            return flatMap(json.sections, bind);
        },
        isochrone: function(context, json) {
            if (! ('geojson' in json)) { return []; }
            return map._makePolygon(context, 'isochrone', json.geojson, json);
        },
        address: function(context, json) {
            return map._makeMarker(context, 'address', json);
        },
        administrative_region: function(context, json) {
            return map._makeMarker('administrative_region', json);
        },
        stop_area: function(context, json) {
            return map._makeMarker(context, 'stop_area', json);
        },
        stop_point: function(context, json) {
            return map._makeMarker(context, 'stop_point', json);
        },
        place: function(context, json) {
            return map._makeMarker(context, 'place', json);
        },
        poi: function(context, json) {
            return map._makeMarker(context, 'poi', json);
        },
        response: function(context, json) {
            var key = responseCollectionName(json);
            if (key === null) {
                return [];
            }
            var type = getType(key);
            if (!(type in map.makeFeatures)) {
                return [];
            }
            var bind = function(s) {
                return map.makeFeatures[type](context, s);
            };
            return flatMap(json[key], bind);
        }
    },

    hasMap: function(context, type, json) {
        return map.getFeatures(context, type, json).length !== 0;
    },

    getFeatures: function(context, type, json) {
        if (! (map.makeFeatures[type] instanceof Function)) { return []; }
        try {
            return map.makeFeatures[type](context, json);
        } catch (e) {
            console.log(sprintf('map.makeFeatures[%s] thows an exception:', type));
            console.log(e);
            return [];
        }
    },

    run: function(context, type, json) {
        var div = $('
');
        // setting for default path of images used by leaflet
        L.Icon.Default.imagePath='lib/img/leaflet/dist/images';
        var features = [];
        if ((features = map.getFeatures(context, type, json)).length) {
            div.addClass('leaflet');
            var m = L.map(div.get(0)).setView([48.843693, 2.373303], 13);
            mapLink = 'OpenStreetMap';
            mapquestLink = 'MapQuest';
            mapquestPic = '';
            L.tileLayer(
                'http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
                    attribution: '© '+mapLink+'. Tiles courtesy of '+mapquestLink+mapquestPic,
                    maxZoom: 17,
                    subdomains: '1234',
            }).addTo(m);
            var overlay = L.featureGroup(features).addTo(m);
            setTimeout(function() {
                m.invalidateSize();
                m.fitBounds(overlay.getBounds());
            }, 100);
        } else {
            div.addClass('noMap');
            div.append('No map');
        }
        return div;
    },

    _makeMarker: function(context, type, json, colorJson, useCustomMarker, label) {
        var lat, lon;
        var obj = json;
        switch (type){
            case 'stop_date_time':
                obj = json.stop_point;
                lat = obj.coord.lat;
                lon = obj.coord.lon;
                break;
            case 'place':
                lat = json[json.embedded_type].coord.lat;
                lon = json[json.embedded_type].coord.lon;
                break;
            default:
                lat = json.coord.lat;
                lon = json.coord.lon;
        }
        var sum = summary.run(context, type, json);
        var t = type === 'place' ? json.embedded_type : type;
        var marker;
        if (! useCustomMarker) {
            marker = L.marker([lat, lon]);
        } else {
            var color = '#000000';
            if (colorJson  && (colorJson instanceof Object) && colorJson.color) {
                color = '#' + colorJson.color;
            }
            marker = L.circleMarker([lat, lon], {color: color, opacity: 1, fillColor: 'white', fillOpacity: 1});
            marker.setRadius(5);
        }
        if (label) {
            marker.bindLabel(label, {noHide: true, className: 'map-marker-label'});
        }
        return [marker.bindPopup(map._makeLink(context, t, obj, sum)[0])];
    },

    bikeColor: { color: 'CED480' },
    carColor: { color: 'EFBF8F' },
    walkingColor: { color: '89C6E5' },

    _makeString: function(context, type, json, colorJson) {
        if (! ( "geojson" in json) || ! json.geojson.coordinates.length) {
            return [];
        }
        if (! (colorJson instanceof Object) || ! (colorJson.color)) {
            colorJson = { color: '000000' };
        }
        var sum = summary.run(context, type, json);
        return [
            L.geoJson(json.geojson, {
                style: {
                    color: getTextColor(colorJson),
                    weight: 6,
                    opacity: 1
                }
            }),
            L.geoJson(json.geojson, {
                style: {
                    color: "#" + colorJson.color,
                    weight: 5,
                    opacity: 1
                }
            }).bindPopup(sum)
        ];
    },
    _makeStopTimesMarker: function(context, json, color, draw_section_option) {
        var stopTimes = json['stop_date_times'];
        var markers = [];

        if (stopTimes) {
            // when section is PT
            stopTimes.forEach(function(st, i) {
                var label = null;
                if (i === 0 &&
                    map._should_draw_section_start(draw_section_option)) {
                    label = map.STARTTEXT;
                }else if (i === (stopTimes.length -1 ) &&
                          map._should_draw_section_end(draw_section_option)) {
                    label = map.ENDTEXT;
                }
                markers = markers.concat(map._makeMarker(context, 'stop_date_time', st, color, true, label));
            });
        } else {
            // when section is Walking
            var from = json.from;
            var to = json.to;
            if (! from || ! to) { return markers; }
            var label_from= null;
            var label_to= null;
            if (map._should_draw_section_start(draw_section_option)) {
                label_from = map.STARTTEXT;
            }
            if (map._should_draw_section_end(draw_section_option)) {
                label_to = map.ENDTEXT;
            }
            markers = markers.concat(map._makeMarker(context, 'place', from, color, true, label_from))
                             .concat(map._makeMarker(context, 'place', to, color, true, label_to));
        }
        return markers;
    },
    _makePolygon: function(context, type, geoJsonCoords, json) {
        var sum = summary.run(context, type, json);
        // TODO use link when navitia has debugged the ticket NAVITIAII-2133
        var link = map._makeLink(context, type, json, sum)[0];
        return [
            L.geoJson(geoJsonCoords, {
                color: '#0000FF',
                opacity: 1.0,
                weight: 3,
                fillColor: '#0000FF',
                fillOpacity: 0.35
            }).bindPopup(link)
        ];
    },
    _makeLink: function(context, type, obj, name) {
        return context.makeLink(type, obj, name);
    }
};
<commit_msg>minor format<commit_after>// Copyright (c) 2016 CanalTP
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

var map = {
    DrawSectionOption: {
        DRAWSTART: 2, // 10
        DRAWEND: 1, // 01
        DRAWBOTH: 3, // 11
        DRAWNEITHER: 0 // 00
    },
    _should_draw_section_start: function(option) {
        return option & 2;
    },
    _should_draw_section_end: function(option) {
        return option & 1;
    },
    STARTTEXT : 'Start',
    ENDTEXT : 'End',
    makeFeatures: {
        region: function(context, json) {
            if (json.shape) {
                var geoJsonShape = wkt2geojson(json.shape);
                return map._makePolygon(context, 'region', geoJsonShape, json);
            }
            return [];
        },
        section: function(context, json, draw_section_option) {
            var color = json.display_informations;
            switch (json.type) {
            case 'street_network':
                switch (json.mode) {
                case 'bike': color = map.bikeColor; break;
                case 'car': color = map.carColor; break;
                case 'walking': color = map.walkingColor; break;
                }
                break;
            case 'transfer':
                switch (json.transfer_type) {
                case 'guaranteed': color = map.carColor; break;
                case 'extension': color = map.bikeColor; break;
                case 'walking': color = map.walkingColor; break;
                }
                break;
            }
            if (draw_section_option === undefined) {
                draw_section_option = map.DrawSectionOption.DRAWBOTH;
            }
            return map._makeString(context, 'section', json, color)
                .concat(map._makeStopTimesMarker(context, json, color, draw_section_option));
        },
        line: function(context, json) {
            return map._makeString(context, 'line', json, json);
        },
        journey: function(context, json) {
            if (! ('sections' in json)) { return []; }
            var bind = function(s, i, array) {
                var draw_section_option = map.DrawSectionOption.DRAWNEITHER;
                if ( i === 0) { draw_section_option |= map.DrawSectionOption.DRAWSTART; }
                if ( i === (array.length -1) ) { draw_section_option |= map.DrawSectionOption.DRAWEND; }
                return map.makeFeatures.section(context, s, draw_section_option);
            };
            return flatMap(json.sections, bind);
        },
        isochrone: function(context, json) {
            if (! ('geojson' in json)) { return []; }
            return map._makePolygon(context, 'isochrone', json.geojson, json);
        },
        address: function(context, json) {
            return map._makeMarker(context, 'address', json);
        },
        administrative_region: function(context, json) {
            return map._makeMarker('administrative_region', json);
        },
        stop_area: function(context, json) {
            return map._makeMarker(context, 'stop_area', json);
        },
        stop_point: function(context, json) {
            return map._makeMarker(context, 'stop_point', json);
        },
        place: function(context, json) {
            return map._makeMarker(context, 'place', json);
        },
        poi: function(context, json) {
            return map._makeMarker(context, 'poi', json);
        },
        response: function(context, json) {
            var key = responseCollectionName(json);
            if (key === null) {
                return [];
            }
            var type = getType(key);
            if (!(type in map.makeFeatures)) {
                return [];
            }
            var bind = function(s) {
                return map.makeFeatures[type](context, s);
            };
            return flatMap(json[key], bind);
        }
    },

    hasMap: function(context, type, json) {
        return map.getFeatures(context, type, json).length !== 0;
    },

    getFeatures: function(context, type, json) {
        if (! (map.makeFeatures[type] instanceof Function)) { return []; }
        try {
            return map.makeFeatures[type](context, json);
        } catch (e) {
            console.log(sprintf('map.makeFeatures[%s] thows an exception:', type));
            console.log(e);
            return [];
        }
    },

    run: function(context, type, json) {
        var div = $('
');
        // setting for default path of images used by leaflet
        L.Icon.Default.imagePath='lib/img/leaflet/dist/images';
        var features = [];
        if ((features = map.getFeatures(context, type, json)).length) {
            div.addClass('leaflet');
            var m = L.map(div.get(0)).setView([48.843693, 2.373303], 13);
            mapLink = 'OpenStreetMap';
            mapquestLink = 'MapQuest';
            mapquestPic = '';
            L.tileLayer(
                'http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
                    attribution: '© '+mapLink+'. Tiles courtesy of '+mapquestLink+mapquestPic,
                    maxZoom: 17,
                    subdomains: '1234',
            }).addTo(m);
            var overlay = L.featureGroup(features).addTo(m);
            setTimeout(function() {
                m.invalidateSize();
                m.fitBounds(overlay.getBounds());
            }, 100);
        } else {
            div.addClass('noMap');
            div.append('No map');
        }
        return div;
    },

    _makeMarker: function(context, type, json, colorJson, useCustomMarker, label) {
        var lat, lon;
        var obj = json;
        switch (type){
            case 'stop_date_time':
                obj = json.stop_point;
                lat = obj.coord.lat;
                lon = obj.coord.lon;
                break;
            case 'place':
                lat = json[json.embedded_type].coord.lat;
                lon = json[json.embedded_type].coord.lon;
                break;
            default:
                lat = json.coord.lat;
                lon = json.coord.lon;
        }
        var sum = summary.run(context, type, json);
        var t = type === 'place' ? json.embedded_type : type;
        var marker;
        if (! useCustomMarker) {
            marker = L.marker([lat, lon]);
        } else {
            var color = '#000000';
            if (colorJson  && colorJson instanceof Object && colorJson.color) {
                color = '#' + colorJson.color;
            }
            marker = L.circleMarker([lat, lon], {color: color, opacity: 1, fillColor: 'white', fillOpacity: 1});
            marker.setRadius(5);
        }
        if (label) {
            marker.bindLabel(label, {noHide: true, className: 'map-marker-label'});
        }
        return [marker.bindPopup(map._makeLink(context, t, obj, sum)[0])];
    },

    bikeColor: { color: 'CED480' },
    carColor: { color: 'EFBF8F' },
    walkingColor: { color: '89C6E5' },

    _makeString: function(context, type, json, colorJson) {
        if (! ( "geojson" in json) || ! json.geojson.coordinates.length) {
            return [];
        }
        if (! (colorJson instanceof Object) || ! (colorJson.color)) {
            colorJson = { color: '000000' };
        }
        var sum = summary.run(context, type, json);
        return [
            L.geoJson(json.geojson, {
                style: {
                    color: getTextColor(colorJson),
                    weight: 6,
                    opacity: 1
                }
            }),
            L.geoJson(json.geojson, {
                style: {
                    color: "#" + colorJson.color,
                    weight: 5,
                    opacity: 1
                }
            }).bindPopup(sum)
        ];
    },
    _makeStopTimesMarker: function(context, json, color, draw_section_option) {
        var stopTimes = json['stop_date_times'];
        var markers = [];

        if (stopTimes) {
            // when section is PT
            stopTimes.forEach(function(st, i) {
                var label = null;
                if (i === 0 &&
                    map._should_draw_section_start(draw_section_option)) {
                    label = map.STARTTEXT;
                }else if (i === (stopTimes.length -1 ) &&
                          map._should_draw_section_end(draw_section_option)) {
                    label = map.ENDTEXT;
                }
                markers = markers.concat(map._makeMarker(context, 'stop_date_time', st, color, true, label));
            });
        } else {
            // when section is Walking
            var from = json.from;
            var to = json.to;
            if (! from || ! to) { return markers; }
            var label_from = null;
            var label_to = null;
            if (map._should_draw_section_start(draw_section_option)) {
                label_from = map.STARTTEXT;
            }
            if (map._should_draw_section_end(draw_section_option)) {
                label_to = map.ENDTEXT;
            }
            markers = markers.concat(map._makeMarker(context, 'place', from, color, true, label_from))
                             .concat(map._makeMarker(context, 'place', to, color, true, label_to));
        }
        return markers;
    },
    _makePolygon: function(context, type, geoJsonCoords, json) {
        var sum = summary.run(context, type, json);
        // TODO use link when navitia has debugged the ticket NAVITIAII-2133
        var link = map._makeLink(context, type, json, sum)[0];
        return [
            L.geoJson(geoJsonCoords, {
                color: '#0000FF',
                opacity: 1.0,
                weight: 3,
                fillColor: '#0000FF',
                fillOpacity: 0.35
            }).bindPopup(link)
        ];
    },
    _makeLink: function(context, type, obj, name) {
        return context.makeLink(type, obj, name);
    }
};
<|endoftext|>