<commit_before>(function () {
    'use strict';

    /*jslint
        browser: true
    */
    /*global
        L, reqwest, loadjs
    */

    var container = document.getElementById('map'),
        service = container.getAttribute('data-service'),
        map,
        statusBar,
        bounds,
        lastReq,
        response,
        oldVehicles = {},
        newVehicles = {},
        busesOnline = document.getElementById('buses-online'),
        button = busesOnline.getElementsByTagName('button')[0];

    button.onclick = function() {
        container.className += ' expanded';
        document.body.style.overflow = 'hidden';

        if (map) {
            map.invalidateSize();
        } else {
            loadjs([window.LEAFLET_CSS_URL, window.LEAFLET_JS_URL], setUpMap);
            if (busesOnlineCount) {
                clearTimeout(timeout);
                load();
            }
        }
    };

    function setUpMap() {
        map = L.map(container, {
            minZoom: 9
        }),
        map.attributionControl.setPrefix('');
        L.tileLayer('https://maps.bustimes.org/styles/klokantech-basic/{z}/{x}/{y}' + (L.Browser.retina ? '@2x' : '') + '.png', {
            attribution: '© MapTiler © OpenStreetMap contributors'
        }).addTo(map);

        statusBar = L.control({
            position: 'bottomleft'
        });

        statusBar.onAdd = function() {
            var div = L.DomUtil.create('div', 'hugemap-status');
            return div;
        };

        statusBar.addTo(map);

        var closeButton = L.control();

        closeButton.onAdd = function() {
            var div = document.createElement('div');
            div.className = 'leaflet-bar';

            var a = document.createElement('a');
            a.href = '#';
            a.style.width = 'auto';
            a.style.padding = '0 8px';
            a.setAttribute('role', 'button');
            a.innerHTML = 'Close map';
            a.onclick = closeMap;

            div.appendChild(a);
            return div;
        };

        closeButton.addTo(map);

        if (window.EXTENT) {
            map.fitBounds([[window.EXTENT[1], window.EXTENT[0]], [window.EXTENT[3], window.EXTENT[2]]]);
        }

        reqwest('/services/' + service + '.json', function(data) {
            L.geoJson(data.geometry, {
                style: {
                    weight: 3,
                    color: '#87f'
                }
            }).addTo(map);
            var options = {
                radius: 3,
                fillColor: "#fff",
                color: "#87f",
                weight: 2,
                fillOpacity: 1
            };

            L.geoJson(data.stops, {
                pointToLayer: function (feature, latlng) {
                    return L.circleMarker(latlng, options).bindPopup('' + feature.properties.name + '');
                }
            }).addTo(map);
        });

        if (response) {
            processData(response);
        }
    }

    function getRotation(direction) {
        if (direction == null) {
            return '';
        }
        var rotation = 'transform: rotate(' + direction + 'deg)';
        return '-ms-' + rotation + ';-webkit-' + rotation + ';-moz-' + rotation + ';-o-' + rotation + ';' + rotation;
    }

    function getIcon(direction, livery, textColour) {
        if (direction !== null) {
            var arrow = '

';
            if (direction < 180) {
                direction -= 90;
            } else {
                direction -= 270;
            }
        }
        var className = 'bus';
        if (livery) {
            var style = 'background:' + livery + ';';
            className += ' coloured';
            if (textColour) {
                className += ' white-text';
            }
        } else {
            style = '';
        }
        style += getRotation(direction);
        var html = '

';
        if (arrow) {
            html += arrow;
        }
        return L.divIcon({
            iconSize: [20, 20],
            html: html,
            popupAnchor: [0, -5],
        });
    }

    function handleVehicle(data) {
        var props = data.properties;

        if (props.vehicle.url in oldVehicles) {
            var marker = oldVehicles[props.vehicle.url];
            newVehicles[props.vehicle.url] = marker;
            if (marker.datetime === props.datetime) {
                return;
            }
        }

        var icon = getIcon(props.direction, props.vehicle.livery, props.vehicle.text_colour),
            latLng = L.latLng(data.geometry.coordinates[1], data.geometry.coordinates[0]);

        bounds.extend(latLng);

        if (marker) {
            marker.setLatLng(latLng);
            marker.setIcon(icon);
        } else {
            marker = L.marker(latLng, {
                icon: icon
            });
            marker.addTo(map);
            newVehicles[props.vehicle.url] = marker;
        }
        marker.datetime = props.datetime;

        var popup = '';

        if (props.delta === 0) {
            popup += 'On time';
        } else if (props.delta) {
            popup += 'About ';
            if (props.delta > 0) {
                popup += props.delta;
            } else {
                popup += props.delta * -1;
            }
            popup += ' minute';
            if (props.delta !== 1 && props.delta !== -1) {
                popup += 's';
            }
            if (props.delta > 0) {
                popup += ' early';
            } else {
                popup += ' late';
            }
        }

        if (popup) {
            popup += '
';
        }

        var dateTime = new Date(props.datetime);
        popup += 'Updated at ' + dateTime.toTimeString().slice(0, 5);

        if (props.vehicle.decker) {
            var vehicleFeatures = 'Double-decker';
            if (props.vehicle.coach) {
                vehicleFeatures += ' coach';
            }
            popup = vehicleFeatures + '
' + popup;
        } else if (props.vehicle.coach) {
            popup = 'Coach' + '
' + popup;
        }

        popup = props.vehicle.name + '
' + popup;

        if (props.destination) {
            popup = props.destination + '
' + popup;
            if (props.destination.indexOf(' to ') === -1) {
                popup = 'To ' + popup;
            }
        }

        marker.bindPopup(popup);
    }

    function processData(data) {
        bounds = L.latLngBounds();

        for (var i = data.features.length - 1; i >= 0; i -= 1) {
            handleVehicle(data.features[i]);
        }
        for (var vehicle in oldVehicles) {
            if (!(vehicle in newVehicles)) {
                map.removeLayer(oldVehicles[vehicle]);
            }
        }
        oldVehicles = newVehicles;
        newVehicles = {};

        if (!map._loaded && bounds.isValid()) {
            map.fitBounds(bounds, {
                padding: [10, 10],
                maxZoom: 12
            });
        }
        statusBar.getContainer().innerHTML = '';
    }

    var timeout, busesOnlineCount;

    function load() {
        if (statusBar) {
            statusBar.getContainer().innerHTML = 'Loading\u2026';
        }
        if (lastReq) {
            lastReq.abort();
        }
        lastReq = reqwest('/vehicles.json?service=' + service, function(data) {
            if (lastReq.request.status === 200 && data && data.features) {
                if (!busesOnlineCount) { // first load
                    if (data.features.length) {
                        busesOnlineCount = document.createElement('span');
                        busesOnline.appendChild(busesOnlineCount);
                        if (document.addEventListener) {
                            document.addEventListener('visibilitychange', handleVisibilityChange);
                        }
                    } else {
                        if (statusBar) {
                            statusBar.getContainer().innerHTML = '';
                        }
                        return;
                    }
                }

                if (data.features.length === 0) {
                    busesOnlineCount.innerHTML = 'No buses online';
                } else if (data.features.length === 1) {
                    busesOnlineCount.innerHTML = '1 bus online';
                } else {
                    busesOnlineCount.innerHTML = data.features.length + ' buses online';
                }
                if (map) {
                    processData(data);
                } else {
                    response = data;
                }
            }
            timeout = setTimeout(function() {
                load();
            }, map ? 10000 : 120000); // 10 seconds or 2 minute
        });
    }

    function handleVisibilityChange(event) {
        if (event.target.hidden) {
            clearTimeout(timeout);
        } else {
            load();
        }
    }

    function closeMap() {
        container.className = container.className.replace(' expanded', '');
        document.body.style.overflow = '';

        return false;
    }

    window.onkeydown = function(event) {
        if (event.keyCode === 27) {
            closeMap();
        }
    };

    load();
})();
<commit_msg>Use single quotes to please ESLint<commit_after>(function () {
    'use strict';

    /*jslint
        browser: true
    */
    /*global
        L, reqwest, loadjs
    */

    var container = document.getElementById('map'),
        service = container.getAttribute('data-service'),
        map,
        statusBar,
        bounds,
        lastReq,
        response,
        oldVehicles = {},
        newVehicles = {},
        busesOnline = document.getElementById('buses-online'),
        button = busesOnline.getElementsByTagName('button')[0];

    button.onclick = function() {
        container.className += ' expanded';
        document.body.style.overflow = 'hidden';

        if (map) {
            map.invalidateSize();
        } else {
            loadjs([window.LEAFLET_CSS_URL, window.LEAFLET_JS_URL], setUpMap);
            if (busesOnlineCount) {
                clearTimeout(timeout);
                load();
            }
        }
    };

    function setUpMap() {
        map = L.map(container, {
            minZoom: 9
        }),
        map.attributionControl.setPrefix('');
        L.tileLayer('https://maps.bustimes.org/styles/klokantech-basic/{z}/{x}/{y}' + (L.Browser.retina ? '@2x' : '') + '.png', {
            attribution: '© MapTiler © OpenStreetMap contributors'
        }).addTo(map);

        statusBar = L.control({
            position: 'bottomleft'
        });

        statusBar.onAdd = function() {
            var div = L.DomUtil.create('div', 'hugemap-status');
            return div;
        };

        statusBar.addTo(map);

        var closeButton = L.control();

        closeButton.onAdd = function() {
            var div = document.createElement('div');
            div.className = 'leaflet-bar';

            var a = document.createElement('a');
            a.href = '#';
            a.style.width = 'auto';
            a.style.padding = '0 8px';
            a.setAttribute('role', 'button');
            a.innerHTML = 'Close map';
            a.onclick = closeMap;

            div.appendChild(a);
            return div;
        };

        closeButton.addTo(map);

        if (window.EXTENT) {
            map.fitBounds([[window.EXTENT[1], window.EXTENT[0]], [window.EXTENT[3], window.EXTENT[2]]]);
        }

        reqwest('/services/' + service + '.json', function(data) {
            L.geoJson(data.geometry, {
                style: {
                    weight: 3,
                    color: '#87f'
                }
            }).addTo(map);
            var options = {
                radius: 3,
                fillColor: '#fff',
                color: '#87f',
                weight: 2,
                fillOpacity: 1
            };

            L.geoJson(data.stops, {
                pointToLayer: function (feature, latlng) {
                    return L.circleMarker(latlng, options).bindPopup('' + feature.properties.name + '');
                }
            }).addTo(map);
        });

        if (response) {
            processData(response);
        }
    }

    function getRotation(direction) {
        if (direction == null) {
            return '';
        }
        var rotation = 'transform: rotate(' + direction + 'deg)';
        return '-ms-' + rotation + ';-webkit-' + rotation + ';-moz-' + rotation + ';-o-' + rotation + ';' + rotation;
    }

    function getIcon(direction, livery, textColour) {
        if (direction !== null) {
            var arrow = '

';
            if (direction < 180) {
                direction -= 90;
            } else {
                direction -= 270;
            }
        }
        var className = 'bus';
        if (livery) {
            var style = 'background:' + livery + ';';
            className += ' coloured';
            if (textColour) {
                className += ' white-text';
            }
        } else {
            style = '';
        }
        style += getRotation(direction);
        var html = '

';
        if (arrow) {
            html += arrow;
        }
        return L.divIcon({
            iconSize: [20, 20],
            html: html,
            popupAnchor: [0, -5],
        });
    }

    function handleVehicle(data) {
        var props = data.properties;

        if (props.vehicle.url in oldVehicles) {
            var marker = oldVehicles[props.vehicle.url];
            newVehicles[props.vehicle.url] = marker;
            if (marker.datetime === props.datetime) {
                return;
            }
        }

        var icon = getIcon(props.direction, props.vehicle.livery, props.vehicle.text_colour),
            latLng = L.latLng(data.geometry.coordinates[1], data.geometry.coordinates[0]);

        bounds.extend(latLng);

        if (marker) {
            marker.setLatLng(latLng);
            marker.setIcon(icon);
        } else {
            marker = L.marker(latLng, {
                icon: icon
            });
            marker.addTo(map);
            newVehicles[props.vehicle.url] = marker;
        }
        marker.datetime = props.datetime;

        var popup = '';

        if (props.delta === 0) {
            popup += 'On time';
        } else if (props.delta) {
            popup += 'About ';
            if (props.delta > 0) {
                popup += props.delta;
            } else {
                popup += props.delta * -1;
            }
            popup += ' minute';
            if (props.delta !== 1 && props.delta !== -1) {
                popup += 's';
            }
            if (props.delta > 0) {
                popup += ' early';
            } else {
                popup += ' late';
            }
        }

        if (popup) {
            popup += '
';
        }

        var dateTime = new Date(props.datetime);
        popup += 'Updated at ' + dateTime.toTimeString().slice(0, 5);

        if (props.vehicle.decker) {
            var vehicleFeatures = 'Double-decker';
            if (props.vehicle.coach) {
                vehicleFeatures += ' coach';
            }
            popup = vehicleFeatures + '
' + popup;
        } else if (props.vehicle.coach) {
            popup = 'Coach' + '
' + popup;
        }

        popup = props.vehicle.name + '
' + popup;

        if (props.destination) {
            popup = props.destination + '
' + popup;
            if (props.destination.indexOf(' to ') === -1) {
                popup = 'To ' + popup;
            }
        }

        marker.bindPopup(popup);
    }

    function processData(data) {
        bounds = L.latLngBounds();

        for (var i = data.features.length - 1; i >= 0; i -= 1) {
            handleVehicle(data.features[i]);
        }
        for (var vehicle in oldVehicles) {
            if (!(vehicle in newVehicles)) {
                map.removeLayer(oldVehicles[vehicle]);
            }
        }
        oldVehicles = newVehicles;
        newVehicles = {};

        if (!map._loaded && bounds.isValid()) {
            map.fitBounds(bounds, {
                padding: [10, 10],
                maxZoom: 12
            });
        }
        statusBar.getContainer().innerHTML = '';
    }

    var timeout, busesOnlineCount;

    function load() {
        if (statusBar) {
            statusBar.getContainer().innerHTML = 'Loading\u2026';
        }
        if (lastReq) {
            lastReq.abort();
        }
        lastReq = reqwest('/vehicles.json?service=' + service, function(data) {
            if (lastReq.request.status === 200 && data && data.features) {
                if (!busesOnlineCount) { // first load
                    if (data.features.length) {
                        busesOnlineCount = document.createElement('span');
                        busesOnline.appendChild(busesOnlineCount);
                        if (document.addEventListener) {
                            document.addEventListener('visibilitychange', handleVisibilityChange);
                        }
                    } else {
                        if (statusBar) {
                            statusBar.getContainer().innerHTML = '';
                        }
                        return;
                    }
                }

                if (data.features.length === 0) {
                    busesOnlineCount.innerHTML = 'No buses online';
                } else if (data.features.length === 1) {
                    busesOnlineCount.innerHTML = '1 bus online';
                } else {
                    busesOnlineCount.innerHTML = data.features.length + ' buses online';
                }
                if (map) {
                    processData(data);
                } else {
                    response = data;
                }
            }
            timeout = setTimeout(function() {
                load();
            }, map ? 10000 : 120000); // 10 seconds or 2 minute
        });
    }

    function handleVisibilityChange(event) {
        if (event.target.hidden) {
            clearTimeout(timeout);
        } else {
            load();
        }
    }

    function closeMap() {
        container.className = container.className.replace(' expanded', '');
        document.body.style.overflow = '';

        return false;
    }

    window.onkeydown = function(event) {
        if (event.keyCode === 27) {
            closeMap();
        }
    };

    load();
})();
<|endoftext|>


