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

    /*global
        L, reqwest
    */

    var map = L.map('hugemap', {
            minZoom: 10
        }),
        stopsGroup = L.layerGroup(),
        vehiclesGroup = L.layerGroup();

    map.attributionControl.setPrefix('');

    L.tileLayer('https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png', {
        attribution: '© Stadia Maps © OpenMapTiles © OpenStreetMap contributors',
    }).addTo(map);

    L.control.locate().addTo(map);

    L.control.layers(null, {
        'Show stops': stopsGroup
    }, {
        collapsed: false
    }).addTo(map);

    var lastStopsReq,
        highWater,
        showStops = true,
        zoomedIn = true;

    if (document.referrer && document.referrer.indexOf('/stops/') > -1) {
        var referrerStop = '/stops/' + document.referrer.split('/stops/')[1];
    } else if (localStorage && localStorage.hideStops) {
        showStops = false;
    }

    stopsGroup.on('add', function() {
        if (map.getZoom() < 14) {
            map.setZoom(14); // loadStops will be called by moveend handler
        } else if (!showStops) {
            loadStops();
        }
        showStops = true;
        if (localStorage) {
            localStorage.removeItem('hideStops');
        }
    }).on('remove', function() {
        showStops = false;
        if (localStorage) {
            localStorage.setItem('hideStops', '1');
        }
    });

    vehiclesGroup.addTo(map);

    function getTransform(heading, scale) {
        if (heading === null && !scale) {
            return '';
        }
        var transform = 'transform:';
        if (heading !== null) {
            transform += ' rotate(' + heading + 'deg)';
        }
        if (scale) {
            transform += ' scale(1.5)';
        }
        return '-webkit-' + transform + ';' + transform;
    }

    function getStopIcon(indicator, bearing) {
        var html = '';
        if (indicator) {
            var parts = indicator.split(' ');
            if (parts.length === 2) {
                var firstPart = parts[0].toLowerCase();
                if (firstPart === 'stop' || firstPart === 'bay' || firstPart === 'stand' || firstPart === 'stance' || firstPart === 'gate') {
                    html = parts[1];
                }
            } else if (parts.length === 0 || indicator.length < 3) {
                html = indicator;
            }
        }
        var className = 'stop stop-' + html.length;
        if (bearing !== null) {
            html += '

';
        } else {
            html += '

';
        }
        return L.divIcon({
            iconSize: [16, 16],
            html: html,
            popupAnchor: [0, -4],
            className: className
        });
    }

    var oldStops = {},
        newStops = {};

    function handleStop(data) {
        if (data.properties.url in oldStops) {
            var marker = oldStops[data.properties.url];
            newStops[data.properties.url] = marker;
            return;
        }

        var a = document.createElement('a');
        marker = L.marker(L.latLng(data.geometry.coordinates[1], data.geometry.coordinates[0]), {
            icon: getStopIcon(data.properties.indicator, data.properties.bearing)
        });

        a.innerHTML = '' + data.properties.name + '' + data.properties.services.join('') + '';
        a.href = data.properties.url;

        marker.bindPopup(a.outerHTML, {
            autoPan: false
        });

        marker.addTo(stopsGroup);
        newStops[data.properties.url] = marker;
    }

    function loadStops() {
        var bounds = map.getBounds();
        var params = '?ymax=' + bounds.getNorth() + '&xmax=' + bounds.getEast() + '&ymin=' + bounds.getSouth() + '&xmin=' + bounds.getWest();

        if (lastStopsReq) {
            lastStopsReq.abort();
        }
        if (highWater && highWater.contains(bounds)) {
            return;
        }
        lastStopsReq = reqwest('/stops.json' + params, function(data) {
            if (data && data.features) {
                highWater = bounds;
                for (var i = data.features.length - 1; i >= 0; i -= 1) {
                    handleStop(data.features[i]);
                }
                for (var stop in oldStops) {
                    if (!(stop in newStops)) {
                        stopsGroup.removeLayer(oldStops[stop]);
                    }
                }
                if (referrerStop) {
                    stop = newStops[referrerStop];
                    if (stop) {
                        stop.openPopup();
                    }
                }
                oldStops = newStops;
                newStops = {};
            }
        });
    }

    function getBusIcon(item, active) {
        var heading = item.h;
        if (heading !== null) {
            var arrow = '

';
            if (heading < 180) {
                heading -= 90;
            } else {
                heading -= 270;
            }
        }
        var className = 'bus';
        if (active) {
            className += ' selected';
        }
        if (item.c) {
            var style = 'background:' + item.c;
            className += ' coloured';
            if (item.t) {
                className += ' white-text';
            }
            style += ';';
        } else {
            style = '';
        }
        style += getTransform(heading, active);
        var html = '
';
        if (item.r) {
            html += item.r;
        }
        html += '
';
        if (arrow) {
            html += arrow;
        }
        return L.divIcon({
            iconSize: [20, 20],
            html: html,
            popupAnchor: [0, -5],
        });
    }

    var clickedMarker, agoTimeout;

    function getDelay(item) {
        if (item.e === 0) {
            return 'On time
';
        }
        if (item.e) {
            var content = 'About ';
            if (item.e > 0) {
                content += item.e;
            } else {
                content += item.e * -1;
            }
            content += ' minute';
            if (item.e !== 1 && item.e !== -1) {
                content += 's';
            }
            if (item.e > 0) {
                content += ' early';
            } else {
                content += ' late';
            }
            content += '
';
            return content;
        }
        return '';
    }

    function getPopupContent(item) {
        var content = getDelay(item);
        var now = new Date();
        var then = new Date(item.d);
        var ago = Math.round((now.getTime() - then.getTime()) / 1000);

        if (ago >= 1800) {
            content += 'Updated at ' + then.toTimeString().slice(0, 5);
        } else if (ago >= 59) {
            var minutes = Math.round(ago / 60);
            if (minutes === 1) {
                content += '1 minute ago';
            } else {
                content += minutes + ' minutes ago';
            }
            agoTimeout = setTimeout(updatePopupContent, (61 - ago % 60) * 1000);
        } else {
            if (ago === 1) {
                content += '1 second ago';
            } else {
                content += ago + ' seconds ago';
            }
            agoTimeout = setTimeout(updatePopupContent, 1000);
        }
        return content;
    }

    function updatePopupContent() {
        if (agoTimeout) {
            clearTimeout(agoTimeout);
        }
        var marker = vehicles[clickedMarker];
        if (marker) {
            var item = marker.options.item;
            marker.getPopup().setContent((marker.options.popupContent || '') + getPopupContent(item, true));
        }
    }

    function handlePopupOpen(event) {
        var marker = event.target;
        var item = marker.options.item;

        clickedMarker = item.i;
        updatePopupContent();

        if (zoomedIn) {
            marker.setIcon(getBusIcon(item, true));
            marker.setZIndexOffset(2000);
        }

        reqwest({
            url: '/vehicles/locations/' + item.i,
            success: function(content) {
                marker.options.popupContent = content;
                updatePopupContent();
            }
        });
    }

    function handlePopupClose(event) {
        if (map.hasLayer(event.target)) {
            clickedMarker = null;
            if (zoomedIn) {
                // make the icon small again
                event.target.setIcon(getBusIcon(event.target.options.item));
                event.target.setZIndexOffset(1000);
            }
        }
    }

    var vehicles;

    function handleVehicle(item) {
        var isClickedMarker = item.i === clickedMarker,
            latLng = L.latLng(item.l[1], item.l[0]),
            marker;

        if (item.i in vehicles) {
            marker = vehicles[item.i];
            marker.setLatLng(latLng);
            if (zoomedIn) {
                marker.setIcon(getBusIcon(item, isClickedMarker));
            }
            marker.options.item = item;
            if (isClickedMarker) {
                updatePopupContent();
            }
        } else {
            if (zoomedIn) {
                marker = L.marker(latLng, {
                    icon: getBusIcon(item, isClickedMarker),
                    zIndexOffset: 1000,
                    item: item,
                });
            } else {
                marker = L.circleMarker(latLng, {
                    stroke: false,
                    fillColor: '#111',
                    fillOpacity: .6,
                    radius: 3,
                    item: item,
                });
            }
            vehicles[item.i] = marker.addTo(vehiclesGroup)
                .bindPopup('', {
                    autoPan: false
                })
                .on('popupopen', handlePopupOpen)
                .on('popupclose', handlePopupClose);

            if (isClickedMarker) {
                marker.openPopup();
            }
        }
    }

    // websocket

    var socket,
        backoff = 1000,
        newSocket;

    function connect() {
        if (socket && socket.readyState < 2) { // already CONNECTING or OPEN
            return; // no need to reconnect
        }
        var url = (window.location.protocol === 'http:' ? 'ws' : 'wss') + '://' + window.location.host + '/ws/vehicle_positions';
        // url = 'wss://bustimes.org/ws/vehicle_positions';
        socket = new WebSocket(url);

        socket.onopen = function() {
            backoff = 1000;
            newSocket = true;

            var bounds = map.getBounds();
            socket.send(JSON.stringify([
                bounds.getWest(),
                bounds.getSouth(),
                bounds.getEast(),
                bounds.getNorth()
            ]));
        };

        socket.onclose = function(event) {
            if (event.code > 1000) {  // not 'normal closure'
                window.setTimeout(connect, backoff);
                backoff += 500;
            }
        };

        socket.onerror = function(event) {
            console.error(event);
        };

        socket.onmessage = function(event) {
            var items = JSON.parse(event.data);
            if (newSocket) {
                if (vehicles) {
                    vehiclesGroup.clearLayers();
                }
                vehicles = {};
            }
            newSocket = false;
            for (var i = items.length - 1; i >= 0; i--) {
                handleVehicle(items[i]);
            }
        };
    }

    // update window location hash
    function updateLocation() {
        var latLng = map.getCenter(),
            string = map.getZoom() + '/' + Math.round(latLng.lat * 10000) / 10000 + '/' + Math.round(latLng.lng * 10000) / 10000;

        if (history.replaceState) {
            try {
                history.replaceState(null, null, location.pathname + '#' + string);
            } catch (error) {
                // probably SecurityError (document is not fully active)
            }
        }
        if (window.localStorage) {
            try {
                localStorage.setItem('vehicleMap', string);
            } catch (error) {
                // never mind
            }
        }
    }

    var first = true;

    map.on('moveend', function() {
        // zoomedIn = (map.getZoom() > 10);

        var bounds = map.getBounds();

        for (var id in vehicles) {
            var vehicle = vehicles[id];
            if (id !== clickedMarker && !bounds.contains(vehicle.getLatLng())) {
                vehiclesGroup.removeLayer(vehicle);
                delete vehicles[id];
            }
        }

        if (!first && socket && socket.readyState === socket.OPEN) {
            socket.send(JSON.stringify([
                bounds.getWest(),
                bounds.getSouth(),
                bounds.getEast(),
                bounds.getNorth()
            ]));
        }

        if (showStops) {
            if (map.getZoom() < 14) {
                stopsGroup.remove();
                showStops = true;
            } else {
                if (map.getZoom() > 14) {
                    document.getElementById('hugemap').classList.add('zoomed-in');
                } else {
                    document.getElementById('hugemap').classList.remove('zoomed-in');
                }
                stopsGroup.addTo(map);
                loadStops();
            }
        }

        updateLocation();

        first = false;
    });

    var parts;
    if (location.hash) {
        parts = location.hash.substring(1).split('/');
    } else if (localStorage && localStorage.vehicleMap) {
        parts = localStorage.vehicleMap.split('/');
    }
    if (parts) {
        if (parts.length === 1) {
            parts = parts[0].split(',');
        }
        try {
            if (parts.length === 3) {
                map.setView([parts[1], parts[2]], parts[0]);
            } else {
                map.setView([parts[0], parts[1]], 14);
            }
        } catch (error) {
            // oh well
        }
    }

    if (!map._loaded) {
        map.setView([51.9, 0.9], 9);
    }

    // zoomedIn = (map.getZoom() > 10);

    connect();

    function handleVisibilityChange(event) {
        if (event.target.hidden) {
            socket.close(1000);
        } else {
            connect();
        }
    }

    if (document.addEventListener) {
        document.addEventListener('visibilitychange', handleVisibilityChange);
    }
})();
<commit_msg>remove minZoom for Christmas<commit_after>(function () {
    'use strict';

    /*global
        L, reqwest
    */

    var map = L.map('hugemap'),
        stopsGroup = L.layerGroup(),
        vehiclesGroup = L.layerGroup();

    map.attributionControl.setPrefix('');

    L.tileLayer('https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png', {
        attribution: '© Stadia Maps © OpenMapTiles © OpenStreetMap contributors',
    }).addTo(map);

    L.control.locate().addTo(map);

    L.control.layers(null, {
        'Show stops': stopsGroup
    }, {
        collapsed: false
    }).addTo(map);

    var lastStopsReq,
        highWater,
        showStops = true,
        zoomedIn = true;

    if (document.referrer && document.referrer.indexOf('/stops/') > -1) {
        var referrerStop = '/stops/' + document.referrer.split('/stops/')[1];
    } else if (localStorage && localStorage.hideStops) {
        showStops = false;
    }

    stopsGroup.on('add', function() {
        if (map.getZoom() < 14) {
            map.setZoom(14); // loadStops will be called by moveend handler
        } else if (!showStops) {
            loadStops();
        }
        showStops = true;
        if (localStorage) {
            localStorage.removeItem('hideStops');
        }
    }).on('remove', function() {
        showStops = false;
        if (localStorage) {
            localStorage.setItem('hideStops', '1');
        }
    });

    vehiclesGroup.addTo(map);

    function getTransform(heading, scale) {
        if (heading === null && !scale) {
            return '';
        }
        var transform = 'transform:';
        if (heading !== null) {
            transform += ' rotate(' + heading + 'deg)';
        }
        if (scale) {
            transform += ' scale(1.5)';
        }
        return '-webkit-' + transform + ';' + transform;
    }

    function getStopIcon(indicator, bearing) {
        var html = '';
        if (indicator) {
            var parts = indicator.split(' ');
            if (parts.length === 2) {
                var firstPart = parts[0].toLowerCase();
                if (firstPart === 'stop' || firstPart === 'bay' || firstPart === 'stand' || firstPart === 'stance' || firstPart === 'gate') {
                    html = parts[1];
                }
            } else if (parts.length === 0 || indicator.length < 3) {
                html = indicator;
            }
        }
        var className = 'stop stop-' + html.length;
        if (bearing !== null) {
            html += '

';
        } else {
            html += '

';
        }
        return L.divIcon({
            iconSize: [16, 16],
            html: html,
            popupAnchor: [0, -4],
            className: className
        });
    }

    var oldStops = {},
        newStops = {};

    function handleStop(data) {
        if (data.properties.url in oldStops) {
            var marker = oldStops[data.properties.url];
            newStops[data.properties.url] = marker;
            return;
        }

        var a = document.createElement('a');
        marker = L.marker(L.latLng(data.geometry.coordinates[1], data.geometry.coordinates[0]), {
            icon: getStopIcon(data.properties.indicator, data.properties.bearing)
        });

        a.innerHTML = '' + data.properties.name + '' + data.properties.services.join('') + '';
        a.href = data.properties.url;

        marker.bindPopup(a.outerHTML, {
            autoPan: false
        });

        marker.addTo(stopsGroup);
        newStops[data.properties.url] = marker;
    }

    function loadStops() {
        var bounds = map.getBounds();
        var params = '?ymax=' + bounds.getNorth() + '&xmax=' + bounds.getEast() + '&ymin=' + bounds.getSouth() + '&xmin=' + bounds.getWest();

        if (lastStopsReq) {
            lastStopsReq.abort();
        }
        if (highWater && highWater.contains(bounds)) {
            return;
        }
        lastStopsReq = reqwest('/stops.json' + params, function(data) {
            if (data && data.features) {
                highWater = bounds;
                for (var i = data.features.length - 1; i >= 0; i -= 1) {
                    handleStop(data.features[i]);
                }
                for (var stop in oldStops) {
                    if (!(stop in newStops)) {
                        stopsGroup.removeLayer(oldStops[stop]);
                    }
                }
                if (referrerStop) {
                    stop = newStops[referrerStop];
                    if (stop) {
                        stop.openPopup();
                    }
                }
                oldStops = newStops;
                newStops = {};
            }
        });
    }

    function getBusIcon(item, active) {
        var heading = item.h;
        if (heading !== null) {
            var arrow = '

';
            if (heading < 180) {
                heading -= 90;
            } else {
                heading -= 270;
            }
        }
        var className = 'bus';
        if (active) {
            className += ' selected';
        }
        if (item.c) {
            var style = 'background:' + item.c;
            className += ' coloured';
            if (item.t) {
                className += ' white-text';
            }
            style += ';';
        } else {
            style = '';
        }
        style += getTransform(heading, active);
        var html = '
';
        if (item.r) {
            html += item.r;
        }
        html += '
';
        if (arrow) {
            html += arrow;
        }
        return L.divIcon({
            iconSize: [20, 20],
            html: html,
            popupAnchor: [0, -5],
        });
    }

    var clickedMarker, agoTimeout;

    function getDelay(item) {
        if (item.e === 0) {
            return 'On time
';
        }
        if (item.e) {
            var content = 'About ';
            if (item.e > 0) {
                content += item.e;
            } else {
                content += item.e * -1;
            }
            content += ' minute';
            if (item.e !== 1 && item.e !== -1) {
                content += 's';
            }
            if (item.e > 0) {
                content += ' early';
            } else {
                content += ' late';
            }
            content += '
';
            return content;
        }
        return '';
    }

    function getPopupContent(item) {
        var content = getDelay(item);
        var now = new Date();
        var then = new Date(item.d);
        var ago = Math.round((now.getTime() - then.getTime()) / 1000);

        if (ago >= 1800) {
            content += 'Updated at ' + then.toTimeString().slice(0, 5);
        } else if (ago >= 59) {
            var minutes = Math.round(ago / 60);
            if (minutes === 1) {
                content += '1 minute ago';
            } else {
                content += minutes + ' minutes ago';
            }
            agoTimeout = setTimeout(updatePopupContent, (61 - ago % 60) * 1000);
        } else {
            if (ago === 1) {
                content += '1 second ago';
            } else {
                content += ago + ' seconds ago';
            }
            agoTimeout = setTimeout(updatePopupContent, 1000);
        }
        return content;
    }

    function updatePopupContent() {
        if (agoTimeout) {
            clearTimeout(agoTimeout);
        }
        var marker = vehicles[clickedMarker];
        if (marker) {
            var item = marker.options.item;
            marker.getPopup().setContent((marker.options.popupContent || '') + getPopupContent(item, true));
        }
    }

    function handlePopupOpen(event) {
        var marker = event.target;
        var item = marker.options.item;

        clickedMarker = item.i;
        updatePopupContent();

        if (zoomedIn) {
            marker.setIcon(getBusIcon(item, true));
            marker.setZIndexOffset(2000);
        }

        reqwest({
            url: '/vehicles/locations/' + item.i,
            success: function(content) {
                marker.options.popupContent = content;
                updatePopupContent();
            }
        });
    }

    function handlePopupClose(event) {
        if (map.hasLayer(event.target)) {
            clickedMarker = null;
            if (zoomedIn) {
                // make the icon small again
                event.target.setIcon(getBusIcon(event.target.options.item));
                event.target.setZIndexOffset(1000);
            }
        }
    }

    var vehicles;

    function handleVehicle(item) {
        var isClickedMarker = item.i === clickedMarker,
            latLng = L.latLng(item.l[1], item.l[0]),
            marker;

        if (item.i in vehicles) {
            marker = vehicles[item.i];
            marker.setLatLng(latLng);
            if (zoomedIn) {
                marker.setIcon(getBusIcon(item, isClickedMarker));
            }
            marker.options.item = item;
            if (isClickedMarker) {
                updatePopupContent();
            }
        } else {
            if (zoomedIn) {
                marker = L.marker(latLng, {
                    icon: getBusIcon(item, isClickedMarker),
                    zIndexOffset: 1000,
                    item: item,
                });
            } else {
                marker = L.circleMarker(latLng, {
                    stroke: false,
                    fillColor: '#111',
                    fillOpacity: .6,
                    radius: 3,
                    item: item,
                });
            }
            vehicles[item.i] = marker.addTo(vehiclesGroup)
                .bindPopup('', {
                    autoPan: false
                })
                .on('popupopen', handlePopupOpen)
                .on('popupclose', handlePopupClose);

            if (isClickedMarker) {
                marker.openPopup();
            }
        }
    }

    // websocket

    var socket,
        backoff = 1000,
        newSocket;

    function connect() {
        if (socket && socket.readyState < 2) { // already CONNECTING or OPEN
            return; // no need to reconnect
        }
        var url = (window.location.protocol === 'http:' ? 'ws' : 'wss') + '://' + window.location.host + '/ws/vehicle_positions';
        // url = 'wss://bustimes.org/ws/vehicle_positions';
        socket = new WebSocket(url);

        socket.onopen = function() {
            backoff = 1000;
            newSocket = true;

            var bounds = map.getBounds();
            socket.send(JSON.stringify([
                bounds.getWest(),
                bounds.getSouth(),
                bounds.getEast(),
                bounds.getNorth()
            ]));
        };

        socket.onclose = function(event) {
            if (event.code > 1000) {  // not 'normal closure'
                window.setTimeout(connect, backoff);
                backoff += 500;
            }
        };

        socket.onerror = function(event) {
            console.error(event);
        };

        socket.onmessage = function(event) {
            var items = JSON.parse(event.data);
            if (newSocket) {
                if (vehicles) {
                    vehiclesGroup.clearLayers();
                }
                vehicles = {};
            }
            newSocket = false;
            for (var i = items.length - 1; i >= 0; i--) {
                handleVehicle(items[i]);
            }
        };
    }

    // update window location hash
    function updateLocation() {
        var latLng = map.getCenter(),
            string = map.getZoom() + '/' + Math.round(latLng.lat * 10000) / 10000 + '/' + Math.round(latLng.lng * 10000) / 10000;

        if (history.replaceState) {
            try {
                history.replaceState(null, null, location.pathname + '#' + string);
            } catch (error) {
                // probably SecurityError (document is not fully active)
            }
        }
        if (window.localStorage) {
            try {
                localStorage.setItem('vehicleMap', string);
            } catch (error) {
                // never mind
            }
        }
    }

    var first = true;

    map.on('moveend', function() {
        // zoomedIn = (map.getZoom() > 10);

        var bounds = map.getBounds();

        for (var id in vehicles) {
            var vehicle = vehicles[id];
            if (id !== clickedMarker && !bounds.contains(vehicle.getLatLng())) {
                vehiclesGroup.removeLayer(vehicle);
                delete vehicles[id];
            }
        }

        if (!first && socket && socket.readyState === socket.OPEN) {
            socket.send(JSON.stringify([
                bounds.getWest(),
                bounds.getSouth(),
                bounds.getEast(),
                bounds.getNorth()
            ]));
        }

        if (showStops) {
            if (map.getZoom() < 14) {
                stopsGroup.remove();
                showStops = true;
            } else {
                if (map.getZoom() > 14) {
                    document.getElementById('hugemap').classList.add('zoomed-in');
                } else {
                    document.getElementById('hugemap').classList.remove('zoomed-in');
                }
                stopsGroup.addTo(map);
                loadStops();
            }
        }

        updateLocation();

        first = false;
    });

    var parts;
    if (location.hash) {
        parts = location.hash.substring(1).split('/');
    } else if (localStorage && localStorage.vehicleMap) {
        parts = localStorage.vehicleMap.split('/');
    }
    if (parts) {
        if (parts.length === 1) {
            parts = parts[0].split(',');
        }
        try {
            if (parts.length === 3) {
                map.setView([parts[1], parts[2]], parts[0]);
            } else {
                map.setView([parts[0], parts[1]], 14);
            }
        } catch (error) {
            // oh well
        }
    }

    if (!map._loaded) {
        map.setView([51.9, 0.9], 9);
    }

    // zoomedIn = (map.getZoom() > 10);

    connect();

    function handleVisibilityChange(event) {
        if (event.target.hidden) {
            socket.close(1000);
        } else {
            connect();
        }
    }

    if (document.addEventListener) {
        document.addEventListener('visibilitychange', handleVisibilityChange);
    }
})();
<|endoftext|>


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

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global require, define, brackets: true, $, PathUtils, window, navigator, Mustache */

