<commit_before>/*
 * This script uses ajax and JQuery to send location data to the server database
 */

    $(document).ready(function (){
        //hide the error labes after page loads.
        $('label.error').hide();
        //onclick lister for the add location button
        $('#add-location-btn').click(function (){
            //form validation
            $('label.error').hide();
            var location_name = $('#location-name').val();
            if(location_name === ""){
                $('input#location-name').focus();
                $('label#location-name-error').fadeIn(1000);

                return false; //stops the form from being submitted
            }

            var location_prefix = $('input#location-prefix').val();
            var about_location = $('textarea#about-location').val();
            var type_of_point = $('select#type-of-point').val();

            var image_x_coordinate = $('input#image-x-coordinate').val();
            if(image_x_coordinate === ""){
                $('input#image-x-coordinate').focus();
                $('label#image-x-coordinate-error').fadeIn(1000);

                return false;
            }

            var image_y_coordinate = $('input#image-Y-coordinate').val();
            if(image_y_coordinate === ""){
                $('input#image-Y-coordinate').focus();
                $('label#image-Y-coordinate-error').fadeIn(1000);

                return false;
            }

            var gps_latitude = $('input#gps-latitude').val();
            if(gps_latitude === ""){
                $('input#gps-latitude').focus();
                $('label#gps-latitude-error').fadeIn(1000);

                return false;
            }

            var gps_longitude = $('input#gps-longitude').val();
            if(gps_longitude === ""){
                $('input#gps-longitude').focus();
                $('label#gps-longitude-error').fadeIn(1000);

                return false;
            }

            //image validation if the image is selected
            var location_image_data = $("input#location-image").prop("files")[0];

            var dataForm = "location-name="+location_name+"&location-prefix="+location_prefix+"&about-location="+about_location+"&type-of-point="+type_of_point
                            +"&X-coordinate="+image_x_coordinate+"&Y-coordinate="+image_y_coordinate+"&gps-latitude="+gps_latitude+"&gps-longitude="+gps_longitude;

            var formdata = new FormData();
            formdata.append("location-image",location_image_data);
            formdata.append("location-name",location_name);
            formdata.append("location-prefix",location_prefix);
            formdata.append("about-location",about_location);
            formdata.append("type-of-point",type_of_point);
            formdata.append("X-coordinate",image_x_coordinate);
            formdata.append("Y-coordinate",image_y_coordinate);
            formdata.append("gps-latitude",gps_latitude);
            formdata.append("gps-longitude",gps_longitude);

            //submit form
            $.ajax({
                cache: false,
                contentType: false,
                processData: false,
                type: 'POST',
                url: "../functions/add_location.php",
                data: formdata,
                success: function(data, textStatus, jqXHR) {
                $("div#add-location-msg-content").html(data)
                        .hide()
                        .fadeIn('slow')
                        .delay(3000)
                        .fadeOut("slow");
            }
            });
        });
    });

<commit_msg>removed unused comment and unused variable<commit_after>/*
 * This script uses ajax and JQuery to send location data to the server database
 */

    $(document).ready(function (){
        //hide the error labes after page loads.
        $('label.error').hide();
        //onclick lister for the add location button
        $('#add-location-btn').click(function (){
            //form validation
            $('label.error').hide();
            var location_name = $('#location-name').val();
            if(location_name === ""){
                $('input#location-name').focus();
                $('label#location-name-error').fadeIn(1000);

                return false; //stops the form from being submitted
            }

            var location_prefix = $('input#location-prefix').val();
            var about_location = $('textarea#about-location').val();
            var type_of_point = $('select#type-of-point').val();

            var image_x_coordinate = $('input#image-x-coordinate').val();
            if(image_x_coordinate === ""){
                $('input#image-x-coordinate').focus();
                $('label#image-x-coordinate-error').fadeIn(1000);

                return false;
            }

            var image_y_coordinate = $('input#image-Y-coordinate').val();
            if(image_y_coordinate === ""){
                $('input#image-Y-coordinate').focus();
                $('label#image-Y-coordinate-error').fadeIn(1000);

                return false;
            }

            var gps_latitude = $('input#gps-latitude').val();
            if(gps_latitude === ""){
                $('input#gps-latitude').focus();
                $('label#gps-latitude-error').fadeIn(1000);

                return false;
            }

            var gps_longitude = $('input#gps-longitude').val();
            if(gps_longitude === ""){
                $('input#gps-longitude').focus();
                $('label#gps-longitude-error').fadeIn(1000);

                return false;
            }

            var location_image_data = $("input#location-image").prop("files")[0];

            var formdata = new FormData();
            formdata.append("location-image",location_image_data);
            formdata.append("location-name",location_name);
            formdata.append("location-prefix",location_prefix);
            formdata.append("about-location",about_location);
            formdata.append("type-of-point",type_of_point);
            formdata.append("X-coordinate",image_x_coordinate);
            formdata.append("Y-coordinate",image_y_coordinate);
            formdata.append("gps-latitude",gps_latitude);
            formdata.append("gps-longitude",gps_longitude);

            //submit form
            $.ajax({
                cache: false,
                contentType: false,
                processData: false,
                type: 'POST',
                url: "../functions/add_location.php",
                data: formdata,
                success: function(data, textStatus, jqXHR) {
                $("div#add-location-msg-content").html(data)
                        .hide()
                        .fadeIn('slow')
                        .delay(3000)
                        .fadeOut("slow");
            }
            });
        });
    });

<|endoftext|>


<commit_before>import moment from 'moment';
import { default as vegaEmbed } from 'vega-embed';
import { WKT } from 'ol/format';
import VectorLayer from 'ol/layer/Vector';
import { Vector as VectorSource } from 'ol/source';
import { Style, Icon, Stroke, Fill, Circle, Text } from 'ol/style';

var labelStyle = new Style({
    geometry: function (feature) {
        var geometry = feature.getGeometry();
        if (geometry.getType() == 'MultiPolygon') {
            // Only render label for the widest polygon of a multipolygon
            var polygons = geometry.getPolygons();
            var widest = 0;
            for (var i = 0, ii = polygons.length; i < ii; ++i) {
                var polygon = polygons[i];
                var width = getWidth(polygon.getExtent());
                if (width > widest) {
                    widest = width;
                    geometry = polygon;
                }
            }
        }
        return geometry;
    },
    text: new Text({
        font: '12px Calibri,sans-serif',
        overflow: true,
        fill: new Fill({
            color: '#000'
        }),
        stroke: new Stroke({
            color: '#fff',
            width: 3
        })
    })
});

var bookmarkStyle = [new Style({
    fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
    }),
    stroke: new Stroke({
        color: '#e49905',
        width: 2
    }),
    image: new Icon({
        src: require('../../components/styles/img/svg/wifi8.svg'),
        crossOrigin: 'anonymous',
        anchor: [0.5, 1]
    })
}), labelStyle];