<commit_before>var crypto = {}

crypto.randomInteger = function (min, max) {
    var rand = min - 0.5 + Math.random() * (max - min + 1)
    rand = Math.round(rand);
    return rand;
}

crypto.decrypt = function (sock, raw, offset, size) {
    try {

        var temp = 0;
        for (var i = 0; i < size; i++) {
            var temp2 = raw[offset + i] & 0xFF;
            raw[offset + i] = (temp2 ^ sock.client.newXorKeyDec[i & 15] ^ temp) & 0xff;
            if (i >= 6 && i <= 10) {
                console.log((raw[offset + i]).toString(16));
            }
            temp = temp2;
        }

        var old = (sock.client.newXorKeyDec[8] << 0x00) & 0xff;
        old |= (sock.client.newXorKeyDec[9] << 0x08) & 0xff00;
        old |= (sock.client.newXorKeyDec[10] << 0x10) & 0xff0000;
        old |= (sock.client.newXorKeyDec[11] << 0x18) & 0xff000000;

        old += size;

        sock.client.newXorKeyDec[8] = ((old >> 0) & 0xff);
        sock.client.newXorKeyDec[9] = ((old >> 0x08) & 0xff);
        sock.client.newXorKeyDec[10] = ((old >> 0x10) & 0xff);
        sock.client.newXorKeyDec[11] = ((old >> 0x18) & 0xff);

    } catch (ex) {
        console.log(ex);
    }
}

crypto.encrypt = function (sock, raw, offset, size) {
    try {

        var temp = 0;
        for (var i = 0; i < size; i++) {
            var temp2 = raw[offset + i] & 0xFF;
            temp = (temp2 ^ sock.client.newXorKeyEnc[i & 15] ^ temp) & 0xff;
            raw[offset + i] = temp;
        }

        var old = (sock.client.newXorKeyEnc[8] << 0x00) & 0xff;
        old |= (sock.client.newXorKeyEnc[9] << 0x08) & 0xff00;
        old |= (sock.client.newXorKeyEnc[10] << 0x10) & 0xff0000;
        old |= (sock.client.newXorKeyEnc[11] << 0x18) & 0xff000000;

        old += size;

        sock.client.newXorKeyEnc[8] = ((old >> 0x00) & 0xff);
        sock.client.newXorKeyEnc[9] = ((old >> 0x08) & 0xff);
        sock.client.newXorKeyEnc[10] = ((old >> 0x10) & 0xff);
        sock.client.newXorKeyEnc[11] = ((old >> 0x18) & 0xff);

    } catch (ex) {
        console.log(ex);
    }
}

crypto.generateNewKey = function () {
    try {
        var key = new Uint8Array(16);

        // randomize the 8 first bytes
        for (var j = 0; j < key.length; j++) {
            key[j] = crypto.randomInteger(1, 254);
        }

        // the last 8 bytes are static
        key[8] = 0xc8;
        key[9] = 0x27;
        key[10] = 0x93;
        key[11] = 0x01;
        key[12] = 0xa1;
        key[13] = 0x6c;
        key[14] = 0x31;
        key[15] = 0x97;
        return key;

    } catch (ex) {
        console.log(ex);
    }
    return [];
}

crypto.appendChecksum = function (raw, offset, size) {
    try {

        var chksum = 0;
        var count = size - 4;
        var ecx;
        var i;

        for (i = offset; i < count; i += 4) {
            ecx = (raw[i] << 0x00) & 0xff;
            ecx |= (raw[i + 1] << 0x08) & 0xff00;
            ecx |= (raw[i + 2] << 0x10) & 0xff0000;
            ecx |= (raw[i + 3] << 0x18) & 0xff000000;

            chksum ^= ecx;
        }

        ecx = (raw[i] >> 0x00) & 0xff;
        ecx |= (raw[i + 1] << 0x08) & 0xff00;
        ecx |= (raw[i + 2] << 0x10) & 0xff0000;
        ecx |= (raw[i + 3] << 0x18) & 0xff000000;

        raw[i] = ((chksum >> 0x00) & 0xff);
        raw[i + 1] = ((chksum >> 0x08) & 0xff);
        raw[i + 2] = ((chksum >> 0x10) & 0xff);
        raw[i + 3] = ((chksum >> 0x18) & 0xff);
        return raw;

    } catch (ex) {
        console.log(ex);
    }
    return [];
}

crypto.newPubKey = function () {
    try {
        var ret = new Uint8Array(16);
        for (var i = 0; i < 16; i++) {
            ret[i] = (parseInt((Math.random() * 50).toFixed(0)));
        }
        return ret;
    } catch (ex) {
        console.log(ex);
    }
    return [];
}

crypto.encXORPass = function (raw, offset, size, key) {
    try {

        var stop = size - 8;
        var pos = 4 + offset;
        var edx;
        var ecx = key; // Initial xor key

        while (pos < stop) {
            edx = (raw[pos] & 0xFF) << 0;
            edx |= (raw[pos + 1] & 0xFF) << 8;
            edx |= (raw[pos + 2] & 0xFF) << 16;
            edx |= (raw[pos + 3] & 0xFF) << 24;

            ecx += edx;

            edx ^= ecx;

            raw[pos++] = ((edx >> 0) & 0xFF);
            raw[pos++] = ((edx >> 8) & 0xFF);
            raw[pos++] = ((edx >> 16) & 0xFF);
            raw[pos++] = ((edx >> 24) & 0xFF);
        }

        raw[pos++] = ((ecx >> 0) & 0xFF);
        raw[pos++] = ((ecx >> 8) & 0xFF);
        raw[pos++] = ((ecx >> 16) & 0xFF);
        raw[pos++] = ((ecx >> 24) & 0xFF);
        return raw;

    } catch (ex) {
        console.log(ex);
    }
    return [];
}

module.exports = crypto;<commit_msg>MBTL packet - 13<commit_after>var crypto = {}

crypto.randomInteger = function (min, max) {
    var rand = min - 0.5 + Math.random() * (max - min + 1)
    rand = Math.round(rand);
    return rand;
}

crypto.decrypt = function (sock, raw, offset, size) {
    try {

        var temp = 0;
        for (var i = 0; i < size; i++) {
            var temp2 = raw[offset + i] & 0xFF;
            if (i == 8) {
                console.log(temp2);
            }
            raw[offset + i] = (temp2 ^ sock.client.newXorKeyDec[i & 15] ^ temp) & 0xff;
            if (i == 8) {
                console.log((raw[offset + i]).toString(16));
            }
            temp = temp2;
        }

        var old = (sock.client.newXorKeyDec[8] << 0x00) & 0xff;
        old |= (sock.client.newXorKeyDec[9] << 0x08) & 0xff00;
        old |= (sock.client.newXorKeyDec[10] << 0x10) & 0xff0000;
        old |= (sock.client.newXorKeyDec[11] << 0x18) & 0xff000000;

        old += size;

        sock.client.newXorKeyDec[8] = ((old >> 0) & 0xff);
        sock.client.newXorKeyDec[9] = ((old >> 0x08) & 0xff);
        sock.client.newXorKeyDec[10] = ((old >> 0x10) & 0xff);
        sock.client.newXorKeyDec[11] = ((old >> 0x18) & 0xff);

    } catch (ex) {
        console.log(ex);
    }
}

crypto.encrypt = function (sock, raw, offset, size) {
    try {

        var temp = 0;
        for (var i = 0; i < size; i++) {
            var temp2 = raw[offset + i] & 0xFF;
            temp = (temp2 ^ sock.client.newXorKeyEnc[i & 15] ^ temp) & 0xff;
            raw[offset + i] = temp;
        }

        var old = (sock.client.newXorKeyEnc[8] << 0x00) & 0xff;
        old |= (sock.client.newXorKeyEnc[9] << 0x08) & 0xff00;
        old |= (sock.client.newXorKeyEnc[10] << 0x10) & 0xff0000;
        old |= (sock.client.newXorKeyEnc[11] << 0x18) & 0xff000000;

        old += size;

        sock.client.newXorKeyEnc[8] = ((old >> 0x00) & 0xff);
        sock.client.newXorKeyEnc[9] = ((old >> 0x08) & 0xff);
        sock.client.newXorKeyEnc[10] = ((old >> 0x10) & 0xff);
        sock.client.newXorKeyEnc[11] = ((old >> 0x18) & 0xff);

    } catch (ex) {
        console.log(ex);
    }
}