require.config({
    paths: {
        "text" : "thirdparty/text",
        "i18n" : "thirdparty/i18n"
    },
    // Use custom brackets property until CEF sets the correct navigator.language
    // NOTE: When we change to navigator.language here, we also should change to
    // navigator.language in ExtensionLoader (when making require contexts for each
    // extension).
    locale: window.localStorage.getItem("locale") || brackets.app.language
});

/**
 * brackets is the root of the Brackets codebase. This file pulls in all other modules as
 * dependencies (or dependencies thereof), initializes the UI, and binds global menus & keyboard
 * shortcuts to their Commands.
 *
 * TODO: (issue #264) break out the definition of brackets into a separate module from the application controller logic
 *
 * Unlike other modules, this one can be accessed without an explicit require() because it exposes
 * a global object, window.brackets.
 */
define(function (require, exports, module) {
    "use strict";

    // Load dependent non-module scripts
    require("widgets/bootstrap-dropdown");
    require("widgets/bootstrap-modal");
    require("thirdparty/path-utils/path-utils.min");
    require("thirdparty/smart-auto-complete/jquery.smart_autocomplete");

    // Load LiveDeveopment
    require("LiveDevelopment/main");

    // Load dependent modules
    var Global                  = require("utils/Global"),
        AppInit                 = require("utils/AppInit"),
        ProjectManager          = require("project/ProjectManager"),
        DocumentManager         = require("document/DocumentManager"),
        EditorManager           = require("editor/EditorManager"),
        CSSInlineEditor         = require("editor/CSSInlineEditor"),
        JSUtils                 = require("language/JSUtils"),
        WorkingSetView          = require("project/WorkingSetView"),
        DocumentCommandHandlers = require("document/DocumentCommandHandlers"),
        FileViewController      = require("project/FileViewController"),
        FileSyncManager         = require("project/FileSyncManager"),
        KeyBindingManager       = require("command/KeyBindingManager"),
        Commands                = require("command/Commands"),
        CommandManager          = require("command/CommandManager"),
        CodeHintManager         = require("editor/CodeHintManager"),
        JSLintUtils             = require("language/JSLintUtils"),
        PerfUtils               = require("utils/PerfUtils"),
        FileIndexManager        = require("project/FileIndexManager"),
        QuickOpen               = require("search/QuickOpen"),
        Menus                   = require("command/Menus"),
        FileUtils               = require("file/FileUtils"),
        MainViewHTML            = require("text!htmlContent/main-view.html"),
        Strings                 = require("strings"),
        Dialogs                 = require("widgets/Dialogs"),
        ExtensionLoader         = require("utils/ExtensionLoader"),
        SidebarView             = require("project/SidebarView"),
        Async                   = require("utils/Async"),
        UpdateNotification      = require("utils/UpdateNotification"),
        UrlParams               = require("utils/UrlParams").UrlParams,
        NativeFileSystem        = require("file/NativeFileSystem").NativeFileSystem,
        PreferencesManager      = require("preferences/PreferencesManager");

    // Local variables
    var params                  = new UrlParams(),
        PREFERENCES_CLIENT_ID   = "com.adobe.brackets.startup";

    // read URL params
    params.parse();

    //Load modules that self-register and just need to get included in the main project
    require("document/ChangedDocumentTracker");
    require("editor/EditorCommandHandlers");
    require("view/ViewCommandHandlers");
    require("debug/DebugCommandHandlers");
    require("help/HelpCommandHandlers");
    require("search/FindInFiles");
    require("search/FindReplace");
    require("utils/ExtensionUtils");

    // TODO: (issue 1029) Add timeout to main extension loading promise, so that we always call this function
    // Making this fix will fix a warning (search for issue 1029) related to the global brackets 'ready' event.
    function _initExtensions() {
        // allow unit tests to override which plugin folder(s) to load
        var paths = params.get("extensions") || "default,user";

        return Async.doInParallel(paths.split(","), function (item) {
            return ExtensionLoader.loadAllExtensionsInNativeDirectory(
                FileUtils.getNativeBracketsDirectoryPath() + "/extensions/" + item,
                "extensions/" + item
            );
        });
    }

    function _initTest() {
        // TODO: (issue #265) Make sure the "test" object is not included in final builds
        // All modules that need to be tested from the context of the application
        // must to be added to this object. The unit tests cannot just pull
        // in the modules since they would run in context of the unit test window,
        // and would not have access to the app html/css.
        brackets.test = {
            PreferencesManager      : require("preferences/PreferencesManager"),
            ProjectManager          : ProjectManager,
            DocumentCommandHandlers : DocumentCommandHandlers,
            FileViewController      : FileViewController,
            DocumentManager         : DocumentManager,
            EditorManager           : EditorManager,
            Commands                : Commands,
            WorkingSetView          : WorkingSetView,
            JSLintUtils             : JSLintUtils,
            PerfUtils               : PerfUtils,
            JSUtils                 : JSUtils,
            CommandManager          : require("command/CommandManager"),
            FileSyncManager         : FileSyncManager,
            FileIndexManager        : FileIndexManager,
            Menus                   : Menus,
            KeyBindingManager       : KeyBindingManager,
            CodeHintManager         : CodeHintManager,
            CSSUtils                : require("language/CSSUtils"),
            LiveDevelopment         : require("LiveDevelopment/LiveDevelopment"),
            Inspector               : require("LiveDevelopment/Inspector/Inspector"),
            NativeApp               : require("utils/NativeApp"),
            ExtensionUtils          : require("utils/ExtensionUtils"),
            UpdateNotification      : require("utils/UpdateNotification"),
            doneLoading             : false
        };

        AppInit.appReady(function () {
            brackets.test.doneLoading = true;
        });
    }

    function _initDragAndDropListeners() {
        // Prevent unhandled drag and drop of files into the browser from replacing
        // the entire Brackets app. This doesn't prevent children from choosing to
        // handle drops.
        $(window.document.body)
            .on("dragover", function (event) {
                if (event.originalEvent.dataTransfer.files) {
                    event.stopPropagation();
                    event.preventDefault();
                    event.originalEvent.dataTransfer.dropEffect = "none";
                }
            })
            .on("drop", function (event) {
                if (event.originalEvent.dataTransfer.files) {
                    event.stopPropagation();
                    event.preventDefault();
                }
            });
    }

    function _initCommandHandlers() {
        // Most command handlers are automatically registered when their module is loaded (see "modules
        // that self-register" above for some). A few commands need an extra kick here though:

        DocumentCommandHandlers.init($("#main-toolbar"));
    }

    function _initWindowListeners() {
        // TODO: (issue 269) to support IE, need to listen to document instead (and even then it may not work when focus is in an input field?)
        $(window).focus(function () {
            FileSyncManager.syncOpenDocuments();
            FileIndexManager.markDirty();
        });

    }

    function _onReady() {
        // Add the platform (mac or win) to the body tag so we can have platform-specific CSS rules
        $("body").addClass("platform-" + brackets.platform);

        EditorManager.setEditorHolder($("#editor-holder"));

        // Let the user know Brackets doesn't run in a web browser yet
        if (brackets.inBrowser) {
            Dialogs.showModalDialog(
                Dialogs.DIALOG_ID_ERROR,
                Strings.ERROR_IN_BROWSER_TITLE,
                Strings.ERROR_IN_BROWSER
            );
        }

        _initDragAndDropListeners();
        _initCommandHandlers();
        KeyBindingManager.init();
        Menus.init(); // key bindings should be initialized first
        _initWindowListeners();

        // Use quiet scrollbars if we aren't on Lion. If we're on Lion, only
        // use native scroll bars when the mouse is not plugged in or when
        // using the "Always" scroll bar setting.
        var osxMatch = /Mac OS X 10\D([\d+])\D/.exec(navigator.userAgent);
        if (osxMatch && osxMatch[1] && Number(osxMatch[1]) >= 7) {
            // test a scrolling div for scrollbars
            var $testDiv = $("

").appendTo(window.document.body);

            if ($testDiv.outerWidth() === $testDiv.get(0).clientWidth) {
                $(".sidebar").removeClass("quiet-scrollbars");
            }

            $testDiv.remove();
        }

        PerfUtils.addMeasurement("Application Startup");

        // finish UI initialization before loading extensions
        var initialProjectPath = ProjectManager.getInitialProjectPath();
        ProjectManager.openProject(initialProjectPath).always(function () {
            _initTest();

            // WARNING: AppInit.appReady won't fire if ANY extension fails to
            // load or throws an error during init. To fix this, we need to
            // make a change to _initExtensions (filed as issue 1029)
            _initExtensions().always(AppInit._dispatchReady(AppInit.APP_READY));

            // If this is the first launch, and we have an index.html file in the project folder (which should be
            // the samples folder on first launch), open it automatically. (We explicitly check for the
            // samples folder in case this is the first time we're launching Brackets after upgrading from
            // an old version that might not have set the "afterFirstLaunch" pref.)
            var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID);
            if (!params.get("skipSampleProjectLoad") && !prefs.getValue("afterFirstLaunch")) {
                prefs.setValue("afterFirstLaunch", "true");
                if (ProjectManager.isWelcomeProjectPath(initialProjectPath)) {
                    var dirEntry = new NativeFileSystem.DirectoryEntry(initialProjectPath);
                    dirEntry.getFile("index.html", {}, function (fileEntry) {
                        CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fileEntry.fullPath });
                    });
                }
            }
        });

        // Check for updates
        if (!params.get("skipUpdateCheck")) {
            UpdateNotification.checkForUpdate();
        }
    }

    // Prevent unhandled mousedown events from triggering native behavior
    // Example: activating AutoScroll when clicking the middle mouse button (see #510)
    $("html").on("mousedown", function(event) {
        event.preventDefault();
    });

    // Localize MainViewHTML and inject into  tag
    var templateVars    = $.extend({
        ABOUT_ICON          : brackets.config.about_icon,
        APP_NAME_ABOUT_BOX  : brackets.config.app_name_about,
        VERSION             : brackets.metadata.version
    }, Strings);

    $("body").html(Mustache.render(MainViewHTML, templateVars));

    // Update title
    $("title").text(brackets.config.app_title);

    // Dispatch htmlReady callbacks
    AppInit._dispatchReady(AppInit.HTML_READY);

    $(window.document).ready(_onReady);

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

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global require, define, brackets: true, $, PathUtils, window, navigator, Mustache */