export default ['hs.utils.service', '$http', 'config', 'hs.map.service', 'hs.layout.service', '$rootScope', '$compile', '$timeout', function (utils, $http, config, hsMap, layoutService, $rootScope, $compile, $timeout) {
    var me = this;
    var endpoint = config.senslog;

    $rootScope.$on('vectorQuery.featureSelected', utils.debounce((event, feature) => {
        if (feature.getLayer(hsMap.map) == me.layer) {
            layoutService.setMainPanel('sensors');
            me.units.forEach(unit => unit.expanded = false);
            me.selectUnit(me.units.filter(unit =>
                unit.unit_id == feature.get('unit_id')
            )[0]);
        }
    }, 150, false, me))

    return angular.extend(me, {
        units: [],
        sensorsSelected: [],
        sensorIdsSelected: [],
        sensorById: {},
        selectSensor(sensor) {
            me.sensorsSelected.forEach(s => s.checked = false);
            sensor.checked = true;
            me.sensorsSelected = [sensor];
            me.sensorIdsSelected = [sensor.sensor_id]
        },
        toggleSensor(sensor) {
            if(sensor.checked) {
                me.sensorsSelected.push(sensor);
                me.sensorIdsSelected.push(sensor.sensor_id);
            } else {
                me.sensorsSelected.splice(me.sensorsSelected.indexOf(sensor), 1);
                me.sensorIdsSelected.splice(me.sensorIdsSelected.indexOf(sensor.sensor_id), 1);
            }
        },
        selectUnit(unit) {
            me.unit = unit;
            unit.expanded = !unit.expanded;
            me.selectSensor(unit.sensors[0]);
            if (!layoutService.contentWrapper.querySelector('.hs-sensor-unit-dialog')) {
                const dir = 'hs.sensors.unit-dialog';
                const html = `<${dir} unit="sensorsService.unit"></${dir}>`;
                const element = angular.element(html)[0];
                layoutService.contentWrapper.querySelector(".hs-gui-overlay").appendChild(element);
                $compile(element)($rootScope.$new());
            } else {
                me.unitDialogVisible = true;
            }
            $timeout(_ => {
                if (angular.isUndefined(me.currentInterval))
                    me.currentInterval = { amount: 1, unit: 'days' };
                me.getObservationHistory(
                    me.unit,
                    me.currentInterval
                ).then(_ => me.createChart(me.unit))

            }, 0)
        },
        createLayer() {
            me.layer = new VectorLayer({
                title: 'Sensor units',
                synchronize: false,
                editor: {
                    editable: false
                },
                style: function (feature) {
                    labelStyle.getText().setText(feature.get('name'));
                    return bookmarkStyle;
                },
                source: new VectorSource({})
            });
            hsMap.map.addLayer(me.layer)
        },
        /**
         * @memberof hs.sensors.service
         * @function getUnits
         * @description Get list of units from Senslog backend
         */
        getUnits() {
            if (me.layer == null) me.createLayer();
            var url = utils.proxify(`${endpoint.url}/senslog-lite/rest/unit`);
            $http.get(url, {
                params: {
                    user_id: endpoint.user_id
                }
            }).then(response => {
                me.units = response.data;
                let features = me.units
                    .filter(unit => unit.unit_position && unit.unit_position.asWKT)
                    .map(unit => {
                        const format = new WKT();
                        const feature = format.readFeature(unit.unit_position.asWKT, {
                            dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857'
                        })
                        feature.set('name', unit.description);
                        feature.set('unit_id', unit.unit_id);
                        return feature
                    })
                me.layer.getSource().addFeatures(features);
                me.fillLastObservations();
                me.units.forEach(unit => {
                    unit.sensorTypes = unit.sensors.map(s => {
                        return {name: s.sensor_type}
                    });
                    unit.sensorTypes = utils.removeDuplicates(unit.sensorTypes, 'name');
                    unit.sensorTypes.map(st =>
                        st.sensors = unit.sensors.filter(
                            s => s.sensor_type == st.name
                        )
                    )
                });
                setInterval(me.fillLastObservations, 60000);

            },
                function (err) {

                });
        },

        fillLastObservations(){
            $http.get(utils.proxify(`${endpoint.url}/senslog1/SensorService`), {
                params: {
                    Operation: 'GetLastObservations',
                    group: endpoint.group,
                    user: endpoint.user
                }
            }).then(response => {
                var sensorValues = {};
                response.data.forEach(sv => {
                    sensorValues[sv.sensorId] = {
                        value: sv.observedValue,
                        timestamp: moment(sv.timeStamp).format('DD.MM.YYYY HH:mm')
                    };
                });
                me.units.forEach(unit => {
                    unit.sensors.forEach(sensor => {
                        me.sensorById[sensor.sensor_id] = sensor;
                        if(sensorValues[sensor.sensor_id]){
                            sensor.lastObservationValue = sensorValues[sensor.sensor_id].value;
                            sensor.lastObservationTimestamp = sensorValues[sensor.sensor_id].timestamp;
                        }
                    })
                })
            })
        },

        /**
         * @memberof hs.sensors.service
         * @function getObservationHistory
         * @param {Object} unit Object containing
         * {description, is_mobile, sensors, unit_id, unit_type}
         * @param {Object} interval Object {amount, unit}. Used to substract time
         * from current time, like 6 months before now
         * @description Gets list of observations in a given time frame for all
         * the sensors on a sensor unit (meteostation).
         */
        getObservationHistory(unit, interval) {
            return new Promise((resolve, reject) => {
                var url = utils.proxify(`${endpoint.url}/senslog-lite/rest/observation`);
                var from_time = moment().subtract(interval.amount, interval.unit);
                from_time = `${from_time.format('YYYY-MM-DD')} ${from_time.format('HH:mm:ssZ')}`;
                interval.loading = true;
                $http.get(url, {
                    params: {
                        user_id: endpoint.user_id,
                        unit_id: unit.unit_id,
                        from_time
                    }
                }).then(
                    response => {
                        interval.loading = false;
                        me.observations = response.data;
                        resolve()
                    },
                    function (err) {
                        reject(err)
                    }).catch((e) => { reject(e) });
            }
            )
        },

        /**
         * @memberof hs.sensors.service
         * @function createChart
         * @description Create vega chart definition and use it in vegaEmbed
         * chart library. Observations for a specific unit from Senslog come
         * in a hierarchy, where 1st level contains object with timestamp and
         * for each timestamp there exist multiple sensor observations for
         * varying count of sensors. This nested list is flatened to simple
         * array of objects with {sensor_id, timestamp, value, sensor_name}
         */
        createChart(unit) {
            var sensorDesc = unit.sensors.filter(s =>
                me.sensorIdsSelected.indexOf(s.sensor_id) > -1
            );
            if (sensorDesc.length > 0) sensorDesc = sensorDesc[0];
            let observations = me.observations.reduce(
                (acc, val) => acc.concat(
                    val.sensors
                        .filter(s => me.sensorIdsSelected.indexOf(s.sensor_id) > -1)
                        .map(s => {
                            var time = moment(val.time_stamp);
                            s.sensor_name = me.sensorById[s.sensor_id].sensor_name;
                            s.time = time.format('DD.MM.YYYY HH:mm');
                            s.time_stamp = time.toDate();
                            return s
                        })
                ), []);
            observations.sort((a, b) => {
                if (a.time_stamp > b.time_stamp) return 1;
                if (b.time_stamp > a.time_stamp) return -1;
                return 0;
            });
            //See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat for flattening array
            var chartData = {
                "$schema": "https://vega.github.io/schema/vega-lite/v3.4.0.json",
                "config": {
                    "mark": {
                        "tooltip": null
                    },
                },
                "width": document.querySelector('#chartplace').offsetWidth - 40,
                "autosize": {
                    "type": "fit",
                    "contains": "padding"
                },
                "data": {
                    "name": "data-062c25e80e0ff23df3803082d5c6f7e7"
                },
                "datasets": {
                    "data-062c25e80e0ff23df3803082d5c6f7e7":
                        observations
                },
                "encoding": {
                    "color": {
                        "field": "sensor_name",
                        "legend": {
                            "title": `Sensor`
                        },
                        "type": "nominal"
                    },
                    "x": {
                        "axis": {
                            "title": "Timestamp",
                            "labelOverlap": true
                        },
                        "field": "time_stamp",
                        "sort": false,
                        "type": "temporal"
                    },
                    "y": {
                        "axis": {
                            "title": `${sensorDesc.phenomenon_name} ${sensorDesc.uom}`
                        },
                        "field": "value",
                        "type": "quantitative"
                    }
                },
                "mark": { "type": "line", "tooltip": { "content": "data" } },
                "selection": {
                    "selector016": {
                        "bind": "scales",
                        "encodings": [
                            "x",
                            "y"
                        ],
                        "type": "interval"
                    }
                }
            }
            try {
                vegaEmbed(document.querySelector('#chartplace'), chartData);
            } catch (ex) {
                console.warn('Could not create vega chart:', ex);
            }
        }

    })
}]<commit_msg>Zoom to sensor when clicked<commit_after>import moment from 'moment';
import { default as vegaEmbed } from 'vega-embed';
import { WKT } from 'ol/format';
import VectorLayer from 'ol/layer/Vector';
import { Vector as VectorSource } from 'ol/source';
import { Style, Icon, Stroke, Fill, Circle, Text } from 'ol/style';

var labelStyle = new Style({
    geometry: function (feature) {
        var geometry = feature.getGeometry();
        if (geometry.getType() == 'MultiPolygon') {
            // Only render label for the widest polygon of a multipolygon
            var polygons = geometry.getPolygons();
            var widest = 0;
            for (var i = 0, ii = polygons.length; i < ii; ++i) {
                var polygon = polygons[i];
                var width = getWidth(polygon.getExtent());
                if (width > widest) {
                    widest = width;
                    geometry = polygon;
                }
            }
        }
        return geometry;
    },
    text: new Text({
        font: '12px Calibri,sans-serif',
        overflow: true,
        fill: new Fill({
            color: '#000'
        }),
        stroke: new Stroke({
            color: '#fff',
            width: 3
        })
    })
});

var bookmarkStyle = [new Style({
    fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
    }),
    stroke: new Stroke({
        color: '#e49905',
        width: 2
    }),
    image: new Icon({
        src: require('../../components/styles/img/svg/wifi8.svg'),
        crossOrigin: 'anonymous',
        anchor: [0.5, 1]
    })
}), labelStyle];