crypto.generateNewKey = function () {
    try {
        var key = new Uint8Array(16);

        // randomize the 8 first bytes
        for (var j = 0; j < key.length; j++) {
            key[j] = crypto.randomInteger(1, 254);
        }

        // the last 8 bytes are static
        key[8] = 0xc8;
        key[9] = 0x27;
        key[10] = 0x93;
        key[11] = 0x01;
        key[12] = 0xa1;
        key[13] = 0x6c;
        key[14] = 0x31;
        key[15] = 0x97;
        return key;

    } catch (ex) {
        console.log(ex);
    }
    return [];
}

crypto.appendChecksum = function (raw, offset, size) {
    try {

        var chksum = 0;
        var count = size - 4;
        var ecx;
        var i;

        for (i = offset; i < count; i += 4) {
            ecx = (raw[i] << 0x00) & 0xff;
            ecx |= (raw[i + 1] << 0x08) & 0xff00;
            ecx |= (raw[i + 2] << 0x10) & 0xff0000;
            ecx |= (raw[i + 3] << 0x18) & 0xff000000;

            chksum ^= ecx;
        }

        ecx = (raw[i] >> 0x00) & 0xff;
        ecx |= (raw[i + 1] << 0x08) & 0xff00;
        ecx |= (raw[i + 2] << 0x10) & 0xff0000;
        ecx |= (raw[i + 3] << 0x18) & 0xff000000;

        raw[i] = ((chksum >> 0x00) & 0xff);
        raw[i + 1] = ((chksum >> 0x08) & 0xff);
        raw[i + 2] = ((chksum >> 0x10) & 0xff);
        raw[i + 3] = ((chksum >> 0x18) & 0xff);
        return raw;

    } catch (ex) {
        console.log(ex);
    }
    return [];
}

crypto.newPubKey = function () {
    try {
        var ret = new Uint8Array(16);
        for (var i = 0; i < 16; i++) {
            ret[i] = (parseInt((Math.random() * 50).toFixed(0)));
        }
        return ret;
    } catch (ex) {
        console.log(ex);
    }
    return [];
}

crypto.encXORPass = function (raw, offset, size, key) {
    try {

        var stop = size - 8;
        var pos = 4 + offset;
        var edx;
        var ecx = key; // Initial xor key

        while (pos < stop) {
            edx = (raw[pos] & 0xFF) << 0;
            edx |= (raw[pos + 1] & 0xFF) << 8;
            edx |= (raw[pos + 2] & 0xFF) << 16;
            edx |= (raw[pos + 3] & 0xFF) << 24;

            ecx += edx;

            edx ^= ecx;

            raw[pos++] = ((edx >> 0) & 0xFF);
            raw[pos++] = ((edx >> 8) & 0xFF);
            raw[pos++] = ((edx >> 16) & 0xFF);
            raw[pos++] = ((edx >> 24) & 0xFF);
        }

        raw[pos++] = ((ecx >> 0) & 0xFF);
        raw[pos++] = ((ecx >> 8) & 0xFF);
        raw[pos++] = ((ecx >> 16) & 0xFF);
        raw[pos++] = ((ecx >> 24) & 0xFF);
        return raw;

    } catch (ex) {
        console.log(ex);
    }
    return [];
}

module.exports = crypto;<|endoftext|>


<commit_before>var utils = {
  osx: '../javascript/utils.js',
  chrome: '../chrome_extension/js/utils.js'
};

module.exports = {
  entry: [utils[process.env.TARGET], '../javascript/main.jsx'],
  output: {
    publicPath: 'public/',
    path: __dirname + '/public',
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {test: /\.jsx$/, loader: 'jsx-loader?harmony'},
      {test: /\.styl$/, loader: 'style-loader!css-loader!stylus-loader'},
      {test: /\.json$/, loader: 'json-loader'},
      {test: /\.ttf$/, loader: 'file-loader' }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx', '.styl' ]
  }
};
<commit_msg>Default webpack configuration to osx<commit_after>var utils = {
  osx: '../javascript/utils.js',
  chrome: '../chrome_extension/js/utils.js'
};

module.exports = {
  entry: [utils[process.env.TARGET || 'osx'], '../javascript/main.jsx'],
  output: {
    publicPath: 'public/',
    path: __dirname + '/public',
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {test: /\.jsx$/, loader: 'jsx-loader?harmony'},
      {test: /\.styl$/, loader: 'style-loader!css-loader!stylus-loader'},
      {test: /\.json$/, loader: 'json-loader'},
      {test: /\.ttf$/, loader: 'file-loader' }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx', '.styl' ]
  }
};
<|endoftext|>


<commit_before>var crypto = require('./crypto.js');
var db = require('../db/db.js');
var serverLoginPackets = require('./login/server.js');
var serverGamePackets = require('./game/server.js');

var helper = {
    defaultKey: [0x6b, 0x60, 0xcb, 0x5b, 0x82, 0xce, 0x90, 0xb1, 0xcc, 0x2b, 0x6c, 0x55, 0x6c, 0x6c, 0x6c, 0x6c],
    autoCreate: true
};

helper.initializeMapRegions = (gameServer) => {
    var query = db.getMapRegions();
    helper.poolGameServer.getConnection(function (err_con, connection) {

        if (err_con) {
            console.log(err_con);
        } else {

            connection.query(query.text, query.values, function (err, result) {

                connection.release();

                if (err) {
                    console.log(err);
                } else {

                    var count2 = 0;

                    if (!gameServer.World.regions) gameServer.World.regions = [];

                    _.each(result, (region) => {
                        regionId = region.region;

                        for (var j = 0; j < 10; j++)
                        {
                            if (!gameServer.World.regions[j]) gameServer.World.regions[j] = [];

                            gameServer.World.regions[j][region] = region["sec" + j];

                            count2++;

                        }
                    });

                    console.log('[GS] Loaded map regions: ' + count2);

                }

            });

        }
    });

};

helper.isInsideRadiusObject = (object, x, y, z, radius, checkZ, strictCheck) => {
    return helper.isInsideRadiusPos(object.X, object.Y, object.Z, x, y, z, radius, checkZ, strictCheck);
};

helper.isInsideRadiusPlayers = (player1, player2, radius, checkZ, strictCheck) => {
    return helper.isInsideRadiusPos(player1.X, player1.Y, player1.Z, player2.X, player2.Y, player2.Z, radius, checkZ, strictCheck);
};

helper.isInsideRadiusPos = (posX1, posY1, posZ1, posX2, posY2, posZ2, radius, checkZ, strictCheck) => {
    var dx = posX2 - posX1;
    var dy = posY2 - posY1;
    var dz = posZ2 - posZ1;

    if (strictCheck) {
        if (checkZ) return ((dx * dx) + (dy * dy) + (dz * dz)) < (radius * radius);

        return ((dx * dx) + (dy * dy)) < (radius * radius);
    }

    if (checkZ) return ((dx * dx) + (dy * dy) + (dz * dz)) <= (radius * radius);

    return ((dx * dx) + (dy * dy)) <= (radius * radius);
}

helper.getMapRegion = (gameServer, posX, posY) => {
    return gameServer.World.regions[helper.getMapRegionX(posX)][helper.getMapRegionY(posY)];
}

helper.getMapRegionX = (posX) => {
    return (posX >> 15) + 4;// + centerTileX;
};

helper.getMapRegionY = (posY) => {
    return (posY >> 15) + 10;// + centerTileX;
};

helper.exceptionHandler = (ex) => {
    console.log('catch exception');
    console.log(ex);
};

helper.disconnectPlayer = (login, clients, error, sock) => {
    try {

        if (!sock) {
            sock = _.find(clients, (s) => {
                var username = sock.client.data ? sock.client.data.login : "";
                return username == login
            });
        }

        // error: 0 - kick; 1 - attemp login; ...
        // TODO: send disconnect packet

    } catch (ex) {
        helper.exceptionHandler(ex);
    }
};

helper.syncPlayersCount = function (gameServer) {
    try {

        var playersCount = gameServer.clients.length;

        if (playersCount != gameServer.onlineSyncCount) {

            var query = db.updateServerData(playersCount);
            helper.poolGameServer.getConnection(function (err_con, connection) {

                if (err_con) {
                    console.log(err_con);
                } else {

                    connection.query(query.text, query.values, function (err, result) {

                        connection.release();

                        if (err) {
                            console.log(err);
                        } else {

                            gameServer.onlineSyncCount = playersCount;
                            console.log('[GS] Online Players counter - synchronized: ' + playersCount);

                        }

                    });

                }

            });

        }

    } catch (ex) {
        helper.exceptionHandler(ex);
    }
};