require.config({
    paths: {
        "text" : "thirdparty/text",
        "i18n" : "thirdparty/i18n"
    },
    // Use custom brackets property until CEF sets the correct navigator.language
    // NOTE: When we change to navigator.language here, we also should change to
    // navigator.language in ExtensionLoader (when making require contexts for each
    // extension).
    locale: window.localStorage.getItem("locale") || brackets.app.language
});

/**
 * brackets is the root of the Brackets codebase. This file pulls in all other modules as
 * dependencies (or dependencies thereof), initializes the UI, and binds global menus & keyboard
 * shortcuts to their Commands.
 *
 * TODO: (issue #264) break out the definition of brackets into a separate module from the application controller logic
 *
 * Unlike other modules, this one can be accessed without an explicit require() because it exposes
 * a global object, window.brackets.
 */
define(function (require, exports, module) {
    "use strict";

    // Load dependent non-module scripts
    require("widgets/bootstrap-dropdown");
    require("widgets/bootstrap-modal");
    require("thirdparty/path-utils/path-utils.min");
    require("thirdparty/smart-auto-complete/jquery.smart_autocomplete");

    // Load LiveDeveopment
    require("LiveDevelopment/main");

    // Load dependent modules
    var Global                  = require("utils/Global"),
        AppInit                 = require("utils/AppInit"),
        ProjectManager          = require("project/ProjectManager"),
        DocumentManager         = require("document/DocumentManager"),
        EditorManager           = require("editor/EditorManager"),
        CSSInlineEditor         = require("editor/CSSInlineEditor"),
        JSUtils                 = require("language/JSUtils"),
        WorkingSetView          = require("project/WorkingSetView"),
        DocumentCommandHandlers = require("document/DocumentCommandHandlers"),
        FileViewController      = require("project/FileViewController"),
        FileSyncManager         = require("project/FileSyncManager"),
        KeyBindingManager       = require("command/KeyBindingManager"),
        Commands                = require("command/Commands"),
        CommandManager          = require("command/CommandManager"),
        CodeHintManager         = require("editor/CodeHintManager"),
        JSLintUtils             = require("language/JSLintUtils"),
        PerfUtils               = require("utils/PerfUtils"),
        FileIndexManager        = require("project/FileIndexManager"),
        QuickOpen               = require("search/QuickOpen"),
        Menus                   = require("command/Menus"),
        FileUtils               = require("file/FileUtils"),
        MainViewHTML            = require("text!htmlContent/main-view.html"),
        Strings                 = require("strings"),
        Dialogs                 = require("widgets/Dialogs"),
        ExtensionLoader         = require("utils/ExtensionLoader"),
        SidebarView             = require("project/SidebarView"),
        Async                   = require("utils/Async"),
        UpdateNotification      = require("utils/UpdateNotification"),
        UrlParams               = require("utils/UrlParams").UrlParams,
        NativeFileSystem        = require("file/NativeFileSystem").NativeFileSystem,
        PreferencesManager      = require("preferences/PreferencesManager");

    // Local variables
    var params                  = new UrlParams(),
        PREFERENCES_CLIENT_ID   = "com.adobe.brackets.startup";

    // read URL params
    params.parse();

    //Load modules that self-register and just need to get included in the main project
    require("document/ChangedDocumentTracker");
    require("editor/EditorCommandHandlers");
    require("view/ViewCommandHandlers");
    require("debug/DebugCommandHandlers");
    require("help/HelpCommandHandlers");
    require("search/FindInFiles");
    require("search/FindReplace");
    require("utils/ExtensionUtils");

    // TODO: (issue 1029) Add timeout to main extension loading promise, so that we always call this function
    // Making this fix will fix a warning (search for issue 1029) related to the global brackets 'ready' event.
    function _initExtensions() {
        // allow unit tests to override which plugin folder(s) to load
        var paths = params.get("extensions") || "default,user";

        return Async.doInParallel(paths.split(","), function (item) {
            return ExtensionLoader.loadAllExtensionsInNativeDirectory(
                FileUtils.getNativeBracketsDirectoryPath() + "/extensions/" + item,
                "extensions/" + item
            );
        });
    }

    function _initTest() {
        // TODO: (issue #265) Make sure the "test" object is not included in final builds
        // All modules that need to be tested from the context of the application
        // must to be added to this object. The unit tests cannot just pull
        // in the modules since they would run in context of the unit test window,
        // and would not have access to the app html/css.
        brackets.test = {
            PreferencesManager      : require("preferences/PreferencesManager"),
            ProjectManager          : ProjectManager,
            DocumentCommandHandlers : DocumentCommandHandlers,
            FileViewController      : FileViewController,
            DocumentManager         : DocumentManager,
            EditorManager           : EditorManager,
            Commands                : Commands,
            WorkingSetView          : WorkingSetView,
            JSLintUtils             : JSLintUtils,
            PerfUtils               : PerfUtils,
            JSUtils                 : JSUtils,
            CommandManager          : require("command/CommandManager"),
            FileSyncManager         : FileSyncManager,
            FileIndexManager        : FileIndexManager,
            Menus                   : Menus,
            KeyBindingManager       : KeyBindingManager,
            CodeHintManager         : CodeHintManager,
            CSSUtils                : require("language/CSSUtils"),
            LiveDevelopment         : require("LiveDevelopment/LiveDevelopment"),
            Inspector               : require("LiveDevelopment/Inspector/Inspector"),
            NativeApp               : require("utils/NativeApp"),
            ExtensionUtils          : require("utils/ExtensionUtils"),
            UpdateNotification      : require("utils/UpdateNotification"),
            doneLoading             : false
        };

        AppInit.appReady(function () {
            brackets.test.doneLoading = true;
        });
    }

    function _initDragAndDropListeners() {
        // Prevent unhandled drag and drop of files into the browser from replacing
        // the entire Brackets app. This doesn't prevent children from choosing to
        // handle drops.
        $(window.document.body)
            .on("dragover", function (event) {
                if (event.originalEvent.dataTransfer.files) {
                    event.stopPropagation();
                    event.preventDefault();
                    event.originalEvent.dataTransfer.dropEffect = "none";
                }
            })
            .on("drop", function (event) {
                if (event.originalEvent.dataTransfer.files) {
                    event.stopPropagation();
                    event.preventDefault();
                }
            });
    }

    function _initCommandHandlers() {
        // Most command handlers are automatically registered when their module is loaded (see "modules
        // that self-register" above for some). A few commands need an extra kick here though:

        DocumentCommandHandlers.init($("#main-toolbar"));
    }

    function _initWindowListeners() {
        // TODO: (issue 269) to support IE, need to listen to document instead (and even then it may not work when focus is in an input field?)
        $(window).focus(function () {
            FileSyncManager.syncOpenDocuments();
            FileIndexManager.markDirty();
        });

    }

    function _onReady() {
        // Add the platform (mac or win) to the body tag so we can have platform-specific CSS rules
        $("body").addClass("platform-" + brackets.platform);

        EditorManager.setEditorHolder($("#editor-holder"));

        // Let the user know Brackets doesn't run in a web browser yet
        if (brackets.inBrowser) {
            Dialogs.showModalDialog(
                Dialogs.DIALOG_ID_ERROR,
                Strings.ERROR_IN_BROWSER_TITLE,
                Strings.ERROR_IN_BROWSER
            );
        }

        _initDragAndDropListeners();
        _initCommandHandlers();
        KeyBindingManager.init();
        Menus.init(); // key bindings should be initialized first
        _initWindowListeners();

        // Use quiet scrollbars if we aren't on Lion. If we're on Lion, only
        // use native scroll bars when the mouse is not plugged in or when
        // using the "Always" scroll bar setting.
        var osxMatch = /Mac OS X 10\D([\d+])\D/.exec(navigator.userAgent);
        if (osxMatch && osxMatch[1] && Number(osxMatch[1]) >= 7) {
            // test a scrolling div for scrollbars
            var $testDiv = $("

").appendTo(window.document.body);

            if ($testDiv.outerWidth() === $testDiv.get(0).clientWidth) {
                $(".sidebar").removeClass("quiet-scrollbars");
            }

            $testDiv.remove();
        }

        PerfUtils.addMeasurement("Application Startup");

        // finish UI initialization before loading extensions
        var initialProjectPath = ProjectManager.getInitialProjectPath();
        ProjectManager.openProject(initialProjectPath).always(function () {
            _initTest();

            // WARNING: AppInit.appReady won't fire if ANY extension fails to
            // load or throws an error during init. To fix this, we need to
            // make a change to _initExtensions (filed as issue 1029)
            _initExtensions().always(AppInit._dispatchReady(AppInit.APP_READY));

            // If this is the first launch, and we have an index.html file in the project folder (which should be
            // the samples folder on first launch), open it automatically. (We explicitly check for the
            // samples folder in case this is the first time we're launching Brackets after upgrading from
            // an old version that might not have set the "afterFirstLaunch" pref.)
            var prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID);
            if (!params.get("skipSampleProjectLoad") && !prefs.getValue("afterFirstLaunch")) {
                prefs.setValue("afterFirstLaunch", "true");
                if (ProjectManager.isWelcomeProjectPath(initialProjectPath)) {
                    var dirEntry = new NativeFileSystem.DirectoryEntry(initialProjectPath);
                    dirEntry.getFile("index.html", {}, function (fileEntry) {
                        CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fileEntry.fullPath });
                    });
                }
            }
        });

        // Check for updates
        if (!params.get("skipUpdateCheck")) {
            UpdateNotification.checkForUpdate();
        }
    }

    // Prevent unhandled mousedown events from triggering native behavior
    // Example: activating AutoScroll when clicking the middle mouse button (see #510)
    $("html").on("mousedown", function (event) {
        event.preventDefault();
    });

    // Localize MainViewHTML and inject into  tag
    var templateVars    = $.extend({
        ABOUT_ICON          : brackets.config.about_icon,
        APP_NAME_ABOUT_BOX  : brackets.config.app_name_about,
        VERSION             : brackets.metadata.version
    }, Strings);

    $("body").html(Mustache.render(MainViewHTML, templateVars));

    // Update title
    $("title").text(brackets.config.app_title);

    // Dispatch htmlReady callbacks
    AppInit._dispatchReady(AppInit.HTML_READY);

    $(window.document).ready(_onReady);

});
<|endoftext|>