export default ['hs.utils.service', '$http', 'config', 'hs.map.service', 'hs.layout.service', '$rootScope', '$compile', '$timeout', function (utils, $http, config, hsMap, layoutService, $rootScope, $compile, $timeout) {
    var me = this;
    var endpoint = config.senslog;

    $rootScope.$on('vectorQuery.featureSelected', utils.debounce((event, feature) => {
        if (feature.getLayer(hsMap.map) == me.layer) {
            layoutService.setMainPanel('sensors');
            me.units.forEach(unit => unit.expanded = false);
            me.selectUnit(me.units.filter(unit =>
                unit.unit_id == feature.get('unit_id')
            )[0]);
        }
    }, 150, false, me))

    return angular.extend(me, {
        units: [],
        sensorsSelected: [],
        sensorIdsSelected: [],
        sensorById: {},
        selectSensor(sensor) {
            me.sensorsSelected.forEach(s => s.checked = false);
            sensor.checked = true;
            me.sensorsSelected = [sensor];
            me.sensorIdsSelected = [sensor.sensor_id]
        },
        toggleSensor(sensor) {
            if (sensor.checked) {
                me.sensorsSelected.push(sensor);
                me.sensorIdsSelected.push(sensor.sensor_id);
            } else {
                me.sensorsSelected.splice(me.sensorsSelected.indexOf(sensor), 1);
                me.sensorIdsSelected.splice(me.sensorIdsSelected.indexOf(sensor.sensor_id), 1);
            }
        },
        selectUnit(unit) {
            me.unit = unit;
            unit.expanded = !unit.expanded;
            me.selectSensor(unit.sensors[0]);
            if (!layoutService.contentWrapper.querySelector('.hs-sensor-unit-dialog')) {
                const dir = 'hs.sensors.unit-dialog';
                const html = `<${dir} unit="sensorsService.unit"></${dir}>`;
                const element = angular.element(html)[0];
                layoutService.contentWrapper.querySelector(".hs-gui-overlay").appendChild(element);
                $compile(element)($rootScope.$new());
            } else {
                me.unitDialogVisible = true;
            }
            $timeout(_ => {
                if (angular.isUndefined(me.currentInterval))
                    me.currentInterval = { amount: 1, unit: 'days' };
                me.getObservationHistory(
                    me.unit,
                    me.currentInterval
                ).then(_ => me.createChart(me.unit))

            }, 0)
            hsMap.map.getView().fit(unit.feature.getGeometry(), {maxZoom: 16});
        },
        createLayer() {
            me.layer = new VectorLayer({
                title: 'Sensor units',
                synchronize: false,
                editor: {
                    editable: false
                },
                style: function (feature) {
                    labelStyle.getText().setText(feature.get('name'));
                    return bookmarkStyle;
                },
                source: new VectorSource({})
            });
            hsMap.map.addLayer(me.layer)
        },
        /**
         * @memberof hs.sensors.service
         * @function getUnits
         * @description Get list of units from Senslog backend
         */
        getUnits() {
            if (me.layer == null) me.createLayer();
            var url = utils.proxify(`${endpoint.url}/senslog-lite/rest/unit`);
            $http.get(url, {
                params: {
                    user_id: endpoint.user_id
                }
            }).then(response => {
                me.units = response.data;
                let features = me.units
                    .filter(unit => unit.unit_position && unit.unit_position.asWKT)
                    .map(unit => {
                        const format = new WKT();
                        const feature = format.readFeature(unit.unit_position.asWKT, {
                            dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857'
                        })
                        feature.set('name', unit.description);
                        feature.set('unit_id', unit.unit_id);
                        unit.feature = feature;
                        return feature
                    })
                me.layer.getSource().addFeatures(features);
                me.fillLastObservations();
                me.units.forEach(unit => {
                    unit.sensorTypes = unit.sensors.map(s => {
                        return { name: s.sensor_type }
                    });
                    unit.sensorTypes = utils.removeDuplicates(unit.sensorTypes, 'name');
                    unit.sensorTypes.map(st =>
                        st.sensors = unit.sensors.filter(
                            s => s.sensor_type == st.name
                        )
                    )
                });
                setInterval(me.fillLastObservations, 60000);

            },
                function (err) {

                });
        },

        fillLastObservations() {
            $http.get(utils.proxify(`${endpoint.url}/senslog1/SensorService`), {
                params: {
                    Operation: 'GetLastObservations',
                    group: endpoint.group,
                    user: endpoint.user
                }
            }).then(response => {
                var sensorValues = {};
                response.data.forEach(sv => {
                    sensorValues[sv.sensorId] = {
                        value: sv.observedValue,
                        timestamp: moment(sv.timeStamp).format('DD.MM.YYYY HH:mm')
                    };
                });
                me.units.forEach(unit => {
                    unit.sensors.forEach(sensor => {
                        me.sensorById[sensor.sensor_id] = sensor;
                        if (sensorValues[sensor.sensor_id]) {
                            sensor.lastObservationValue = sensorValues[sensor.sensor_id].value;
                            sensor.lastObservationTimestamp = sensorValues[sensor.sensor_id].timestamp;
                        }
                    })
                })
            })
        },

        /**
         * @memberof hs.sensors.service
         * @function getObservationHistory
         * @param {Object} unit Object containing
         * {description, is_mobile, sensors, unit_id, unit_type}
         * @param {Object} interval Object {amount, unit}. Used to substract time
         * from current time, like 6 months before now
         * @description Gets list of observations in a given time frame for all
         * the sensors on a sensor unit (meteostation).
         */
        getObservationHistory(unit, interval) {
            return new Promise((resolve, reject) => {
                var url = utils.proxify(`${endpoint.url}/senslog-lite/rest/observation`);
                var from_time = moment().subtract(interval.amount, interval.unit);
                from_time = `${from_time.format('YYYY-MM-DD')} ${from_time.format('HH:mm:ssZ')}`;
                interval.loading = true;
                $http.get(url, {
                    params: {
                        user_id: endpoint.user_id,
                        unit_id: unit.unit_id,
                        from_time
                    }
                }).then(
                    response => {
                        interval.loading = false;
                        me.observations = response.data;
                        resolve()
                    },
                    function (err) {
                        reject(err)
                    }).catch((e) => { reject(e) });
            }
            )
        },

        /**
         * @memberof hs.sensors.service
         * @function createChart
         * @description Create vega chart definition and use it in vegaEmbed
         * chart library. Observations for a specific unit from Senslog come
         * in a hierarchy, where 1st level contains object with timestamp and
         * for each timestamp there exist multiple sensor observations for
         * varying count of sensors. This nested list is flatened to simple
         * array of objects with {sensor_id, timestamp, value, sensor_name}
         */
        createChart(unit) {
            var sensorDesc = unit.sensors.filter(s =>
                me.sensorIdsSelected.indexOf(s.sensor_id) > -1
            );
            if (sensorDesc.length > 0) sensorDesc = sensorDesc[0];
            let observations = me.observations.reduce(
                (acc, val) => acc.concat(
                    val.sensors
                        .filter(s => me.sensorIdsSelected.indexOf(s.sensor_id) > -1)
                        .map(s => {
                            var time = moment(val.time_stamp);
                            s.sensor_name = me.sensorById[s.sensor_id].sensor_name;
                            s.time = time.format('DD.MM.YYYY HH:mm');
                            s.time_stamp = time.toDate();
                            return s
                        })
                ), []);
            observations.sort((a, b) => {
                if (a.time_stamp > b.time_stamp) return 1;
                if (b.time_stamp > a.time_stamp) return -1;
                return 0;
            });
            //See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat for flattening array
            var chartData = {
                "$schema": "https://vega.github.io/schema/vega-lite/v3.4.0.json",
                "config": {
                    "mark": {
                        "tooltip": null
                    },
                },
                "width": document.querySelector('#chartplace').offsetWidth - 40,
                "autosize": {
                    "type": "fit",
                    "contains": "padding"
                },
                "data": {
                    "name": "data-062c25e80e0ff23df3803082d5c6f7e7"
                },
                "datasets": {
                    "data-062c25e80e0ff23df3803082d5c6f7e7":
                        observations
                },
                "encoding": {
                    "color": {
                        "field": "sensor_name",
                        "legend": {
                            "title": `Sensor`
                        },
                        "type": "nominal"
                    },
                    "x": {
                        "axis": {
                            "title": "Timestamp",
                            "labelOverlap": true
                        },
                        "field": "time_stamp",
                        "sort": false,
                        "type": "temporal"
                    },
                    "y": {
                        "axis": {
                            "title": `${sensorDesc.phenomenon_name} ${sensorDesc.uom}`
                        },
                        "field": "value",
                        "type": "quantitative"
                    }
                },
                "mark": { "type": "line", "tooltip": { "content": "data" } },
                "selection": {
                    "selector016": {
                        "bind": "scales",
                        "encodings": [
                            "x",
                            "y"
                        ],
                        "type": "interval"
                    }
                }
            }
            try {
                vegaEmbed(document.querySelector('#chartplace'), chartData);
            } catch (ex) {
                console.warn('Could not create vega chart:', ex);
            }
        }

    })
}]<|endoftext|>


<commit_before>var vumigo = require("vumigo_v01");
var jed = require("jed");

if (api === undefined) {
  // testing hook (supplies api when it is not passed in by the real sandbox)
  var api = this.api = new vumigo.dummy_api.DummyApi();
}

var FreeText = vumigo.states.FreeText;
var EndState = vumigo.states.EndState;
var ChoiceState = vumigo.states.ChoiceState;
var PaginatedChoiceState = vumigo.states.PaginatedChoiceState;
var Choice = vumigo.states.Choice;
var InteractionMachine = vumigo.state_machine.InteractionMachine;
var StateCreator = vumigo.state_machine.StateCreator;
var HttpApi = vumigo.http_api.HttpApi;
var Promise = vumigo.promise.Promise;

function Hangman() {
    var self = this;
    StateCreator.call(self, 'new_game');

    self.word_url = 'http://randomword.setgetgo.com/get.php';

    self.load_game = function (msisdn) {
        var p = im.api_request('kv.get', {
            key: msisdn
        });
        p.add_callback(function (result) {
            return result.value;
        });
        return p;
    };

    self.save_game = function (msisdn, game) {
        var p = im.api_request('kv.set', {
            key: msisdn,
            value: game
        });
        p.add_callback(function() {
            return game;
        });
        return p;
    };

    self.draw_board = function (game) {
        var word = game.word.split('').map(function (letter) {
            if(game.guesses.indexOf(letter) > -1)
                return letter;
            return '_';
        }).join('');
        var guesses = game.guesses.join('');
        if(self.won(game)) {
            return [
                game.msg,
                'The word was: ' + word
            ].join('\n');
        } else {
            return [
                game.msg,
                'Word: ' + word,
                'Letters guessed so far: ' + guesses,
                game.prompt + '(0 to quit):'
            ].join('\n');
        }
    };

    self.get_random_word = function () {
        var p = im.api_request('http.get', {
            'url': self.word_url,
            'headers': {
                'content-type': ['text/plain']
            }
        });
        p.add_callback(function (result) {
            var lp = im.log('Word: ' + result);
            lp.add_callback(function() {
                return result;
            });
            return lp;
        });
        p.add_callback(function (result) {
            return result.body;
        });
        return p;
    };

    self.create_new_game = function (word) {
        return {
            msg: 'New game!',
            word: word,
            guesses: [],
            prompt: ''
        };
    };

    self.game_won = function (game) {
        return game.word.split('').filter(function(letter) {
            return game.guesses.indexOf(letter) == -1;
        }).length === 0;
    };

    self.game_logic_callback = function(im, game) {
        return function (content, done) {
            var p = self.game_logic(im, game, content);
            p.add_callback(function (next_state) {
                done(next_state);
            });
            return p;
        };
    };

    self.game_logic = function (im, game, content) {
        var next_state;
        if(!content) {
            game.msg = 'Some input required please.';
            game.prompt = 'Enter next guess';
            next_state = 'resume_game';
        } else if (content.length > 1) {
            game.msg = 'Single character only please.';
            game.prompt = 'Enter next guess';
            next_state = 'resume_game';
        } else if (content == '0') {
            next_state = 'end_game';
        } else if (game.guesses.indexOf(content) > -1) {
            game.msg = 'You\'ve already guessed \'' + content + '\'.';
            game.prompt = 'Enter next guess';
            next_state = 'resume_game';
        } else {
            game.guesses.push(content);
            if(game.word.indexOf(content) > -1) {
                game.msg = 'Word contains at least one \'' + content + '\'! :D';
            } else {
                game.msg = 'Word contains no \'' + content + '\'. :(';
            }
            game.prompt = 'Enter next guess';
            next_state = 'resume_game';
        }

        if(self.won(game)) {
            game.msg = self.victory_message(game);
            next_state = 'win';
        }

        var p = self.save_game(im.user_addr, game);
        p.add_callback(function (game) {
            return {
                next_state: next_state,
                game: game
            };
        });
        return p;
    };

    self.victory_message = function(game) {
        var uniques = game.word.length;
        var guesses = game.guesses.length;
        var win_messages = [
            [1, "Flawless victory!"],
            [1.5, "Epic victory!"],
            [2, "Standard victory!"],
            [3, "Sub-par victory!"],
            [4, "Random victory!"]
        ];

        for(var i=0; i < win_messages.length; i++) {
            var factor = win_messages[i][0],
                msg = win_messages[i][1];

            if(guesses <= (uniques * factor)) {
                return msg;
            }
        }
        return "Button mashing!";
    };

    self.won = function(game) {
        for(var i = 0; i < game.word.length; i++) {
            var letter = game.word[i];
            if(game.guesses.indexOf(letter) == -1 ) {
                return false;
            }
        }
        return true;
    };

    self.add_creator('new_game', function (state_name, im) {
        var p = self.get_random_word();
        p.add_callback(function (word) {
            return self.save_game(im.user_addr,
                                  self.create_new_game(word));
        });
        p.add_callback(function (game) {
            return new FreeText(
                state_name,
                'resume_game',
                self.draw_board(game)
            );
        });
        return p;
    });

    self.add_creator('resume_game', function (state_name, im) {
        var p = self.load_game(im.user_addr);
        p.add_callback(function (game) {
            //  Yoink! I need to get a the content outside of
            //  whatever state the machine thinks I'm in.
            var content = im.msg.content;
            return self.game_logic(im, game, content);
        });
        p.add_callback(function (game_state) {
            return new FreeText(
                state_name,
                game_state.next_state,
                self.draw_board(game_state.game)
            );
        });
        return p;
    });

    self.add_creator('win', function (state_name, im) {
        var p = self.load_game(im.user_addr);
        p.add_callback(function (game) {
            return new EndState(
                state_name,
                self.draw_board(game),
                'new_game');
        });
        return p;
    });

    self.add_state(new EndState(
        'end_game',
        'Adieu!',
        'new_game'));
}