helper.getPlanDistanceSq = function (x, y) {
    var dist = 0;
    try {
        dist = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
    return dist;
};

helper.setIntention = function (sock, intention, args) {
    try {

        // TODO: Stop the follow mode if necessary
        //if ((intention != "AI_INTENTION_FOLLOW") && (intention != "AI_INTENTION_ATTACK"))
        // sock.client.char.intention

        switch (intention) {
            case "AI_INTENTION_MOVE_TO":

                if (sock.client.char.intention == "AI_INTENTION_REST") {
                    helper.sendGamePacket('ActionFailed', sock);
                }

                // TODO: isAllSkillsDisabled -> ActionFailed

                // changeIntention(AI_INTENTION_MOVE_TO, pos, null);

                // clientStopAutoAttack();

                break;
        }

    } catch (ex) {
        helper.exceptionHandler(ex);
    }

};

helper.uncnownLoginPacket = function (sock, packetId, packetsArrayParse) {
    console.log('[LS] UNKNOWN PACKET - ' + packetId);
    sock.destroy();
};

helper.uncnownGamePacket = function (sock, packetId, packetsArrayParse) {
    console.log('[GS] UNKNOWN PACKET - ' + packetId);
};

helper.sendLoginPacket = function (packetName, sock) {
    try {
        var packet = serverLoginPackets[packetName](arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10]);
        var packetArray = helper.preSendLogin(packet.getContent(), sock);
        sock.write(new Buffer(packetArray));
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
}

helper.sendGamePacket = function (packetName, sock) {
    try {
        var packet = serverGamePackets[packetName](arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10]);
        var packetArray = helper.preSendGame(packet.getContent(), sock);
        sock.write(new Buffer(packetArray));
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
}

helper.preSendGame = function (array, sock) {
    try {
        crypto.encrypt(sock, array, 0, array.length);

        var newArray1 = new Uint8Array(array.length + 2);
        newArray1.fill(0, 0, array.length + 2);
        for (var i = 0; i < array.length; i++) {
            newArray1[i + 2] = array[i] || 0;
        }

        var len = array.length + 2;
        newArray1[0] = (len & 0xff);
        newArray1[1] = ((len >> 8) & 0xff);

        return newArray1;
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
    return [];
}

helper.cryptPreSendGame = function (array, sock) {
    try {
        var newArray1 = new Uint8Array(array.length + 2);
        newArray1.fill(0, 0, array.length + 2);
        for (var i = 0; i < array.length; i++) {
            newArray1[i + 2] = array[i] || 0;
        }

        var len = array.length + 2;
        newArray1[0] = (len & 0xff);
        newArray1[1] = ((len >> 8) & 0xff);

        return newArray1;
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
    return [];
}

helper.preSendLogin = function (array, sock) {
    try {

        var newArray1 = new Uint8Array(array.length + 4);
        newArray1.fill(0, 0, array.length + 4);
        for (var i = 0; i < array.length; i++) {
            newArray1[i] = array[i] || 0;
        }

        var newArray2 = new Uint8Array((newArray1.length + 8) - newArray1.length % 8);
        newArray2.fill(0, 0, (newArray1.length + 8) - newArray1.length % 8);
        for (var i = 0; i < newArray1.length; i++) {
            newArray2[i] = newArray1[i] || 0;
        }

        crypto.appendChecksum(newArray2, 0, newArray2.length);
        sock.client.blowFish.encrypt(newArray2, 0, newArray2.length);

        var newArray4 = new Uint8Array(newArray2.length + 2);
        var len = newArray2.length + 2;
        newArray4[0] = (len & 0xff);
        newArray4[1] = ((len >> 8) & 0xff);
        for (var i = 0; i < newArray2.length; i++) {
            newArray4[i + 2] = newArray2[i] || 0;
        }

        return newArray4;

    } catch (ex) {
        helper.exceptionHandler(ex);
    }

    return [];
}

helper.initPreSendLogin = function (array, pubKey, sock) {
    try {
        var newArray1 = new Uint8Array(array.length + 6);
        newArray1.fill(0, 0, array.length + 6);
        for (var i = 0; i < array.length; i++) {
            newArray1[i] = array[i] || 0;
        }

        var newArray2 = new Uint8Array((newArray1.length + 8) - newArray1.length % 8);
        newArray2.fill(0, 0, (newArray1.length + 8) - newArray1.length % 8);
        for (var i = 0; i < newArray1.length; i++) {
            newArray2[i] = newArray1[i] || 0;
        }

        var xorKey = (parseInt((Math.random() * 1000000000).toFixed(0)));
        var newArray3 = crypto.encXORPass(newArray2, 0, newArray2.length, xorKey)

        sock.client.blowFish.init(helper.defaultKey);
        sock.client.blowFish.encrypt(newArray3, 0, newArray3.length);
        sock.client.blowFish.init(pubKey);

        var newArray4 = new Uint8Array(186);
        newArray4[0] = 186;
        newArray4[1] = 0;
        for (var i = 0; i < newArray3.length; i++) {
            newArray4[i + 2] = newArray3[i] || 0;
        }

        return newArray4;

    } catch (ex) {
        helper.exceptionHandler(ex);
    }

    return [];
};

module.exports = helper;<commit_msg>fix say2 helper underscore<commit_after>var _ = require('underscore');
var crypto = require('./crypto.js');
var db = require('../db/db.js');
var serverLoginPackets = require('./login/server.js');
var serverGamePackets = require('./game/server.js');

var helper = {
    defaultKey: [0x6b, 0x60, 0xcb, 0x5b, 0x82, 0xce, 0x90, 0xb1, 0xcc, 0x2b, 0x6c, 0x55, 0x6c, 0x6c, 0x6c, 0x6c],
    autoCreate: true
};

helper.initializeMapRegions = (gameServer) => {
    var query = db.getMapRegions();
    helper.poolGameServer.getConnection(function (err_con, connection) {

        if (err_con) {
            console.log(err_con);
        } else {

            connection.query(query.text, query.values, function (err, result) {

                connection.release();

                if (err) {
                    console.log(err);
                } else {

                    var count2 = 0;

                    if (!gameServer.World.regions) gameServer.World.regions = [];

                    _.each(result, (region) => {
                        regionId = region.region;

                        for (var j = 0; j < 10; j++)
                        {
                            if (!gameServer.World.regions[j]) gameServer.World.regions[j] = [];

                            gameServer.World.regions[j][region] = region["sec" + j];

                            count2++;

                        }
                    });

                    console.log('[GS] Loaded map regions: ' + count2);

                }

            });

        }
    });

};

helper.isInsideRadiusObject = (object, x, y, z, radius, checkZ, strictCheck) => {
    return helper.isInsideRadiusPos(object.X, object.Y, object.Z, x, y, z, radius, checkZ, strictCheck);
};

helper.isInsideRadiusPlayers = (player1, player2, radius, checkZ, strictCheck) => {
    return helper.isInsideRadiusPos(player1.X, player1.Y, player1.Z, player2.X, player2.Y, player2.Z, radius, checkZ, strictCheck);
};

helper.isInsideRadiusPos = (posX1, posY1, posZ1, posX2, posY2, posZ2, radius, checkZ, strictCheck) => {
    var dx = posX2 - posX1;
    var dy = posY2 - posY1;
    var dz = posZ2 - posZ1;

    if (strictCheck) {
        if (checkZ) return ((dx * dx) + (dy * dy) + (dz * dz)) < (radius * radius);

        return ((dx * dx) + (dy * dy)) < (radius * radius);
    }

    if (checkZ) return ((dx * dx) + (dy * dy) + (dz * dz)) <= (radius * radius);

    return ((dx * dx) + (dy * dy)) <= (radius * radius);
}

helper.getMapRegion = (gameServer, posX, posY) => {
    return gameServer.World.regions[helper.getMapRegionX(posX)][helper.getMapRegionY(posY)];
}

helper.getMapRegionX = (posX) => {
    return (posX >> 15) + 4;// + centerTileX;
};

helper.getMapRegionY = (posY) => {
    return (posY >> 15) + 10;// + centerTileX;
};

helper.exceptionHandler = (ex) => {
    console.log('catch exception');
    console.log(ex);
};

helper.disconnectPlayer = (login, clients, error, sock) => {
    try {

        if (!sock) {
            sock = _.find(clients, (s) => {
                var username = sock.client.data ? sock.client.data.login : "";
                return username == login
            });
        }

        // error: 0 - kick; 1 - attemp login; ...
        // TODO: send disconnect packet

    } catch (ex) {
        helper.exceptionHandler(ex);
    }
};

helper.syncPlayersCount = function (gameServer) {
    try {

        var playersCount = gameServer.clients.length;

        if (playersCount != gameServer.onlineSyncCount) {

            var query = db.updateServerData(playersCount);
            helper.poolGameServer.getConnection(function (err_con, connection) {

                if (err_con) {
                    console.log(err_con);
                } else {

                    connection.query(query.text, query.values, function (err, result) {

                        connection.release();

                        if (err) {
                            console.log(err);
                        } else {

                            gameServer.onlineSyncCount = playersCount;
                            console.log('[GS] Online Players counter - synchronized: ' + playersCount);

                        }

                    });

                }

            });

        }

    } catch (ex) {
        helper.exceptionHandler(ex);
    }
};

helper.getPlanDistanceSq = function (x, y) {
    var dist = 0;
    try {
        dist = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
    return dist;
};

helper.setIntention = function (sock, intention, args) {
    try {

        // TODO: Stop the follow mode if necessary
        //if ((intention != "AI_INTENTION_FOLLOW") && (intention != "AI_INTENTION_ATTACK"))
        // sock.client.char.intention

        switch (intention) {
            case "AI_INTENTION_MOVE_TO":

                if (sock.client.char.intention == "AI_INTENTION_REST") {
                    helper.sendGamePacket('ActionFailed', sock);
                }

                // TODO: isAllSkillsDisabled -> ActionFailed

                // changeIntention(AI_INTENTION_MOVE_TO, pos, null);

                // clientStopAutoAttack();

                break;
        }

    } catch (ex) {
        helper.exceptionHandler(ex);
    }

};

helper.uncnownLoginPacket = function (sock, packetId, packetsArrayParse) {
    console.log('[LS] UNKNOWN PACKET - ' + packetId);
    sock.destroy();
};

helper.uncnownGamePacket = function (sock, packetId, packetsArrayParse) {
    console.log('[GS] UNKNOWN PACKET - ' + packetId);
};

helper.sendLoginPacket = function (packetName, sock) {
    try {
        var packet = serverLoginPackets[packetName](arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10]);
        var packetArray = helper.preSendLogin(packet.getContent(), sock);
        sock.write(new Buffer(packetArray));
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
}

helper.sendGamePacket = function (packetName, sock) {
    try {
        var packet = serverGamePackets[packetName](arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10]);
        var packetArray = helper.preSendGame(packet.getContent(), sock);
        sock.write(new Buffer(packetArray));
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
}

helper.preSendGame = function (array, sock) {
    try {
        crypto.encrypt(sock, array, 0, array.length);

        var newArray1 = new Uint8Array(array.length + 2);
        newArray1.fill(0, 0, array.length + 2);
        for (var i = 0; i < array.length; i++) {
            newArray1[i + 2] = array[i] || 0;
        }

        var len = array.length + 2;
        newArray1[0] = (len & 0xff);
        newArray1[1] = ((len >> 8) & 0xff);

        return newArray1;
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
    return [];
}

helper.cryptPreSendGame = function (array, sock) {
    try {
        var newArray1 = new Uint8Array(array.length + 2);
        newArray1.fill(0, 0, array.length + 2);
        for (var i = 0; i < array.length; i++) {
            newArray1[i + 2] = array[i] || 0;
        }

        var len = array.length + 2;
        newArray1[0] = (len & 0xff);
        newArray1[1] = ((len >> 8) & 0xff);

        return newArray1;
    } catch (ex) {
        helper.exceptionHandler(ex);
    }
    return [];
}

helper.preSendLogin = function (array, sock) {
    try {

        var newArray1 = new Uint8Array(array.length + 4);
        newArray1.fill(0, 0, array.length + 4);
        for (var i = 0; i < array.length; i++) {
            newArray1[i] = array[i] || 0;
        }

        var newArray2 = new Uint8Array((newArray1.length + 8) - newArray1.length % 8);
        newArray2.fill(0, 0, (newArray1.length + 8) - newArray1.length % 8);
        for (var i = 0; i < newArray1.length; i++) {
            newArray2[i] = newArray1[i] || 0;
        }

        crypto.appendChecksum(newArray2, 0, newArray2.length);
        sock.client.blowFish.encrypt(newArray2, 0, newArray2.length);

        var newArray4 = new Uint8Array(newArray2.length + 2);
        var len = newArray2.length + 2;
        newArray4[0] = (len & 0xff);
        newArray4[1] = ((len >> 8) & 0xff);
        for (var i = 0; i < newArray2.length; i++) {
            newArray4[i + 2] = newArray2[i] || 0;
        }

        return newArray4;

    } catch (ex) {
        helper.exceptionHandler(ex);
    }

    return [];
}

helper.initPreSendLogin = function (array, pubKey, sock) {
    try {
        var newArray1 = new Uint8Array(array.length + 6);
        newArray1.fill(0, 0, array.length + 6);
        for (var i = 0; i < array.length; i++) {
            newArray1[i] = array[i] || 0;
        }

        var newArray2 = new Uint8Array((newArray1.length + 8) - newArray1.length % 8);
        newArray2.fill(0, 0, (newArray1.length + 8) - newArray1.length % 8);
        for (var i = 0; i < newArray1.length; i++) {
            newArray2[i] = newArray1[i] || 0;
        }

        var xorKey = (parseInt((Math.random() * 1000000000).toFixed(0)));
        var newArray3 = crypto.encXORPass(newArray2, 0, newArray2.length, xorKey)

        sock.client.blowFish.init(helper.defaultKey);
        sock.client.blowFish.encrypt(newArray3, 0, newArray3.length);
        sock.client.blowFish.init(pubKey);

        var newArray4 = new Uint8Array(186);
        newArray4[0] = 186;
        newArray4[1] = 0;
        for (var i = 0; i < newArray3.length; i++) {
            newArray4[i + 2] = newArray3[i] || 0;
        }

        return newArray4;

    } catch (ex) {
        helper.exceptionHandler(ex);
    }

    return [];
};

module.exports = helper;<|endoftext|>


<commit_before>// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as Platform from '../platform/platform.js';

import {GlassPane} from './GlassPane.js';
import {ShortcutRegistry} from './ShortcutRegistry.js';
import {createShadowRootWithCoreStyles} from './utils/create-shadow-root-with-core-styles.js';
import {Events as ZoomManagerEvents, ZoomManager} from './ZoomManager.js';

/**
 * @unrestricted
 */
export class Tooltip {
  /**
   * @param {!Document} doc
   */
  constructor(doc) {
    this.element = doc.body.createChild('div');
    this._shadowRoot = createShadowRootWithCoreStyles(
        this.element, {cssFile: 'ui/tooltip.css', enableLegacyPatching: true, delegatesFocus: undefined});

    /** @type {!HTMLElement} */
    this._tooltipElement = /** @type {!HTMLElement} */ (this._shadowRoot.createChild('div', 'tooltip'));
    doc.addEventListener('mousemove', this._mouseMove.bind(this), true);
    doc.addEventListener('mousedown', this._hide.bind(this, true), true);
    doc.addEventListener('mouseleave', this._hide.bind(this, false), true);
    doc.addEventListener('keydown', this._hide.bind(this, true), true);
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    doc[_symbol] = this;
    ZoomManager.instance().addEventListener(ZoomManagerEvents.ZoomChanged, this._reset, this);
    if (doc.defaultView) {
      doc.defaultView.addEventListener('resize', this._reset.bind(this), false);
    }
  }

  /**
   * @param {!Document} doc
   */
  static installHandler(doc) {
    new Tooltip(doc);
  }

  /**
   * @param {!Element} element
   * @param {?Element|string} tooltipContent
   * @param {string=} actionId
   * @param {?TooltipOptions=} options
   */
  static install(element, tooltipContent, actionId, options) {
    if (!tooltipContent) {
      // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
      delete element[_symbol];
      return;
    }
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    element[_symbol] = {content: tooltipContent, actionId: actionId, options: options || {}};
    /** @type {?number} */
    let timeout;
    element.addEventListener('focus', /** @param {!Event} event */ event => {
      // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
      const tooltipInstance = element.ownerDocument[_symbol];
      if (tooltipInstance) {
        timeout = window.setTimeout(() => {
          if (element.matches(':focus-visible')) {
            tooltipInstance._show(element, event);
          }
          timeout = null;
        }, Timing.OpeningDelay);
      }
    });
    element.addEventListener('blur', () => {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
      const tooltipInstance = element.ownerDocument[_symbol];
      if (tooltipInstance) {
        tooltipInstance._hide();
      }
    });
  }

  /**
   * @param {!Element} element
   */
  static addNativeOverrideContainer(element) {
    _nativeOverrideContainer.push(element);
  }

  /**
   * @param {!Event} event
   */
  _mouseMove(event) {
    const mouseEvent = /** @type {!MouseEvent} */ (event);
    const path = mouseEvent.composedPath();
    if (!path || mouseEvent.buttons !== 0 || (mouseEvent.movementX === 0 && mouseEvent.movementY === 0)) {
      return;
    }

    if (this._anchorElement && path.indexOf(this._anchorElement) === -1) {
      this._hide(false);
    }

    for (const element of path) {
      if (element === this._anchorElement) {
        return;
      }
      // The offsetParent is null when the element or an ancestor has 'display: none'.
      if (!(element instanceof HTMLElement) || element.offsetParent === null) {
        continue;
      }
      // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
      if (element[_symbol]) {
        this._show(element, mouseEvent);
        return;
      }
    }
  }

  /**
   * @param {!Element} anchorElement
   * @param {!MouseEvent} event
   */
  _reposition(anchorElement, event) {
    // Reposition to ensure text doesn't overflow unnecessarily.
    this._tooltipElement.positionAt(0, 0);
    // Get container element.
    const container = GlassPane.container(/** @type {!Document} */ (anchorElement.ownerDocument));
    // Position tooltip based on the anchor element.
    const containerBox = container.boxInWindow(this.element.window());
    const anchorBox = /** @type {!Element} */ (this._anchorElement).boxInWindow(this.element.window());
    const anchorOffset = 2;
    const pageMargin = 2;
    const cursorOffset = 10;
    const textContentMatchesWhitespace = this._tooltipElement && (this._tooltipElement.textContent || '').match('\\s');
    this._tooltipElement.classList.toggle('tooltip-breakword', !textContentMatchesWhitespace);
    this._tooltipElement.style.maxWidth = (containerBox.width - pageMargin * 2) + 'px';
    this._tooltipElement.style.maxHeight = '';
    const tooltipWidth = this._tooltipElement.offsetWidth;
    const tooltipHeight = this._tooltipElement.offsetHeight;
    const anchorTooltipAtElement = this._anchorTooltipAtElement() || event.x === undefined;
    let tooltipX = anchorTooltipAtElement ? anchorBox.x : event.x + cursorOffset;
    tooltipX = Platform.NumberUtilities.clamp(
        tooltipX, containerBox.x + pageMargin, containerBox.x + containerBox.width - tooltipWidth - pageMargin);
    let tooltipY;
    if (!anchorTooltipAtElement) {
      tooltipY = event.y + cursorOffset + tooltipHeight < containerBox.y + containerBox.height ?
          event.y + cursorOffset :
          event.y - tooltipHeight - 1;
    } else {
      const onBottom =
          anchorBox.y + anchorOffset + anchorBox.height + tooltipHeight < containerBox.y + containerBox.height;
      tooltipY = onBottom ? anchorBox.y + anchorBox.height + anchorOffset : anchorBox.y - tooltipHeight - anchorOffset;
    }
    this._tooltipElement.positionAt(tooltipX, tooltipY);
  }

  /**
   * @returns {boolean}
   */
  _anchorTooltipAtElement() {
    if (!this._anchorElement) {
      throw new Error('No _anchorElement set');
    }
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    const tooltip = this._anchorElement[_symbol];

    if (tooltip.options.anchorTooltipAtElement !== undefined) {
      return tooltip.options.anchorTooltipAtElement;
    }

    // default legacy behavior; better to explicitly configure tooltip placement via options
    return this._anchorElement.nodeName === 'BUTTON' || this._anchorElement.nodeName === 'LABEL';
  }

  /**
   * @param {!Element} anchorElement
   * @param {!MouseEvent} event
   */
  _show(anchorElement, event) {
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    const tooltip = anchorElement[_symbol];
    this._anchorElement = anchorElement;
    this._tooltipElement.removeChildren();

    // Check if native tooltips should be used.
    if (this._shouldUseNativeTooltips()) {
      Object.defineProperty(this._anchorElement, 'title', /** @type {!Object} */ (_nativeTitle));
      Tooltip.install(this._anchorElement, tooltip.content);
      return;
    }

    if (typeof tooltip.content === 'string') {
      this._tooltipElement.setTextContentTruncatedIfNeeded(tooltip.content);
    } else {
      this._tooltipElement.appendChild(tooltip.content);
    }

    if (tooltip.actionId) {
      const shortcuts = ShortcutRegistry.instance().shortcutsForAction(tooltip.actionId);
      for (const shortcut of shortcuts) {
        const shortcutElement = this._tooltipElement.createChild('div', 'tooltip-shortcut');
        shortcutElement.textContent = shortcut.title();
      }
    }

    // Show tooltip instantly if a tooltip was shown recently.
    const now = Date.now();
    const instant = (!!this._tooltipLastClosed && now - this._tooltipLastClosed < Timing.InstantThreshold);
    this._tooltipElement.classList.toggle('instant', instant);
    this._tooltipLastOpened = instant ? now : now + Timing.OpeningDelay;

    this._reposition(anchorElement, event);
    this._tooltipElement.classList.add('shown');
  }

  /**
   * @return {boolean}
   */
  _shouldUseNativeTooltips() {
    for (const element of _nativeOverrideContainer) {
      if (this._anchorElement && this._anchorElement.isSelfOrDescendant(element)) {
        return true;
      }
    }
    return false;
  }

  /**
   * @param {boolean} removeInstant
   */
  _hide(removeInstant) {
    delete this._anchorElement;
    this._tooltipElement.classList.remove('shown');
    if (this._tooltipLastOpened && Date.now() > this._tooltipLastOpened) {
      this._tooltipLastClosed = Date.now();
    }
    if (removeInstant) {
      delete this._tooltipLastClosed;
    }
  }

  _reset() {
    this._hide(true);
    this._tooltipElement.positionAt(0, 0);
    this._tooltipElement.style.maxWidth = '0';
    this._tooltipElement.style.maxHeight = '0';
  }
}

/**
 * @typedef {{
 * anchorTooltipAtElement: (boolean|undefined)
 * }}
 */
// @ts-ignore typedef
export let TooltipOptions;

const Timing = {
  // Max time between tooltips showing that no opening delay is required.
  'InstantThreshold': 300,
  // Wait time before opening a tooltip.
  'OpeningDelay': 600
};

const _symbol = Symbol('Tooltip');

// Exported for layout tests.
export const TooltipSymbol = _symbol;

/** @type {!Array.<!Element>} */
const _nativeOverrideContainer = [];

const _nativeTitle = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'title');

Object.defineProperty(HTMLElement.prototype, 'title', {
  /**
   * @return {!Element|string}
   * @this {!Element}
   */
  get: function() {
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    const tooltip = this[_symbol];
    return tooltip ? tooltip.content : '';
  },

  /**
   * @param {!Element|string} x
   * @this {!Element}
   */
  set: function(x) {
    Tooltip.install(this, x);
  }
});
<commit_msg>Introduce static content getter for Tooltip<commit_after>// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as Platform from '../platform/platform.js';

import {GlassPane} from './GlassPane.js';
import {ShortcutRegistry} from './ShortcutRegistry.js';
import {createShadowRootWithCoreStyles} from './utils/create-shadow-root-with-core-styles.js';
import {Events as ZoomManagerEvents, ZoomManager} from './ZoomManager.js';

/**
 * @unrestricted
 */
export class Tooltip {
  /**
   * @param {!Document} doc
   */
  constructor(doc) {
    this.element = doc.body.createChild('div');
    this._shadowRoot = createShadowRootWithCoreStyles(
        this.element, {cssFile: 'ui/tooltip.css', enableLegacyPatching: true, delegatesFocus: undefined});

    /** @type {!HTMLElement} */
    this._tooltipElement = /** @type {!HTMLElement} */ (this._shadowRoot.createChild('div', 'tooltip'));
    doc.addEventListener('mousemove', this._mouseMove.bind(this), true);
    doc.addEventListener('mousedown', this._hide.bind(this, true), true);
    doc.addEventListener('mouseleave', this._hide.bind(this, false), true);
    doc.addEventListener('keydown', this._hide.bind(this, true), true);
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    doc[_symbol] = this;
    ZoomManager.instance().addEventListener(ZoomManagerEvents.ZoomChanged, this._reset, this);
    if (doc.defaultView) {
      doc.defaultView.addEventListener('resize', this._reset.bind(this), false);
    }
  }

  /**
   * @param {!Document} doc
   */
  static installHandler(doc) {
    new Tooltip(doc);
  }

  /**
   * @param {!Element} element
   * @param {?Element|string} tooltipContent
   * @param {string=} actionId
   * @param {?TooltipOptions=} options
   */
  static install(element, tooltipContent, actionId, options) {
    if (!tooltipContent) {
      // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
      delete element[_symbol];
      return;
    }
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    element[_symbol] = {content: tooltipContent, actionId: actionId, options: options || {}};
    /** @type {?number} */
    let timeout;
    element.addEventListener('focus', /** @param {!Event} event */ event => {
      // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
      const tooltipInstance = element.ownerDocument[_symbol];
      if (tooltipInstance) {
        timeout = window.setTimeout(() => {
          if (element.matches(':focus-visible')) {
            tooltipInstance._show(element, event);
          }
          timeout = null;
        }, Timing.OpeningDelay);
      }
    });
    element.addEventListener('blur', () => {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
      const tooltipInstance = element.ownerDocument[_symbol];
      if (tooltipInstance) {
        tooltipInstance._hide();
      }
    });
  }

  /**
   * @param {(!Element|!Document)} element
   * @return {string}
   */
  static getContent(element) {
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    const tooltip = element[_symbol];
    return tooltip ? tooltip.content : '';
  }

  /**
   * @param {!Element} element
   */
  static addNativeOverrideContainer(element) {
    _nativeOverrideContainer.push(element);
  }

  /**
   * @param {!Event} event
   */
  _mouseMove(event) {
    const mouseEvent = /** @type {!MouseEvent} */ (event);
    const path = mouseEvent.composedPath();
    if (!path || mouseEvent.buttons !== 0 || (mouseEvent.movementX === 0 && mouseEvent.movementY === 0)) {
      return;
    }

    if (this._anchorElement && path.indexOf(this._anchorElement) === -1) {
      this._hide(false);
    }

    for (const element of path) {
      if (element === this._anchorElement) {
        return;
      }
      // The offsetParent is null when the element or an ancestor has 'display: none'.
      if (!(element instanceof HTMLElement) || element.offsetParent === null) {
        continue;
      }
      if (Tooltip.getContent(element)) {
        this._show(element, mouseEvent);
        return;
      }
    }
  }

  /**
   * @param {!Element} anchorElement
   * @param {!MouseEvent} event
   */
  _reposition(anchorElement, event) {
    // Reposition to ensure text doesn't overflow unnecessarily.
    this._tooltipElement.positionAt(0, 0);
    // Get container element.
    const container = GlassPane.container(/** @type {!Document} */ (anchorElement.ownerDocument));
    // Position tooltip based on the anchor element.
    const containerBox = container.boxInWindow(this.element.window());
    const anchorBox = /** @type {!Element} */ (this._anchorElement).boxInWindow(this.element.window());
    const anchorOffset = 2;
    const pageMargin = 2;
    const cursorOffset = 10;
    const textContentMatchesWhitespace = this._tooltipElement && (this._tooltipElement.textContent || '').match('\\s');
    this._tooltipElement.classList.toggle('tooltip-breakword', !textContentMatchesWhitespace);
    this._tooltipElement.style.maxWidth = (containerBox.width - pageMargin * 2) + 'px';
    this._tooltipElement.style.maxHeight = '';
    const tooltipWidth = this._tooltipElement.offsetWidth;
    const tooltipHeight = this._tooltipElement.offsetHeight;
    const anchorTooltipAtElement = this._anchorTooltipAtElement() || event.x === undefined;
    let tooltipX = anchorTooltipAtElement ? anchorBox.x : event.x + cursorOffset;
    tooltipX = Platform.NumberUtilities.clamp(
        tooltipX, containerBox.x + pageMargin, containerBox.x + containerBox.width - tooltipWidth - pageMargin);
    let tooltipY;
    if (!anchorTooltipAtElement) {
      tooltipY = event.y + cursorOffset + tooltipHeight < containerBox.y + containerBox.height ?
          event.y + cursorOffset :
          event.y - tooltipHeight - 1;
    } else {
      const onBottom =
          anchorBox.y + anchorOffset + anchorBox.height + tooltipHeight < containerBox.y + containerBox.height;
      tooltipY = onBottom ? anchorBox.y + anchorBox.height + anchorOffset : anchorBox.y - tooltipHeight - anchorOffset;
    }
    this._tooltipElement.positionAt(tooltipX, tooltipY);
  }

  /**
   * @returns {boolean}
   */
  _anchorTooltipAtElement() {
    if (!this._anchorElement) {
      throw new Error('No _anchorElement set');
    }
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    const tooltip = this._anchorElement[_symbol];

    if (tooltip.options.anchorTooltipAtElement !== undefined) {
      return tooltip.options.anchorTooltipAtElement;
    }

    // default legacy behavior; better to explicitly configure tooltip placement via options
    return this._anchorElement.nodeName === 'BUTTON' || this._anchorElement.nodeName === 'LABEL';
  }

  /**
   * @param {!Element} anchorElement
   * @param {!MouseEvent} event
   */
  _show(anchorElement, event) {
    // @ts-ignore crbug.com/1150762: HTMLElement#title magic override.
    const tooltip = anchorElement[_symbol];
    this._anchorElement = anchorElement;
    this._tooltipElement.removeChildren();

    // Check if native tooltips should be used.
    if (this._shouldUseNativeTooltips()) {
      Object.defineProperty(this._anchorElement, 'title', /** @type {!Object} */ (_nativeTitle));
      Tooltip.install(this._anchorElement, tooltip.content);
      return;
    }

    if (typeof tooltip.content === 'string') {
      this._tooltipElement.setTextContentTruncatedIfNeeded(tooltip.content);
    } else {
      this._tooltipElement.appendChild(tooltip.content);
    }

    if (tooltip.actionId) {
      const shortcuts = ShortcutRegistry.instance().shortcutsForAction(tooltip.actionId);
      for (const shortcut of shortcuts) {
        const shortcutElement = this._tooltipElement.createChild('div', 'tooltip-shortcut');
        shortcutElement.textContent = shortcut.title();
      }
    }

    // Show tooltip instantly if a tooltip was shown recently.
    const now = Date.now();
    const instant = (!!this._tooltipLastClosed && now - this._tooltipLastClosed < Timing.InstantThreshold);
    this._tooltipElement.classList.toggle('instant', instant);
    this._tooltipLastOpened = instant ? now : now + Timing.OpeningDelay;

    this._reposition(anchorElement, event);
    this._tooltipElement.classList.add('shown');
  }

  /**
   * @return {boolean}
   */
  _shouldUseNativeTooltips() {
    for (const element of _nativeOverrideContainer) {
      if (this._anchorElement && this._anchorElement.isSelfOrDescendant(element)) {
        return true;
      }
    }
    return false;
  }

  /**
   * @param {boolean} removeInstant
   */
  _hide(removeInstant) {
    delete this._anchorElement;
    this._tooltipElement.classList.remove('shown');
    if (this._tooltipLastOpened && Date.now() > this._tooltipLastOpened) {
      this._tooltipLastClosed = Date.now();
    }
    if (removeInstant) {
      delete this._tooltipLastClosed;
    }
  }

  _reset() {
    this._hide(true);
    this._tooltipElement.positionAt(0, 0);
    this._tooltipElement.style.maxWidth = '0';
    this._tooltipElement.style.maxHeight = '0';
  }
}

/**
 * @typedef {{
 * anchorTooltipAtElement: (boolean|undefined)
 * }}
 */
// @ts-ignore typedef
export let TooltipOptions;

const Timing = {
  // Max time between tooltips showing that no opening delay is required.
  'InstantThreshold': 300,
  // Wait time before opening a tooltip.
  'OpeningDelay': 600
};

const _symbol = Symbol('Tooltip');

// Exported for layout tests.
export const TooltipSymbol = _symbol;

/** @type {!Array.<!Element>} */
const _nativeOverrideContainer = [];

const _nativeTitle = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'title');

Object.defineProperty(HTMLElement.prototype, 'title', {
  /**
   * @return {!Element|string}
   * @this {!Element}
   */
  get: function() {
    return Tooltip.getContent(this);
  },

  /**
   * @param {!Element|string} x
   * @this {!Element}
   */
  set: function(x) {
    Tooltip.install(this, x);
  }
});
<|endoftext|>


<commit_before>
//define the key ordering for level-sublevelq

var join = '\x01', separate = '\x00'
var join = '#', separate = '!'

exports.encode = function (e) {
  return separate + e[0].join(join) + separate + e[1]
}

exports.decode = function (s) {
  var i = s.indexOf(separate, 1)
  return [s.substring(1, i).split(join).filter(Boolean), s.substring(++i)]
}
<commit_msg>codec must expose whether they want binary or string<commit_after>
//define the key ordering for level-sublevelq

var join = '\x01', separate = '\x00'
var join = '#', separate = '!'

exports.encode = function (e) {
  return separate + e[0].join(join) + separate + e[1]
}

exports.decode = function (s) {
  var i = s.indexOf(separate, 1)
  return [s.substring(1, i).split(join).filter(Boolean), s.substring(++i)]
}

exports.buffer = false
<|endoftext|>


<commit_before>var app = angular.module("app", ["xeditable", "mc.resizer", "ui.bootstrap"]);

app.controller('NodeCtrl', [
        '$scope','$http','$location','$q', '$uibModal', '$log',
        function($scope,$http,$location,$q, $uibModal, $log) {
  var keyPrefix = '/v2/keys',
      statsPrefix = '/v2/stats';

  $scope.urlPrefix = $location.search().etcd || $location.protocol() + "://" + document.location.host;
  $scope.new_item = {
    name: '',
    value: '',
    isDir: false,
    node: null
  };

  $scope.getPrefix = function() {
    if ($scope.urlPrefix) {
      var splitted = $scope.urlPrefix.split("/");
      return splitted[0] + "//" + splitted[2]
    }
    return ''
  }

  $scope.setActiveNode = function(node) {
    $scope.activeNode = node;
    if(!node.open){
      $scope.toggleNode(node);
    }else{
      $scope.loadNode(node);
    }
  }

  function keyErrorHandler(data, url){
    var message = data;
    if(data.message) {
      message = data.message;
    }
    $scope.error = "Request failed - " + message + " - " + url;
  }

  function errorHandler(data, status, headers, config){
    var message = data;
    if(data.message) {
      message = data.message;
    }
    $scope.error = "Request failed - " + message + " - " + config.url;
    $scope.loading = false;
  }

  $scope.loadNode = function(node){
    delete $scope.error;
    $scope.loading = true;
    var url = $scope.getPrefix() + keyPrefix + node.key;
    $http({method: 'GET', url: url}).
      success(function(data) {
        if (! angular.isDefined(data.node)) {
            keyErrorHandler(data, url);
        } else {
            prepNodes(data.node.nodes,node);
            node.nodes = data.node.nodes;
            $scope.urlPrefix = $scope.getPrefix() + keyPrefix + node.key
        }
        $scope.loading = false;
      }).
      error(errorHandler);
  }

  $scope.toggleNode = function(node) {
    node.open = !node.open;
    if(node.open){
      $scope.loadNode(node);
    } else {
      node.nodes = [];
    }
  };
  $scope.hasProperties = function(node){
    for(var key in node.nodes){
      if(!node.nodes[key].dir){
        return true;
      }
    }
  }
  $scope.submit = function(){
    var splitted = $scope.urlPrefix.split("/");
    // var etcd = splitted[0] + "//" + splitted[2];
    // if (etcd !== $location.protocol() + "://" + document.location.host === !$location.search().etcd) {
    //   $location.search('etcd', etcd);
    // }
    $scope.root = {
        key: '/' + splitted.slice(5).join('/'),
        name: splitted.slice(-1)
    }
    delete $scope.activeNode;
    $scope.loadNode($scope.root);
  }

  $scope.resetRoot = function () {
    $scope.root = {
        key: '/',
        name: '/'
    }
    delete $scope.activeNode;
    $scope.loadNode($scope.root);
  }

  $scope.addNode = function(node){
    $scope.modalNewItem({
        name: '',
        value: '',
        isDir: false,
        node: node,
        title: 'New Key/Value pair for node ' + node.key,
        nameTitle: 'Name',
        op: 'addPair'
    }, $scope.addEtcdKeyValue);
  }

  $scope.addEtcdKeyValue = function() {
    var name = $scope.new_item.name;
    var value = $scope.new_item.value;
    var node = $scope.new_item.node;

    if(!name || name == "") return;

    $http({method: 'PUT',
    	   url: $scope.getPrefix() + keyPrefix + node.key + (node.key != "/" ? "/" : "") + name,
    	   params: {"value": value}}).
    success(function(data) {
      $scope.loadNode(node);
    }).
    error(errorHandler);
  }

  $scope.checkboxModel = {
    use_json_validation : false
  };
  $scope.updateNode = function(node,value){
    if ($scope.checkboxModel.use_json_validation) {
      try {
        JSON.parse(value);
      } catch (err) {
        return 'Not a json';
      }
    }
    $http({method: 'PUT',
      url: $scope.getPrefix() + keyPrefix + node.key,
      params: {"value": value}}).
    success(function(data) {
      $scope.loadNode(node);
    }).
    error(errorHandler);
  }

  $scope.renameNode = function(node,keyName){
    var newkey = node.key.slice(0, node.key.lastIndexOf('/')+1) + keyName;
    if (newkey == node.key) {
       return;
    }
    var d = $q.defer();
    var reject = function(e) {
      d.reject('Server Error');
    }
    $http({method: 'GET', url: $scope.getPrefix() + keyPrefix + node.key}).
      success(function(data) {
        if (data.node.value != node.value) {
          d.resolve('The value has changed by someone else');
          return
        }
        $http({method: 'PUT',
               url: $scope.getPrefix() + keyPrefix + newkey,
               params: {"value": node.value}}).
          success(function(data) {
            $http({method: 'GET', url: $scope.getPrefix() + keyPrefix + node.key}).
              success(function(data) {
                if (data.node.value != node.value) {
                  $http({method: 'DELETE', url: $scope.getPrefix() + keyPrefix + newkey}).
                    success(function(data) {
                      d.resolve('The value has changed by someone else');
                    }).
                    error(reject);
                } else {
                  $http({method: 'DELETE', url: $scope.getPrefix() + keyPrefix + node.key}).
                    success(function(data) {
                      $scope.loadNode(node.parent);
                      d.resolve();
                    }).
                    error(reject);
                }
              }).
              error(reject);
          }).
          error(reject);
      }).
      error(reject);
    return d.promise;
  }

  $scope.deleteNode = function(node){
    $http({method: 'DELETE', url: $scope.getPrefix() + keyPrefix + node.key}).
    success(function(data) {
      $scope.loadNode(node.parent);
    }).
    error(errorHandler);
  }

  $scope.copyNode = function(node){
    var dirName = prompt("Copy property to directory","/");
    if(!dirName || dirName == "") return;
    dirName = $scope.formatDir(dirName);
    $http({method: 'PUT',
      url: $scope.getPrefix() + keyPrefix + dirName + node.name,
      params: {"value": node.value}}).
    error(errorHandler);
  }

  $scope.createDir = function(node){
    $scope.modalNewItem({
        name: '',
        value: '',
        isDir: true,
        node: node,
        title: 'New Node under ' + node.key,
        nameTitle: 'Name',
        op: 'addDir'
    }, $scope.createEtcdDir);
  }

  $scope.createEtcdDir = function() {
    if (!$scope.new_item.name || $scope.new_item.name == "") return;
    var dirName = $scope.new_item.name;
    var node = $scope.new_item.node;
    $http({method: 'PUT',
      url: $scope.getPrefix() + keyPrefix + node.key + (node.key != "/" ? "/" : "") + dirName,
      params: {"dir": true}}).
    success(function(data) {
      $scope.loadNode(node);
    }).
    error(errorHandler);
  }

  $scope.copyDirAux = function(node, tarjet){
    $http({method: 'GET', url: $scope.getPrefix() + keyPrefix + node.key}).
      success(function(data) {
        prepNodes(data.node.nodes,node);
        node.nodes = data.node.nodes;
        for(var key in node.nodes){
          if (node.nodes[key].dir) {
            $scope.copyDirAux(node.nodes[key], tarjet + node.nodes[key].name + "/")
          } else {
            var url = $scope.getPrefix() + keyPrefix + tarjet + node.nodes[key].name
            $http({method: 'PUT',
              url: url,
              params: {"value": node.nodes[key].value}}).
            error(errorHandler);
          }
        }
      }).
      error(errorHandler);
  }

  $scope.copyDir = function(node){
    $scope.modalNewItem({
        name: node.key,
        value: '',
        isDir: true,
        node: node,
        op: 'copyDir',
        title: 'Copy Node from ' + node.key,
        nameTitle: 'To'
    }, $scope.etcdCopyDir);
  }

  $scope.etcdCopyDir = function() {
    var dirName = $scope.new_item.name;
    var node = $scope.new_item.node;

    if(!dirName || dirName == "") return;
    dirName = $scope.formatDir(dirName);
    $scope.copyDirAux(node, dirName)
  }

  $scope.deleteDir = function(node) {
    if(!confirm("Are you sure you want to delete " + node.key)) return;
    $http({method: 'DELETE',
      url: $scope.getPrefix() + keyPrefix + node.key + "?dir=true&recursive=true"}).
    success(function(data) {
      $scope.loadNode(node.parent);
    }).
    error(errorHandler);
  }

  $scope.formatDir = function(dirName){
    if(dirName.substr(dirName.trim().length - 1) != '/'){
      dirName += '/';
    }
    return dirName;
  }

  $scope.submit();

  function prepNodes(nodes,parent){
    for(var key in nodes){
      var node = nodes[key];
      var name = node.key.substring(node.key.lastIndexOf("/")+1);
      node.name = name;
      node.parent = parent;
    }
  }

  $scope.loadStats = function(){
    console.log("LOAD STATS");
    $scope.stats = {};
    $http({method: 'GET', url: $scope.getPrefix() + statsPrefix + "/store"}).
    success(function(data) {
      $scope.stats.store = JSON.stringify(data, null, " ");
    }).
    error(errorHandler);
    delete $scope.storeStats;
    $http({method: 'GET', url: $scope.getPrefix() + statsPrefix + "/leader"}).
    success(function(data) {
      $scope.stats.leader = JSON.stringify(data, null, " ");
    }).
    error(errorHandler);
    delete $scope.storeStats;
    $http({method: 'GET', url: $scope.getPrefix() + statsPrefix + "/self"}).
    success(function(data) {
      $scope.stats.self = JSON.stringify(data, null, " ");
    }).
    error(errorHandler);
  }

  $scope.modalNewItem = function (item, onPromise) {
    $scope.new_item = item;
    var modalInstance = $uibModal.open({
      templateUrl: 'modal-dialog.html',
      controller: 'ModalInstanceCtrl',
      resolve: {
        new_item: function () {
          return $scope.new_item;
        }
      }
    });

    modalInstance.result.then(function (new_item) {
        onPromise();
    }, function () {
        // dismissed - do nothing
    });
  }

}]);

app.run(function(editableOptions, editableThemes) {
  editableThemes.bs3.inputClass = 'input-sm';
  editableThemes.bs3.buttonsClass = 'btn-sm';
  editableOptions.theme = 'bs3';
});

app.controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, new_item) {
    $scope.new_item = new_item;

    $scope.newItemOk = function () {
      $uibModalInstance.close($scope.new_item);
    };

    $scope.newItemCancel = function () {
      $uibModalInstance.dismiss('cancel');
    };
});

app.directive('treeItem', function () {
  return {
    restrict: 'E',
    transclude: true,
    templateUrl: 'tree-item.html'
  };
});

<commit_msg>Converted some functions to anonymous<commit_after>var app = angular.module("app", ["xeditable", "mc.resizer", "ui.bootstrap"]);

app.controller('NodeCtrl', [
        '$scope','$http','$location','$q', '$uibModal', '$log',
        function($scope,$http,$location,$q, $uibModal, $log) {
  var keyPrefix = '/v2/keys',
      statsPrefix = '/v2/stats';

  $scope.urlPrefix = $location.search().etcd || $location.protocol() + "://" + document.location.host;
  $scope.new_item = {
    name: '',
    value: '',
    isDir: false,
    node: null
  };

  $scope.getPrefix = function() {
    if ($scope.urlPrefix) {
      var splitted = $scope.urlPrefix.split("/");
      return splitted[0] + "//" + splitted[2]
    }
    return ''
  }

  $scope.setActiveNode = function(node) {
    $scope.activeNode = node;
    if(!node.open){
      $scope.toggleNode(node);
    }else{
      $scope.loadNode(node);
    }
  }

  function keyErrorHandler(data, url){
    var message = data;
    if(data.message) {
      message = data.message;
    }
    $scope.error = "Request failed - " + message + " - " + url;
  }

  function errorHandler(data, status, headers, config){
    var message = data;
    if(data.message) {
      message = data.message;
    }
    $scope.error = "Request failed - " + message + " - " + config.url;
    $scope.loading = false;
  }

  $scope.loadNode = function(node){
    delete $scope.error;
    $scope.loading = true;
    var url = $scope.getPrefix() + keyPrefix + node.key;
    $http({method: 'GET', url: url}).
      success(function(data) {
        if (! angular.isDefined(data.node)) {
            keyErrorHandler(data, url);
        } else {
            prepNodes(data.node.nodes,node);
            node.nodes = data.node.nodes;
            $scope.urlPrefix = $scope.getPrefix() + keyPrefix + node.key
        }
        $scope.loading = false;
      }).
      error(errorHandler);
  }

  $scope.toggleNode = function(node) {
    node.open = !node.open;
    if(node.open){
      $scope.loadNode(node);
    } else {
      node.nodes = [];
    }
  };
  $scope.hasProperties = function(node){
    for(var key in node.nodes){
      if(!node.nodes[key].dir){
        return true;
      }
    }
  }
  $scope.submit = function(){
    var splitted = $scope.urlPrefix.split("/");
    // var etcd = splitted[0] + "//" + splitted[2];
    // if (etcd !== $location.protocol() + "://" + document.location.host === !$location.search().etcd) {
    //   $location.search('etcd', etcd);
    // }
    $scope.root = {
        key: '/' + splitted.slice(5).join('/'),
        name: splitted.slice(-1)
    }
    delete $scope.activeNode;
    $scope.loadNode($scope.root);
  }

  $scope.resetRoot = function () {
    $scope.root = {
        key: '/',
        name: '/'
    }
    delete $scope.activeNode;
    $scope.loadNode($scope.root);
  }

  $scope.addNode = function(node){
    $scope.modalNewItem({
        name: '',
        value: '',
        isDir: false,
        node: node,
        title: 'New Key/Value pair for node ' + node.key,
        nameTitle: 'Name',
        op: 'addPair'
    }, function() {
        var name = $scope.new_item.name;
        var value = $scope.new_item.value;
        var node = $scope.new_item.node;

        if (!name || name == "") return;

        $http({method: 'PUT',
               url: $scope.getPrefix() + keyPrefix + node.key + (node.key != "/" ? "/" : "") + name,
               params: {"value": value}}).
        success(function(data) {
          $scope.loadNode(node);
        }).
        error(errorHandler);
      });
  }

  $scope.checkboxModel = {
    use_json_validation : false
  };
  $scope.updateNode = function(node,value){
    if ($scope.checkboxModel.use_json_validation) {
      try {
        JSON.parse(value);
      } catch (err) {
        return 'Not a json';
      }
    }
    $http({method: 'PUT',
      url: $scope.getPrefix() + keyPrefix + node.key,
      params: {"value": value}}).
    success(function(data) {
      $scope.loadNode(node);
    }).
    error(errorHandler);
  }

  $scope.renameNode = function(node,keyName){
    var newkey = node.key.slice(0, node.key.lastIndexOf('/')+1) + keyName;
    if (newkey == node.key) {
       return;
    }
    var d = $q.defer();
    var reject = function(e) {
      d.reject('Server Error');
    }
    $http({method: 'GET', url: $scope.getPrefix() + keyPrefix + node.key}).
      success(function(data) {
        if (data.node.value != node.value) {
          d.resolve('The value has changed by someone else');
          return
        }
        $http({method: 'PUT',
               url: $scope.getPrefix() + keyPrefix + newkey,
               params: {"value": node.value}}).
          success(function(data) {
            $http({method: 'GET', url: $scope.getPrefix() + keyPrefix + node.key}).
              success(function(data) {
                if (data.node.value != node.value) {
                  $http({method: 'DELETE', url: $scope.getPrefix() + keyPrefix + newkey}).
                    success(function(data) {
                      d.resolve('The value has changed by someone else');
                    }).
                    error(reject);
                } else {
                  $http({method: 'DELETE', url: $scope.getPrefix() + keyPrefix + node.key}).
                    success(function(data) {
                      $scope.loadNode(node.parent);
                      d.resolve();
                    }).
                    error(reject);
                }
              }).
              error(reject);
          }).
          error(reject);
      }).
      error(reject);
    return d.promise;
  }

  $scope.deleteNode = function(node){
    $http({method: 'DELETE', url: $scope.getPrefix() + keyPrefix + node.key}).
    success(function(data) {
      $scope.loadNode(node.parent);
    }).
    error(errorHandler);
  }

  $scope.copyNode = function(node){
    var dirName = prompt("Copy property to directory","/");
    if(!dirName || dirName == "") return;
    dirName = $scope.formatDir(dirName);
    $http({method: 'PUT',
      url: $scope.getPrefix() + keyPrefix + dirName + node.name,
      params: {"value": node.value}}).
    error(errorHandler);
  }

  $scope.createDir = function(node){
    $scope.modalNewItem({
        name: '',
        value: '',
        isDir: true,
        node: node,
        title: 'New Node under ' + node.key,
        nameTitle: 'Name',
        op: 'addDir'
    }, function() {
        if (!$scope.new_item.name || $scope.new_item.name == "") return;
        var dirName = $scope.new_item.name;
        var node = $scope.new_item.node;
        $http({method: 'PUT',
          url: $scope.getPrefix() + keyPrefix + node.key + (node.key != "/" ? "/" : "") + dirName,
          params: {"dir": true}}).
        success(function(data) {
          $scope.loadNode(node);
        }).
        error(errorHandler);
      }
    );
  }

  $scope.copyDirAux = function(node, tarjet){
    $http({method: 'GET', url: $scope.getPrefix() + keyPrefix + node.key}).
      success(function(data) {
        prepNodes(data.node.nodes,node);
        node.nodes = data.node.nodes;
        for(var key in node.nodes){
          if (node.nodes[key].dir) {
            $scope.copyDirAux(node.nodes[key], tarjet + node.nodes[key].name + "/")
          } else {
            var url = $scope.getPrefix() + keyPrefix + tarjet + node.nodes[key].name
            $http({method: 'PUT',
              url: url,
              params: {"value": node.nodes[key].value}}).
            error(errorHandler);
          }
        }
      }).
      error(errorHandler);
  }

  $scope.copyDir = function(node){
    $scope.modalNewItem({
        name: node.key,
        value: '',
        isDir: true,
        node: node,
        op: 'copyDir',
        title: 'Copy Node from ' + node.key,
        nameTitle: 'To'
    }, function() {
        var dirName = $scope.new_item.name;
        var node = $scope.new_item.node;

        if(!dirName || dirName == "") return;
        dirName = $scope.formatDir(dirName);
        $scope.copyDirAux(node, dirName)
      }
    );
  }

  $scope.deleteDir = function(node) {
    if(!confirm("Are you sure you want to delete " + node.key)) return;
    $http({method: 'DELETE',
      url: $scope.getPrefix() + keyPrefix + node.key + "?dir=true&recursive=true"}).
    success(function(data) {
      $scope.loadNode(node.parent);
    }).
    error(errorHandler);
  }

  $scope.formatDir = function(dirName){
    if(dirName.substr(dirName.trim().length - 1) != '/'){
      dirName += '/';
    }
    return dirName;
  }

  $scope.submit();

  function prepNodes(nodes,parent){
    for(var key in nodes){
      var node = nodes[key];
      var name = node.key.substring(node.key.lastIndexOf("/")+1);
      node.name = name;
      node.parent = parent;
    }
  }

  $scope.loadStats = function(){
    console.log("LOAD STATS");
    $scope.stats = {};
    $http({method: 'GET', url: $scope.getPrefix() + statsPrefix + "/store"}).
    success(function(data) {
      $scope.stats.store = JSON.stringify(data, null, " ");
    }).
    error(errorHandler);
    delete $scope.storeStats;
    $http({method: 'GET', url: $scope.getPrefix() + statsPrefix + "/leader"}).
    success(function(data) {
      $scope.stats.leader = JSON.stringify(data, null, " ");
    }).
    error(errorHandler);
    delete $scope.storeStats;
    $http({method: 'GET', url: $scope.getPrefix() + statsPrefix + "/self"}).
    success(function(data) {
      $scope.stats.self = JSON.stringify(data, null, " ");
    }).
    error(errorHandler);
  }

  $scope.modalNewItem = function (item, onPromise) {
    $scope.new_item = item;
    var modalInstance = $uibModal.open({
      templateUrl: 'modal-dialog.html',
      controller: 'ModalInstanceCtrl',
      resolve: {
        new_item: function () {
          return $scope.new_item;
        }
      }
    });

    modalInstance.result.then(function (new_item) {
        onPromise();
    }, function () {
        // dismissed - do nothing
    });
  }

}]);

app.run(function(editableOptions, editableThemes) {
  editableThemes.bs3.inputClass = 'input-sm';
  editableThemes.bs3.buttonsClass = 'btn-sm';
  editableOptions.theme = 'bs3';
});

app.controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, new_item) {
    $scope.new_item = new_item;

    $scope.newItemOk = function () {
      $uibModalInstance.close($scope.new_item);
    };

    $scope.newItemCancel = function () {
      $uibModalInstance.dismiss('cancel');
    };
});