<commit_before>const sayHello = () => console.log('What up?');
const gamesAreFun = require('./game.js');

sayHello();
gamesAreFun();

var canvas = document.getElementById('game');
var context = canvas.getContext('2d');

var x = 50;
var y = 50;
var width = 10;
var height = 10;

requestAnimationFrame(function gameLoop() {
  context.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas.
  context.fillRect(x++, y++, width, height);
  requestAnimationFrame(gameLoop);
});
<commit_msg>Added diagonal squares<commit_after>
const sayHello = () => console.log('What up?');
const gamesAreFun = require('./game.js');

sayHello();
gamesAreFun();

var canvas = document.getElementById('game');
var context = canvas.getContext('2d');

function Square (empty, color, x, y, width, height, canvas, context) {
   this.empty = empty;
   this.color = color;
   this.x = x;
   this.y = y;
   this.width = width;
   this.height = height;
   this.canvas = canvas;
   this.context = context;
}

Square.prototype.draw = function () {
    this.context.fillStyle = 'black';
    this.context.fillRect(this.x, this.y, this.width, this.height);
    this.context.fillStyle = 'green';
    this.context.fillRect(this.x+5, this.y+5, this.width-10, this.height-10);
    return this;
};

var squares = [];

for(var i = 0; i < 800; i += 50) {
   squares.push(new Square(false, "green", i, i, 50, 50, canvas, context));
}
squares.forEach(function(square){
   square.draw();
});