// launch app
var states = new Hangman();
var im = new InteractionMachine(api, states);
im.attach();
<commit_msg>log word not response object<commit_after>var vumigo = require("vumigo_v01");
var jed = require("jed");

if (api === undefined) {
  // testing hook (supplies api when it is not passed in by the real sandbox)
  var api = this.api = new vumigo.dummy_api.DummyApi();
}

var FreeText = vumigo.states.FreeText;
var EndState = vumigo.states.EndState;
var ChoiceState = vumigo.states.ChoiceState;
var PaginatedChoiceState = vumigo.states.PaginatedChoiceState;
var Choice = vumigo.states.Choice;
var InteractionMachine = vumigo.state_machine.InteractionMachine;
var StateCreator = vumigo.state_machine.StateCreator;
var HttpApi = vumigo.http_api.HttpApi;
var Promise = vumigo.promise.Promise;

function Hangman() {
    var self = this;
    StateCreator.call(self, 'new_game');

    self.word_url = 'http://randomword.setgetgo.com/get.php';

    self.load_game = function (msisdn) {
        var p = im.api_request('kv.get', {
            key: msisdn
        });
        p.add_callback(function (result) {
            return result.value;
        });
        return p;
    };

    self.save_game = function (msisdn, game) {
        var p = im.api_request('kv.set', {
            key: msisdn,
            value: game
        });
        p.add_callback(function() {
            return game;
        });
        return p;
    };

    self.draw_board = function (game) {
        var word = game.word.split('').map(function (letter) {
            if(game.guesses.indexOf(letter) > -1)
                return letter;
            return '_';
        }).join('');
        var guesses = game.guesses.join('');
        if(self.won(game)) {
            return [
                game.msg,
                'The word was: ' + word
            ].join('\n');
        } else {
            return [
                game.msg,
                'Word: ' + word,
                'Letters guessed so far: ' + guesses,
                game.prompt + '(0 to quit):'
            ].join('\n');
        }
    };

    self.get_random_word = function () {
        var p = im.api_request('http.get', {
            'url': self.word_url,
            'headers': {
                'content-type': ['text/plain']
            }
        });
        p.add_callback(function (result) {
            var lp = im.log('Word: ' + result.body);
            lp.add_callback(function() {
                return result;
            });
            return lp;
        });
        p.add_callback(function (result) {
            return result.body;
        });
        return p;
    };

    self.create_new_game = function (word) {
        return {
            msg: 'New game!',
            word: word,
            guesses: [],
            prompt: ''
        };
    };

    self.game_won = function (game) {
        return game.word.split('').filter(function(letter) {
            return game.guesses.indexOf(letter) == -1;
        }).length === 0;
    };

    self.game_logic_callback = function(im, game) {
        return function (content, done) {
            var p = self.game_logic(im, game, content);
            p.add_callback(function (next_state) {
                done(next_state);
            });
            return p;
        };
    };

    self.game_logic = function (im, game, content) {
        var next_state;
        if(!content) {
            game.msg = 'Some input required please.';
            game.prompt = 'Enter next guess';
            next_state = 'resume_game';
        } else if (content.length > 1) {
            game.msg = 'Single character only please.';
            game.prompt = 'Enter next guess';
            next_state = 'resume_game';
        } else if (content == '0') {
            next_state = 'end_game';
        } else if (game.guesses.indexOf(content) > -1) {
            game.msg = 'You\'ve already guessed \'' + content + '\'.';
            game.prompt = 'Enter next guess';
            next_state = 'resume_game';
        } else {
            game.guesses.push(content);
            if(game.word.indexOf(content) > -1) {
                game.msg = 'Word contains at least one \'' + content + '\'! :D';
            } else {
                game.msg = 'Word contains no \'' + content + '\'. :(';
            }
            game.prompt = 'Enter next guess';
            next_state = 'resume_game';
        }

        if(self.won(game)) {
            game.msg = self.victory_message(game);
            next_state = 'win';
        }

        var p = self.save_game(im.user_addr, game);
        p.add_callback(function (game) {
            return {
                next_state: next_state,
                game: game
            };
        });
        return p;
    };

    self.victory_message = function(game) {
        var uniques = game.word.length;
        var guesses = game.guesses.length;
        var win_messages = [
            [1, "Flawless victory!"],
            [1.5, "Epic victory!"],
            [2, "Standard victory!"],
            [3, "Sub-par victory!"],
            [4, "Random victory!"]
        ];

        for(var i=0; i < win_messages.length; i++) {
            var factor = win_messages[i][0],
                msg = win_messages[i][1];

            if(guesses <= (uniques * factor)) {
                return msg;
            }
        }
        return "Button mashing!";
    };

    self.won = function(game) {
        for(var i = 0; i < game.word.length; i++) {
            var letter = game.word[i];
            if(game.guesses.indexOf(letter) == -1 ) {
                return false;
            }
        }
        return true;
    };

    self.add_creator('new_game', function (state_name, im) {
        var p = self.get_random_word();
        p.add_callback(function (word) {
            return self.save_game(im.user_addr,
                                  self.create_new_game(word));
        });
        p.add_callback(function (game) {
            return new FreeText(
                state_name,
                'resume_game',
                self.draw_board(game)
            );
        });
        return p;
    });

    self.add_creator('resume_game', function (state_name, im) {
        var p = self.load_game(im.user_addr);
        p.add_callback(function (game) {
            //  Yoink! I need to get a the content outside of
            //  whatever state the machine thinks I'm in.
            var content = im.msg.content;
            return self.game_logic(im, game, content);
        });
        p.add_callback(function (game_state) {
            return new FreeText(
                state_name,
                game_state.next_state,
                self.draw_board(game_state.game)
            );
        });
        return p;
    });

    self.add_creator('win', function (state_name, im) {
        var p = self.load_game(im.user_addr);
        p.add_callback(function (game) {
            return new EndState(
                state_name,
                self.draw_board(game),
                'new_game');
        });
        return p;
    });

    self.add_state(new EndState(
        'end_game',
        'Adieu!',
        'new_game'));
}

// launch app
var states = new Hangman();
var im = new InteractionMachine(api, states);
im.attach();
<|endoftext|>


<commit_before>'use babel'

/* @flow */

import { Range, Point } from 'atom'
import type Buffers from './buffers'
import type { Linter$Message } from './types'

export function map<TValue, TResult>(iterable: Array<TValue> | Set<TValue>, callback: ((param: TValue) => TResult)): Array<TResult> {
  const toReturn = []
  for (const entry of iterable) {
    toReturn.push(callback(entry))
  }
  return toReturn
}

export function visitMessage(message: Linter$Message): Promise {
  return atom.workspace.open(message.filePath).then(function() {
    if (message.range) {
      const textEditor = atom.workspace.getActiveTextEditor()
      textEditor.setCursorBufferPosition(message.range[0] || message.range.start)
    }
  })
}

export function getBuffersMap(buffers: Buffers): { buffersMap: Object, filePaths: Set<string> } {
  const buffersMap = {}
  const filePaths = new Set()
  for (const buffer of buffers.getBuffers()) {
    const filePath = buffer.getBuffer().getPath()
    buffersMap[filePath] = {
      buffer,
      added: [],
      removed: []
    }
    filePaths.add(filePath)
  }
  return { buffersMap, filePaths }
}

export function getMessageRange(message: Linter$Message): Range {
  return Array.isArray(message.range) ? Range.fromObject(message.range) : message.range
}
export function getMessageClass(message: Linter$Message): string {
  return `${message.class || ''} ${message.type.toLowerCase()}`
}

export function getMessagesOnPoint(messages: Set<Linter$Message>, filePath: string, cursorPosition: Point): Set<Linter$Message> {
  const filtered = new Set()
  const range = new Range(cursorPosition, cursorPosition)
  for (const message of messages) {
    if (message.filePath === filePath && message.range && range.intersectsWith(Range.fromObject(message.range))) {
      filtered.add(message)
    }
  }
  return filtered
}

export function sortMessages(messages: Array<Linter$Message>): Array<Linter$Message> {
  return messages.sort(function(a, b) {
    if (a.filePath !== b.filePath) {
      return -1
    }
    if (!a.range || b.range) {
      return -1
    }
    return getMessageRange(a).compare(b)
  })
}
<commit_msg>:art: Supress a flow warning<commit_after>'use babel'

/* @flow */

import { Range, Point } from 'atom'
import type Buffers from './buffers'
import type { Linter$Message } from './types'

export function map<TValue, TResult>(iterable: Array<TValue> | Set<TValue>, callback: ((param: TValue) => TResult)): Array<TResult> {
  const toReturn = []
  for (const entry of iterable) {
    toReturn.push(callback(entry))
  }
  return toReturn
}

export function visitMessage(message: Linter$Message): Promise {
  return atom.workspace.open(message.filePath).then(function() {
    if (message.range) {
      const textEditor = atom.workspace.getActiveTextEditor()
      // $FlowIgnore: Flow doesn't believe me
      textEditor.setCursorBufferPosition(message.range[0] || message.range.start)
    }
  })
}

export function getBuffersMap(buffers: Buffers): { buffersMap: Object, filePaths: Set<string> } {
  const buffersMap = {}
  const filePaths = new Set()
  for (const buffer of buffers.getBuffers()) {
    const filePath = buffer.getBuffer().getPath()
    buffersMap[filePath] = {
      buffer,
      added: [],
      removed: []
    }
    filePaths.add(filePath)
  }
  return { buffersMap, filePaths }
}