<|endoftext|>


<commit_before>export const colors = {
  blue: "#3B7A9E",
  lightBlue: "#61BDE0",
  darkBlue: "#5F7682",
  grey: "#999999",
  darkGrey: "#666666",
  lightGrey: "#c3c3c3",
  lighterGrey: "#f5f5f5",
  red: "#D0021B",
  orange: "#FDBD56",
  black: "#333333",
  white: "#FFFFFF"
};

colors.primary = colors.blue;
colors.secondary = colors.darkBlue;
colors.tertiary = colors.orange;
colors.text = colors.black;
colors.textLight = colors.darkGrey;
colors.borders = colors.grey;
colors.bordersLight = colors.lightGrey;

export const radius = "4px";
export const shadow = "0 2px 4px rgba(0,0,0,0.1)";

export default {
  colors,
  radius,
  shadow
};
<commit_msg>Add light medium grey colour to constants<commit_after>export const colors = {
  blue: "#3B7A9E",
  lightBlue: "#61BDE0",
  darkBlue: "#5F7682",
  grey: "#999999",
  darkGrey: "#666666",
  lightGrey: "#c3c3c3",
  lightMediumGrey: "#E4E8EB",
  lighterGrey: "#f5f5f5",
  red: "#D0021B",
  orange: "#FDBD56",
  black: "#333333",
  white: "#FFFFFF"
};