<|endoftext|>


<commit_before>/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false, brackets: true, $: false, JSLINT: false, PathUtils: false */

// TODO: break out the definition of brackets into a separate module from the application controller logic
define(function (require, exports, module) {
    'use strict';

    // Load dependent non-module scripts
    require("widgets/bootstrap-dropdown");
    require("widgets/bootstrap-modal");
    require("thirdparty/path-utils/path-utils.min");
    require("thirdparty/jslint/jslint");

    // Load dependent modules
    var ProjectManager          = require("ProjectManager"),
        DocumentManager         = require("DocumentManager"),
        EditorManager           = require("EditorManager"),
        WorkingSetView          = require("WorkingSetView"),
        FileCommandHandlers     = require("FileCommandHandlers"),
        FileViewController      = require("FileViewController"),
        KeyBindingManager       = require("KeyBindingManager").KeyBindingManager,
        KeyMap                  = require("KeyBindingManager").KeyMap,
        Commands                = require("Commands"),
        CommandManager          = require("CommandManager");

    // Load native shell when brackets is run in a native shell rather than the browser
    // TODO: load conditionally
    brackets.shellAPI = require("ShellAPI");

    // Define core brackets namespace if it isn't already defined
    //
    // We can't simply do 'brackets = {}' to define it in the global namespace because
    // we're in "use strict" mode. Most likely, 'window' will always point to the global
    // object when this code is running. However, in case it isn't (e.g. if we're running
    // inside Node for CI testing) we use this trick to get the global object.
    //
    // Taken from:
    //   http://stackoverflow.com/questions/3277182/how-to-get-the-global-object-in-javascript
    var Fn = Function, global = (new Fn('return this'))();
    if (!global.brackets) {
        global.brackets = {};
    }

    // TODO: Make sure the "test" object is not included in final builds
    // All modules that need to be tested from the context of the application
    // must to be added to this object. The unit tests cannot just pull
    // in the modules since they would run in context of the unit test window,
    // and would not have access to the app html/css.
    brackets.test = {
        PreferencesManager      : require("PreferencesManager"),
        ProjectManager          : ProjectManager,
        FileCommandHandlers     : FileCommandHandlers,
        FileViewController      : FileViewController,
        DocumentManager         : DocumentManager,
        Commands                : Commands,
        WorkingSetView          : WorkingSetView,
        CommandManager          : require("CommandManager")
    };

    brackets.DIALOG_BTN_CANCEL = "cancel";
    brackets.DIALOG_BTN_OK = "ok";
    brackets.DIALOG_BTN_DONTSAVE = "dontsave";

    brackets.DIALOG_ID_ERROR = "error-dialog";
    brackets.DIALOG_ID_SAVE_CLOSE = "save-close-dialog";

    /**
     * General purpose modal dialog. Assumes that the HTML for the dialog contains elements with "title"
     * and "message" classes, as well as a number of elements with "dialog-button" class, each of which has
     * a "data-button-id".
     *
     * @param {string} id The ID of the dialog node in the HTML.
     * @param {string} title The title of the error dialog. Can contain HTML markup.
     * @param {string} message The message to display in the error dialog. Can contain HTML markup.
     * @return {Deferred} a $.Deferred() that will be resolved with the ID of the clicked button when the dialog
     *     is dismissed. Never rejected.
     */
    brackets.showModalDialog = function (id, title, message, callback) {
        var result = $.Deferred();
        var dlg = $("#" + id);

        // Set title and message
        $(".dialog-title", dlg).html(title);
        $(".dialog-message", dlg).html(message);

        function dismissDialog(buttonId) {
            dlg.one("hidden", function () {
                // Let call stack return before notifying that dialog has closed; this avoids issue #191
                // if the handler we're triggering might show another dialog (as long as there's no
                // fade-out animation)
                setTimeout(function () {
                    result.resolve(buttonId);
                }, 0);
            });

            dlg.modal(true).hide();
        }

        function stopEvent(e) {
            // Stop the event if the target is not inside the dialog
            if (!($.contains(dlg.get(0), e.target))) {
                e.stopPropagation();
                e.preventDefault();
            }
        }

        // Enter/Return handler for the primary button. Need to
        // add both keydown and keyup handlers here to make sure
        // the enter key was pressed while the dialog was showing.
        // Otherwise, if a keydown or keypress from somewhere else
        // triggered an alert, the keyup could immediately dismiss it.
        var enterKeyPressed = false;

        function keydownHandler(e) {
            if (e.keyCode === 13) {
                enterKeyPressed = true;
            }
            stopEvent(e);
        }

        function keyupHandler(e) {
            if (e.keyCode === 13 && enterKeyPressed) {
                var primaryBtn = dlg.find(".primary");
                if (primaryBtn) {
                    dismissDialog(primaryBtn.attr("data-button-id"));
                }
            }
            enterKeyPressed = false;
            stopEvent(e);
        }

        // These handlers are added at the capture phase to make sure we
        // get first crack at the events.
        document.body.addEventListener("keydown", keydownHandler, true);
        document.body.addEventListener("keyup", keyupHandler, true);

        // Click handler for buttons
        dlg.one("click", ".dialog-button", function (e) {
            dismissDialog($(this).attr("data-button-id"));
        });

        // Run the dialog
        dlg.modal({
            backdrop: "static",
            show: true
        }).on("hide", function (e) {
            // Remove key event handlers
            document.body.removeEventListener("keydown", keydownHandler, true);
            document.body.removeEventListener("keyup", keyupHandler, true);
        });
        return result;
    };

    $(document).ready(function () {

        var _enableJSLint = true; // TODO: Decide if this should be opt-in or opt-out.

        function initListeners() {
            // Prevent unhandled drag and drop of files into the browser from replacing
            // the entire Brackets app. This doesn't prevent children from choosing to
            // handle drops.
            $(document.body)
                .on("dragover", function (event) {
                    if (event.originalEvent.dataTransfer.files) {
                        event.stopPropagation();
                        event.preventDefault();
                        event.originalEvent.dataTransfer.dropEffect = "none";
                    }
                })
                .on("drop", function (event) {
                    if (event.originalEvent.dataTransfer.files) {
                        event.stopPropagation();
                        event.preventDefault();
                    }
                });
        }

        function initProject() {
            ProjectManager.loadProject();

            // Open project button
            $("#btn-open-project").click(function () {
                ProjectManager.openProject();
            });

            // Handle toggling top level disclosure arrows of file list area
            $("#open-files-disclosure-arrow").click(function () {
                $(this).toggleClass("disclosure-arrow-closed");
                $("#open-files-container").toggle();
            });
            $("#project-files-disclosure-arrow").click(function () {
                $(this).toggleClass("disclosure-arrow-closed");
                $("#project-files-container").toggle();
            });

        }

        function runJSLint() {
            var currentDoc = DocumentManager.getCurrentDocument();
            var ext = currentDoc ? PathUtils.filenameExtension(currentDoc.file.fullPath) : "";
            var lintResults = $("#jslint-results");
            var goldStar = $("#gold-star");

            if (_enableJSLint && /^(\.js|\.htm|\.html)$/i.test(ext)) {
                var text = currentDoc.getText();

                // If a line contains only whitespace, remove the whitespace
                // This should be doable with a regexp: text.replace(/\r[\x20|\t]+\r/g, "\r\r");,
                // but that doesn't work.
                var i, arr = text.split("\n");
                for (i = 0; i < arr.length; i++) {
                    if (!arr[i].match(/\S/)) {
                        arr[i] = "";
                    }
                }
                text = arr.join("\n");

                var result = JSLINT(text, null);

                if (!result) {
                    var errorTable = $("<table class='zebra-striped condensed-table'>")
                                       .append("<tbody>");
                    var selectedRow;

                    JSLINT.errors.forEach(function (item, i) {
                        if (item) {
                            var makeCell = function (content) {
                                return $("<td/>").text(content);
                            };

                            // Add row to error table
                            var row = $("<tr/>")
                                .append(makeCell(item.line))
                                .append(makeCell(item.reason))
                                .append(makeCell(item.evidence || ""))
                                .appendTo(errorTable);

                            row.click(function () {
                                if (selectedRow) {
                                    selectedRow.removeClass("selected");
                                }
                                row.addClass("selected");
                                selectedRow = row;
                                currentDoc.setCursor(item.line - 1, item.character - 1);
                                EditorManager.focusEditor();
                            });
                        }
                    });

                    $("#jslint-results .table-container")
                        .empty()
                        .append(errorTable);
                    lintResults.show();
                    goldStar.hide();
                } else {
                    lintResults.hide();
                    goldStar.show();
                }
            } else {
                // JSLint is disabled or does not apply to the current file, hide
                // both the results and the gold star
                lintResults.hide();
                goldStar.hide();
            }

            EditorManager.resizeEditor();
        }

        function initMenus() {
            // Implements the File menu items
            $("#menu-file-new").click(function () {
                CommandManager.execute(Commands.FILE_NEW);
            });
            $("#menu-file-open").click(function () {
                CommandManager.execute(Commands.FILE_OPEN);
            });
            $("#menu-file-close").click(function () {
                CommandManager.execute(Commands.FILE_CLOSE);
            });
            $("#menu-file-save").click(function () {
                CommandManager.execute(Commands.FILE_SAVE);
            });
            $("#menu-file-quit").click(function () {
                CommandManager.execute(Commands.FILE_QUIT);
            });

            // Implements the 'Run Tests' menu to bring up the Jasmine unit test window
            var testWindow = null;
            $("#menu-debug-runtests").click(function () {
                if (testWindow) {
                    try {
                        testWindow.location.reload();
                    } catch (e) {
                        testWindow = null;  // the window was probably closed
                    }
                }

                if (testWindow === null) {
                    testWindow = window.open("../test/SpecRunner.html");
                    testWindow.location.reload(); // if it was opened before, we need to reload because it will be cached
                }
            });

            // Other debug menu items
//            $("#menu-debug-wordwrap").click(function() {
//                editor.setOption("lineWrapping", !(editor.getOption("lineWrapping")));
//            });

            $("#menu-debug-jslint").click(function () {
                _enableJSLint = !_enableJSLint;
                runJSLint();
                $("#jslint-enabled-checkbox").css("display", _enableJSLint ? "" : "none");
            });
        }

        function initCommandHandlers() {
            FileCommandHandlers.init($("#main-toolbar .title"));
        }

        function initKeyBindings() {
            // Register keymaps and install the keyboard handler
            // TODO: show keyboard equivalents in the menus
            var _globalKeymap = new KeyMap({
                "Ctrl-O": Commands.FILE_OPEN,
                "Ctrl-S": Commands.FILE_SAVE,
                "Ctrl-W": Commands.FILE_CLOSE
            });
            KeyBindingManager.installKeymap(_globalKeymap);

            $(document.body).keydown(function (event) {
                var keyDescriptor = [];
                if (event.metaKey || event.ctrlKey) {
                    keyDescriptor.push("Ctrl");
                }
                if (event.altKey) {
                    keyDescriptor.push("Alt");
                }
                if (event.shiftKey) {
                    keyDescriptor.push("Shift");
                }
                keyDescriptor.push(String.fromCharCode(event.keyCode).toUpperCase());
                if (KeyBindingManager.handleKey(keyDescriptor.join("-"))) {
                    event.preventDefault();
                }
            });
        }

        EditorManager.setEditorHolder($('#editorHolder'));

        initListeners();
        initProject();
        initMenus();
        initCommandHandlers();
        initKeyBindings();

        $(DocumentManager).on("currentDocumentChange", function () {
            runJSLint();
        });

        $(DocumentManager).on("documentSaved", function (event, document) {
            if (document === DocumentManager.getCurrentDocument()) {
                runJSLint();
            }
        });
    });

    //If we hanve't caught the close yet, catch it now
    $(window).unload(function () {
        CommandManager.execute(Commands.FILE_CLOSE_WINDOW);
    });

});
<commit_msg>fix line shuffling that occurred past master merge<commit_after>/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false, brackets: true, $: false, JSLINT: false, PathUtils: false */

