<commit_before>/*global define, console*/

/*
 | Copyright 2015 ESRI (UK) Limited
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */

define([
    'dojo/text!./templates/Nearest.html',
    'dojo/_base/declare',
    "dojo/_base/lang",
    "dojo/promise/all",
    'dijit/_Widget',
    'dijit/_TemplatedMixin',
    'dijit/_WidgetsInTemplateMixin',
    './_NearestBase',
    "dojo/dom-construct",
    "./tasks/ClientNearestTask",
    "./tasks/LayerInfoTask",
    "./NearestLayer",
    'dojo/topic'
],
function (
    template, declare, lang, all, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _NearestBase, domConstruct, ClientNearestTask, LayerInfoTask, NearestLayer, topic) {

    return declare([_Widget, _NearestBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
        // description:
        //    Find the nearest features around a point

        templateString: template,
        baseClass: 'nearest',
        widgetsInTemplate: true,

        layerPopUpFields: [],

        // Properties to be sent into constructor

        constructor: function (options, srcRefNode) {
            this.options = {
                webmapId: "", // The id of the webmap to use.
                location: null, // The location to use as the centre point.
                maxResults: 10, // The maximum number of features to return.
                searchRadius: 5, // The search radius in miles.
                display: "expandable", // How to display the results. Expandable or fixed.
                layerOptions: [], // Options for each layer. These override the default radius and max results
                showOnMap: true, // Display the 'Show On Map' link
                showCounters: true, // Show the feature counts
                showDistance: true, // Show the distance
                findNearestMode: "geodesic", // Set the mode for the find nearest calculation
                showEmptyLayers: true // Should layers show with no results
            };

            /*
                layerOptions:[
                    {
                        itemId: ""
                        maxResults:
                        searchRadius:,
                        showOnMap:
                        showCounters:
                        display:
                    }
                ]
            */

            // mix in settings and defaults
            var defaults = lang.mixin({}, this.options, options);

            // Set properties
            this.set("webmapId", defaults.webmapId);
            this.set("location", defaults.location);
            this.set("maxResults", defaults.maxResults);
            this.set("searchRadius", defaults.searchRadius);
            this.set("display", defaults.display);
            this.set("layerOptions", defaults.layerOptions);
            this.set("showOnMap", defaults.showOnMap);
            this.set("showCounters", defaults.showCounters);
            this.set("showDistance", defaults.showDistance);
            this.set("findNearestMode", defaults.findNearestMode);
            this.set("showEmptyLayers", defaults.showEmptyLayers);

            // widget node
            this.domNode = srcRefNode;
        },

        buildRendering: function () {
            this.inherited(arguments);

        },

        postCreate: function() {
            // summary:
            //    Overrides method of same name in dijit._Widget.
            // tags:
            //    private
            //console.log('app.Nearest::postCreate', arguments);

            this.setupConnections();

            this.inherited(arguments);
        },

        // start widget. called by user
        startup: function () {
            this._init();
        },

        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function () {
            // call the superclass method of the same name.
            this.inherited(arguments);
        },

        setupConnections: function() {
            // summary:
            //    wire events, and such
            //
            //console.log('app.Nearest::setupConnections', arguments);

        },

        /* ---------------- */
        /* Public Functions */
        /* ---------------- */

        /* ---------------- */
        /* Private Functions */
        /* ---------------- */

        _init: function () {
            var _this = this;

            // Do query and build results
            if (!this._isNullOrEmpty(this.webmapId)) {
                this._getItemData(this.webmapId, this.token).then(function (webMap) {
                    var queryTasks = [], i = 0, iL = 0, task = null, opLayers, layerOpts;

                    if (webMap) {
                        topic.publish("Nearest::data-loaded", _this);

                        _this.webMap = webMap;
                        opLayers = webMap.operationalLayers;

                        // Get the details and pop up information for each layer
                        _this._getLayerDetails(opLayers);

                        // Run a query to get the features
                        // Go through operational layers and query each one
                        for (i = 0, iL = opLayers.length; i < iL; i++) {
                            layerOpts = _this._getlayerOptions(opLayers[i].itemId, opLayers[i].id);

                            // check if layer has a url to be able to perform a query
                            if (!_this._isNullOrEmpty(opLayers[i].url)) {
                                task = new LayerInfoTask({
                                    currentPoint: _this.location,
                                    searchRadius: layerOpts.searchRadius,
                                    serviceUrl: _this._swapProtocol(opLayers[i].url),
                                    layerId: opLayers[i].id,
                                    itemId: opLayers[i].itemId
                                });

                                queryTasks.push(task.execute());
                            }
                        }

                        // Once all queries have finished do the find nearest
                        all(queryTasks).then(function (queryResults) {
                            var j = 0, jL = queryResults.length, nearestTask = null, nearestTasks = [], layerName = "", layerOpts;

                            topic.publish("Nearest::query-done", _this, queryResults);

                            for (j = 0; j < jL; j++) {
                                layerOpts = _this._getlayerOptions(queryResults[j].itemId, queryResults[j].id);

                                // Perform find nearest on each set of features
                                if (((queryResults[j].error === null) && (queryResults[j].results) && (queryResults[j].results.features.length > 0)) || (_this.showEmptyLayers && queryResults[j].error === null)) {

                                    nearestTask = new ClientNearestTask({
                                        maxResults: layerOpts.maxResults,
                                        layerId: queryResults[j].id,
                                        itemId: queryResults[j].itemId,
                                        mode: _this.findNearestMode
                                    });

                                    nearestTasks.push(nearestTask.execute(_this.location, queryResults[j].results, queryResults[j].layerInfo));
                                }
                            }

                            // Once all of the find nearest tasks have finished display the results
                            all(nearestTasks).then(function (nearestResults) {
                                var k = 0, kL = nearestResults.length, lpInd = 0;

                                topic.publish("Nearest::nearest-task-done", _this, nearestResults);

                                for (k = 0; k < kL; k++) {
                                    if (nearestResults[k].error === null && nearestResults[k].result !== null) {
                                        _this._displayResults(nearestResults[k]);
                                    }
                                }

                                // Finished
                                topic.publish("Nearest::loaded", _this);

                                //displayResults
                            }, function (err) {

                            });
                        });
                    }
                });
            }
            else {
                topic.publish("Nearest::loaded", this);
            }
            // Output events
        },

        _getlayerOptions: function(itemId, id) {
            var i = 0, iL = 0, layerOpts = {
                webmapId: this.webmapId,
                maxResults: this.maxResults,
                searchRadius: this.searchRadius,
                showOnMap: this.showOnMap,
                showCounters: this.showCounters,
                display: this.display,
                showDistance: this.showDistance
            },
            field = "itemId", value = itemId;

            if ((this.layerOptions) && (this.layerOptions.length > 0)) {
                // If we have an id then use that, otherwise use the item id. Item id could be the same for all items.
                field = (!this._isNullOrEmpty(id) && !this._isNullOrEmpty(this.layerOptions[0].id)) ? "id" : "itemId";
                value = (field === "id") ? id : itemId;

                for (i = 0, iL = this.layerOptions.length; i < iL; i++) {
                    if (this.layerOptions[i][field] === value) {
                        return lang.mixin({}, layerOpts, this.layerOptions[i]);
                    }
                }
            }
            return layerOpts;
        },

        _displayResults: function(results) {
            var lpInd = 0, currentLayerInd, layerInfo, layerDiv, layer, layerOpts;

            // Make sure there are some results
            if ((this.showEmptyLayers) || (!this._isNullOrEmpty(results) && !this._isNullOrEmpty(results.result))) {

                for (lpInd = 0; lpInd < this.layerPopUpFields.length; lpInd++) {
                    if (this.layerPopUpFields[lpInd].id === results.id) {
                        currentLayerInd = lpInd;
                        break;
                    }
                }

                layerInfo = this.layerPopUpFields[currentLayerInd];

                // layer node
                layerDiv = domConstruct.create("div", {
                    className: "panel-body"
                });
                domConstruct.place(layerDiv, this._layers, "last");

                layerOpts = this._getlayerOptions(results.itemId, results.id);

                layer = new NearestLayer({
                    results: results,
                    layerInfo: layerInfo,
                    maxFeatures: layerOpts.maxResults,
                    distance: layerOpts.searchRadius,
                    distanceUnits: "miles",
                    layerOptions: layerOpts
                }, layerDiv);

                layer.startup();
            }
        },

        _getLayerDetails: function (layers) {
            var _this = this, i = 0, iL = 0, popupInfo = null, fields = [], j = 0, jL = 0, layerFields = null;

            if (!this._isNullOrEmpty(layers)) {
                // Iterate through any operational layers
                for (i = 0, iL = layers.length; i < iL; i++) {

                    // check if it has any popups defined
                    if (layers[i].hasOwnProperty("popupInfo")) {
                        popupInfo = layers[i].popupInfo;
                        fields = [];

                        for (j = 0, jL = popupInfo.fieldInfos.length; j < jL; j++) {
                            // Check each field and see if it is visible in the popup
                            if (popupInfo.fieldInfos[j].visible) {
                                fields.push(popupInfo.fieldInfos[j].fieldName);
                            }
                        }

                        // If any fields are visible create an object to hold the fields and the layer name
                        layerFields = {
                            "layerName": layers[i].title,
                            "id": layers[i].id,
                            "fields": fields,
                            "popupInfo": popupInfo
                        };
                        this.layerPopUpFields.push(layerFields);

                    }
                    else {
                        // Might not have the popup info saved with the webmap or it could be a feature collection

                        if (!this._isNullOrEmpty(layers[i].itemId)) {
                            var _layer = layers[i];

                            (function (l, t) {
                                t._getItemData(l.itemId).then(function (data) {
                                    if (data && data.layers) {
                                        var lFields = {
                                            "layerName": l.title,
                                            "id": l.id,
                                            "popupInfo": data.layers[0].popupInfo
                                        };

                                        t.layerPopUpFields.push(lFields);
                                    }
                                });
                            }(_layer, _this));
                        }
                        else if (!this._isNullOrEmpty(layers[i].featureCollection)) {
                            var _layers = layers[i].featureCollection.layers;

                            for (var k = 0; k < _layers.length; k++) {
                                var lyFields = {
                                    "layerName": _layers[k].popupInfo.title,
                                    "id": _layers[k].id,
                                    "popupInfo": _layers[k].popupInfo
                                };

                                t.layerPopUpFields.push(lyFields);
                            }
                        }
                    }
                }
            }
        }

    });
});<commit_msg>Support feature collection popups<commit_after>/*global define, console*/