export function getMessageRange(message: Linter$Message): Range {
  return Array.isArray(message.range) ? Range.fromObject(message.range) : message.range
}
export function getMessageClass(message: Linter$Message): string {
  return `${message.class || ''} ${message.type.toLowerCase()}`
}

export function getMessagesOnPoint(messages: Set<Linter$Message>, filePath: string, cursorPosition: Point): Set<Linter$Message> {
  const filtered = new Set()
  const range = new Range(cursorPosition, cursorPosition)
  for (const message of messages) {
    if (message.filePath === filePath && message.range && range.intersectsWith(Range.fromObject(message.range))) {
      filtered.add(message)
    }
  }
  return filtered
}

export function sortMessages(messages: Array<Linter$Message>): Array<Linter$Message> {
  return messages.sort(function(a, b) {
    if (a.filePath !== b.filePath) {
      return -1
    }
    if (!a.range || b.range) {
      return -1
    }
    return getMessageRange(a).compare(b)
  })
}
<|endoftext|>


<commit_before>define(function(require, exports, module) {
  'use strict';
  // compile all the templates
  var flight = require('flight');
  var Handlebars = require('handlebars');
  var _ = require('lodash');
  var $ = require('jquery');
  var needTreatmentTemplate = require('text!templates/needTreatment.html');
  var inputTemplate = require('text!templates/input.html');
  var formTemplate = require('text!templates/form.html');
  var facetTemplate = require('text!templates/facet.html');
  var facetControlsTemplate = require('text!templates/facetControls.html');
  var templates = {
    needTreatment: Handlebars.compile(needTreatmentTemplate),
    input: Handlebars.compile(inputTemplate),
    form: Handlebars.compile(formTemplate),
    facet: Handlebars.compile(facetTemplate),
    facetControls: Handlebars.compile(facetControlsTemplate)
  };

  module.exports = flight.component(function () {
    this.configureFacets = function(ev, config) {
      this.facetConfig = config.facets;
    };

    // -1 is start with intro question that is not a facet
    this.facetOffset = -1;

    this.meetsFacetDependency = function(facetData, key, dependency) {
      return _.find(facetData, function(facets) {
        return _.find(facets, function(facet) {
          return facet.value === dependency && facet.selected;
        });
      });
    };

    this.getFacetConfig = function(key, attr) {
      if (this.facetConfig[key]) {
        return this.facetConfig[key][attr];
      }
    };

    this.displayFacets = function(ev, facetData) {
      // cache facet data so that you can call it internally instead of waiting
      //   for event from data facet
      if (facetData) {
        this.facetData = facetData;
      } else {
        facetData = this.facetData;
      }

      this.noSelectionsAvailable = false;

      // show first question if you're looking for a treatment facility
      if (this.facetOffset === -1) {
        this.$node.html(templates.needTreatment()).show();
        this.on('.js-next-prev', 'click', this.nextPrevHandler);
        this.on('.js-no-treatment', 'click', this.showNoTreatment);
        this.on('.js-not-sure-treatment', 'click', this.showNoTreatment);
        return;
      }

      var facets = _.keys(facetData);
      var key = facets[this.facetOffset];
      if (!this.showAllFacets) {
        if (this.facetOffset >= facets.length) {
          this.$node.find('.js-offer-results[data-offer-results=true]').click();
          return;
        }

        // does the facet have a dependency?
        if (key) {
          var dependency = this.getFacetConfig(key, 'dependency');
          if (dependency) {
            if (!this.meetsFacetDependency(facetData, key, dependency)) {
              this.setFacetOffset(this.facetOffset + 1);
              return;
            }
          }
        }

        var newFacetData = {};
        newFacetData[key] = facetData[key];
        facetData = newFacetData;
      }

      var facet = _.chain(facetData).map(
          _.bind(function(values, key) {
            // only one facet available that has no facilities
            if (values.length === 1 && values[0].count === 0) {
              this.noSelectionsAvailable = true;
            }
            var hasSelected = _.some(values, 'selected');
            var configKey = this.showAllFacets ? 'title' : 'survey_title';
            // render a template for each facet
            return templates.facet({
              title: this.getFacetConfig(key, configKey),
              key: key,
              // render the form for each value of the facet
              form: templates.form({
                key: key,
                has_selected: hasSelected,
                inputs: _.chain(values).filter('count').map(templates.input).
                                        value()
              })
            });
          }, this)).value().join('');

      var previousOffset;
      if (typeof this.facetHistory === 'object') {
        previousOffset = this.facetHistory[this.facetHistory.length - 1] || -1;
      } else {
        previousOffset = -1;
      }
      this.$node.html(
        facet +
        templates.facetControls({
          showResults: this.showAllFacets,
          facetOffset: this.facetOffset + 1,
          previousFacetOffset: previousOffset
        })
      ).show();

      this.on('.js-next-prev', 'click', this.nextPrevHandler);
      this.on('.js-offer-results', 'click', this.showResultsHandler);

      if (this.noSelectionsAvailable === true) {
        // click button to advance to the next facet.
        // NOTE(chaserx): I couldn't find a way to use `facetOffset` without
        //    creating infinite loop.
        this.$node.find('button.btn-next').trigger('click');
        this.noSelectionsAvailable = false;
        return;
      }
    };

    this.showResultsHandler = function(ev) {
      // can be true or false
      var offerResults = $(ev.target).data('offerResults');
      this.showAllFacets = offerResults;
      if (this.showAllFacets) {
        $('#facets').addClass('control-sidebar');
        $('#facets').removeClass('control-survey');
        $(document).trigger('uiShowResults', {});
      } else {
        $('#facets').removeClass('control-sidebar');
        $('#facets').addClass('control-survey');
        $(document).trigger('uiHideResults', {});
      }
      this.displayFacets();
    };

    this.nextPrevHandler = function(ev) {
      if (typeof this.facetHistory === 'undefined') {
        this.facetHistory = [];
      }
      var clickedEl = $(ev.target);
      var offset = parseInt(clickedEl.data('nextFacetOffset'), 10);
      if (clickedEl.is('.previous')) {
        var facet = _.keys(this.facetData)[offset];
        $(document).trigger('uiClearFacets', {facet: facet});
        this.setFacetOffset(this.facetHistory.pop());
      } else {
        var lastItem = this.facetHistory[this.facetHistory.length - 1];
        if (lastItem !== this.facetOffset) {
          this.facetHistory.push(this.facetOffset);
        }
        this.setFacetOffset(offset);
      }
    };

    this.setFacetOffset = function(offset) {
      this.facetOffset = offset;
      this.displayFacets();
    };

    this.clearFacets = function(ev) {
      ev.preventDefault();
      var facet = $(ev.target).data('facet');
      $(document).trigger('uiClearFacets', {facet: facet});
    };

    this.selectFacet = function(ev) {
      var $form = $(ev.target).parents('form'),
          facet = $form.data('facet'),
          selected = _.map($form.serializeArray(),
                           'name');
      window.setTimeout(function() {
        $(document).trigger('uiFilterFacet', {
          facet: facet,
          selected: selected
        });
      }, 0);
    };

    this.showNoTreatment = function() {
      this.$node.html("Thank you for your time.");
    };

    // defaultAttrs is now deprecated in favor of 'attributes', but our
    //    version of flight still uses this.
    this.defaultAttrs({
      clearFacetsSelector : ".clear-facets"
    });

    this.after('initialize', function() {
      this.on('change', this.selectFacet);
      this.on(document, 'config', this.configureFacets);
      this.on(document, 'dataFacets', this.displayFacets);
      this.on(document, 'uiFacetChangeRequest', function(ev, facet) {
        var input = $('input[name=' + facet.name + ']');
        input.prop('checked', true);
        input.trigger('change');
      });
      this.on('click', { clearFacetsSelector : this.clearFacets });
    });
  });
});
<commit_msg>Fix bug where you couldn't return to Man/Woman question<commit_after>define(function(require, exports, module) {
  'use strict';
  // compile all the templates
  var flight = require('flight');
  var Handlebars = require('handlebars');
  var _ = require('lodash');
  var $ = require('jquery');
  var needTreatmentTemplate = require('text!templates/needTreatment.html');
  var inputTemplate = require('text!templates/input.html');
  var formTemplate = require('text!templates/form.html');
  var facetTemplate = require('text!templates/facet.html');
  var facetControlsTemplate = require('text!templates/facetControls.html');
  var templates = {
    needTreatment: Handlebars.compile(needTreatmentTemplate),
    input: Handlebars.compile(inputTemplate),
    form: Handlebars.compile(formTemplate),
    facet: Handlebars.compile(facetTemplate),
    facetControls: Handlebars.compile(facetControlsTemplate)
  };

  module.exports = flight.component(function () {
    this.configureFacets = function(ev, config) {
      this.facetConfig = config.facets;
    };

    // -1 is start with intro question that is not a facet
    this.facetOffset = -1;

    this.meetsFacetDependency = function(facetData, key, dependency) {
      return _.find(facetData, function(facets) {
        return _.find(facets, function(facet) {
          return facet.value === dependency && facet.selected;
        });
      });
    };

    this.getFacetConfig = function(key, attr) {
      if (this.facetConfig[key]) {
        return this.facetConfig[key][attr];
      }
    };

    this.displayFacets = function(ev, facetData) {
      // cache facet data so that you can call it internally instead of waiting
      //   for event from data facet
      if (facetData) {
        this.facetData = facetData;
      } else {
        facetData = this.facetData;
      }

      this.noSelectionsAvailable = false;

      // show first question if you're looking for a treatment facility
      if (this.facetOffset === -1) {
        this.$node.html(templates.needTreatment()).show();
        this.on('.js-next-prev', 'click', this.nextPrevHandler);
        this.on('.js-no-treatment', 'click', this.showNoTreatment);
        this.on('.js-not-sure-treatment', 'click', this.showNoTreatment);
        return;
      }

      var facets = _.keys(facetData);
      var key = facets[this.facetOffset];
      if (!this.showAllFacets) {
        if (this.facetOffset >= facets.length) {
          this.$node.find('.js-offer-results[data-offer-results=true]').click();
          return;
        }

        // does the facet have a dependency?
        if (key) {
          var dependency = this.getFacetConfig(key, 'dependency');
          if (dependency) {
            if (!this.meetsFacetDependency(facetData, key, dependency)) {
              this.setFacetOffset(this.facetOffset + 1);
              return;
            }
          }
        }

        var newFacetData = {};
        newFacetData[key] = facetData[key];
        facetData = newFacetData;
      }

      var facet = _.chain(facetData).map(
          _.bind(function(values, key) {
            // only one facet available that has no facilities
            if (values.length === 1 && values[0].count === 0) {
              this.noSelectionsAvailable = true;
            }
            var hasSelected = _.some(values, 'selected');
            var configKey = this.showAllFacets ? 'title' : 'survey_title';
            // render a template for each facet
            return templates.facet({
              title: this.getFacetConfig(key, configKey),
              key: key,
              // render the form for each value of the facet
              form: templates.form({
                key: key,
                has_selected: hasSelected,
                inputs: _.chain(values).filter('count').map(templates.input).
                                        value()
              })
            });
          }, this)).value().join('');

      var previousOffset;
      if (typeof this.facetHistory === 'object') {
        previousOffset = this.facetHistory[this.facetHistory.length - 1] || -1;
      } else {
        previousOffset = -1;
      }
      this.$node.html(
        facet +
        templates.facetControls({
          showResults: this.showAllFacets,
          facetOffset: this.facetOffset + 1,
          previousFacetOffset: previousOffset
        })
      ).show();

      this.on('.js-next-prev', 'click', this.nextPrevHandler);
      this.on('.js-offer-results', 'click', this.showResultsHandler);

      if (this.noSelectionsAvailable === true) {
        // click button to advance to the next facet.
        // NOTE(chaserx): I couldn't find a way to use `facetOffset` without
        //    creating infinite loop.
        this.$node.find('button.btn-next').trigger('click');
        this.facetHistory.pop();
        this.noSelectionsAvailable = false;
        return;
      }
    };

    this.showResultsHandler = function(ev) {
      // can be true or false
      var offerResults = $(ev.target).data('offerResults');
      this.showAllFacets = offerResults;
      if (this.showAllFacets) {
        $('#facets').addClass('control-sidebar');
        $('#facets').removeClass('control-survey');
        $(document).trigger('uiShowResults', {});
      } else {
        $('#facets').removeClass('control-sidebar');
        $('#facets').addClass('control-survey');
        $(document).trigger('uiHideResults', {});
      }
      this.displayFacets();
    };

    this.nextPrevHandler = function(ev) {
      if (typeof this.facetHistory === 'undefined') {
        this.facetHistory = [];
      }
      var clickedEl = $(ev.target);
      var offset = parseInt(clickedEl.data('nextFacetOffset'), 10);
      if (clickedEl.is('.previous')) {
        var facet = _.keys(this.facetData)[offset];
        $(document).trigger('uiClearFacets', {facet: facet});
        this.setFacetOffset(this.facetHistory.pop());
      } else {
        var lastItem = this.facetHistory[this.facetHistory.length - 1];
        if (lastItem !== this.facetOffset) {
          this.facetHistory.push(this.facetOffset);
        }
        this.setFacetOffset(offset);
      }
    };

    this.setFacetOffset = function(offset) {
      this.facetOffset = offset;
      this.displayFacets();
    };

    this.clearFacets = function(ev) {
      ev.preventDefault();
      var facet = $(ev.target).data('facet');
      $(document).trigger('uiClearFacets', {facet: facet});
    };

    this.selectFacet = function(ev) {
      var $form = $(ev.target).parents('form'),
          facet = $form.data('facet'),
          selected = _.map($form.serializeArray(),
                           'name');
      window.setTimeout(function() {
        $(document).trigger('uiFilterFacet', {
          facet: facet,
          selected: selected
        });
      }, 0);
    };

    this.showNoTreatment = function() {
      this.$node.html("Thank you for your time.");
    };

    // defaultAttrs is now deprecated in favor of 'attributes', but our
    //    version of flight still uses this.
    this.defaultAttrs({
      clearFacetsSelector : ".clear-facets"
    });

    this.after('initialize', function() {
      this.on('change', this.selectFacet);
      this.on(document, 'config', this.configureFacets);
      this.on(document, 'dataFacets', this.displayFacets);
      this.on(document, 'uiFacetChangeRequest', function(ev, facet) {
        var input = $('input[name=' + facet.name + ']');
        input.prop('checked', true);
        input.trigger('change');
      });
      this.on('click', { clearFacetsSelector : this.clearFacets });
    });
  });
});
<|endoftext|>