// TODO: break out the definition of brackets into a separate module from the application controller logic
define(function (require, exports, module) {
    'use strict';

    // Load dependent non-module scripts
    require("widgets/bootstrap-dropdown");
    require("widgets/bootstrap-modal");
    require("thirdparty/path-utils/path-utils.min");
    require("thirdparty/jslint/jslint");

    // Load dependent modules
    var ProjectManager          = require("ProjectManager"),
        DocumentManager         = require("DocumentManager"),
        EditorManager           = require("EditorManager"),
        WorkingSetView          = require("WorkingSetView"),
        FileCommandHandlers     = require("FileCommandHandlers"),
        FileViewController      = require("FileViewController"),
        KeyBindingManager       = require("KeyBindingManager").KeyBindingManager,
        KeyMap                  = require("KeyBindingManager").KeyMap,
        Commands                = require("Commands"),
        CommandManager          = require("CommandManager");

    // Define core brackets namespace if it isn't already defined
    //
    // We can't simply do 'brackets = {}' to define it in the global namespace because
    // we're in "use strict" mode. Most likely, 'window' will always point to the global
    // object when this code is running. However, in case it isn't (e.g. if we're running
    // inside Node for CI testing) we use this trick to get the global object.
    //
    // Taken from:
    //   http://stackoverflow.com/questions/3277182/how-to-get-the-global-object-in-javascript
    var Fn = Function, global = (new Fn('return this'))();
    if (!global.brackets) {
        global.brackets = {};
    }

    // Load native shell when brackets is run in a native shell rather than the browser
    // TODO: load conditionally
    brackets.shellAPI = require("ShellAPI");

    brackets.inBrowser = !brackets.hasOwnProperty("fs");

    // TODO: Make sure the "test" object is not included in final builds
    // All modules that need to be tested from the context of the application
    // must to be added to this object. The unit tests cannot just pull
    // in the modules since they would run in context of the unit test window,
    // and would not have access to the app html/css.
    brackets.test = {
        PreferencesManager      : require("PreferencesManager"),
        ProjectManager          : ProjectManager,
        FileCommandHandlers     : FileCommandHandlers,
        FileViewController      : FileViewController,
        DocumentManager         : DocumentManager,
        Commands                : Commands,
        WorkingSetView          : WorkingSetView,
        CommandManager          : require("CommandManager")
    };

    brackets.DIALOG_BTN_CANCEL = "cancel";
    brackets.DIALOG_BTN_OK = "ok";
    brackets.DIALOG_BTN_DONTSAVE = "dontsave";

    brackets.DIALOG_ID_ERROR = "error-dialog";
    brackets.DIALOG_ID_SAVE_CLOSE = "save-close-dialog";

    /**
     * General purpose modal dialog. Assumes that the HTML for the dialog contains elements with "title"
     * and "message" classes, as well as a number of elements with "dialog-button" class, each of which has
     * a "data-button-id".
     *
     * @param {string} id The ID of the dialog node in the HTML.
     * @param {string} title The title of the error dialog. Can contain HTML markup.
     * @param {string} message The message to display in the error dialog. Can contain HTML markup.
     * @return {Deferred} a $.Deferred() that will be resolved with the ID of the clicked button when the dialog
     *     is dismissed. Never rejected.
     */
    brackets.showModalDialog = function (id, title, message, callback) {
        var result = $.Deferred();
        var dlg = $("#" + id);

        // Set title and message
        $(".dialog-title", dlg).html(title);
        $(".dialog-message", dlg).html(message);

        function dismissDialog(buttonId) {
            dlg.one("hidden", function () {
                // Let call stack return before notifying that dialog has closed; this avoids issue #191
                // if the handler we're triggering might show another dialog (as long as there's no
                // fade-out animation)
                setTimeout(function () {
                    result.resolve(buttonId);
                }, 0);
            });

            dlg.modal(true).hide();
        }

        function stopEvent(e) {
            // Stop the event if the target is not inside the dialog
            if (!($.contains(dlg.get(0), e.target))) {
                e.stopPropagation();
                e.preventDefault();
            }
        }

        // Enter/Return handler for the primary button. Need to
        // add both keydown and keyup handlers here to make sure
        // the enter key was pressed while the dialog was showing.
        // Otherwise, if a keydown or keypress from somewhere else
        // triggered an alert, the keyup could immediately dismiss it.
        var enterKeyPressed = false;

        function keydownHandler(e) {
            if (e.keyCode === 13) {
                enterKeyPressed = true;
            }
            stopEvent(e);
        }

        function keyupHandler(e) {
            if (e.keyCode === 13 && enterKeyPressed) {
                var primaryBtn = dlg.find(".primary");
                if (primaryBtn) {
                    dismissDialog(primaryBtn.attr("data-button-id"));
                }
            }
            enterKeyPressed = false;
            stopEvent(e);
        }

        // These handlers are added at the capture phase to make sure we
        // get first crack at the events.
        document.body.addEventListener("keydown", keydownHandler, true);
        document.body.addEventListener("keyup", keyupHandler, true);

        // Click handler for buttons
        dlg.one("click", ".dialog-button", function (e) {
            dismissDialog($(this).attr("data-button-id"));
        });

        // Run the dialog
        dlg.modal({
            backdrop: "static",
            show: true
        }).on("hide", function (e) {
            // Remove key event handlers
            document.body.removeEventListener("keydown", keydownHandler, true);
            document.body.removeEventListener("keyup", keyupHandler, true);
        });
        return result;
    };

    $(document).ready(function () {

        var _enableJSLint = true; // TODO: Decide if this should be opt-in or opt-out.

        function initListeners() {
            // Prevent unhandled drag and drop of files into the browser from replacing
            // the entire Brackets app. This doesn't prevent children from choosing to
            // handle drops.
            $(document.body)
                .on("dragover", function (event) {
                    if (event.originalEvent.dataTransfer.files) {
                        event.stopPropagation();
                        event.preventDefault();
                        event.originalEvent.dataTransfer.dropEffect = "none";
                    }
                })
                .on("drop", function (event) {
                    if (event.originalEvent.dataTransfer.files) {
                        event.stopPropagation();
                        event.preventDefault();
                    }
                });
        }

        function initProject() {
            ProjectManager.loadProject();

            // Open project button
            $("#btn-open-project").click(function () {
                ProjectManager.openProject();
            });

            // Handle toggling top level disclosure arrows of file list area
            $("#open-files-disclosure-arrow").click(function () {
                $(this).toggleClass("disclosure-arrow-closed");
                $("#open-files-container").toggle();
            });
            $("#project-files-disclosure-arrow").click(function () {
                $(this).toggleClass("disclosure-arrow-closed");
                $("#project-files-container").toggle();
            });

        }

        function runJSLint() {
            var currentDoc = DocumentManager.getCurrentDocument();
            var ext = currentDoc ? PathUtils.filenameExtension(currentDoc.file.fullPath) : "";
            var lintResults = $("#jslint-results");
            var goldStar = $("#gold-star");

            if (_enableJSLint && /^(\.js|\.htm|\.html)$/i.test(ext)) {
                var text = currentDoc.getText();

                // If a line contains only whitespace, remove the whitespace
                // This should be doable with a regexp: text.replace(/\r[\x20|\t]+\r/g, "\r\r");,
                // but that doesn't work.
                var i, arr = text.split("\n");
                for (i = 0; i < arr.length; i++) {
                    if (!arr[i].match(/\S/)) {
                        arr[i] = "";
                    }
                }
                text = arr.join("\n");

                var result = JSLINT(text, null);

                if (!result) {
                    var errorTable = $("<table class='zebra-striped condensed-table'>")
                                       .append("<tbody>");
                    var selectedRow;

                    JSLINT.errors.forEach(function (item, i) {
                        if (item) {
                            var makeCell = function (content) {
                                return $("<td/>").text(content);
                            };

                            // Add row to error table
                            var row = $("<tr/>")
                                .append(makeCell(item.line))
                                .append(makeCell(item.reason))
                                .append(makeCell(item.evidence || ""))
                                .appendTo(errorTable);

                            row.click(function () {
                                if (selectedRow) {
                                    selectedRow.removeClass("selected");
                                }
                                row.addClass("selected");
                                selectedRow = row;
                                currentDoc.setCursor(item.line - 1, item.character - 1);
                                EditorManager.focusEditor();
                            });
                        }
                    });

                    $("#jslint-results .table-container")
                        .empty()
                        .append(errorTable);
                    lintResults.show();
                    goldStar.hide();
                } else {
                    lintResults.hide();
                    goldStar.show();
                }
            } else {
                // JSLint is disabled or does not apply to the current file, hide
                // both the results and the gold star
                lintResults.hide();
                goldStar.hide();
            }

            EditorManager.resizeEditor();
        }

        function initMenus() {
            // Implements the File menu items
            $("#menu-file-new").click(function () {
                CommandManager.execute(Commands.FILE_NEW);
            });
            $("#menu-file-open").click(function () {
                CommandManager.execute(Commands.FILE_OPEN);
            });
            $("#menu-file-close").click(function () {
                CommandManager.execute(Commands.FILE_CLOSE);
            });
            $("#menu-file-save").click(function () {
                CommandManager.execute(Commands.FILE_SAVE);
            });
            $("#menu-file-quit").click(function () {
                CommandManager.execute(Commands.FILE_QUIT);
            });

            // Implements the 'Run Tests' menu to bring up the Jasmine unit test window
            var testWindow = null;
            $("#menu-debug-runtests").click(function () {
                if (testWindow) {
                    try {
                        testWindow.location.reload();
                    } catch (e) {
                        testWindow = null;  // the window was probably closed
                    }
                }

                if (testWindow === null) {
                    testWindow = window.open("../test/SpecRunner.html");
                    testWindow.location.reload(); // if it was opened before, we need to reload because it will be cached
                }
            });

            // Other debug menu items
//            $("#menu-debug-wordwrap").click(function() {
//                editor.setOption("lineWrapping", !(editor.getOption("lineWrapping")));
//            });

            $("#menu-debug-jslint").click(function () {
                _enableJSLint = !_enableJSLint;
                runJSLint();
                $("#jslint-enabled-checkbox").css("display", _enableJSLint ? "" : "none");
            });
        }

        function initCommandHandlers() {
            FileCommandHandlers.init($("#main-toolbar .title"));
        }

        function initKeyBindings() {
            // Register keymaps and install the keyboard handler
            // TODO: show keyboard equivalents in the menus
            var _globalKeymap = new KeyMap({
                "Ctrl-O": Commands.FILE_OPEN,
                "Ctrl-S": Commands.FILE_SAVE,
                "Ctrl-W": Commands.FILE_CLOSE
            });
            KeyBindingManager.installKeymap(_globalKeymap);

            $(document.body).keydown(function (event) {
                var keyDescriptor = [];
                if (event.metaKey || event.ctrlKey) {
                    keyDescriptor.push("Ctrl");
                }
                if (event.altKey) {
                    keyDescriptor.push("Alt");
                }
                if (event.shiftKey) {
                    keyDescriptor.push("Shift");
                }
                keyDescriptor.push(String.fromCharCode(event.keyCode).toUpperCase());
                if (KeyBindingManager.handleKey(keyDescriptor.join("-"))) {
                    event.preventDefault();
                }
            });
        }

        EditorManager.setEditorHolder($('#editorHolder'));

        initListeners();
        initProject();
        initMenus();
        initCommandHandlers();
        initKeyBindings();

        $(DocumentManager).on("currentDocumentChange", function () {
            runJSLint();
        });

        $(DocumentManager).on("documentSaved", function (event, document) {
            if (document === DocumentManager.getCurrentDocument()) {
                runJSLint();
            }
        });
    });

    //If we hanve't caught the close yet, catch it now
    $(window).unload(function () {
        CommandManager.execute(Commands.FILE_CLOSE_WINDOW);
    });

});
<|endoftext|>