colors.primary = colors.blue;
colors.secondary = colors.darkBlue;
colors.tertiary = colors.orange;
colors.text = colors.black;
colors.textLight = colors.darkGrey;
colors.borders = colors.grey;
colors.bordersLight = colors.lightGrey;

export const radius = "4px";
export const shadow = "0 2px 4px rgba(0,0,0,0.1)";

export default {
  colors,
  radius,
  shadow
};
<|endoftext|>


<commit_before>import React from 'react'
import {
  Provider,
  Banner,
  Heading,
  Lead,
  Container,
  Flex,
  Box,
  Text,
  Subhead,
  Absolute,
  ButtonOutline
} from 'rebass'
import theme, { colors, mx } from '../theme'
import { Head, Link } from 'react-static'
import Features from '../components/Features'
import Stat from '../components/Stat'

const css = `
  body { background-color: #000; }
  #root > div, #features *, #stats span {
    color: ${colors.green[6]} !important;
    font-family: ${theme.monospace} !important;
    text-shadow: 0 1px 3px ${colors.green[4]};
    letter-spacing: -.02em;
  }
  #features > div > div {
    background-color: #000;
    border: 1px solid ${colors.green[6]};
    border-radius: 0;
  }
  #features img { display: none !important; }
  #features * {
    font-size: ${theme.fontSizes[2]};
  }
  #stats > div {
    padding-left: .5rem;
    padding-right: .5rem;
  }
  #stats p { color: ${colors.green[8]}; }
  #stats span { font-weight: 400; }
`