/*
 | Copyright 2015 ESRI (UK) Limited
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */

define([
    'dojo/text!./templates/Nearest.html',
    'dojo/_base/declare',
    "dojo/_base/lang",
    "dojo/promise/all",
    'dijit/_Widget',
    'dijit/_TemplatedMixin',
    'dijit/_WidgetsInTemplateMixin',
    './_NearestBase',
    "dojo/dom-construct",
    "./tasks/ClientNearestTask",
    "./tasks/LayerInfoTask",
    "./NearestLayer",
    'dojo/topic'
],
function (
    template, declare, lang, all, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _NearestBase, domConstruct, ClientNearestTask, LayerInfoTask, NearestLayer, topic) {

    return declare([_Widget, _NearestBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
        // description:
        //    Find the nearest features around a point

        templateString: template,
        baseClass: 'nearest',
        widgetsInTemplate: true,

        layerPopUpFields: [],

        // Properties to be sent into constructor

        constructor: function (options, srcRefNode) {
            this.options = {
                webmapId: "", // The id of the webmap to use.
                location: null, // The location to use as the centre point.
                maxResults: 10, // The maximum number of features to return.
                searchRadius: 5, // The search radius in miles.
                display: "expandable", // How to display the results. Expandable or fixed.
                layerOptions: [], // Options for each layer. These override the default radius and max results
                showOnMap: true, // Display the 'Show On Map' link
                showCounters: true, // Show the feature counts
                showDistance: true, // Show the distance
                findNearestMode: "geodesic", // Set the mode for the find nearest calculation
                showEmptyLayers: true // Should layers show with no results
            };

            /*
                layerOptions:[
                    {
                        itemId: ""
                        maxResults:
                        searchRadius:,
                        showOnMap:
                        showCounters:
                        display:
                    }
                ]
            */

            // mix in settings and defaults
            var defaults = lang.mixin({}, this.options, options);

            // Set properties
            this.set("webmapId", defaults.webmapId);
            this.set("location", defaults.location);
            this.set("maxResults", defaults.maxResults);
            this.set("searchRadius", defaults.searchRadius);
            this.set("display", defaults.display);
            this.set("layerOptions", defaults.layerOptions);
            this.set("showOnMap", defaults.showOnMap);
            this.set("showCounters", defaults.showCounters);
            this.set("showDistance", defaults.showDistance);
            this.set("findNearestMode", defaults.findNearestMode);
            this.set("showEmptyLayers", defaults.showEmptyLayers);

            // widget node
            this.domNode = srcRefNode;
        },

        buildRendering: function () {
            this.inherited(arguments);

        },

        postCreate: function() {
            // summary:
            //    Overrides method of same name in dijit._Widget.
            // tags:
            //    private
            //console.log('app.Nearest::postCreate', arguments);

            this.setupConnections();

            this.inherited(arguments);
        },

        // start widget. called by user
        startup: function () {
            this._init();
        },

        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function () {
            // call the superclass method of the same name.
            this.inherited(arguments);
        },

        setupConnections: function() {
            // summary:
            //    wire events, and such
            //
            //console.log('app.Nearest::setupConnections', arguments);

        },

        /* ---------------- */
        /* Public Functions */
        /* ---------------- */

        /* ---------------- */
        /* Private Functions */
        /* ---------------- */

        _init: function () {
            var _this = this;

            // Do query and build results
            if (!this._isNullOrEmpty(this.webmapId)) {
                this._getItemData(this.webmapId, this.token).then(function (webMap) {
                    var queryTasks = [], i = 0, iL = 0, task = null, opLayers, layerOpts;

                    if (webMap) {
                        topic.publish("Nearest::data-loaded", _this);

                        _this.webMap = webMap;
                        opLayers = webMap.operationalLayers;

                        // Get the details and pop up information for each layer
                        _this._getLayerDetails(opLayers);

                        // Run a query to get the features
                        // Go through operational layers and query each one
                        for (i = 0, iL = opLayers.length; i < iL; i++) {
                            layerOpts = _this._getlayerOptions(opLayers[i].itemId, opLayers[i].id);

                            // check if layer has a url to be able to perform a query
                            if (!_this._isNullOrEmpty(opLayers[i].url)) {
                                task = new LayerInfoTask({
                                    currentPoint: _this.location,
                                    searchRadius: layerOpts.searchRadius,
                                    serviceUrl: _this._swapProtocol(opLayers[i].url),
                                    layerId: opLayers[i].id,
                                    itemId: opLayers[i].itemId
                                });

                                queryTasks.push(task.execute());
                            }
                        }

                        // Once all queries have finished do the find nearest
                        all(queryTasks).then(function (queryResults) {
                            var j = 0, jL = queryResults.length, nearestTask = null, nearestTasks = [], layerName = "", layerOpts;

                            topic.publish("Nearest::query-done", _this, queryResults);

                            for (j = 0; j < jL; j++) {
                                layerOpts = _this._getlayerOptions(queryResults[j].itemId, queryResults[j].id);

                                // Perform find nearest on each set of features
                                if (((queryResults[j].error === null) && (queryResults[j].results) && (queryResults[j].results.features.length > 0)) || (_this.showEmptyLayers && queryResults[j].error === null)) {

                                    nearestTask = new ClientNearestTask({
                                        maxResults: layerOpts.maxResults,
                                        layerId: queryResults[j].id,
                                        itemId: queryResults[j].itemId,
                                        mode: _this.findNearestMode
                                    });

                                    nearestTasks.push(nearestTask.execute(_this.location, queryResults[j].results, queryResults[j].layerInfo));
                                }
                            }

                            // Once all of the find nearest tasks have finished display the results
                            all(nearestTasks).then(function (nearestResults) {
                                var k = 0, kL = nearestResults.length, lpInd = 0;

                                topic.publish("Nearest::nearest-task-done", _this, nearestResults);

                                for (k = 0; k < kL; k++) {
                                    if (nearestResults[k].error === null && nearestResults[k].result !== null) {
                                        _this._displayResults(nearestResults[k]);
                                    }
                                }

                                // Finished
                                topic.publish("Nearest::loaded", _this);

                                //displayResults
                            }, function (err) {

                            });
                        });
                    }
                });
            }
            else {
                topic.publish("Nearest::loaded", this);
            }
            // Output events
        },

        _getlayerOptions: function(itemId, id) {
            var i = 0, iL = 0, layerOpts = {
                webmapId: this.webmapId,
                maxResults: this.maxResults,
                searchRadius: this.searchRadius,
                showOnMap: this.showOnMap,
                showCounters: this.showCounters,
                display: this.display,
                showDistance: this.showDistance
            },
            field = "itemId", value = itemId;

            if ((this.layerOptions) && (this.layerOptions.length > 0)) {
                // If we have an id then use that, otherwise use the item id. Item id could be the same for all items.
                field = (!this._isNullOrEmpty(id) && !this._isNullOrEmpty(this.layerOptions[0].id)) ? "id" : "itemId";
                value = (field === "id") ? id : itemId;

                for (i = 0, iL = this.layerOptions.length; i < iL; i++) {
                    if (this.layerOptions[i][field] === value) {
                        return lang.mixin({}, layerOpts, this.layerOptions[i]);
                    }
                }
            }
            return layerOpts;
        },

        _displayResults: function(results) {
            var lpInd = 0, currentLayerInd, layerInfo, layerDiv, layer, layerOpts;

            // Make sure there are some results
            if ((this.showEmptyLayers) || (!this._isNullOrEmpty(results) && !this._isNullOrEmpty(results.result))) {

                for (lpInd = 0; lpInd < this.layerPopUpFields.length; lpInd++) {
                    if (this.layerPopUpFields[lpInd].id === results.id) {
                        currentLayerInd = lpInd;
                        break;
                    }
                }

                layerInfo = this.layerPopUpFields[currentLayerInd];

                // layer node
                layerDiv = domConstruct.create("div", {
                    className: "panel-body"
                });
                domConstruct.place(layerDiv, this._layers, "last");

                layerOpts = this._getlayerOptions(results.itemId, results.id);

                layer = new NearestLayer({
                    results: results,
                    layerInfo: layerInfo,
                    maxFeatures: layerOpts.maxResults,
                    distance: layerOpts.searchRadius,
                    distanceUnits: "miles",
                    layerOptions: layerOpts
                }, layerDiv);

                layer.startup();
            }
        },

        _getLayerDetails: function (layers) {
            var _this = this, i = 0, iL = 0, popupInfo = null, fields = [], j = 0, jL = 0, layerFields = null;

            if (!this._isNullOrEmpty(layers)) {
                // Iterate through any operational layers
                for (i = 0, iL = layers.length; i < iL; i++) {

                    // check if it has any popups defined
                    if (layers[i].hasOwnProperty("popupInfo")) {
                        popupInfo = layers[i].popupInfo;
                        fields = [];

                        for (j = 0, jL = popupInfo.fieldInfos.length; j < jL; j++) {
                            // Check each field and see if it is visible in the popup
                            if (popupInfo.fieldInfos[j].visible) {
                                fields.push(popupInfo.fieldInfos[j].fieldName);
                            }
                        }

                        // If any fields are visible create an object to hold the fields and the layer name
                        layerFields = {
                            "layerName": layers[i].title,
                            "id": layers[i].id,
                            "fields": fields,
                            "popupInfo": popupInfo
                        };
                        this.layerPopUpFields.push(layerFields);

                    }
                    else {
                        // Might not have the popup info saved with the webmap or it could be a feature collection

                        if (!this._isNullOrEmpty(layers[i].itemId)) {
                            var _layer = layers[i];

                            (function (l, t) {
                                t._getItemData(l.itemId).then(function (data) {
                                    if (data && data.layers) {
                                        var lFields = {
                                            "layerName": l.title,
                                            "id": l.id,
                                            "popupInfo": data.layers[0].popupInfo
                                        };

                                        t.layerPopUpFields.push(lFields);
                                    }
                                });
                            }(_layer, _this));
                        }
                        else if (!this._isNullOrEmpty(layers[i].featureCollection)) {
                            var _layers = layers[i].featureCollection.layers;

                            for (var k = 0; k < _layers.length; k++) {
                                var lyFields = {
                                    "layerName": _layers[k].popupInfo.title,
                                    "id": _layers[k].id,
                                    "popupInfo": _layers[k].popupInfo
                                };

                                _this.layerPopUpFields.push(lyFields);
                            }
                        }
                    }
                }
            }
        }

    });
});<|endoftext|>