<commit_before>/**
 * Fastly API client.
 *
 * @package fastly
 * @author Andrew Sliwinski <andrew@diy.org>
 */

/**
 * Dependencies
 */
var request = require('request');

/**
 * Constructor
 */
function Fastly (apikey) {
    this.apikey = apikey || '';
}

/**
 * Adapter helper method.
 *
 * @param {string} Method
 * @param {string} URL
 * @param {params} Optional params to update.
 * @param {callback} callback to execute with response.
 *
 * @return {Object}
 */
Fastly.prototype.request = function (method, url, params, callback) {
    var self = this;

    // Allow for optional update params.
    if (typeof params === 'function') {
        callback = params;
        params = null;
    }

    // Construct headers
    var headers = { 'x-fastly-key': self.apikey };

    // HTTP request
    request({
        method: method,
        url: 'https://api.fastly.com' + url,
        headers: headers,
        form: params
    }, function (err, response, body) {
        if (err) return callback(err);
        if (response.statusCode < 200) return callback(body);
        if (response.statusCode > 302) return callback(body);

        if (response.headers['content-type'] === 'application/json') {
            try {
                body = JSON.parse(body);
            } catch (er) {
                return callback(er);
            }
        }

        callback(null, body);
    });
};

// -------------------------------------------------------