<commit_before>var urlProcessor = require('./processor');
/*
* @module config/server/url-builder
* @param url - url with params such as http://url/entity/${id}
* @param method - HTTP verb {GET, POST, PUT, DELETE}
* @return {function}
*/
module.exports =  function(url, method){
  /**
   * Function returns by the module.
   * @param  {object} data - The JSON data to inject in the URL.
   * @return {function} returns a function which takes the URL as parameters.
   */
  return function generateUrl(data){
    return {
      url: urlProcessor(url, data),
      method: method
    };
  };
};
<commit_msg>[url][builder] Add data as parameter.<commit_after>var urlProcessor = require('./processor');
/*
* @module config/server/url-builder
* @param url - url with params such as http://url/entity/${id}
* @param method - HTTP verb {GET, POST, PUT, DELETE}
* @return {function}
*/
module.exports =  function(url, method){
  /**
   * Function returns by the module.
   * @param  {object} urlData - The JSON data to inject in the URL.
   * @param  {object} data - The JSON data to give to the request.
   * @return {function} returns a function which takes the URL as parameters.
   */
  return function generateUrl(urlData, data){
    return {
      url: urlProcessor(url, urlData),
      method: method,
      data: data
    };
  };
};
<|endoftext|>


<commit_before>"use strict";

const path = require("path");
const mkdirp = require("mkdirp");
const touch = require("touch");

/**
 * Determines the base directory of the given glob pattern.
 * This is used to determine the relative paths of matched files.
 *
 * @param {string} pattern - A glob pattern, such as "dir/subdir/*.js"
 * @returns {string}
 */
exports.getBaseDir = function getBaseDir (pattern) {
  // Some examples:
  //  - *.js                          =>  .
  //  - dir/**/*.js                   =>  dir
  //  - dir/subdir/main-*.js          =>  dir/subdir
  //  - dir/subdir/index.js           =>  dir/subdir
  //  - dir/subdir/index.(js|coffee)  =>  dir/subdir

  let wildcard = pattern.indexOf("*");
  if (wildcard >= 0) {
    pattern = pattern.substr(0, wildcard + 1);
  }
  return path.dirname(pattern);
};

/**
 * Determines whether the given output filename is a directory.
 *
 * @param {string} pattern - A file path, directory path, or pattern such as "dist/*.min.js"
 * @returns {boolean}
 */
exports.isDirectory = function isDirectory (pattern) {
  let basename = path.basename(pattern);
  if (basename.indexOf("*") >= 0) {
    // The pattern includes a filename pattern (e.g. "dist/*.min.js"),
    // which counts as a directory path
    return true;
  }
  else if (basename.indexOf(".") === -1) {
    // The pattern has no file extension, so assume it's a directory
    return true;
  }

  return false;
};

/**
 * Renames the given file according to the given pattern.
 *
 * @param {string} prefix - Either an empty string or "--outfile="
 * @param {string} pattern - The output file path and pattern (e.g. "dest/*.min.js")
 * @param {string} file - The source file path and name (e.g. "lib/subdir/my-file.js")
 * @param {string} baseDir - The directory to calculate the relative path from (e.g. "lib")
 * @returns {string} - The output file path and name (e.g. "dest/subdir/my-file.min.js")
 */
exports.rename = function rename (prefix, pattern, file, baseDir) {
  if (!file) {
    // No filename, so return the original pattern
    return prefix + pattern;
  }

  let fileExtName = path.extname(file);                                             // .js
  let fileBaseName = path.basename(file, fileExtName);                              // my-file
  let relativeDir = path.dirname(path.relative(baseDir, file));                     // subdir

  let patternFileName = path.basename(pattern);                                     // *.min.js
  let patternDir;
  if (patternFileName.indexOf("*") === -1) {
    patternDir = pattern;                                                           // dest
  }
  else {
    patternDir = exports.getBaseDir(pattern);                                       // dest
    fileExtName = patternFileName.substr(patternFileName.indexOf("*") + 1);         // .min.js
  }

  let outputDir = path.join(patternDir, relativeDir);                               // dest/subdir
  let outputPath = path.join(outputDir, fileBaseName + fileExtName);                // dest/subdir/my-file.min.js

  // Create the output directory and file,
  // since browserify throws errors if they don't exist
  mkdirp(outputDir, () => {
    touch(outputPath);
  });

  return prefix + outputPath;
};
<commit_msg>Removed "mkdirp" dependency, now that fs.rmdir() has a "recursive" option<commit_after>"use strict";

const fs = require("fs");
const path = require("path");
const touch = require("touch");

/**
 * Determines the base directory of the given glob pattern.
 * This is used to determine the relative paths of matched files.
 *
 * @param {string} pattern - A glob pattern, such as "dir/subdir/*.js"
 * @returns {string}
 */
exports.getBaseDir = function getBaseDir (pattern) {
  // Some examples:
  //  - *.js                          =>  .
  //  - dir/**/*.js                   =>  dir
  //  - dir/subdir/main-*.js          =>  dir/subdir
  //  - dir/subdir/index.js           =>  dir/subdir
  //  - dir/subdir/index.(js|coffee)  =>  dir/subdir

  let wildcard = pattern.indexOf("*");
  if (wildcard >= 0) {
    pattern = pattern.substr(0, wildcard + 1);
  }
  return path.dirname(pattern);
};

/**
 * Determines whether the given output filename is a directory.
 *
 * @param {string} pattern - A file path, directory path, or pattern such as "dist/*.min.js"
 * @returns {boolean}
 */
exports.isDirectory = function isDirectory (pattern) {
  let basename = path.basename(pattern);
  if (basename.indexOf("*") >= 0) {
    // The pattern includes a filename pattern (e.g. "dist/*.min.js"),
    // which counts as a directory path
    return true;
  }
  else if (basename.indexOf(".") === -1) {
    // The pattern has no file extension, so assume it's a directory
    return true;
  }

  return false;
};

/**
 * Renames the given file according to the given pattern.
 *
 * @param {string} prefix - Either an empty string or "--outfile="
 * @param {string} pattern - The output file path and pattern (e.g. "dest/*.min.js")
 * @param {string} file - The source file path and name (e.g. "lib/subdir/my-file.js")
 * @param {string} baseDir - The directory to calculate the relative path from (e.g. "lib")
 * @returns {string} - The output file path and name (e.g. "dest/subdir/my-file.min.js")
 */