<commit_before>/**
 * Class Sliders
 */
Humble( function () {

    var Sliders = function (node, model, options) {

        this.model      = model;
        this.node       = node;
        this.sliders    = {};

        this.render();
    }

    Sliders.prototype = {

        render : function () {

            var dimensions  = Humble.Config.DVZ.budget.dimensions,
                sliders     = {},
                node        = this.node;

            _.each(dimensions, function (dimension, key) {
                var slider = this._renderSlider(dimension);
                node.append(slider);
                slider.data('key', key);
                sliders[key] = slider;
            }, this);

            this._sliders = sliders;

            this.bind();
        },

        _renderSlider : function (dimension) {

            var value  = 0,
                name   = dimension.name,
                color  = dimension.color,
                label  = $('
$'+value+'
'),
                slider = $('

'),
                widget = $('

'),
                title  = $('
'+name+'
'),
                legend = $('

'),
                config;

            slider.append(label);
            slider.append(title);
            slider.append(widget);
            slider.append(legend);

            config = {
                max : 1000,
                value : value
            };

            widget.slider(config);

            return slider;
        },

        bind : function () {
            this.node.delegate('.slider', 'slide', {sliders : this}, this._onSlide);
        },

        update : function () {

            var sliders = this._sliders;

            var items   = this.model.getItems(),
                node    = this.node;

            _.each(sliders, function (slider, key) {
                var value = items[key]['mycosti'];
                this._updateSlider(slider, value);
            }, this);
        },

        _onSlide : function (e, ui) {

            var sliders = e.data.sliders,
                key     = $(this).data('key'),
                label   = $(this).find('.mycosti'),
                value   = sliders.translateB(ui.value);

            sliders.model.set(key, 'mycosti', value);
            sliders.update();
        },

        _updateSlider : function (slider, value) {

            var widget = slider.find('.ui-slider'),
                label  = slider.find('.mycosti');

            widget.slider('value', [this._translate(value)]);
            this._updateSliderLabel(label, value);
        },

        _updateSliderLabel : function (label, value) {
            label.html('$'+value);
        },

        /**
         * Slider Value
         *
         * Slider goes from 0 to 100
         */
        _translate : function (value) {

            if (value < 1) return 0;

            var income = 50000;

            value = Math.log(value)/Math.log(income)
            value = value * 1000;

            return value;
        },

        translateB : function (value) {

            var income = 50000;

            value = value / 1000;
            value = Math.exp(value * Math.log(50000));
            value = Math.round(value*100)/100;
            return value;
        }
    }

    Humble.Sliders = Sliders;
});
<commit_msg>Added observer for dimensionHover.  Do highlight, unhighlight of legend.<commit_after>/**
 * Class Sliders
 */
Humble( function () {

    var Sliders = function (node, model, options) {

        this.model      = model;
        this.node       = node;
        this.sliders    = {};

        this.render();
    }

    Sliders.prototype = {

        render : function () {

            var dimensions  = Humble.Config.DVZ.budget.dimensions,
                sliders     = {},
                node        = this.node;

            _.each(dimensions, function (dimension, key) {
                var slider = this._renderSlider(dimension);
                node.append(slider);
                slider.data('key', key);
                sliders[key] = slider;
            }, this);

            this._sliders = sliders;

            this.bind();
        },

        _renderSlider : function (dimension) {

            var value  = 0,
                name   = dimension.name,
                color  = dimension.color,
                label  = $('
$'+value+'
'),
                slider = $('

'),
                widget = $('

'),
                title  = $('
'+name+'
'),
                legend = $('

'),
                config;

            slider.append(label);
            slider.append(title);
            slider.append(widget);
            slider.append(legend);

            config = {
                max : 1000,
                value : value
            };

            widget.slider(config);

            return slider;
        },

        bind : function () {
            this.node.delegate('.slider', 'slide', {sliders : this}, this._onSlide);

            var that = this;
            Humble.Event.bind('humble:dvc:dimensionHover', function (e, key, hover) {
                if (hover) {
                    that.highlight(key);
                } else {
                    that.unHighlight(key);
                }
            });

        },

        update : function () {

            var sliders = this._sliders;

            var items   = this.model.getItems(),
                node    = this.node;

            _.each(sliders, function (slider, key) {
                var value = items[key]['mycosti'];
                this._updateSlider(slider, value);
            }, this);
        },

        highlight : function (key) {
            var slider = this._sliders[key];
            slider.find('.legend').addClass('hover');
        },

        unHighlight : function (key) {
            var slider = this._sliders[key];
            slider.find('.legend').removeClass('hover');
        },

        _onSlide : function (e, ui) {

            var sliders = e.data.sliders,
                key     = $(this).data('key'),
                label   = $(this).find('.mycosti'),
                value   = sliders.translateB(ui.value);

            sliders.model.set(key, 'mycosti', value);
            sliders.update();
        },

        _updateSlider : function (slider, value) {

            var widget = slider.find('.ui-slider'),
                label  = slider.find('.mycosti');

            widget.slider('value', [this._translate(value)]);
            this._updateSliderLabel(label, value);
        },

        _updateSliderLabel : function (label, value) {
            label.html('$'+value);
        },

        /**
         * Slider Value
         *
         * Slider goes from 0 to 100
         */
        _translate : function (value) {

            if (value < 1) return 0;

            var income = 50000;

            value = Math.log(value)/Math.log(income)
            value = value * 1000;

            return value;
        },

        translateB : function (value) {

            var income = 50000;

            value = value / 1000;
            value = Math.exp(value * Math.log(50000));
            value = Math.round(value*100)/100;
            return value;
        }
    }

    Humble.Sliders = Sliders;
});
<|endoftext|>


<commit_before>/**
 * Main application container for the Legislature Tracker
 *
 * An 'e' prefix is referring to editorialized content.
 */
(function($, w, undefined) {

  LT.Application = Backbone.Router.extend({
    routes: {
      'categories': 'categories',
      'category/:category': 'category',
      'bill/:bill': 'bill',
      '*defaultR': 'defaultR'
    },

    initialize: function(options) {
      options = LT.options = _.extend(LT.defaultOptions, options);
      this.options = options;
      this.options.app = this;

      // Bind to help with some event callbacks
      _.bindAll(this);

      // Main view for application
      this.mainView = new LT.MainApplicationView(options);
      this.mainView.router = this;
      this.mainView.loading();

      // Get data from spreadsheets
      this.tabletop = Tabletop.init({
        key: this.options.dataKey,
        callback: this.loadEBills,
        callbackContext: this,
        wanted: this.options.eBillsWanted
      });
    },

    // Function to call when bill data is loaded
    loadEBills: function(data, tabletop) {
      var thisRouter = this;

      // Parse out data from sheets
      var parsed = LT.parse.eData(tabletop, this.options);

      // Set up collections
      this.categories = new LT.CategoriesCollection(null, this.options);
      this.bills = new LT.BillsCollection(null, this.options);

      // Add bill models
      _.each(parsed.bills, function(d) {
        thisRouter.bills.add(LT.utils.getModel('OSBillModel', 'bill_id', d));
      });

      // Add category models
      _.each(parsed.categories, function(c) {
        thisRouter.categories.add(LT.utils.getModel('CategoryModel', 'id', c));
      });

      // Load up bill count
      if (this.options.billCountDataSource) {
        $.jsonp({
          url: this.options.billCountDataSource,
          success: this.loadBillCounts
        });
      }
      else {
        // Start application/routing
        this.start();
      }
    },

    // Function to call when bill data is loaded
    loadBillCounts: function(billCountData) {
      this.categories.each(function(c) {
        var cats = c.get('legislator_subjects');
        var billCount = 0;

        if (_.isArray(cats) && cats.length > 0) {
          _.each(cats, function(cat) {
            var catData = _.find(billCountData, function(b) { return b.topic === cat; });
            billCount += catData.bill_count;
          });

          c.set('total_bill_count', billCount);
        }
      });

      // Start application/routing
      this.start();
    },

    // Start application (after data has been loaded)
    start: function() {
      // Start handling routing and history
      Backbone.history.start();
    },

    // Default route
    defaultR: function() {
      this.navigate('/categories', { trigger: true, replace: true });
      this.mainView.render();
    },

    // Categories view
    categories: function() {
      this.mainView.renderCategories();
    },

    // Single Category view
    category: function(category) {
      var thisRouter = this;

      category = decodeURI(category);
      category = this.categories.get(category);

      // Load up bill data from open states
      this.mainView.loading();
      category.loadBills(function() {
        thisRouter.mainView.renderCategory(category);
      }, thisRouter.error());
    },

    // Bill route
    bill: function(bill) {
      var thisRouter = this;

      bill = decodeURI(bill);
      bill = this.bills.where({ bill_id: bill })[0];
      this.mainView.loading();

      $.when(LT.utils.fetchModel(bill)).then(function() {
        thisRouter.mainView.renderBill(bill);
      }, this.error);
    },

    error: function(e) {
      // Handle error

    }
  });

})(jQuery, window);<commit_msg>Adding the ability to get the basic bill data from OS for the categories view.<commit_after>/**
 * Main application container for the Legislature Tracker
 *
 * An 'e' prefix is referring to editorialized content.
 */
(function($, w, undefined) {

  LT.Application = Backbone.Router.extend({
    routes: {
      'categories': 'categories',
      'category/:category': 'category',
      'bill/:bill': 'bill',
      '*defaultR': 'defaultR'
    },

    initialize: function(options) {
      options = LT.options = _.extend(LT.defaultOptions, options);
      this.options = options;
      this.options.app = this;

      // Bind to help with some event callbacks
      _.bindAll(this);

      // Main view for application
      this.mainView = new LT.MainApplicationView(options);
      this.mainView.router = this;
      this.mainView.loading();

      // Get data from spreadsheets
      this.tabletop = Tabletop.init({
        key: this.options.dataKey,
        callback: this.loadEBills,
        callbackContext: this,
        wanted: this.options.eBillsWanted
      });
    },

    // Function to call when bill data is loaded
    loadEBills: function(data, tabletop) {
      var thisRouter = this;

      // Parse out data from sheets
      var parsed = LT.parse.eData(tabletop, this.options);

      // Set up collections
      this.categories = new LT.CategoriesCollection(null, this.options);
      this.bills = new LT.BillsCollection(null, this.options);

      // Add bill models
      _.each(parsed.bills, function(d) {
        thisRouter.bills.add(LT.utils.getModel('OSBillModel', 'bill_id', d));
      });

      // Add category models
      _.each(parsed.categories, function(c) {
        thisRouter.categories.add(LT.utils.getModel('CategoryModel', 'id', c));
      });

      // Load up bill count
      if (this.options.billCountDataSource) {
        $.jsonp({
          url: this.options.billCountDataSource,
          success: this.loadBillCounts
        });
      }
      else {
        // Start application/routing
        this.start();
      }
    },

    // Function to call when bill data is loaded
    loadBillCounts: function(billCountData) {
      this.categories.each(function(c) {
        var cats = c.get('legislator_subjects');
        var billCount = 0;

        if (_.isArray(cats) && cats.length > 0) {
          _.each(cats, function(cat) {
            var catData = _.find(billCountData, function(b) { return b.topic === cat; });
            billCount += catData.bill_count;
          });

          c.set('total_bill_count', billCount);
        }
      });

      // Start application/routing
      this.start();
    },

    // Start application (after data has been loaded)
    start: function() {
      // Start handling routing and history
      Backbone.history.start();
    },

    // Default route
    defaultR: function() {
      this.navigate('/categories', { trigger: true, replace: true });
      this.mainView.render();
    },

    // Categories view
    categories: function() {
      // If we are viewing the categories, we want to get
      // some basic data about the bills from Open States
      // but not ALL the data.  We can use the bill search
      // to do this.
      this.getOSBasicBills(this.mainView.renderCategories, this.error);
    },

    // Single Category view
    category: function(category) {
      var thisRouter = this;

      category = decodeURI(category);
      category = this.categories.get(category);

      // Load up bill data from open states
      this.mainView.loading();
      category.loadBills(function() {
        thisRouter.mainView.renderCategory(category);
      }, thisRouter.error());
    },

    // Bill route
    bill: function(bill) {
      var thisRouter = this;

      bill = decodeURI(bill);
      bill = this.bills.where({ bill_id: bill })[0];
      this.mainView.loading();

      $.when(LT.utils.fetchModel(bill)).then(function() {
        thisRouter.mainView.renderBill(bill);
      }, this.error);
    },

    getOSBasicBills: function(callback, error) {
      var thisRouter = this;
      var url = 'http://openstates.org/api/v1/bills/?state=' + this.options.state +
        '&search_window=session:' + this.options.session +
        '&bill_id__in=' + encodeURI(this.bills.pluck('bill_id').join('|')) +
        '&apikey=' + this.options.apiKey + '&callback=?';

      $.jsonp({
        url: url,
        success: function(data) {
          _.each(data, function(d) {
            d.created_at = moment(d.created_at);
            d.updated_at = moment(d.updated_at);
            thisRouter.bills.where({ bill_id: d.bill_id })[0].set(d);
          });
          callback.call(thisRouter);
        },
        error: error
      });
    },

    error: function(e) {
      // Handle error

    }
  });

})(jQuery, window);<|endoftext|>


<commit_before>var behancekey = "PutYourKeyHere";

var behanceAPI = function() {
	var key;
	var baseURL = "http://www.behance.net/v2/";

	function setKey(k) {
		key = k;
	}

	function getProjects(user, cb) {
		var url = baseURL + "users/" + user + "/projects?api_key=" + key + "&callback=";
		$.get(url, {}, function(res, code) {
			cb(res.projects);
		}, "JSONP");
	}

	function getProjectDetails(project, cb) {
		var url = baseURL + "projects/" + project + "?api_key=" + key + "&callback=";
		$.get(url, {}, function(res, code) {
			cb(res.project);
		}, "JSONP");
	}

	return {
		setKey: setKey,
		getProjects: getProjects,
		getProjectDetails: getProjectDetails
	};

}();<commit_msg>full project list<commit_after>var behancekey = "PutYourKeyHere";

var behanceAPI = function() {
	var key;
	var baseURL = "http://www.behance.net/v2/";
	var userProjects = new Array();
	var offsetPage = 1; // optionally you can set up which page to start
	var numPages = 2; // Set up the max of pages to retrieve from behance (Each page gets 10 itens max).

	function setKey(k) {
		key = k;
	}

	function getProjects(user, cb) {
		var url = "";
		$.each([offsetPage,numPages], function(i, numb) {

			url = baseURL + "users/" + user + "/projects?api_key=" + key + "&callback=&page="+ numb;

			$.get(url, {}, function(res, code) {
				$.each(res.projects, function(i, obj) {
					userProjects.push(obj);
				});
			}, "JSONP").done(function() {
				cb(userProjects);
			});

		});
	}

	function getProjectDetails(project, cb) {
		var url = baseURL + "projects/" + project + "?api_key=" + key + "&callback=";
		$.get(url, {}, function(res, code) {
			cb(res.project);
		}, "JSONP");
	}

	return {
		setKey: setKey,
		getProjects: getProjects,
		getProjectDetails: getProjectDetails
	};

}();<|endoftext|>


<commit_before>var Marionlite = (function(global, $, _){
  "use strict";

    var Marionlite = function(options){
        this._modules = {};
        this._events = {};
        _.extend(this, options);
    };

    _.extend(Marionlite.prototype,{
        initialize: function(){
            this.trigger('initialize');
            _.each(this._modules, function(mod){
                //prevent reinitializing a module
                if(!mod.isInitialized && _.isFunction(mod.initialize)){
                    mod.initialize();
                    mod.isInitialized = true;
                }
            });
            return this;
        },
        start: function(){
            this.initialize();
            this.trigger('start');
            _.each(this._modules, function(mod){
                if(_.isFunction(mod.start)){
                    mod.start();
                }
            });
            return this;
        },
        on: function(name, callback, context){
            var events = this._events[name] || (this._events[name] = []);
            events.push({callback: callback, ctx: context || this });
            return this;
        },
        off: function(name){
            delete this._events[name];
            return this;
        },
        trigger: function(name){
            var array = [];
            var args = array.slice.call(arguments, 1);
            var events = this._events[name];
            if (events) this._triggerEvents(events, args);
            return this;
        },
        //optimized trigger copied from backbone
        _triggerEvents: function(events, args) {
            var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
            switch (args.length) {
              case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
              case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
              case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
              case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
              default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
            }
        },
        module: function(module_name, define){
            this[module_name] = this[module_name] || new Marionlite.module();

            define.call(this[module_name], this[module_name], this, $, _);
            this._modules[module_name] = this[module_name];

            return this;
        }
    });

    Marionlite.module = function(){
        this.isInitialized = false;
    };

    _.extend(Marionlite.module.prototype, {
        extend: function(obj){
            _.extend(this, obj);
        }
    });

    return Marionlite;
})(this, $, _);
<commit_msg>add options to initialize and start<commit_after>var Marionlite = (function(global, $, _){
  "use strict";

    var Marionlite = function(options){
        this._modules = {};
        this._events = {};
        _.extend(this, options);
    };

    _.extend(Marionlite.prototype,{
        initialize: function(options){
            this.trigger('initialize');
            _.extend(this, options);
            _.each(this._modules, function(mod){
                //prevent reinitializing a module
                if(!mod.isInitialized && _.isFunction(mod.initialize)){
                    mod.initialize();
                    mod.isInitialized = true;
                }
            });
            return this;
        },
        start: function(options){
            _.extend(this, options);
            this.initialize();
            this.trigger('start');
            _.each(this._modules, function(mod){
                if(_.isFunction(mod.start)){
                    mod.start();
                }
            });
            return this;
        },
        on: function(name, callback, context){
            var events = this._events[name] || (this._events[name] = []);
            events.push({callback: callback, ctx: context || this });
            return this;
        },
        off: function(name){
            delete this._events[name];
            return this;
        },
        trigger: function(name){
            var array = [];
            var args = array.slice.call(arguments, 1);
            var events = this._events[name];
            if (events) this._triggerEvents(events, args);
            return this;
        },
        //optimized trigger copied from backbone
        _triggerEvents: function(events, args) {
            var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
            switch (args.length) {
              case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
              case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
              case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
              case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
              default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
            }
        },
        module: function(module_name, define){
            this[module_name] = this[module_name] || new Marionlite.module();

            define.call(this[module_name], this[module_name], this, $, _);
            this._modules[module_name] = this[module_name];

            return this;
        }
    });

    Marionlite.module = function(){
        this.isInitialized = false;
    };

    _.extend(Marionlite.module.prototype, {
        extend: function(obj){
            _.extend(this, obj);
        }
    });

    return Marionlite;
})(this, $, _);
<|endoftext|>


<commit_before>#!/usr/bin/env node

var repl = require('repl')
  , ravendb = require('ravendb')

var useStore = function(url) {
  r.context.store = ravendb.use(url)
  r.context.db = r.context.store.defaultDb
}

console.log('RavenDB shell')

var r = repl.start("> ")

r.defineCommand('store', {
  help: 'Use the RavenDB datastore at a url ".store <url>"',
  action: function(url) {
    if (!url) url = r.context.db.getUrl()
    else useStore(url)

    console.log('Using datastore at: ' + url)
    r.displayPrompt()
  }
})

r.defineCommand('collections', {
  help: 'Show all collections in the current database',
  action: function() {
    try {
			r.context.db.getCollections(function(error, collections) {
        if (error) {
          console.error(error)
          r.displayPrompt()
          return
        }

        if (!collections) console.log("No collections found.")
        else {
          for(var i=0; i < collections.length; i++) {
            console.log(collections[i])
          }
        }
        r.context._ = collections
        r.displayPrompt()
      })
    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('create', {
	help: 'Save a document to a collection (e.g., .create CollectionName { id: "users/tony", firstName: "Tony" })',
	action: function(args) {
		try {
			var match = /(\w+)\s+(.*)/.exec(args)
			if (match.length != 3) throw Error('Wrong number of arguments; see .help for .savedoc usage')

			var collection = match[1]
			eval('var doc = ' + match[2])

			r.context.db.saveDocument(collection, doc, function(error, result) {
				if (error) console.error(error)

				if (result) console.log(result)
				r.context._ = result
				r.displayPrompt()
			})

		} catch (e) {
			console.error(e)
			r.displayPrompt()
		}
	}
})

r.defineCommand('read', {
  help: 'Get a document given its id (e.g., .read users/tony)',
  action: function(args) {
    try {
      if (!args) throw Error('Wrong number of arguments; see .help for more information')

      var id = args
      r.context.db.getDocument(id, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })

    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('delete', {
  help: 'Delete a document given its id (e.g., .delete users/tony)',
  action: function(args) {
    try {
      if (!args) throw Error('Wrong number of arguments; see .help for more information')

      var id = args
      r.context.db.deleteDocument(id, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })

    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('find', {
  help: 'Find documents (e.g., .find { firstName: "Tony" })',
  action: function(args) {
    try {
      if (!args) throw Error('Wrong number of arguments; see .help for .find usage')

      eval('var argsDoc = ' + args)

      r.context.db.find(argsDoc, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })

    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('docs', {
  help: 'Retrieve documents in a collection (e.g., .doc Users)',
  action: function(args) {
    try {
      var match = /(\w+)/.exec(args)

      var collection = (match && match.length == 2) ? match[1] : null

      r.context.db.getDocsInCollection(collection, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })

    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('count', {
  help: 'Show the count of documents in a collection or in the database if left blank (e.g., .count Users)',
  action: function(args) {
    try {
      r.context.db.getDocumentCount(args, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })
    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

useStore('http://localhost:8080')
<commit_msg>add stats command<commit_after>#!/usr/bin/env node

var repl = require('repl')
  , ravendb = require('ravendb')

var useStore = function(url) {
  r.context.store = ravendb.use(url)
  r.context.db = r.context.store.defaultDb
}

console.log('RavenDB shell')

var r = repl.start("> ")

r.defineCommand('store', {
  help: 'Use the RavenDB datastore at a url ".store <url>"',
  action: function(url) {
    if (!url) url = r.context.db.getUrl()
    else useStore(url)

    console.log('Using datastore at: ' + url)
    r.displayPrompt()
  }
})

r.defineCommand('stats', {
  help: 'Show statistics for the current database',
  action: function() {
    try {
      r.context.db.getStats(function(error, stats) {
        if (error) {
          console.error(error)
          r.displayPrompt()
          return
        }

        console.log(stats)
        r.context._ = stats
        r.displayPrompt()
      })
    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('collections', {
  help: 'Show all collections in the current database',
  action: function() {
    try {
			r.context.db.getCollections(function(error, collections) {
        if (error) {
          console.error(error)
          r.displayPrompt()
          return
        }

        if (!collections) console.log("No collections found.")
        else {
          for(var i=0; i < collections.length; i++) {
            console.log(collections[i])
          }
        }
        r.context._ = collections
        r.displayPrompt()
      })
    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('create', {
	help: 'Save a document to a collection (e.g., .create CollectionName { id: "users/tony", firstName: "Tony" })',
	action: function(args) {
		try {
			var match = /(\w+)\s+(.*)/.exec(args)
			if (match.length != 3) throw Error('Wrong number of arguments; see .help for .savedoc usage')

			var collection = match[1]
			eval('var doc = ' + match[2])

			r.context.db.saveDocument(collection, doc, function(error, result) {
				if (error) console.error(error)

				if (result) console.log(result)
				r.context._ = result
				r.displayPrompt()
			})

		} catch (e) {
			console.error(e)
			r.displayPrompt()
		}
	}
})

r.defineCommand('read', {
  help: 'Get a document given its id (e.g., .read users/tony)',
  action: function(args) {
    try {
      if (!args) throw Error('Wrong number of arguments; see .help for more information')

      var id = args
      r.context.db.getDocument(id, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })

    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('delete', {
  help: 'Delete a document given its id (e.g., .delete users/tony)',
  action: function(args) {
    try {
      if (!args) throw Error('Wrong number of arguments; see .help for more information')

      var id = args
      r.context.db.deleteDocument(id, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })

    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('find', {
  help: 'Find documents (e.g., .find { firstName: "Tony" })',
  action: function(args) {
    try {
      if (!args) throw Error('Wrong number of arguments; see .help for .find usage')

      eval('var argsDoc = ' + args)

      r.context.db.find(argsDoc, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })

    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('docs', {
  help: 'Retrieve documents in a collection (e.g., .doc Users)',
  action: function(args) {
    try {
      var match = /(\w+)/.exec(args)

      var collection = (match && match.length == 2) ? match[1] : null

      r.context.db.getDocsInCollection(collection, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })

    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

r.defineCommand('count', {
  help: 'Show the count of documents in a collection or in the database if left blank (e.g., .count Users)',
  action: function(args) {
    try {
      r.context.db.getDocumentCount(args, function(error, result) {
        if (error) console.error(error)

        if (result) console.log(result)
        r.context._ = result
        r.displayPrompt()
      })
    } catch (e) {
      console.error(e)
      r.displayPrompt()
    }
  }
})

useStore('http://localhost:8080')
<|endoftext|>


<commit_before>/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */

window.matchMedia || (window.matchMedia = function() {
    "use strict";

    // For browsers that support matchMedium api such as IE 9 and webkit
    var styleMedia = (window.styleMedia || window.media);

    // For those that don't support matchMedium
    if (!styleMedia) {
        var style       = document.createElement('style'),
            script      = document.getElementsByTagName('script')[0],
            info        = null;

        style.type  = 'text/css';
        style.id    = 'matchmediajs-test';

        script.parentNode.insertBefore(style, script);

        // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
        info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;

        styleMedia = {
            matchMedium: function(media) {
                var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';

                // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
                if (style.styleSheet) {
                    style.styleSheet.cssText = text;
                } else {
                    style.textContent = text;
                }

                // Test if media query is true or false
                return info.width === '1px';
            }
        };
    }

    return function(media) {
        return {
            matches: styleMedia.matchMedium(media || 'all'),
            media: media || 'all'
        };
    };
}());
<commit_msg>Handle no script tags in document<commit_after>/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */

window.matchMedia || (window.matchMedia = function() {
    "use strict";

    // For browsers that support matchMedium api such as IE 9 and webkit
    var styleMedia = (window.styleMedia || window.media);

    // For those that don't support matchMedium
    if (!styleMedia) {
        var style       = document.createElement('style'),
            script      = document.getElementsByTagName('script')[0],
            info        = null;

        style.type  = 'text/css';
        style.id    = 'matchmediajs-test';

        if (!script) {
          document.head.appendChild(style);
        } else {
          script.parentNode.insertBefore(style, script);
        }

        // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
        info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;

        styleMedia = {
            matchMedium: function(media) {
                var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';

                // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
                if (style.styleSheet) {
                    style.styleSheet.cssText = text;
                } else {
                    style.textContent = text;
                }

                // Test if media query is true or false
                return info.width === '1px';
            }
        };
    }

    return function(media) {
        return {
            matches: styleMedia.matchMedium(media || 'all'),
            media: media || 'all'
        };
    };
}());
<|endoftext|>


<commit_before>"use strict";

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

const Exchange = require ('./base/Exchange')
const { ExchangeError, InsufficientFunds, OrderNotFound, DDoSProtection } = require ('./base/errors')

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

module.exports = class bithumb extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'bithumb',
            'name': 'Bithumb',
            'countries': 'KR', // South Korea
            'rateLimit': 500,
            'hasCORS': true,
            'hasFetchTickers': true,
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30597177-ea800172-9d5e-11e7-804c-b9d4fa9b56b0.jpg',
                'api': {
                    'public': 'https://api.bithumb.com/public',
                    'private': 'https://api.bithumb.com',
                },
                'www': 'https://www.bithumb.com',
                'doc': 'https://www.bithumb.com/u1/US127',
            },
            'api': {
                'public': {
                    'get': [
                        'ticker/{currency}',
                        'ticker/all',
                        'orderbook/{currency}',
                        'orderbook/all',
                        'recent_transactions/{currency}',
                        'recent_transactions/all',
                    ],
                },
                'private': {
                    'post': [
                        'info/account',
                        'info/balance',
                        'info/wallet_address',
                        'info/ticker',
                        'info/orders',
                        'info/user_transactions',
                        'trade/place',
                        'info/order_detail',
                        'trade/cancel',
                        'trade/btc_withdrawal',
                        'trade/krw_deposit',
                        'trade/krw_withdrawal',
                        'trade/market_buy',
                        'trade/market_sell',
                    ],
                },
            },
            'markets': {
                'BTC/KRW': { 'id': 'BTC', 'symbol': 'BTC/KRW', 'base': 'BTC', 'quote': 'KRW' },
                'ETH/KRW': { 'id': 'ETH', 'symbol': 'ETH/KRW', 'base': 'ETH', 'quote': 'KRW' },
                'LTC/KRW': { 'id': 'LTC', 'symbol': 'LTC/KRW', 'base': 'LTC', 'quote': 'KRW' },
                'ETC/KRW': { 'id': 'ETC', 'symbol': 'ETC/KRW', 'base': 'ETC', 'quote': 'KRW' },
                'XRP/KRW': { 'id': 'XRP', 'symbol': 'XRP/KRW', 'base': 'XRP', 'quote': 'KRW' },
                'BCH/KRW': { 'id': 'BCH', 'symbol': 'BCH/KRW', 'base': 'BCH', 'quote': 'KRW' },
                'XMR/KRW': { 'id': 'XMR', 'symbol': 'XMR/KRW', 'base': 'XMR', 'quote': 'KRW' },
                'ZEC/KRW': { 'id': 'ZEC', 'symbol': 'ZEC/KRW', 'base': 'ZEC', 'quote': 'KRW' },
                'DASH/KRW': { 'id': 'DASH', 'symbol': 'DASH/KRW', 'base': 'DASH', 'quote': 'KRW' },
                'QTUM/KRW': { 'id': 'QTUM', 'symbol': 'QTUM/KRW', 'base': 'QTUM', 'quote': 'KRW' },
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostInfoBalance (this.extend ({
            'currency': 'ALL',
        }, params));
        let result = { 'info': response };
        let balances = response['data'];
        for (let c = 0; c < this.currencies.length; c++) {
            let currency = this.currencies[c];
            let account = this.account ();
            let lowercase = currency.toLowerCase ();
            account['total'] = this.safeFloat (balances, 'total_' + lowercase);
            account['used'] = this.safeFloat (balances, 'in_use_' + lowercase);
            account['free'] = this.safeFloat (balances, 'available_' + lowercase);
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, params = {}) {
        let market = this.market (symbol);
        let response = await this.publicGetOrderbookCurrency (this.extend ({
            'count': 50, // max = 50
            'currency': market['base'],
        }, params));
        let orderbook = response['data'];
        let timestamp = parseInt (orderbook['timestamp']);
        return this.parseOrderBook (orderbook, timestamp, 'bids', 'asks', 'price', 'quantity');
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = parseInt (ticker['date']);
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'max_price'),
            'low': this.safeFloat (ticker, 'min_price'),
            'bid': this.safeFloat (ticker, 'buy_price'),
            'ask': this.safeFloat (ticker, 'sell_price'),
            'vwap': undefined,
            'open': this.safeFloat (ticker, 'opening_price'),
            'close': this.safeFloat (ticker, 'closing_price'),
            'first': undefined,
            'last': this.safeFloat (ticker, 'last_trade'),
            'change': undefined,
            'percentage': undefined,
            'average': this.safeFloat (ticker, 'average_price'),
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'volume_1day'),
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        let response = await this.publicGetTickerAll (params);
        let result = {};
        let timestamp = response['data']['date'];
        let tickers = this.omit (response['data'], 'date');
        let ids = Object.keys (tickers);
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = this.markets_by_id[id];
            let symbol = market['symbol'];
            let ticker = tickers[id];
            ticker['date'] = timestamp;
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        let market = this.market (symbol);
        let response = await this.publicGetTickerCurrency (this.extend ({
            'currency': market['base'],
        }, params));
        return this.parseTicker (response['data'], market);
    }

    parseTrade (trade, market) {
        // a workaround for their bug in date format, hours are not 0-padded
        let [ transaction_date, transaction_time ] = trade['transaction_date'].split (' ');
        let transaction_time_short = transaction_time.length < 8;
        if (transaction_time_short)
            transaction_time = '0' + transaction_time;
        let timestamp = this.parse8601 (transaction_date + ' ' + transaction_time);
        let side = (trade['type'] == 'ask') ? 'sell' : 'buy';
        return {
            'id': undefined,
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'order': undefined,
            'type': undefined,
            'side': side,
            'price': parseFloat (trade['price']),
            'amount': parseFloat (trade['units_traded']),
        };
    }

    async fetchTrades (symbol, params = {}) {
        let market = this.market (symbol);
        let response = await this.publicGetRecentTransactionsCurrency (this.extend ({
            'currency': market['base'],
            'count': 100, // max = 100
        }, params));
        return this.parseTrades (response['data'], market);
    }

    createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        throw new NotSupported (this.id + ' private API not implemented yet');
        //     let prefix = '';
        //     if (type == 'market')
        //         prefix = 'market_';
        //     let order = {
        //         'pair': this.marketId (symbol),
        //         'quantity': amount,
        //         'price': price || 0,
        //         'type': prefix + side,
        //     };
        //     let response = await this.privatePostOrderCreate (this.extend (order, params));
        //     return {
        //         'info': response,
        //         'id': response['order_id'].toString (),
        //     };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        let side = ('side' in params);
        if (!side)
            throw new ExchangeError (this.id + ' cancelOrder requires a side parameter (sell or buy)');
        side = (side == 'buy') ? 'purchase' : 'sales';
        let currency = ('currency' in params);
        if (!currency)
            throw new ExchangeError (this.id + ' cancelOrder requires a currency parameter');
        return await this.privatePostTradeCancel ({
            'order_id': id,
            'type': params['side'],
            'currency': params['currency'],
        });
    }

    nonce () {
        return this.milliseconds ();
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let endpoint = '/' + this.implodeParams (path, params);
        let url = this.urls['api'][api] + endpoint;
        let query = this.omit (params, this.extractParams (path));
        if (api == 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            body = this.urlencode (this.extend ({
                'endpoint': endpoint,
            }, query));
            let nonce = this.nonce ().toString ();
            let auth = endpoint + "\0" + body + "\0" + nonce;
            let signature = this.hmac (this.encode (auth), this.encode (this.secret), 'sha512');
            headers = {
                'Api-Key': this.apiKey,
                'Api-Sign': this.stringToBase64 (this.encode (signature)),
                'Api-Nonce': nonce,
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('status' in response) {
            if (response['status'] == '0000')
                return response;
            throw new ExchangeError (this.id + ' ' + this.json (response));
        }
        return response;
    }
}<commit_msg>bitthumb imports #448<commit_after>"use strict";

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

const Exchange = require ('./base/Exchange')
const { ExchangeError, NotSupported } = require ('./base/errors')

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

module.exports = class bithumb extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'bithumb',
            'name': 'Bithumb',
            'countries': 'KR', // South Korea
            'rateLimit': 500,
            'hasCORS': true,
            'hasFetchTickers': true,
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30597177-ea800172-9d5e-11e7-804c-b9d4fa9b56b0.jpg',
                'api': {
                    'public': 'https://api.bithumb.com/public',
                    'private': 'https://api.bithumb.com',
                },
                'www': 'https://www.bithumb.com',
                'doc': 'https://www.bithumb.com/u1/US127',
            },
            'api': {
                'public': {
                    'get': [
                        'ticker/{currency}',
                        'ticker/all',
                        'orderbook/{currency}',
                        'orderbook/all',
                        'recent_transactions/{currency}',
                        'recent_transactions/all',
                    ],
                },
                'private': {
                    'post': [
                        'info/account',
                        'info/balance',
                        'info/wallet_address',
                        'info/ticker',
                        'info/orders',
                        'info/user_transactions',
                        'trade/place',
                        'info/order_detail',
                        'trade/cancel',
                        'trade/btc_withdrawal',
                        'trade/krw_deposit',
                        'trade/krw_withdrawal',
                        'trade/market_buy',
                        'trade/market_sell',
                    ],
                },
            },
            'markets': {
                'BTC/KRW': { 'id': 'BTC', 'symbol': 'BTC/KRW', 'base': 'BTC', 'quote': 'KRW' },
                'ETH/KRW': { 'id': 'ETH', 'symbol': 'ETH/KRW', 'base': 'ETH', 'quote': 'KRW' },
                'LTC/KRW': { 'id': 'LTC', 'symbol': 'LTC/KRW', 'base': 'LTC', 'quote': 'KRW' },
                'ETC/KRW': { 'id': 'ETC', 'symbol': 'ETC/KRW', 'base': 'ETC', 'quote': 'KRW' },
                'XRP/KRW': { 'id': 'XRP', 'symbol': 'XRP/KRW', 'base': 'XRP', 'quote': 'KRW' },
                'BCH/KRW': { 'id': 'BCH', 'symbol': 'BCH/KRW', 'base': 'BCH', 'quote': 'KRW' },
                'XMR/KRW': { 'id': 'XMR', 'symbol': 'XMR/KRW', 'base': 'XMR', 'quote': 'KRW' },
                'ZEC/KRW': { 'id': 'ZEC', 'symbol': 'ZEC/KRW', 'base': 'ZEC', 'quote': 'KRW' },
                'DASH/KRW': { 'id': 'DASH', 'symbol': 'DASH/KRW', 'base': 'DASH', 'quote': 'KRW' },
                'QTUM/KRW': { 'id': 'QTUM', 'symbol': 'QTUM/KRW', 'base': 'QTUM', 'quote': 'KRW' },
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let response = await this.privatePostInfoBalance (this.extend ({
            'currency': 'ALL',
        }, params));
        let result = { 'info': response };
        let balances = response['data'];
        for (let c = 0; c < this.currencies.length; c++) {
            let currency = this.currencies[c];
            let account = this.account ();
            let lowercase = currency.toLowerCase ();
            account['total'] = this.safeFloat (balances, 'total_' + lowercase);
            account['used'] = this.safeFloat (balances, 'in_use_' + lowercase);
            account['free'] = this.safeFloat (balances, 'available_' + lowercase);
            result[currency] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, params = {}) {
        let market = this.market (symbol);
        let response = await this.publicGetOrderbookCurrency (this.extend ({
            'count': 50, // max = 50
            'currency': market['base'],
        }, params));
        let orderbook = response['data'];
        let timestamp = parseInt (orderbook['timestamp']);
        return this.parseOrderBook (orderbook, timestamp, 'bids', 'asks', 'price', 'quantity');
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = parseInt (ticker['date']);
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'max_price'),
            'low': this.safeFloat (ticker, 'min_price'),
            'bid': this.safeFloat (ticker, 'buy_price'),
            'ask': this.safeFloat (ticker, 'sell_price'),
            'vwap': undefined,
            'open': this.safeFloat (ticker, 'opening_price'),
            'close': this.safeFloat (ticker, 'closing_price'),
            'first': undefined,
            'last': this.safeFloat (ticker, 'last_trade'),
            'change': undefined,
            'percentage': undefined,
            'average': this.safeFloat (ticker, 'average_price'),
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'volume_1day'),
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        let response = await this.publicGetTickerAll (params);
        let result = {};
        let timestamp = response['data']['date'];
        let tickers = this.omit (response['data'], 'date');
        let ids = Object.keys (tickers);
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let market = this.markets_by_id[id];
            let symbol = market['symbol'];
            let ticker = tickers[id];
            ticker['date'] = timestamp;
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        let market = this.market (symbol);
        let response = await this.publicGetTickerCurrency (this.extend ({
            'currency': market['base'],
        }, params));
        return this.parseTicker (response['data'], market);
    }

    parseTrade (trade, market) {
        // a workaround for their bug in date format, hours are not 0-padded
        let [ transaction_date, transaction_time ] = trade['transaction_date'].split (' ');
        let transaction_time_short = transaction_time.length < 8;
        if (transaction_time_short)
            transaction_time = '0' + transaction_time;
        let timestamp = this.parse8601 (transaction_date + ' ' + transaction_time);
        let side = (trade['type'] == 'ask') ? 'sell' : 'buy';
        return {
            'id': undefined,
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'order': undefined,
            'type': undefined,
            'side': side,
            'price': parseFloat (trade['price']),
            'amount': parseFloat (trade['units_traded']),
        };
    }

    async fetchTrades (symbol, params = {}) {
        let market = this.market (symbol);
        let response = await this.publicGetRecentTransactionsCurrency (this.extend ({
            'currency': market['base'],
            'count': 100, // max = 100
        }, params));
        return this.parseTrades (response['data'], market);
    }

    createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        throw new NotSupported (this.id + ' private API not implemented yet');
        //     let prefix = '';
        //     if (type == 'market')
        //         prefix = 'market_';
        //     let order = {
        //         'pair': this.marketId (symbol),
        //         'quantity': amount,
        //         'price': price || 0,
        //         'type': prefix + side,
        //     };
        //     let response = await this.privatePostOrderCreate (this.extend (order, params));
        //     return {
        //         'info': response,
        //         'id': response['order_id'].toString (),
        //     };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        let side = ('side' in params);
        if (!side)
            throw new ExchangeError (this.id + ' cancelOrder requires a side parameter (sell or buy)');
        side = (side == 'buy') ? 'purchase' : 'sales';
        let currency = ('currency' in params);
        if (!currency)
            throw new ExchangeError (this.id + ' cancelOrder requires a currency parameter');
        return await this.privatePostTradeCancel ({
            'order_id': id,
            'type': params['side'],
            'currency': params['currency'],
        });
    }

    nonce () {
        return this.milliseconds ();
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let endpoint = '/' + this.implodeParams (path, params);
        let url = this.urls['api'][api] + endpoint;
        let query = this.omit (params, this.extractParams (path));
        if (api == 'public') {
            if (Object.keys (query).length)
                url += '?' + this.urlencode (query);
        } else {
            body = this.urlencode (this.extend ({
                'endpoint': endpoint,
            }, query));
            let nonce = this.nonce ().toString ();
            let auth = endpoint + "\0" + body + "\0" + nonce;
            let signature = this.hmac (this.encode (auth), this.encode (this.secret), 'sha512');
            headers = {
                'Api-Key': this.apiKey,
                'Api-Sign': this.stringToBase64 (this.encode (signature)),
                'Api-Nonce': nonce,
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        if ('status' in response) {
            if (response['status'] == '0000')
                return response;
            throw new ExchangeError (this.id + ' ' + this.json (response));
        }
        return response;
    }
}<|endoftext|>