Fastly.prototype.purge = function (host, url, callback) {
    this.request('POST', '/purge/' + host + url, callback);
};

Fastly.prototype.purgeAll = function (service, callback) {
    var url = '/service/' + encodeURIComponent(service) + '/purge_all';
    this.request('POST', url, callback);
};

Fastly.prototype.purgeKey = function (service, key, callback) {
    var url = '/service/' + encodeURIComponent(service) + '/purge/' + key;
    this.request('POST', url, callback);
};

Fastly.prototype.stats = function (service, callback) {
    var url = '/service/' + encodeURIComponent(service) + '/stats/summary';
    this.request('GET', url, callback);
};

/**
 * Export
 */
module.exports = function (apikey) {
    return new Fastly(apikey);
};
<commit_msg>Always return Error objects, and provide statusCode on failure<commit_after>/**
 * Fastly API client.
 *
 * @package fastly
 * @author Andrew Sliwinski <andrew@diy.org>
 */

/**
 * Dependencies
 */
var request = require('request');

/**
 * Constructor
 */
function Fastly (apikey) {
    this.apikey = apikey || '';
}

/**
 * Adapter helper method.
 *
 * @param {string} Method
 * @param {string} URL
 * @param {params} Optional params to update.
 * @param {callback} callback to execute with response.
 *
 * @return {Object}
 */
Fastly.prototype.request = function (method, url, params, callback) {
    var self = this;

    // Allow for optional update params.
    if (typeof params === 'function') {
        callback = params;
        params = null;
    }

    // Construct headers
    var headers = { 'x-fastly-key': self.apikey };

    // HTTP request
    request({
        method: method,
        url: 'https://api.fastly.com' + url,
        headers: headers,
        form: params
    }, function (err, response, body) {
        if (response) {
            var statusCode = response.statusCode;
            if (!err && (statusCode < 200 || statusCode > 302))
                err = new Error(body);
            if (err) err.statusCode = statusCode;
        }
        if (err) return callback(err);
        if (response.headers['content-type'] === 'application/json') {
            try {
                body = JSON.parse(body);
            } catch (er) {
                return callback(er);
            }
        }

        callback(null, body);
    });
};

// -------------------------------------------------------

Fastly.prototype.purge = function (host, url, callback) {
    this.request('POST', '/purge/' + host + url, callback);
};

Fastly.prototype.purgeAll = function (service, callback) {
    var url = '/service/' + encodeURIComponent(service) + '/purge_all';
    this.request('POST', url, callback);
};

Fastly.prototype.purgeKey = function (service, key, callback) {
    var url = '/service/' + encodeURIComponent(service) + '/purge/' + key;
    this.request('POST', url, callback);
};

Fastly.prototype.stats = function (service, callback) {
    var url = '/service/' + encodeURIComponent(service) + '/stats/summary';
    this.request('GET', url, callback);
};

/**
 * Export
 */
module.exports = function (apikey) {
    return new Fastly(apikey);
};
<|endoftext|>


<commit_before>Package.describe({
  summary: "Password support for accounts",
  // Note: 2.2.0-beta.3 was published during the Meteor 1.6 prerelease
  // process, so it might be best to skip to 2.3.x instead of reusing
  // 2.2.x in the future. The version was also bumped to 2.0.0 temporarily
  // during the Meteor 1.5.1 release process, so versions 2.0.0-beta.2
  // through -beta.5 and -rc.0 have already been published.
  version: "1.5.2"
});

Package.onUse(api => {
  api.use('npm-bcrypt', 'server');

  api.use([
    'accounts-base',
    'srp',
    'sha',
    'ejson',
    'ddp'
  ], ['client', 'server']);

  // Export Accounts (etc) to packages using this one.
  api.imply('accounts-base', ['client', 'server']);

  api.use('email', 'server');
  api.use('random', 'server');
  api.use('check', 'server');
  api.use('ecmascript');

  api.addFiles('email_templates.js', 'server');
  api.addFiles('password_server.js', 'server');
  api.addFiles('password_client.js', 'client');
});

Package.onTest(api => {
  api.use(['accounts-password', 'tinytest', 'test-helpers', 'tracker',
           'accounts-base', 'random', 'email', 'check', 'ddp', 'ecmascript']);
  api.addFiles('password_tests_setup.js', 'server');
  api.addFiles('password_tests.js', ['client', 'server']);
  api.addFiles('email_tests_setup.js', 'server');
  api.addFiles('email_tests.js', 'client');
});
<commit_msg>Update accounts-password to version 1.5.2. - api versions from 1.8.1<commit_after>Package.describe({
  summary: "Password support for accounts",
  // Note: 2.2.0-beta.3 was published during the Meteor 1.6 prerelease
  // process, so it might be best to skip to 2.3.x instead of reusing
  // 2.2.x in the future. The version was also bumped to 2.0.0 temporarily
  // during the Meteor 1.5.1 release process, so versions 2.0.0-beta.2
  // through -beta.5 and -rc.0 have already been published.
  version: "1.5.2"
});

Package.onUse(api => {
  api.versionsFrom("1.8.1");
  api.use('npm-bcrypt', 'server');

  api.use([
    'accounts-base',
    'srp',
    'sha',
    'ejson',
    'ddp'
  ], ['client', 'server']);

  // Export Accounts (etc) to packages using this one.
  api.imply('accounts-base', ['client', 'server']);

  api.use('email', 'server');
  api.use('random', 'server');
  api.use('check', 'server');
  api.use('ecmascript');

  api.addFiles('email_templates.js', 'server');
  api.addFiles('password_server.js', 'server');
  api.addFiles('password_client.js', 'client');
});

Package.onTest(api => {
  api.use(['accounts-password', 'tinytest', 'test-helpers', 'tracker',
           'accounts-base', 'random', 'email', 'check', 'ddp', 'ecmascript']);
  api.addFiles('password_tests_setup.js', 'server');
  api.addFiles('password_tests.js', ['client', 'server']);
  api.addFiles('email_tests_setup.js', 'server');
  api.addFiles('email_tests.js', 'client');
});
<|endoftext|>