exports.rename = function rename (prefix, pattern, file, baseDir) {
  if (!file) {
    // No filename, so return the original pattern
    return prefix + pattern;
  }

  let fileExtName = path.extname(file);                                             // .js
  let fileBaseName = path.basename(file, fileExtName);                              // my-file
  let relativeDir = path.dirname(path.relative(baseDir, file));                     // subdir

  let patternFileName = path.basename(pattern);                                     // *.min.js
  let patternDir;
  if (patternFileName.indexOf("*") === -1) {
    patternDir = pattern;                                                           // dest
  }
  else {
    patternDir = exports.getBaseDir(pattern);                                       // dest
    fileExtName = patternFileName.substr(patternFileName.indexOf("*") + 1);         // .min.js
  }

  let outputDir = path.join(patternDir, relativeDir);                               // dest/subdir
  let outputPath = path.join(outputDir, fileBaseName + fileExtName);                // dest/subdir/my-file.min.js

  // Create the output directory and file,
  // since browserify throws errors if they don't exist
  fs.mkdir(outputDir, { recursive: true }, () => {
    touch(outputPath);
  });

  return prefix + outputPath;
};
<|endoftext|>


<commit_before>/**
 * Copyright 2018-present Facebook.
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 * @format
 */
export type {StyledComponent} from './styled/index.js';

//
export {default as Button} from './components/Button.js';
export {default as ToggleButton} from './components/ToggleSwitch.js';
export {
  default as ButtonNavigationGroup,
} from './components/ButtonNavigationGroup.js';
export {default as ButtonGroup} from './components/ButtonGroup.js';

//
export {colors, darkColors, brandColors} from './components/colors.js';

//
export {default as Glyph, ColoredIcon} from './components/Glyph.js';

//
export {default as LoadingIndicator} from './components/LoadingIndicator.js';

//
export {default as Popover} from './components/Popover.js';

//
export {default as ClickableList} from './components/ClickableList.js';
export {default as ClickableListItem} from './components/ClickableListItem.js';

//
export type {
  TableColumns,
  TableRows,
  TableBodyColumn,
  TableBodyRow,
  TableHighlightedRows,
  TableRowSortOrder,
  TableColumnOrder,
  TableColumnSizes,
} from './components/table/types.js';
export {default as Table} from './components/table/Table.js';
export {default as ManagedTable} from './components/table/ManagedTable.js';
export type {ManagedTableProps} from './components/table/ManagedTable.js';

//
export type {
  DataValueExtractor,
  DataInspectorExpanded,
} from './components/data-inspector/DataInspector.js';
export {
  default as DataInspector,
} from './components/data-inspector/DataInspector.js';
export {
  default as ManagedDataInspector,
} from './components/data-inspector/ManagedDataInspector.js';

// tabs
export {default as Tabs} from './components/Tabs.js';
export {default as Tab} from './components/Tab.js';

// inputs
export {default as Input} from './components/Input.js';
export {default as Textarea} from './components/Textarea.js';
export {default as Select} from './components/Select.js';
export {default as Checkbox} from './components/Checkbox.js';

// code
export {default as CodeBlock} from './components/CodeBlock.js';

// error
export {default as ErrorBlock} from './components/ErrorBlock.js';
export {default as ErrorBoundary} from './components/ErrorBoundary.js';

// interactive components
export type {OrderableOrder} from './components/Orderable.js';
export {default as Interactive} from './components/Interactive.js';
export {default as Orderable} from './components/Orderable.js';
export {default as VirtualList} from './components/VirtualList.js';

// base components
export {Component, PureComponent} from 'react';

// context menus and dropdowns
export {
  default as ContextMenuProvider,
} from './components/ContextMenuProvider.js';
export {default as ContextMenu} from './components/ContextMenu.js';
export {default as InlineContextMenu} from './components/InlineContextMenu.js';
export {default as Dropdown} from './components/Dropdown.js';

// file
export type {FileListFile, FileListFiles} from './components/FileList.js';
export {default as FileList} from './components/FileList.js';
export {default as File} from './components/File.js';

// context menu items
export {
  DesktopDropdownItem,
  DesktopDropdownSelectedItem,
  DesktopDropdown,
} from './components/desktop-toolbar.js';

// utility elements
export {default as View} from './components/View.js';
export {default as ViewWithSize} from './components/ViewWithSize.js';
export {default as Block} from './components/Block.js';
export {default as FocusableBox} from './components/FocusableBox.js';
export {default as Sidebar} from './components/Sidebar.js';
export {default as SidebarLabel} from './components/SidebarLabel.js';
export {default as Box} from './components/Box.js';
export {default as FlexBox} from './components/FlexBox.js';
export {default as FlexRow} from './components/FlexRow.js';
export {default as FlexColumn} from './components/FlexColumn.js';
export {default as FlexCenter} from './components/FlexCenter.js';
export {default as Toolbar, Spacer} from './components/Toolbar.js';
export {default as Panel} from './components/Panel.js';
export {default as Text} from './components/Text.js';
export {default as TextParagraph} from './components/TextParagraph.js';
export {default as Link} from './components/Link.js';
export {default as PathBreadcrumbs} from './components/PathBreadcrumbs.js';
export {default as ModalOverlay} from './components/ModalOverlay.js';
export {default as Tooltip} from './components/Tooltip.js';
export {default as TooltipProvider} from './components/TooltipProvider.js';
export {default as ResizeSensor} from './components/ResizeSensor.js';

// typhography
export {default as HorizontalRule} from './components/HorizontalRule.js';
export {default as VerticalRule} from './components/VerticalRule.js';
export {default as Label} from './components/Label.js';
export {default as Heading} from './components/Heading.js';

// filters
export type {Filter} from './components/filter/types.js';

//
export {
  SearchBox,
  SearchInput,
  SearchIcon,
  default as Searchable,
} from './components/searchable/Searchable.js';
export {
  default as SearchableTable,
} from './components/searchable/SearchableTable.js';
export type {SearchableProps} from './components/searchable/Searchable.js';

//
export type {
  ElementID,
  ElementData,
  ElementAttribute,
  Element,
  ElementSearchResultSet,
} from './components/elements-inspector/ElementsInspector.js';
export {Elements} from './components/elements-inspector/elements.js';
export {
  default as ElementsInspector,
} from './components/elements-inspector/ElementsInspector.js';
export {InspectorSidebar} from './components/elements-inspector/sidebar.js';

export {Console} from './components/console.js';
<commit_msg>Added export for the DataDescription component<commit_after>/**
 * Copyright 2018-present Facebook.
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 * @format
 */
export type {StyledComponent} from './styled/index.js';

//
export {default as Button} from './components/Button.js';
export {default as ToggleButton} from './components/ToggleSwitch.js';
export {
  default as ButtonNavigationGroup,
} from './components/ButtonNavigationGroup.js';
export {default as ButtonGroup} from './components/ButtonGroup.js';

//
export {colors, darkColors, brandColors} from './components/colors.js';

//
export {default as Glyph, ColoredIcon} from './components/Glyph.js';

//
export {default as LoadingIndicator} from './components/LoadingIndicator.js';

//
export {default as Popover} from './components/Popover.js';

//
export {default as ClickableList} from './components/ClickableList.js';
export {default as ClickableListItem} from './components/ClickableListItem.js';

//
export type {
  TableColumns,
  TableRows,
  TableBodyColumn,
  TableBodyRow,
  TableHighlightedRows,
  TableRowSortOrder,
  TableColumnOrder,
  TableColumnSizes,
} from './components/table/types.js';
export {default as Table} from './components/table/Table.js';
export {default as ManagedTable} from './components/table/ManagedTable.js';
export type {ManagedTableProps} from './components/table/ManagedTable.js';

//
export type {
  DataValueExtractor,
  DataInspectorExpanded,
} from './components/data-inspector/DataInspector.js';
export {
  default as DataInspector,
} from './components/data-inspector/DataInspector.js';
export {
  default as ManagedDataInspector,
} from './components/data-inspector/ManagedDataInspector.js';
export {
  default as DataDescription,
} from './components/data-inspector/DataDescription.js';

// tabs
export {default as Tabs} from './components/Tabs.js';
export {default as Tab} from './components/Tab.js';

// inputs
export {default as Input} from './components/Input.js';
export {default as Textarea} from './components/Textarea.js';
export {default as Select} from './components/Select.js';
export {default as Checkbox} from './components/Checkbox.js';

// code
export {default as CodeBlock} from './components/CodeBlock.js';

// error
export {default as ErrorBlock} from './components/ErrorBlock.js';
export {default as ErrorBoundary} from './components/ErrorBoundary.js';

// interactive components
export type {OrderableOrder} from './components/Orderable.js';
export {default as Interactive} from './components/Interactive.js';
export {default as Orderable} from './components/Orderable.js';
export {default as VirtualList} from './components/VirtualList.js';

// base components
export {Component, PureComponent} from 'react';

// context menus and dropdowns
export {
  default as ContextMenuProvider,
} from './components/ContextMenuProvider.js';
export {default as ContextMenu} from './components/ContextMenu.js';
export {default as InlineContextMenu} from './components/InlineContextMenu.js';
export {default as Dropdown} from './components/Dropdown.js';

// file
export type {FileListFile, FileListFiles} from './components/FileList.js';
export {default as FileList} from './components/FileList.js';
export {default as File} from './components/File.js';

// context menu items
export {
  DesktopDropdownItem,
  DesktopDropdownSelectedItem,
  DesktopDropdown,
} from './components/desktop-toolbar.js';

// utility elements
export {default as View} from './components/View.js';
export {default as ViewWithSize} from './components/ViewWithSize.js';
export {default as Block} from './components/Block.js';
export {default as FocusableBox} from './components/FocusableBox.js';
export {default as Sidebar} from './components/Sidebar.js';
export {default as SidebarLabel} from './components/SidebarLabel.js';
export {default as Box} from './components/Box.js';
export {default as FlexBox} from './components/FlexBox.js';
export {default as FlexRow} from './components/FlexRow.js';
export {default as FlexColumn} from './components/FlexColumn.js';
export {default as FlexCenter} from './components/FlexCenter.js';
export {default as Toolbar, Spacer} from './components/Toolbar.js';
export {default as Panel} from './components/Panel.js';
export {default as Text} from './components/Text.js';
export {default as TextParagraph} from './components/TextParagraph.js';
export {default as Link} from './components/Link.js';
export {default as PathBreadcrumbs} from './components/PathBreadcrumbs.js';
export {default as ModalOverlay} from './components/ModalOverlay.js';
export {default as Tooltip} from './components/Tooltip.js';
export {default as TooltipProvider} from './components/TooltipProvider.js';
export {default as ResizeSensor} from './components/ResizeSensor.js';