const Header = Flex.extend.attrs({
  is: 'header',
  align: 'center',
  justify: 'center',
  direction: 'column',
  px: [3, 0],
  py: [5, 3]
})`
  background: #000 url('/map-repl.svg') no-repeat;
  background-size: cover;
  background-position: 33% top;
  border-bottom: 1px solid ${colors.green[9]};
  text-align: center;
  ${mx[0]} {
    background-position: center top;
    min-height: 75vh !important;
  }
`
const Section = Box.extend.attrs({ is: 'section', py: 4 })`
  border-bottom: 1px solid ${colors.green[9]};
  text-align: center;
`
const Footer = Box.extend.attrs({
  is: 'footer',
  py: 4,
  f: 2
})`text-align: center;`

const Tagline = Text.extend.attrs({
  f: 3,
  mb: 2
})`
  text-align: center;
  text-transform: uppercase;
`
const Headline = Heading.extend.attrs({
  is: 'h1',
  f: 6,
  mb: 2
})`line-height: 1.125;`
const Subheadline = Heading.extend.attrs({
  f: 5,
  mt: 4,
  px: 3
})``

const CTA = Box.extend.attrs({
  is: 'a',
  color: colors.green[6],
  px: [2, 3, 4],
  py: [2, 3],
  mx: 2,
  f: [3, 4]
})`
  border: 2px solid ${colors.green[6]};
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;
  cursor: pointer;
`