// typhography
export {default as HorizontalRule} from './components/HorizontalRule.js';
export {default as VerticalRule} from './components/VerticalRule.js';
export {default as Label} from './components/Label.js';
export {default as Heading} from './components/Heading.js';

// filters
export type {Filter} from './components/filter/types.js';

//
export {
  SearchBox,
  SearchInput,
  SearchIcon,
  default as Searchable,
} from './components/searchable/Searchable.js';
export {
  default as SearchableTable,
} from './components/searchable/SearchableTable.js';
export type {SearchableProps} from './components/searchable/Searchable.js';

//
export type {
  ElementID,
  ElementData,
  ElementAttribute,
  Element,
  ElementSearchResultSet,
} from './components/elements-inspector/ElementsInspector.js';
export {Elements} from './components/elements-inspector/elements.js';
export {
  default as ElementsInspector,
} from './components/elements-inspector/ElementsInspector.js';
export {InspectorSidebar} from './components/elements-inspector/sidebar.js';

export {Console} from './components/console.js';
<|endoftext|>


<commit_before>steal({
	src: './zepto.0.8.js',
	_skip: true
}).then('./data').then('../event','../fragment.js',function(){

// extend what you can out of Zepto
$.extend(can,Zepto);

var arrHas = function(obj, name){
	return obj[0] && obj[0][name] || obj[name]
}

// do what's similar for jQuery
can.trigger = function(obj, event, args, bubble){
	if(obj.trigger){
		obj.trigger(event, args)
	} else if(arrHas(obj, "dispatchEvent")){
		if(bubble === false){
			$([obj]).triggerHandler(event, args)
		} else {
			$([obj]).trigger(event, args)
		}

	} else {
		if(typeof event == "string"){
			event = {type: event}
		}
		event.data = args;
		can.dispatch.call(obj, event)
	}

}

can.$ = Zepto

	can.bind = function( ev, cb){
		// if we can bind to it ...
		if(this.bind){
			this.bind(ev, cb)
		} else if(arrHas(this, "addEventListener")){
			$([this]).bind(ev, cb)
		} else {
			can.addEvent.call(this, ev, cb)
		}
		return this;
	}
	can.unbind = function(ev, cb){
		// if we can bind to it ...
		if(this.unbind){
			this.unbind(ev, cb)
		} else if(arrHas(this, "addEventListener")){
			$([this]).unbind(ev, cb)
		} else {
			can.removeEvent.call(this, ev, cb)
		}
		return this;
	}
	can.delegate = function(selector,ev, cb){
		if(this.delegate){
			this.delegate(selector, ev, cb)
		} else {
			$([this]).delegate(selector,ev, cb)
		}
	}
	can.undelegate = function(selector,ev, cb){
		if(this.undelegate){
			this.undelegate(selector, ev, cb)
		} else {
			$([this]).undelegate(selector,ev, cb)
		}
	}

	$.each(["append","filter","addClass","remove","data"], function(i,name){
		can[name] = function(wrapped){
			return wrapped[name].apply(wrapped, can.makeArray(arguments).slice(1))
		}
	})

	can.makeArray = function(arr){
		var ret = []
		can.each(arr, function(i,a){
			ret[i] = a
		})
		return ret;
	};
	can.inArray =function(item, arr){
		return arr.indexOf(item)
	}

	can.proxy = function(f, ctx){
		return function(){
			return f.apply(ctx, arguments)
		}
	}

	// make ajax
	var XHR = $.ajaxSettings.xhr;
	$.ajaxSettings.xhr = function(){
		var xhr = XHR()
		var open = xhr.open;
		xhr.open = function(type, url, async){
			open.call(this, type, url, ASYNC === undefined ? true : ASYNC)
		}
		return xhr;
	}
	var ASYNC;
	var AJAX = $.ajax;
	var updateDeferred = function(xhr, d){
		for(var prop in xhr){
			if(typeof d[prop] == 'function'){
				d[prop] = function(){
					xhr[prop].apply(xhr, arguments)
				}
			} else {
				d[prop] = prop[xhr]
			}
		}
	}
	can.ajax = function(options){

		var success = options.success,
			error = options.error;
		var d = can.Deferred();

		options.success = function(){

			updateDeferred(xhr, d);
			d.resolve.apply(d, arguments);
			success && success.apply(this,arguments);
		}
		options.error = function(){
			updateDeferred(xhr, d);
			d.reject.apply(d, arguments);
			error && error.apply(this,arguments);
		}
		if(options.async === false){
			ASYNC = false
		}
		var xhr = AJAX(options);
		ASYNC = undefined;
		updateDeferred(xhr, d);
		return d;
	};

	// make destroyed and empty work
	$.fn.empty = function(){
		return this.each(function(){
			$.cleanData(this.getElementsByTagName('*'))
			this.innerHTML = ''
		})
	}

	$.fn.remove= function () {
		$.cleanData(this);
		this.each(function () {
			if (this.parentNode != null) {
				// might be a text node
				this.getElementsByTagName && $.cleanData(this.getElementsByTagName('*'))
				this.parentNode.removeChild(this);
			}
		});
		return this;
    }

    can.trim = function(str){
    	return str.trim();
    }
	can.isEmptyObject = function(object){
		var name;
		for(name in object){};
		return name !== undefined;
	}
	// make extend handle true for deep

	can.extend = function(first){
		if(first === true){
			var args = can.makeArray(arguments);
			args.shift();
			return $.extend.apply($, args)
		}
		return $.extend.apply($, arguments)
	}

	can.get = function(wrapped, index){
		return wrapped[index];
	}

}).then('../deferred.js')
<commit_msg>Fixed an issue with event triggering not setting the target in Zepto<commit_after>steal({
	src: './zepto.0.8.js',
	_skip: true
}).then('./data').then('../event','../fragment.js',function(){

// extend what you can out of Zepto
$.extend(can,Zepto);

var arrHas = function(obj, name){
	return obj[0] && obj[0][name] || obj[name]
}

// do what's similar for jQuery
can.trigger = function(obj, event, args, bubble){
	if(obj.trigger){
		obj.trigger(event, args)
	} else if(arrHas(obj, "dispatchEvent")){
		if(bubble === false){
			$([obj]).triggerHandler(event, args)
		} else {
			$([obj]).trigger(event, args)
		}

	} else {
		if(typeof event == "string"){
			event = {type: event}
		}
		event.target = event.target || obj;
		event.data = args;
		can.dispatch.call(obj, event)
	}

}

can.$ = Zepto

	can.bind = function( ev, cb){
		// if we can bind to it ...
		if(this.bind){
			this.bind(ev, cb)
		} else if(arrHas(this, "addEventListener")){
			$([this]).bind(ev, cb)
		} else {
			can.addEvent.call(this, ev, cb)
		}
		return this;
	}
	can.unbind = function(ev, cb){
		// if we can bind to it ...
		if(this.unbind){
			this.unbind(ev, cb)
		} else if(arrHas(this, "addEventListener")){
			$([this]).unbind(ev, cb)
		} else {
			can.removeEvent.call(this, ev, cb)
		}
		return this;
	}
	can.delegate = function(selector,ev, cb){
		if(this.delegate){
			this.delegate(selector, ev, cb)
		} else {
			$([this]).delegate(selector,ev, cb)
		}
	}
	can.undelegate = function(selector,ev, cb){
		if(this.undelegate){
			this.undelegate(selector, ev, cb)
		} else {
			$([this]).undelegate(selector,ev, cb)
		}
	}

	$.each(["append","filter","addClass","remove","data"], function(i,name){
		can[name] = function(wrapped){
			return wrapped[name].apply(wrapped, can.makeArray(arguments).slice(1))
		}
	})

	can.makeArray = function(arr){
		var ret = []
		can.each(arr, function(i,a){
			ret[i] = a
		})
		return ret;
	};
	can.inArray =function(item, arr){
		return arr.indexOf(item)
	}

	can.proxy = function(f, ctx){
		return function(){
			return f.apply(ctx, arguments)
		}
	}

	// make ajax
	var XHR = $.ajaxSettings.xhr;
	$.ajaxSettings.xhr = function(){
		var xhr = XHR()
		var open = xhr.open;
		xhr.open = function(type, url, async){
			open.call(this, type, url, ASYNC === undefined ? true : ASYNC)
		}
		return xhr;
	}
	var ASYNC;
	var AJAX = $.ajax;
	var updateDeferred = function(xhr, d){
		for(var prop in xhr){
			if(typeof d[prop] == 'function'){
				d[prop] = function(){
					xhr[prop].apply(xhr, arguments)
				}
			} else {
				d[prop] = prop[xhr]
			}
		}
	}
	can.ajax = function(options){

		var success = options.success,
			error = options.error;
		var d = can.Deferred();

		options.success = function(){

			updateDeferred(xhr, d);
			d.resolve.apply(d, arguments);
			success && success.apply(this,arguments);
		}
		options.error = function(){
			updateDeferred(xhr, d);
			d.reject.apply(d, arguments);
			error && error.apply(this,arguments);
		}
		if(options.async === false){
			ASYNC = false
		}
		var xhr = AJAX(options);
		ASYNC = undefined;
		updateDeferred(xhr, d);
		return d;
	};

	// make destroyed and empty work
	$.fn.empty = function(){
		return this.each(function(){
			$.cleanData(this.getElementsByTagName('*'))
			this.innerHTML = ''
		})
	}

	$.fn.remove= function () {
		$.cleanData(this);
		this.each(function () {
			if (this.parentNode != null) {
				// might be a text node
				this.getElementsByTagName && $.cleanData(this.getElementsByTagName('*'))
				this.parentNode.removeChild(this);
			}
		});
		return this;
    }

    can.trim = function(str){
    	return str.trim();
    }
	can.isEmptyObject = function(object){
		var name;
		for(name in object){};
		return name !== undefined;
	}
	// make extend handle true for deep

	can.extend = function(first){
		if(first === true){
			var args = can.makeArray(arguments);
			args.shift();
			return $.extend.apply($, args)
		}
		return $.extend.apply($, arguments)
	}

	can.get = function(wrapped, index){
		return wrapped[index];
	}

}).then('../deferred.js')
<|endoftext|>