export default () => (
  <Provider theme={theme}>

      <title>Repl.it – Hack Club</title>


<commit_before>import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';

import selectUsers from 'src/selectors/users';
import selectRoomsUsers from 'src/selectors/rooms-users';
import selectRoomsMessages from 'src/selectors/rooms-messages';
import roomsActions from 'src/actions/rooms';
import Room from 'src/components/Room';
import RoomGroup from 'src/components/RoomGroup';
import RoomMessages from 'src/components/RoomMessages';
import Message from 'src/components/Message';
import RoomType from 'src/components/RoomType';

const mapStateToProps = function (state) {
  return {
    users: selectUsers(state),
    roomsUsers: selectRoomsUsers(state),
    roomsMessages: selectRoomsMessages(state),
  };
};

class RoomContainer extends Component {

  constructor () {
    super(...arguments);
  }

  render () {

    const { params, users, roomsUsers, roomsMessages } = this.props;
    const { roomId } = params;

    const onSend = (details) => {
      roomsActions.message({
        room: roomId,
        content: details.message
      });
    };

    let groupsEls;
    if (roomId) {

      const roomMessages = roomsMessages.find(rm => rm.id === roomId);

      if (!roomMessages) return null;

      const { groups } = roomMessages;

      groupsEls = [];

      groups.forEach((group, index) => {

        const messages = group.messages.map(msg => {

          const roomUser = roomsUsers.
            find(ru => ru.id === roomId).
            users.
            find(usr => usr.id === msg.user);
          const userData = users.find(usr => usr.id === msg.user);
          const user = { ...roomUser, ...userData };
          const timestamp = msg.createdAt;

          return (
            <Message key={msg.id} {...user} timestamp={timestamp}>
              {msg.content}
            </Message>
          );
        });

        groupsEls.push(
          <RoomGroup key={index} header={group.title}>
            <RoomMessages>
              {messages}
            </RoomMessages>
          </RoomGroup>
        );
      });
    }

    return (
      <Room>
        {groupsEls}
        { roomId ? <RoomType onSend={onSend} /> : null }
      </Room>
    );
  }
}

export default withRouter(connect(mapStateToProps)(RoomContainer));
<commit_msg>[fix] room<commit_after>import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';

import selectUsers from 'src/selectors/users';
import selectRoomsUsers from 'src/selectors/rooms-users';
import selectRoomsMessages from 'src/selectors/rooms-messages';
import roomsActions from 'src/actions/rooms';
import Room from 'src/components/Room';
import RoomGroup from 'src/components/RoomGroup';
import RoomMessages from 'src/components/RoomMessages';
import Message from 'src/components/Message';
import RoomType from 'src/components/RoomType';

const mapStateToProps = function (state) {
  return {
    users: selectUsers(state),
    roomsUsers: selectRoomsUsers(state),
    roomsMessages: selectRoomsMessages(state),
  };
};

class RoomContainer extends Component {

  constructor () {
    super(...arguments);
  }

  render () {

    const { params, users, roomsUsers, roomsMessages } = this.props;
    const { roomId } = params;

    const onSend = (details) => {
      roomsActions.message({
        room: roomId,
        content: details.message
      });
    };

    let groupsEls;
    if (roomId) {

      const roomMessages = roomsMessages.find(rm => rm.id === roomId);

      if (!roomMessages) return null;

      const { groups } = roomMessages;

      groupsEls = [];

      groups.forEach((group, index) => {

        const messages = group.messages.map(msg => {

          const roomUser = roomsUsers.
            find(ru => ru.id === roomId).
            users.
            find(usr => usr.id === msg.user);
          const { moderator } = roomUser;

          const user = users.find(usr => usr.id === msg.user);
          const { name, photo } = user;

          const messageData = { name, photo, moderator };
          const timestamp = msg.createdAt;

          return (
            <Message key={msg.id} {...messageData} timestamp={timestamp}>
              {msg.content}
            </Message>
          );
        });

        groupsEls.push(
          <RoomGroup key={index} header={group.title}>
            <RoomMessages>
              {messages}
            </RoomMessages>
          </RoomGroup>
        );
      });
    }

    return (
      <Room>
        {groupsEls}
        { roomId ? <RoomType onSend={onSend} /> : null }
      </Room>
    );
  }
}

export default withRouter(connect(mapStateToProps)(RoomContainer));
<|endoftext|>