<commit_before>$.cssHooks.backgroundColor = {
    get: function(elem) {
        if (elem.currentStyle)
            var bg = elem.currentStyle["backgroundColor"];
        else if (window.getComputedStyle)
            var bg = document.defaultView.getComputedStyle(elem,
                null).getPropertyValue("background-color");
        if (bg.search("rgb") == -1)
            return bg;
        else {
            bg = bg.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
            function hex(x) {
                return ("0" + parseInt(x).toString(16)).slice(-2);
            }
            return "#" + hex(bg[1]) + hex(bg[2]) + hex(bg[3]);
        }
    }
};

$.fn.dataTableExt.oSort['numeric_ignore_nan-asc']  = function(x,y) {
    if (isNaN(x) && isNaN(y)) return ((x < y) ? 1 : ((x > y) ?  -1 : 0));

    if (isNaN(x)) return 1;
    if (isNaN(y)) return -1;

    x = parseFloat( x );
    y = parseFloat( y );
    return ((x < y) ? -1 : ((x > y) ?  1 : 0));
};

$.fn.dataTableExt.oSort['numeric_ignore_nan-desc'] = function(x,y) {
    if (isNaN(x) && isNaN(y)) return ((x < y) ? 1 : ((x > y) ?  -1 : 0));

    if (isNaN(x)) return 1;
    if (isNaN(y)) return -1;

    x = parseFloat( x );
    y = parseFloat( y );
    return ((x < y) ?  1 : ((x > y) ? -1 : 0));
};

$.fn.dataTableExt.afnFiltering.push(
    function(oSettings, aData, iDataIndex) {
        var selected_tags = $('.filter_labels h3 span.tag-checked').map(function(k, v) {
                return $(this).text();
            }).get(),
            row_tags = aData[9].split(',');

        if (!selected_tags.length) { // nothing to filter out
            return true;
        } else {
            if (!row_tags.length || (row_tags.length === 1 && row_tags[0] === "")) {
                return false;
            }
            for (var i = 0; i < selected_tags.length; i++) {
                for (var j = 0; j < row_tags.length; j++) {
                    if (selected_tags[i] === row_tags[j]) {
                        return true;
                    }
                }
            }
            return false;
        }
    }
);

$.fn.dataTableExt.afnFiltering.push(
    function(oSettings, aData, iDataIndex) {
        var selected_categories = $('.category_labels h2 span.tag-checked').map(function(k, v) {
                return $(this).css('background-color');
            }).get(),
            row_color = aData[10];
        if (!selected_categories.length) { // nothing to filter out
            return true;
        } else {
            for (var i = 0; i < selected_categories.length; i++) {
                if (selected_categories[i] === row_color) {
                    return true;
                }
            }
        }
        return false;
    }
);

var genomeData = $('#genomeData');
var reset_checkboxes = function(checkbox_settings) {
    console.log('reset checkboxes: %o', checkbox_settings);
    var checkboxes = $(".checkbox-row input");
    checkbox_settings.forEach(function(element, index) {
        var checkbox = $(checkboxes[index]);
        checkbox.prop('checked', element).trigger('change');
    });

};
$(document).ready(function() {
    var genome_url = genomeData.data('genome_url');
    var genomeTable = genomeData.dataTable({
        "ajax": genome_url,
        "columns": [
            {"data": "rsid" },
            {"data": "chromosome_position" },
            {"data": "risk_allele" },
            {"data": "genotype" },
            {"data": "disease_trait" },
            {"data": "p_value" },
            {"data": "or_or_beta" },
            {"data": "risk" },
            {"data": "priority", "defaultContent": "0" },
            {"data": "tags", "defaultContent": " "},
            {"data": "color", "defaultContent": ""}
        ],
        "pageLength": 100,
        "aoColumnDefs": [
            { "sType": "numeric_ignore_nan", "aTargets": [ 5, 6 ] },
            { "bSearchable": false, "bVisible": false, "aTargets": [ 8 ] }
        ],
        "columnDefs": [{"targets": [ 8 ], "visible": false, "searchable": false}],
        "order": [[ 8, "desc" ]],
        "processing": true,
        "drawCallback": function( settings ) {
            var rows = $('#genomeData tbody tr');

            // Remove existing event handlers;
            rows.off('click');

            rows.click(function(e) {
                e.preventDefault();
                var row = $(this);
                window.open(row.data('url'), 'Your genome', "height=" + window.screen.height +",width=" + window.screen.width);
            });
            // Fix datatable for fluid container
            genomeData.css('width', '');

            // Ugly way to make table columns show/hide on init as requested
            var checkbox_settings = [
                false, // RSID
                false, // CHROMOSOME POS
                false, // RISK ALLELE
                true, // GENOTYPE
                true, // DISEASE TRAIT
                false, // P VALUE
                false, // OR
                false, // RISK
                false, // PRIORITY
                false, // TAGS
                false  // CATEGORY COLOR
            ];
            $('.table-settings').data('default-values', checkbox_settings);
            reset_checkboxes($('.table-settings').data('default-values'));

            rowRender()
        }
    }).columnFilter({ sPlaceHolder: "head:after",
        aoColumns: [
            { type: "number-range" },
            { type: "number-range" },
            { type: "select" },
            { type: "select" },
            { type: "select" },
            { type: "number-range" },
            { type: "number-range" },
            { type: "select" },
            { type: "number-range" },
            { type: "select" },
            { type: "select" },
            { type: "select" }
        ]
    });

    function rowRender() {
        $('#genomeData').DataTable().rows().every(function() {
            var row = $(this.node()),
                rowData = this.data();
            row.data('url', encodeURI(rowData.link + '?allele=' + rowData.genotype))
                .css('background-color', rowData.color);
        });
    }

});

var progressbar = $('.progress-bar');
var interval;

function updateBar(values) {
    var l = values.received;
    var tot = values.size;

    var perc = (l / tot) * (100.00);
    progressbar.css('width', perc + '%');
    progressbar.text(perc + '%');
    if (values.status === 'done') {
        window.clearInterval(interval);
    }
}

$("form#upload_form").submit(function(e){
    $('form#upload_form input[type=submit]').hide();
    progressbar.parent().show();
    var getProgress = function() {
        $.ajax({
            url: "/progress",
            headers: {"X-Progress-ID": $('#progress-bar').data('upload_id')},
            dataType: 'json',
            success: function(data) {
                updateBar(data);
            }
        });
    };
    interval = window.setInterval(getProgress, 1000);
});

$('.genomeData_advanced').click(function(e) {
    $('#genomeData thead tr.filter-visiblity, .dataTables_length, .dataTables_filter, .table-settings').toggle();
});

$(".checkbox-row input").change(function() {
    var checked = $(this).is(":checked");
    var index = $(this).parent().parent().index();
    $('#genomeData tbody tr').each(function() {
        if(checked) {
            $(this).find("td").eq(index).show();
        } else {
            $(this).find("td").eq(index).hide();
        }
    });
    $('#genomeData thead tr').each(function() {
        if(checked) {
            $(this).find("th").eq(index).show();
        } else {
            $(this).find("th").eq(index).hide();
        }
    });
    $('#genomeData tfoot tr').each(function() {
        if(checked) {
            $(this).find("th").eq(index).show();
        } else {
            $(this).find("th").eq(index).hide();
        }
    });
});
$(".table-settings .defaultbutton").click(function() {
    reset_checkboxes($('.table-settings').data('default-values'));
    return false;
});

$('.filter_labels h3 span.label').on('click', function(e) {
    var label = $(e.delegateTarget),
        labelColorOff = label.data('color-off'),
        labelColorOn = label.data('color-on');
    label.toggleClass('tag-checked');
    if (label.hasClass('tag-checked')) {
        label.css('background-color', labelColorOn);
    } else {
        label.css('background-color', labelColorOff);
    }
    genomeData.DataTable().draw();
});

$('.category_labels h2 span.label').on('click', function(e) {
    var category = $(e.delegateTarget);
    category.toggleClass('tag-checked');
    genomeData.DataTable().draw();
});

/**
 * Layout expand
 */
function setLayout() {
    if(window.localStorage['expand'] == 'true') {
        $('.layout').removeClass('container container-fluid').addClass('container-fluid')
        $('[data-toggle=layout-fluid] .glyphicon.glyphicon-resize-full').removeClass('glyphicon-resize-full').addClass('glyphicon-resize-small')
    } else {
        $('.layout').removeClass('container container-fluid').addClass('container')
        $('[data-toggle=layout-fluid] .glyphicon.glyphicon-resize-small').removeClass('glyphicon-resize-small').addClass('glyphicon-resize-full')
    }
}

//setLayout();

$('[data-toggle=layout-fluid]').click(function() {
    window.localStorage['expand'] = String(!(window.localStorage['expand'] == 'true'));
    setLayout();
    return false;
});

if (window.location.href === '/disease/browse/') {
    (function poll(){
        setTimeout(function(){
            if ($('.alert.alert-info').length) {
                location.reload();
                poll();
            }
        }, 1000);
    })();
}

<commit_msg>removed debug in js<commit_after>$.cssHooks.backgroundColor = {
    get: function(elem) {
        if (elem.currentStyle)
            var bg = elem.currentStyle["backgroundColor"];
        else if (window.getComputedStyle)
            var bg = document.defaultView.getComputedStyle(elem,
                null).getPropertyValue("background-color");
        if (bg.search("rgb") == -1)
            return bg;
        else {
            bg = bg.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
            function hex(x) {
                return ("0" + parseInt(x).toString(16)).slice(-2);
            }
            return "#" + hex(bg[1]) + hex(bg[2]) + hex(bg[3]);
        }
    }
};

$.fn.dataTableExt.oSort['numeric_ignore_nan-asc']  = function(x,y) {
    if (isNaN(x) && isNaN(y)) return ((x < y) ? 1 : ((x > y) ?  -1 : 0));

    if (isNaN(x)) return 1;
    if (isNaN(y)) return -1;

    x = parseFloat( x );
    y = parseFloat( y );
    return ((x < y) ? -1 : ((x > y) ?  1 : 0));
};

$.fn.dataTableExt.oSort['numeric_ignore_nan-desc'] = function(x,y) {
    if (isNaN(x) && isNaN(y)) return ((x < y) ? 1 : ((x > y) ?  -1 : 0));

    if (isNaN(x)) return 1;
    if (isNaN(y)) return -1;

    x = parseFloat( x );
    y = parseFloat( y );
    return ((x < y) ?  1 : ((x > y) ? -1 : 0));
};

$.fn.dataTableExt.afnFiltering.push(
    function(oSettings, aData, iDataIndex) {
        var selected_tags = $('.filter_labels h3 span.tag-checked').map(function(k, v) {
                return $(this).text();
            }).get(),
            row_tags = aData[9].split(',');

        if (!selected_tags.length) { // nothing to filter out
            return true;
        } else {
            if (!row_tags.length || (row_tags.length === 1 && row_tags[0] === "")) {
                return false;
            }
            for (var i = 0; i < selected_tags.length; i++) {
                for (var j = 0; j < row_tags.length; j++) {
                    if (selected_tags[i] === row_tags[j]) {
                        return true;
                    }
                }
            }
            return false;
        }
    }
);

$.fn.dataTableExt.afnFiltering.push(
    function(oSettings, aData, iDataIndex) {
        var selected_categories = $('.category_labels h2 span.tag-checked').map(function(k, v) {
                return $(this).css('background-color');
            }).get(),
            row_color = aData[10];
        if (!selected_categories.length) { // nothing to filter out
            return true;
        } else {
            for (var i = 0; i < selected_categories.length; i++) {
                if (selected_categories[i] === row_color) {
                    return true;
                }
            }
        }
        return false;
    }
);

var genomeData = $('#genomeData');
var reset_checkboxes = function(checkbox_settings) {
    var checkboxes = $(".checkbox-row input");
    checkbox_settings.forEach(function(element, index) {
        var checkbox = $(checkboxes[index]);
        checkbox.prop('checked', element).trigger('change');
    });

};
$(document).ready(function() {
    var genome_url = genomeData.data('genome_url');
    var genomeTable = genomeData.dataTable({
        "ajax": genome_url,
        "columns": [
            {"data": "rsid" },
            {"data": "chromosome_position" },
            {"data": "risk_allele" },
            {"data": "genotype" },
            {"data": "disease_trait" },
            {"data": "p_value" },
            {"data": "or_or_beta" },
            {"data": "risk" },
            {"data": "priority", "defaultContent": "0" },
            {"data": "tags", "defaultContent": " "},
            {"data": "color", "defaultContent": ""}
        ],
        "pageLength": 100,
        "aoColumnDefs": [
            { "sType": "numeric_ignore_nan", "aTargets": [ 5, 6 ] },
            { "bSearchable": false, "bVisible": false, "aTargets": [ 8 ] }
        ],
        "columnDefs": [{"targets": [ 8 ], "visible": false, "searchable": false}],
        "order": [[ 8, "desc" ]],
        "processing": true,
        "drawCallback": function( settings ) {
            var rows = $('#genomeData tbody tr');

            // Remove existing event handlers;
            rows.off('click');

            rows.click(function(e) {
                e.preventDefault();
                var row = $(this);
                window.open(row.data('url'), 'Your genome', "height=" + window.screen.height +",width=" + window.screen.width);
            });
            // Fix datatable for fluid container
            genomeData.css('width', '');

            // Ugly way to make table columns show/hide on init as requested
            var checkbox_settings = [
                false, // RSID
                false, // CHROMOSOME POS
                false, // RISK ALLELE
                true, // GENOTYPE
                true, // DISEASE TRAIT
                false, // P VALUE
                false, // OR
                false, // RISK
                false, // PRIORITY
                false, // TAGS
                false  // CATEGORY COLOR
            ];
            $('.table-settings').data('default-values', checkbox_settings);
            reset_checkboxes($('.table-settings').data('default-values'));

            rowRender()
        }
    }).columnFilter({ sPlaceHolder: "head:after",
        aoColumns: [
            { type: "number-range" },
            { type: "number-range" },
            { type: "select" },
            { type: "select" },
            { type: "select" },
            { type: "number-range" },
            { type: "number-range" },
            { type: "select" },
            { type: "number-range" },
            { type: "select" },
            { type: "select" },
            { type: "select" }
        ]
    });

    function rowRender() {
        $('#genomeData').DataTable().rows().every(function() {
            var row = $(this.node()),
                rowData = this.data();
            row.data('url', encodeURI(rowData.link + '?allele=' + rowData.genotype))
                .css('background-color', rowData.color);
        });
    }

});

var progressbar = $('.progress-bar');
var interval;

function updateBar(values) {
    var l = values.received;
    var tot = values.size;

    var perc = (l / tot) * (100.00);
    progressbar.css('width', perc + '%');
    progressbar.text(perc + '%');
    if (values.status === 'done') {
        window.clearInterval(interval);
    }
}

$("form#upload_form").submit(function(e){
    $('form#upload_form input[type=submit]').hide();
    progressbar.parent().show();
    var getProgress = function() {
        $.ajax({
            url: "/progress",
            headers: {"X-Progress-ID": $('#progress-bar').data('upload_id')},
            dataType: 'json',
            success: function(data) {
                updateBar(data);
            }
        });
    };
    interval = window.setInterval(getProgress, 1000);
});

$('.genomeData_advanced').click(function(e) {
    $('#genomeData thead tr.filter-visiblity, .dataTables_length, .dataTables_filter, .table-settings').toggle();
});

$(".checkbox-row input").change(function() {
    var checked = $(this).is(":checked");
    var index = $(this).parent().parent().index();
    $('#genomeData tbody tr').each(function() {
        if(checked) {
            $(this).find("td").eq(index).show();
        } else {
            $(this).find("td").eq(index).hide();
        }
    });
    $('#genomeData thead tr').each(function() {
        if(checked) {
            $(this).find("th").eq(index).show();
        } else {
            $(this).find("th").eq(index).hide();
        }
    });
    $('#genomeData tfoot tr').each(function() {
        if(checked) {
            $(this).find("th").eq(index).show();
        } else {
            $(this).find("th").eq(index).hide();
        }
    });
});
$(".table-settings .defaultbutton").click(function() {
    reset_checkboxes($('.table-settings').data('default-values'));
    return false;
});

$('.filter_labels h3 span.label').on('click', function(e) {
    var label = $(e.delegateTarget),
        labelColorOff = label.data('color-off'),
        labelColorOn = label.data('color-on');
    label.toggleClass('tag-checked');
    if (label.hasClass('tag-checked')) {
        label.css('background-color', labelColorOn);
    } else {
        label.css('background-color', labelColorOff);
    }
    genomeData.DataTable().draw();
});

$('.category_labels h2 span.label').on('click', function(e) {
    var category = $(e.delegateTarget);
    category.toggleClass('tag-checked');
    genomeData.DataTable().draw();
});

/**
 * Layout expand
 */
function setLayout() {
    if(window.localStorage['expand'] == 'true') {
        $('.layout').removeClass('container container-fluid').addClass('container-fluid')
        $('[data-toggle=layout-fluid] .glyphicon.glyphicon-resize-full').removeClass('glyphicon-resize-full').addClass('glyphicon-resize-small')
    } else {
        $('.layout').removeClass('container container-fluid').addClass('container')
        $('[data-toggle=layout-fluid] .glyphicon.glyphicon-resize-small').removeClass('glyphicon-resize-small').addClass('glyphicon-resize-full')
    }
}

//setLayout();

$('[data-toggle=layout-fluid]').click(function() {
    window.localStorage['expand'] = String(!(window.localStorage['expand'] == 'true'));
    setLayout();
    return false;
});

if (window.location.href === '/disease/browse/') {
    (function poll(){
        setTimeout(function(){
            if ($('.alert.alert-info').length) {
                location.reload();
                poll();
            }
        }, 1000);
    })();
}

<|endoftext|>


<commit_before>import jsonp from 'jsonp';

export default function getPages() {
	jsonp(`https://en.wikipedia.org/w/api.php?format=jsonfm&action=query&generator=random&grnnamespace=0&prop=revisions|images&rvprop=content&grnlimit=2&uselang=user/`, function (err, data) {
		console.log('Error: ', err);
		console.log('Data: ', data);
		return data;
	});
}<commit_msg>removing the wrong type in the url<commit_after>import jsonp from 'jsonp';

export default function getPages() {
	jsonp(`https://en.wikipedia.org/w/api.php?format=json&action=query&generator=random&grnnamespace=0&prop=revisions|images&rvprop=content&grnlimit=2&uselang=user/`, function (err, data) {
		console.log('Error: ', err);
		console.log('Data: ', data);
		return data;
	});
}<|endoftext|>


<commit_before>/* global d3 */
histomicstk.views.Visualization = girder.View.extend({
    initialize: function () {
        // rendered annotation layers
        this._annotations = {};

        // the map object
        this._map = null;

        // the rendered map layers
        this._layers = [];

        // control model for file widget
        this._controlModel = histomicstk.dialogs.image.model;

        this._annotationList = new histomicstk.views.AnnotationSelectorWidget({
            parentView: this
        });

        // prebind the onResize method so we can remove it on destroy
        this._onResize = _.bind(this._onResize, this);

        // shared viewport object for annotation layers
        this.viewport = new girder.annotation.Viewport();
        this._onResize();
        $(window).resize(this._onResize);

        this.listenTo(this._controlModel, 'change:value', function (model) {
            if (!model.get('value')) {
                return;
            }

            var id = model.get('value').id;
            girder.restRequest({
                path: 'item/' + id
            })
            .then(_.bind(function (item) {
                this._controlModel.get('value').set(item);
                histomicstk.router.setQuery('image', id);
                return this.addItem(this._controlModel.get('value'));
            }, this))
            .fail(_.bind(function () {
                var info = {
                    text: 'Could not render item as an image',
                    type: 'danger',
                    timeout: 5000,
                    icon: 'attention'
                };
                girder.events.trigger('g:alert', info);
                histomicstk.router.setQuery('image', null, {replace: true});
            }, this));
        });

        this.listenTo(histomicstk.events, 'query:image', _.bind(function (image) {
            var currentImage = this._controlModel.get('value') || {};
            if (image && currentImage.id !== image) {
                this._controlModel.set('value', new girder.models.ItemModel({_id: image}));
            } else if (!image) {
                this.removeItem();
                this._controlModel.set('value', null);
            }
        }, this));

        // fallback to canvas renderer rather than dom
        geo.gl.vglRenderer.fallback = function () {return 'canvas';};
    },

    /**
     * Create a map object with the given global bounds.
     * @TODO Either fix the map.maxBounds setter or recreate all the current layers
     * in the new map object.
     */
    _createMap: function (bounds) {
        if (this._map) {
            this._map.exit();
        }
        bounds.left = bounds.left || 0;
        bounds.top = bounds.top || 0;
        var w = bounds.right - bounds.left;
        var h = bounds.bottom - bounds.top;
        var interactor = geo.mapInteractor({
            zoomAnimation: false
        });

        this._map = geo.map({
            node: '
',
            width: this.$el.width() || 100,
            height: this.$el.height() || 100,
            ingcs: '+proj=longlat +axis=esu',
            gcs: '+proj=longlat +axis=enu',
            maxBounds: bounds,
            clampBoundsX: false,
            clampBoundsY: false,
            center: {x: w / 2, y: h / 2},
            zoom: 0,
            discreteZoom: false,
            interactor: interactor
        });

        this._syncViewport();
        this._map.geoOn(geo.event.pan, _.bind(this._syncViewport, this));
        this.$('.h-visualization-body').empty().append(this._map.node());
    },

    renderAnnotationList: function (item) {
        if (this._annotationList.collection) {
            this.stopListening(this._annotationList);
        }
        this._annotationList
            .setItem(item)
            .setElement(this.$('.h-annotation-panel'))
            .render()
            .$el.removeClass('hidden');

        this.listenTo(this._annotationList.collection, 'change:displayed', this._toggleAnnotation);
    },

    /**
     * Add a map layer from a girder item object.  The girder item should contain a
     * single image file (the first encountered will be used) or be registered
     * as a tiled image via the large_image plugin.
     *
     * This method is async, errors encountered will trigger an error event and
     * reject the returned promise.  The promise is resolved with the added map
     * layer.
     *
     * @TODO: How do we pass in bounds?
     * @TODO: Allow multiple layers (don't reset map on add).
     */
    addItem: function (item) {
        var promise;

        this.resetAnnotations();
        this.renderAnnotationList(item);

        // first check if it is a tiled image
        if (item.id === 'test' || item.has('largeImage')) {
            promise = girder.restRequest({
                path: 'item/' + item.id + '/tiles'
            })
            .then(_.bind(function (tiles) {
                // It is a tile item
                return this.addTileLayer(
                    {
                        url: girder.apiRoot + '/item/' + item.id + '/tiles/zxy/{z}/{x}/{y}',
                        maxLevel: tiles.levels,
                        tileWidth: tiles.tileWidth,
                        tileHeight: tiles.tileHeight,
                        sizeX: tiles.sizeX,
                        sizeY: tiles.sizeY
                    }
                );
            }, this));
        } else { // check for an image file
            promise = girder.restRequest({
                path: 'item/' + item.id + '/files',
                limit: 1 // we *could* look through all the files,
            })
            .then(_.bind(function (files) {
                var img = null, defer, imgElement;

                _.each(files, function (file) {
                    if ((file.mimeType || '').startsWith('image/')) {
                        img = new girder.models.FileModel(file);
                    }
                });

                if (!img) {
                    // no image is present, so return a reject promise
                    return new $.Deferred().reject('No renderable image file found').promise();
                }

                // Download the file to get the image size
                defer = new $.Deferred();
                imgElement = new Image();
                imgElement.onload = function () {
                    defer.resolve(imgElement);
                };
                imgElement.onerror = function () {
                    defer.reject('Could not load image');
                };
                imgElement.src = girder.apiRoot + '/file/' + img.id + '/download';
                return defer.promise();
            }))
            .then(_.bind(function (img) {
                // Inspect the image and add it to the map
                return this.addImageLayer(
                    img.src,
                    {
                        right: img.width,
                        bottom: img.height
                    }
                );
            }, this));
        }

        return promise;
    },

    /**
     * Add a single image as a quad feature on the viewer from an image url.
     *
     * @param {string} url The url of the image
     * @param {object} bounds
     *  The coordinate bounds of the image (left, right, top, bottom).
     */
    addImageLayer: function (url, bounds) {
        this._createMap(bounds);
        var layer = this._map.createLayer('feature', {renderer: 'vgl'});
        var quad = layer.createFeature('quad');
        quad.data([
            {
                ll: {x: bounds.left || 0, y: -bounds.bottom},
                ur: {x: bounds.right, y: bounds.top || 0},
                image: url
            }
        ]);
        this._layers.push(layer);
        this._map.draw();
        return quad;
    },

    removeItem: function () {
        this.resetAnnotations();
        this._annotationList.render().$el.addClass('hidden');
        if (this._map) {
            this._map.exit();
            this._map = null;
            this.$('.h-visualization-body').empty();
        }
    },

    /**
     * Add a tiled image as a tileLayer on the view from an options object.
     * The options object takes options supported by geojs's tileLayer:
     *
     *   https://github.com/OpenGeoscience/geojs/blob/master/src/tileLayer.js
     *
     * @param {object} opts Tile layer required options
     * @param {string|function} opts.url
     */
    addTileLayer: function (opts) {
        var layer;
        if (!_.has(opts, 'url')) {
            throw new Error('`url` parameter required.');
        }

        _.defaults(opts, {
            useCredentials: true,
            maxLevel: 10,
            wrapX: false,
            wrapY: false,
            tileOffset: function () {
                return {x: 0, y: 0};
            },
            attribution: '',
            tileWidth: 256,
            tileHeight: 256,
            tileRounding: Math.ceil
        });

        // estimate the global bounds if not provided
        if (!opts.sizeX) {
            opts.sizeX = Math.pow(2, opts.maxLevel) * opts.tileWidth;
        }
        if (!opts.sizeY) {
            opts.sizeY = Math.pow(2, opts.maxLevel) * opts.tileHeight;
        }

        this._createMap({
            right: opts.sizeX - 1,
            bottom: opts.sizeY - 1
        });
        layer = this._map.createLayer('osm', opts);
        this._layers.push(layer);
        this._map.draw();
        return layer;
    },

    addAnnotationLayer: function (annotation) {
        var el = d3.select(this.el)
                .select('.h-annotation-layers')
                .append('svg')
                .node();

        this._onResize();
        var settings = $.extend({
            el: el,
            viewport: this.viewport
        }, annotation.annotation);

        this._annotations[annotation._id] = new girder.annotation.Annotation(settings).render();
        return this;
    },

    removeAnnotationLayer: function (id) {
        if (_.has(this._annotations, id)) {
            this._annotations[id].remove();
            delete this._annotations[id];
        }
        return this;
    },

    resetAnnotations: function () {
        _.each(_.keys(this._annotations), _.bind(this.removeAnnotationLayer, this));
        return this;
    },

    render: function () {

        this.$el.html(histomicstk.templates.visualization());
        return this;
    },

    destroy: function () {
        $(window).off('resize', this._onResize);
        this._map.exit();
        this.$el.empty();
        this._controlModel.destroy();
        girder.View.prototype.destroy.apply(this, arguments);
    },

    /**
     * Resize the viewport according to the size of the container.
     */
    _onResize: function () {
        var width = this.$el.width() || 100;
        var height = this.$el.height() || 100;
        var layers = this.$('.h-annotation-layers > svg');

        this.viewport.set({
            width: width,
            height: height
        });
        layers.attr('width', width);
        layers.attr('height', height);
        this._syncViewport();
    },

    _syncViewport: function () {
        var bds;
        if (!this._map) {
            return;
        }
        bds = this._map.bounds(undefined, null);

        this.viewport.set({
            scale: (bds.right - bds.left) / this.viewport.get('width')
        });
        this.viewport.set({
            top: -bds.top,
            left: bds.left
        });
    },

    _toggleAnnotation: function (model) {
        if (model.get('displayed') && !_.has(this._annotations, model.id)) {
            girder.restRequest({
                path: 'annotation/' + model.id
            }).then(_.bind(this.addAnnotationLayer, this));
        } else if (!model.get('displayed') && _.has(this._annotations, model.id)) {
            this.removeAnnotationLayer(model.id);
        }
    }
});

histomicstk.dialogs.image = new histomicstk.views.ItemSelectorWidget({
    parentView: null,
    model: new histomicstk.models.Widget({
        type: 'file'
    })
});
<commit_msg>Add pixel scaling to handle odd sized images<commit_after>/* global d3 */
histomicstk.views.Visualization = girder.View.extend({
    initialize: function () {
        // rendered annotation layers
        this._annotations = {};

        // the map object
        this._map = null;

        // the rendered map layers
        this._layers = [];

        // control model for file widget
        this._controlModel = histomicstk.dialogs.image.model;

        this._annotationList = new histomicstk.views.AnnotationSelectorWidget({
            parentView: this
        });

        // extra scaling factor to handle images that are not powers of 2 in size
        this._unitsPerPixel = 1;

        // prebind the onResize method so we can remove it on destroy
        this._onResize = _.bind(this._onResize, this);

        // shared viewport object for annotation layers
        this.viewport = new girder.annotation.Viewport();
        this._onResize();
        $(window).resize(this._onResize);

        this.listenTo(this._controlModel, 'change:value', function (model) {
            if (!model.get('value')) {
                return;
            }

            var id = model.get('value').id;
            girder.restRequest({
                path: 'item/' + id
            })
            .then(_.bind(function (item) {
                this._controlModel.get('value').set(item);
                histomicstk.router.setQuery('image', id);
                return this.addItem(this._controlModel.get('value'));
            }, this))
            .fail(_.bind(function () {
                var info = {
                    text: 'Could not render item as an image',
                    type: 'danger',
                    timeout: 5000,
                    icon: 'attention'
                };
                girder.events.trigger('g:alert', info);
                histomicstk.router.setQuery('image', null, {replace: true});
            }, this));
        });

        this.listenTo(histomicstk.events, 'query:image', _.bind(function (image) {
            var currentImage = this._controlModel.get('value') || {};
            if (image && currentImage.id !== image) {
                this._controlModel.set('value', new girder.models.ItemModel({_id: image}));
            } else if (!image) {
                this.removeItem();
                this._controlModel.set('value', null);
            }
        }, this));

        // fallback to canvas renderer rather than dom
        geo.gl.vglRenderer.fallback = function () {return 'canvas';};
    },

    /**
     * Create a map object with the given global bounds.
     * @TODO Either fix the map.maxBounds setter or recreate all the current layers
     * in the new map object.
     */
    _createMap: function (bounds) {
        if (this._map) {
            this._map.exit();
        }
        bounds.left = bounds.left || 0;
        bounds.top = bounds.top || 0;
        var w = bounds.right - bounds.left;
        var h = bounds.bottom - bounds.top;
        var interactor = geo.mapInteractor({
            zoomAnimation: false
        });

        this._map = geo.map({
            node: '
',
            width: this.$el.width() || 100,
            height: this.$el.height() || 100,
            ingcs: '+proj=longlat +axis=esu',
            gcs: '+proj=longlat +axis=enu',
            maxBounds: bounds,
            clampBoundsX: false,
            clampBoundsY: false,
            center: {x: w / 2, y: h / 2},
            zoom: 0,
            discreteZoom: false,
            interactor: interactor
        });
        window.map = this._map;

        this._syncViewport();
        this._map.geoOn(geo.event.pan, _.bind(this._syncViewport, this));
        this.$('.h-visualization-body').empty().append(this._map.node());
    },

    renderAnnotationList: function (item) {
        if (this._annotationList.collection) {
            this.stopListening(this._annotationList);
        }
        this._annotationList
            .setItem(item)
            .setElement(this.$('.h-annotation-panel'))
            .render()
            .$el.removeClass('hidden');

        this.listenTo(this._annotationList.collection, 'change:displayed', this._toggleAnnotation);
    },

    /**
     * Add a map layer from a girder item object.  The girder item should contain a
     * single image file (the first encountered will be used) or be registered
     * as a tiled image via the large_image plugin.
     *
     * This method is async, errors encountered will trigger an error event and
     * reject the returned promise.  The promise is resolved with the added map
     * layer.
     *
     * @TODO: How do we pass in bounds?
     * @TODO: Allow multiple layers (don't reset map on add).
     */
    addItem: function (item) {
        var promise;

        this.resetAnnotations();
        this.renderAnnotationList(item);

        // first check if it is a tiled image
        if (item.id === 'test' || item.has('largeImage')) {
            promise = girder.restRequest({
                path: 'item/' + item.id + '/tiles'
            })
            .then(_.bind(function (tiles) {
                // It is a tile item
                return this.addTileLayer(
                    {
                        url: girder.apiRoot + '/item/' + item.id + '/tiles/zxy/{z}/{x}/{y}',
                        maxLevel: tiles.levels,
                        tileWidth: tiles.tileWidth,
                        tileHeight: tiles.tileHeight,
                        sizeX: tiles.sizeX,
                        sizeY: tiles.sizeY
                    }
                );
            }, this));
        } else { // check for an image file
            promise = girder.restRequest({
                path: 'item/' + item.id + '/files',
                limit: 1 // we *could* look through all the files,
            })
            .then(_.bind(function (files) {
                var img = null, defer, imgElement;

                _.each(files, function (file) {
                    if ((file.mimeType || '').startsWith('image/')) {
                        img = new girder.models.FileModel(file);
                    }
                });

                if (!img) {
                    // no image is present, so return a reject promise
                    return new $.Deferred().reject('No renderable image file found').promise();
                }

                // Download the file to get the image size
                defer = new $.Deferred();
                imgElement = new Image();
                imgElement.onload = function () {
                    defer.resolve(imgElement);
                };
                imgElement.onerror = function () {
                    defer.reject('Could not load image');
                };
                imgElement.src = girder.apiRoot + '/file/' + img.id + '/download';
                return defer.promise();
            }))
            .then(_.bind(function (img) {
                // Inspect the image and add it to the map
                return this.addImageLayer(
                    img.src,
                    {
                        right: img.width,
                        bottom: img.height
                    }
                );
            }, this));
        }

        return promise;
    },

    /**
     * Add a single image as a quad feature on the viewer from an image url.
     *
     * @param {string} url The url of the image
     * @param {object} bounds
     *  The coordinate bounds of the image (left, right, top, bottom).
     */
    addImageLayer: function (url, bounds) {
        this._createMap(bounds);
        var layer = this._map.createLayer('feature', {renderer: 'vgl'});
        var quad = layer.createFeature('quad');
        quad.data([
            {
                ll: {x: bounds.left || 0, y: -bounds.bottom},
                ur: {x: bounds.right, y: bounds.top || 0},
                image: url
            }
        ]);
        this._layers.push(layer);
        this._map.draw();
        return quad;
    },

    removeItem: function () {
        this.resetAnnotations();
        this._annotationList.render().$el.addClass('hidden');
        if (this._map) {
            this._map.exit();
            this._map = null;
            this.$('.h-visualization-body').empty();
        }
    },

    /**
     * Add a tiled image as a tileLayer on the view from an options object.
     * The options object takes options supported by geojs's tileLayer:
     *
     *   https://github.com/OpenGeoscience/geojs/blob/master/src/tileLayer.js
     *
     * @param {object} opts Tile layer required options
     * @param {string|function} opts.url
     */
    addTileLayer: function (opts) {
        var layer;
        if (!_.has(opts, 'url')) {
            throw new Error('`url` parameter required.');
        }

        _.defaults(opts, {
            useCredentials: true,
            maxLevel: 10,
            wrapX: false,
            wrapY: false,
            tileOffset: function () {
                return {x: 0, y: 0};
            },
            attribution: '',
            tileWidth: 256,
            tileHeight: 256,
            tileRounding: Math.ceil
        });

        // estimate the global bounds if not provided
        if (!opts.sizeX) {
            opts.sizeX = Math.pow(2, opts.maxLevel) * opts.tileWidth;
        }
        if (!opts.sizeY) {
            opts.sizeY = Math.pow(2, opts.maxLevel) * opts.tileHeight;
        }

        this._createMap({
            right: opts.sizeX - 1,
            bottom: opts.sizeY - 1
        });
        layer = this._map.createLayer('osm', opts);
        this._unitsPerPixel = this._map.unitsPerPixel(opts.maxLevel - 1);
        this._layers.push(layer);
        this._map.draw();
        return layer;
    },

    addAnnotationLayer: function (annotation) {
        var el = d3.select(this.el)
                .select('.h-annotation-layers')
                .append('svg')
                .node();

        this._onResize();
        var settings = $.extend({
            el: el,
            viewport: this.viewport
        }, annotation.annotation);

        this._annotations[annotation._id] = new girder.annotation.Annotation(settings).render();
        return this;
    },

    removeAnnotationLayer: function (id) {
        if (_.has(this._annotations, id)) {
            this._annotations[id].remove();
            delete this._annotations[id];
        }
        return this;
    },

    resetAnnotations: function () {
        _.each(_.keys(this._annotations), _.bind(this.removeAnnotationLayer, this));
        return this;
    },

    render: function () {

        this.$el.html(histomicstk.templates.visualization());
        return this;
    },

    destroy: function () {
        $(window).off('resize', this._onResize);
        this._map.exit();
        this.$el.empty();
        this._controlModel.destroy();
        girder.View.prototype.destroy.apply(this, arguments);
    },

    /**
     * Resize the viewport according to the size of the container.
     */
    _onResize: function () {
        var width = this.$el.width() || 100;
        var height = this.$el.height() || 100;
        var layers = this.$('.h-annotation-layers > svg');

        this.viewport.set({
            width: width,
            height: height
        });
        layers.attr('width', width);
        layers.attr('height', height);
        this._syncViewport();
    },

    _syncViewport: function () {
        var bds;
        if (!this._map) {
            return;
        }
        bds = this._map.bounds(undefined, null);

        this.viewport.set({
            scale: (bds.right - bds.left) / (this.viewport.get('width') * this._unitsPerPixel)
        });
        this.viewport.set({
            top: -bds.top / this._unitsPerPixel,
            left: bds.left / this._unitsPerPixel
        });
    },

    _toggleAnnotation: function (model) {
        if (model.get('displayed') && !_.has(this._annotations, model.id)) {
            girder.restRequest({
                path: 'annotation/' + model.id
            }).then(_.bind(this.addAnnotationLayer, this));
        } else if (!model.get('displayed') && _.has(this._annotations, model.id)) {
            this.removeAnnotationLayer(model.id);
        }
    }
});

histomicstk.dialogs.image = new histomicstk.views.ItemSelectorWidget({
    parentView: null,
    model: new histomicstk.models.Widget({
        type: 'file'
    })
});
<|endoftext|>


<commit_before>import RpmMeter from 'spin-bike-rpm-meter';

export const START_LISTENING_TO_PULSES = 'START_LISTENING_TO_PULSES';

export function startRpmMeter() {
	return function(dispatch) {
		const rpmMeter = new RpmMeter();

		return rpmMeter.start()
			.then(stopFunction => {
				console.log('Starting listening to pulses...'); // Refactor to standard logging routine.

				dispatch(startListeningToPulses(rpmMeter, stopFunction));
			});
	}
}

function startListeningToPulses(rpmMeter, stopFunction) {
	return {
		type: START_LISTENING_TO_PULSES,
		payload: {
			rpmMeter,
			stopFunction
		}
	};
}<commit_msg>Emit getPulseData action on each PULSE_EVENT<commit_after>import RpmMeter, { PULSE_EVENT } from 'spin-bike-rpm-meter';

export const START_LISTENING_TO_PULSES = 'START_LISTENING_TO_PULSES';
export const GET_PULSE_DATA = 'GET_PULSE_DATA';

export function startRpmMeter() {
	return function(dispatch) {
		const rpmMeter = new RpmMeter();

		return rpmMeter.start()
			.then(stopFunction => {
				dispatch(startListeningToPulses(rpmMeter, stopFunction));

				rpmMeter.on(PULSE_EVENT, pulseData => {
					dispatch(getPulseData(pulseData));
				});
			});
	}
}

function getPulseData(pulseData) {
	return {
		type: GET_PULSE_DATA,
		payload: pulseData
	};
}

function startListeningToPulses(rpmMeter, stopFunction) {
	return {
		type: START_LISTENING_TO_PULSES,
		payload: {
			rpmMeter,
			stopFunction
		}
	};
}<|endoftext|>


<commit_before>import {getFaucet, getTestFaucet} from "../branding";

export const blockTradesAPIs = {
    BASE: "https://api.blocktrades.us/v2",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const openledgerAPIs = {
    BASE: "https://ol-api1.openledger.info/api/v0/ol/support",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount",
    RPC_URL: "https://openledger.info/api/"
};

export const rudexAPIs = {
    BASE: "https://gateway.rudex.org/api/rudex",
    COINS_LIST: "/coins",
    NEW_DEPOSIT_ADDRESS: "/simple-api/initiate-trade"
};

export const bitsparkAPIs = {
    BASE: "https://dex-api.bitspark.io/api/v1",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const cryptoBridgeAPIs = {
    BASE: "https://api.crypto-bridge.org/api/v1",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/wallets",
    MARKETS: "/markets",
    TRADING_PAIRS: "/trading-pairs"
};

export const citadelAPIs = {
    BASE: "https://citadel.li/trade",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const gdex2APIs = {
    BASE: "https://api.gdex.io/adjust",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs"
};

// Legacy Deposit/Withdraw
export const gdexAPIs = {
    BASE: "https://api.gdex.io",
    ASSET_LIST: "/gateway/asset/assetList",
    ASSET_DETAIL: "/gateway/asset/assetDetail",
    GET_DEPOSIT_ADDRESS: "/gateway/address/getAddress",
    CHECK_WITHDRAY_ADDRESS: "/gateway/address/checkAddress",
    DEPOSIT_RECORD_LIST: "/gateway/deposit/recordList",
    DEPOSIT_RECORD_DETAIL: "/gateway/deposit/recordDetail",
    WITHDRAW_RECORD_LIST: "/gateway/withdraw/recordList",
    WITHDRAW_RECORD_DETAIL: "/gateway/withdraw/recordDetail",
    GET_USER_INFO: "/gateway/user/getUserInfo",
    USER_AGREEMENT: "/gateway/user/isAgree",
    WITHDRAW_RULE: "/gateway/withdraw/rule"
};

export const xbtsxAPIs = {
    BASE: "https://apis.xbts.io/api/v1",
    COINS_LIST: "/coin"
};

export const nodeRegions = [
    // region of the node follows roughly https://en.wikipedia.org/wiki/Subregion#/media/File:United_Nations_geographical_subregions.png
    "Northern Europe",
    "Western Europe",
    "Southern Europe",
    "Eastern Europe",
    "Northern Asia",
    "Western Asia",
    "Southern Asia",
    "Eastern Asia",
    "Central Asia",
    "Southeastern Asia",
    "Australia and New Zealand",
    "Melanesia",
    "Polynesia",
    "Micronesia",
    "Northern Africa",
    "Western Africa",
    "Middle Africa",
    "Eastern Africa",
    "Southern Africa",
    "Northern America",
    "Central America",
    "Caribbean",
    "South America"
];

export const settingsAPIs = {
    // If you want a location to be translated, add the translation to settings in locale-xx.js
    // and use an object {translate: key} in WS_NODE_LIST
    DEFAULT_WS_NODE: "wss://fake.automatic-selection.com",
    WS_NODE_LIST: [
        {
            url: "wss://fake.automatic-selection.com",
            location: {translate: "settings.api_closest"}
        },
        {
            url: "ws://127.0.0.1:8090",
            location: "Locally hosted"
        },
        {
            url: "wss://nexus01.co.uk/ws",
            region: "Northern Europe",
            country: "England",
            location: "Gloucester",
            operator: "Witness: nexus01",
            contact: "telegram:rosswlkr"
        },
        {
            url: "wss://dex.iobanker.com/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Frankfurt",
            operator: "Witness: iobanker-core",
            contact: "email:admin@iobanker.com"
        },
        {
            url: "wss://ws.gdex.top",
            region: "Eastern Asia",
            country: "China",
            location: "Shanghai",
            operator: "Witness: gdex-witness",
            contact: "telegram:BrianZhang"
        },
        {
            url: "wss://api.weaccount.cn",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: btspp-witness",
            contact: "telegram:btsplusplus"
        },
        {
            url: "wss://api.bts.mobi/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "Virginia",
            operator: "Witness: in.abit",
            contact: "telegram:abitmore"
        },
        {
            url: "wss://btsws.roelandp.nl/ws",
            region: "Northern Europe",
            country: "Finland",
            location: "Helsinki",
            operator: "Witness: roelandp",
            contact: "telegram:roelandp"
        },
        {
            url: "wss://api.bitshares.bhuz.info/ws",
            region: "Northern America",
            country: "Canada",
            operator: "Witness: bhuz",
            contact: "telegram:bhuzor"
        },
        {
            url: "wss://api.btsgo.net/ws",
            region: "Southeastern Asia",
            location: "Singapore",
            operator: "Witness: xn-delegate",
            contact: "wechat:Necklace"
        },
        {
            url: "wss://bts.open.icowallet.net/ws",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: magicwallet.witness",
            contact: "telegram:plus_wave"
        },
        {
            url: "wss://freedom.bts123.cc:15138/",
            region: "Eastern Asia",
            country: "China",
            location: "Changsha",
            operator: "Witness: delegate.freedom",
            contact: "telegram:eggplant"
        },
        {
            url: "wss://bitshares.bts123.cc:15138/",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: delegate.freedom",
            contact: "telegram:eggplant"
        },
        // TODO the owner said it's temporarily closed. Recheck later.
        //{
        //    url: "wss://api.bts.ai",
        //    region: "Eastern Asia",
        //    country: "China",
        //    location: "Beijing",
        //    operator: "Witness: witness.hiblockchain",
        //    contact: "telegram:vianull;wechat:strugglingl"
        //},
        {
            url: "wss://bts-seoul.clockwork.gr",
            region: "Southeastern Asia",
            country: "Korea",
            location: "Seoul",
            operator: "Witness: clockwork",
            contact: "telegram:clockworkgr"
        },
        {
            url: "wss://api.61bts.com",
            region: "Eastern Asia",
            country: "China",
            location: "Shandong",
            operator: "Witness: liuye",
            contact: "email:work@domyself.me"
        },
        {
            url: "wss://api.dex.trading/",
            region: "Western Europe",
            country: "France",
            location: "Paris",
            operator: "Witness: zapata42-witness",
            contact: "telegram:Zapata_42"
        },
        {
            url: "wss://api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        {
            url: "wss://us.api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        {
            url: "wss://asia.api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        // TODO node is out of sync, recheck later
        //{
        //    url: "wss://citadel.li/node",
        //    region: "Western Europe",
        //    country: "Iceland",
        //    location: "Reykjavik",
        //    operator: "CITADEL",
        //    contact: "email:citadel.li;support"
        //},
        {
            url: "wss://api-bts.liondani.com/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Falkenstein",
            operator: "Witness: liondani",
            contact: "telegram:liondani"
        },
        {
            url: "wss://public.xbts.io/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Nuremberg",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://cloud.xbts.io/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "VG, Ashburn",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://node.xbts.io/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Falkenstein",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://api.gbacenter.org/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "Fremont, CA",
            operator: "Witness: gbac-ety001",
            contact: "email:work@domyself.me"
        },
        {
            url: "wss://api.cnvote.vip:888/",
            region: "Eastern Asia",
            country: "China",
            location: "Zhejiang",
            operator: "Witness: ioex",
            contact: "wechat:xiaoyuan_409"
        },
        {
            url: "wss://singapore.bitshares.im/ws",
            region: "Southeast Asia",
            country: "Singapore",
            location: "Singapore",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        {
            url: "wss://newyork.bitshares.im/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "New York",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        // Testnet
        {
            url: "wss://node.testnet.bitshares.eu",
            region: "TESTNET - Western Europe",
            country: "Germany",
            location: "Frankfurt",
            operator: "BitShares Europe",
            contact: "telegram:xeroc"
        },
        {
            url: "wss://testnet.dex.trading/",
            region: "TESTNET - Western Europe",
            country: "France",
            location: "Paris",
            operator: "Witness: zapata42-witness",
            contact: "telegram:Zapata_42"
        },
        {
            url: "wss://testnet.xbts.io/ws",
            region: "TESTNET - Europe",
            country: "Germany",
            location: "Nuremberg",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://testnet.bitshares.im/ws",
            region: "Eastern Asia",
            country: "Japan",
            location: "Tokyo",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        }

    ],
    ES_WRAPPER_LIST: [
    ],
    DEFAULT_FAUCET: getFaucet().url,
    TESTNET_FAUCET: getTestFaucet().url
};
<commit_msg>add es wrapper from blocksights<commit_after>import {getFaucet, getTestFaucet} from "../branding";

export const blockTradesAPIs = {
    BASE: "https://api.blocktrades.us/v2",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const openledgerAPIs = {
    BASE: "https://ol-api1.openledger.info/api/v0/ol/support",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount",
    RPC_URL: "https://openledger.info/api/"
};

export const rudexAPIs = {
    BASE: "https://gateway.rudex.org/api/rudex",
    COINS_LIST: "/coins",
    NEW_DEPOSIT_ADDRESS: "/simple-api/initiate-trade"
};

export const bitsparkAPIs = {
    BASE: "https://dex-api.bitspark.io/api/v1",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const cryptoBridgeAPIs = {
    BASE: "https://api.crypto-bridge.org/api/v1",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/wallets",
    MARKETS: "/markets",
    TRADING_PAIRS: "/trading-pairs"
};

export const citadelAPIs = {
    BASE: "https://citadel.li/trade",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs",
    DEPOSIT_LIMIT: "/deposit-limits",
    ESTIMATE_OUTPUT: "/estimate-output-amount",
    ESTIMATE_INPUT: "/estimate-input-amount"
};

export const gdex2APIs = {
    BASE: "https://api.gdex.io/adjust",
    COINS_LIST: "/coins",
    ACTIVE_WALLETS: "/active-wallets",
    TRADING_PAIRS: "/trading-pairs"
};

// Legacy Deposit/Withdraw
export const gdexAPIs = {
    BASE: "https://api.gdex.io",
    ASSET_LIST: "/gateway/asset/assetList",
    ASSET_DETAIL: "/gateway/asset/assetDetail",
    GET_DEPOSIT_ADDRESS: "/gateway/address/getAddress",
    CHECK_WITHDRAY_ADDRESS: "/gateway/address/checkAddress",
    DEPOSIT_RECORD_LIST: "/gateway/deposit/recordList",
    DEPOSIT_RECORD_DETAIL: "/gateway/deposit/recordDetail",
    WITHDRAW_RECORD_LIST: "/gateway/withdraw/recordList",
    WITHDRAW_RECORD_DETAIL: "/gateway/withdraw/recordDetail",
    GET_USER_INFO: "/gateway/user/getUserInfo",
    USER_AGREEMENT: "/gateway/user/isAgree",
    WITHDRAW_RULE: "/gateway/withdraw/rule"
};

export const xbtsxAPIs = {
    BASE: "https://apis.xbts.io/api/v1",
    COINS_LIST: "/coin"
};

export const nodeRegions = [
    // region of the node follows roughly https://en.wikipedia.org/wiki/Subregion#/media/File:United_Nations_geographical_subregions.png
    "Northern Europe",
    "Western Europe",
    "Southern Europe",
    "Eastern Europe",
    "Northern Asia",
    "Western Asia",
    "Southern Asia",
    "Eastern Asia",
    "Central Asia",
    "Southeastern Asia",
    "Australia and New Zealand",
    "Melanesia",
    "Polynesia",
    "Micronesia",
    "Northern Africa",
    "Western Africa",
    "Middle Africa",
    "Eastern Africa",
    "Southern Africa",
    "Northern America",
    "Central America",
    "Caribbean",
    "South America"
];

export const settingsAPIs = {
    // If you want a location to be translated, add the translation to settings in locale-xx.js
    // and use an object {translate: key} in WS_NODE_LIST
    DEFAULT_WS_NODE: "wss://fake.automatic-selection.com",
    WS_NODE_LIST: [
        {
            url: "wss://fake.automatic-selection.com",
            location: {translate: "settings.api_closest"}
        },
        {
            url: "ws://127.0.0.1:8090",
            location: "Locally hosted"
        },
        {
            url: "wss://nexus01.co.uk/ws",
            region: "Northern Europe",
            country: "England",
            location: "Gloucester",
            operator: "Witness: nexus01",
            contact: "telegram:rosswlkr"
        },
        {
            url: "wss://dex.iobanker.com/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Frankfurt",
            operator: "Witness: iobanker-core",
            contact: "email:admin@iobanker.com"
        },
        {
            url: "wss://ws.gdex.top",
            region: "Eastern Asia",
            country: "China",
            location: "Shanghai",
            operator: "Witness: gdex-witness",
            contact: "telegram:BrianZhang"
        },
        {
            url: "wss://api.weaccount.cn",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: btspp-witness",
            contact: "telegram:btsplusplus"
        },
        {
            url: "wss://api.bts.mobi/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "Virginia",
            operator: "Witness: in.abit",
            contact: "telegram:abitmore"
        },
        {
            url: "wss://btsws.roelandp.nl/ws",
            region: "Northern Europe",
            country: "Finland",
            location: "Helsinki",
            operator: "Witness: roelandp",
            contact: "telegram:roelandp"
        },
        {
            url: "wss://api.bitshares.bhuz.info/ws",
            region: "Northern America",
            country: "Canada",
            operator: "Witness: bhuz",
            contact: "telegram:bhuzor"
        },
        {
            url: "wss://api.btsgo.net/ws",
            region: "Southeastern Asia",
            location: "Singapore",
            operator: "Witness: xn-delegate",
            contact: "wechat:Necklace"
        },
        {
            url: "wss://bts.open.icowallet.net/ws",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: magicwallet.witness",
            contact: "telegram:plus_wave"
        },
        {
            url: "wss://freedom.bts123.cc:15138/",
            region: "Eastern Asia",
            country: "China",
            location: "Changsha",
            operator: "Witness: delegate.freedom",
            contact: "telegram:eggplant"
        },
        {
            url: "wss://bitshares.bts123.cc:15138/",
            region: "Eastern Asia",
            country: "China",
            location: "Hangzhou",
            operator: "Witness: delegate.freedom",
            contact: "telegram:eggplant"
        },
        // TODO the owner said it's temporarily closed. Recheck later.
        //{
        //    url: "wss://api.bts.ai",
        //    region: "Eastern Asia",
        //    country: "China",
        //    location: "Beijing",
        //    operator: "Witness: witness.hiblockchain",
        //    contact: "telegram:vianull;wechat:strugglingl"
        //},
        {
            url: "wss://bts-seoul.clockwork.gr",
            region: "Southeastern Asia",
            country: "Korea",
            location: "Seoul",
            operator: "Witness: clockwork",
            contact: "telegram:clockworkgr"
        },
        {
            url: "wss://api.61bts.com",
            region: "Eastern Asia",
            country: "China",
            location: "Shandong",
            operator: "Witness: liuye",
            contact: "email:work@domyself.me"
        },
        {
            url: "wss://api.dex.trading/",
            region: "Western Europe",
            country: "France",
            location: "Paris",
            operator: "Witness: zapata42-witness",
            contact: "telegram:Zapata_42"
        },
        {
            url: "wss://api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        {
            url: "wss://us.api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        {
            url: "wss://asia.api.bitshares.org/ws",
            region: "Western Europe",
            country: "France",
            location: "",
            operator: "bitshares.org",
            contact: ""
        },
        // TODO node is out of sync, recheck later
        //{
        //    url: "wss://citadel.li/node",
        //    region: "Western Europe",
        //    country: "Iceland",
        //    location: "Reykjavik",
        //    operator: "CITADEL",
        //    contact: "email:citadel.li;support"
        //},
        {
            url: "wss://api-bts.liondani.com/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Falkenstein",
            operator: "Witness: liondani",
            contact: "telegram:liondani"
        },
        {
            url: "wss://public.xbts.io/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Nuremberg",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://cloud.xbts.io/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "VG, Ashburn",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://node.xbts.io/ws",
            region: "Western Europe",
            country: "Germany",
            location: "Falkenstein",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://api.gbacenter.org/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "Fremont, CA",
            operator: "Witness: gbac-ety001",
            contact: "email:work@domyself.me"
        },
        {
            url: "wss://api.cnvote.vip:888/",
            region: "Eastern Asia",
            country: "China",
            location: "Zhejiang",
            operator: "Witness: ioex",
            contact: "wechat:xiaoyuan_409"
        },
        {
            url: "wss://singapore.bitshares.im/ws",
            region: "Southeast Asia",
            country: "Singapore",
            location: "Singapore",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        {
            url: "wss://newyork.bitshares.im/ws",
            region: "Northern America",
            country: "U.S.A.",
            location: "New York",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        },
        // Testnet
        {
            url: "wss://node.testnet.bitshares.eu",
            region: "TESTNET - Western Europe",
            country: "Germany",
            location: "Frankfurt",
            operator: "BitShares Europe",
            contact: "telegram:xeroc"
        },
        {
            url: "wss://testnet.dex.trading/",
            region: "TESTNET - Western Europe",
            country: "France",
            location: "Paris",
            operator: "Witness: zapata42-witness",
            contact: "telegram:Zapata_42"
        },
        {
            url: "wss://testnet.xbts.io/ws",
            region: "TESTNET - Europe",
            country: "Germany",
            location: "Nuremberg",
            operator: "Witness: xbtsio-wallet",
            contact: "telegram: xbtsio"
        },
        {
            url: "wss://testnet.bitshares.im/ws",
            region: "Eastern Asia",
            country: "Japan",
            location: "Tokyo",
            operator: "Witness: clone",
            contact: "telegram: yexiao"
        }
    ],
    ES_WRAPPER_LIST: [
        {
            url: "https://api.bitshares.ws/openexplorer",
            region: "Western Europe",
            country: "Germany",
            operator: "blocksights.info",
            contact: "bitshares:blocksights"
        }
    ],
    DEFAULT_FAUCET: getFaucet().url,
    TESTNET_FAUCET: getTestFaucet().url
};
<|endoftext|>


<commit_before>import Enemy from './Enemy.js'
class Golem extends Enemy {
  constructor(game, x, y) {
    super(game, x, y, 'golemSprite')
    this.body.clearShapes()
    this.body.addRectangle(60, 100, 0, 0)

    // Attributes
    this.body.mass = 50
    this.health = this.maxHealth = 150 + this.game.floor * 25
    this.speed = 85
    this.meleeAttackRange = 80
    this.meleeAttackPower = 20 + this.game.floor * 3
    this.meleeTTA = 1000

    this.animations.add('standing', [0], 0, false)
    this.animations.add('walking', [1, 0, 2, 0], 6, false)
    this.animations.add('meleeAttack', [3, 3, 3, 4], 4, false)
    this.play('standing')
  }

  update() {
    super.update()
  }
}

module.exports = Golem<commit_msg>Increased Golem attack damage<commit_after>import Enemy from './Enemy.js'
class Golem extends Enemy {
  constructor(game, x, y) {
    super(game, x, y, 'golemSprite')
    this.body.clearShapes()
    this.body.addRectangle(60, 100, 0, 0)

    // Attributes
    this.body.mass = 50
    this.health = this.maxHealth = 150 + this.game.floor * 25
    this.speed = 85
    this.meleeAttackRange = 90
    this.meleeAttackPower = 20 + this.game.floor * 3
    this.meleeTTA = 1000

    this.animations.add('standing', [0], 0, false)
    this.animations.add('walking', [1, 0, 2, 0], 6, false)
    this.animations.add('meleeAttack', [3, 3, 3, 4], 4, false)
    this.play('standing')
  }

  update() {
    super.update()
  }
}

module.exports = Golem<|endoftext|>


<commit_before>/**
 * Created by YouHan on 2016/4/25.
 */

(function () {

    var host = 'https://rally-test.firebaseio.com';

    var constant = {
        host: host,
        story: host + '/story',
        index: host + '/index',
        release: host + '/release',
        bug: host + '/bug'
    };

    module.exports = constant;
})();<commit_msg>add member manage page<commit_after>/**
 * Created by YouHan on 2016/4/25.
 */

(function () {

    var host = 'https://mimikiyru.firebaseio.com';

    var constant = {
        host: host,
        story: host + '/story',
        index: host + '/index',
        release: host + '/release',
        bug: host + '/bug'
    };

    module.exports = constant;
})();<|endoftext|>


<commit_before>/* @flow */
/*
---
id: declarations
title: Declarations
permalink: /docs/declarations.html
prev: modules.html
next: react.html
---
*/

/*
  Sometimes we just want to _declare_ the types of some definitions, so that
  code that _uses_ those definitions may be typechecked, without worrying about
  the code that _implements_ those definitions. The implementation code may
  simply not be available for typechecking (such as for JavaScript built-ins
  like `Math` or `Array`). Alternatively, the implementation code may be
  available but we may not want to typecheck it (yet). Declarations also enable
  a powerful modular approach to typechecking libraries, separating the checking
  of uses from the checking of implementations.

  As we shall see below, declarations can not only express types of definitions
  in global scope (variables, functions, classes), but also express signatures
  of modules.

  ## Declarations should be distinct from regular code

  Note that declarations are exclusively _compile-time_ entities: they are
  transpiled away, so they have no effect at run time. In fact, declarations
  without backing implementations may cause typechecked uses to break at run
  time! Thus, it is important to distinguish declaration code from regular code.

  In Flow, there are two recommended styles of doing declarations: let's call
  them the [".flowconfig"-style](#pointing-your-project-to-declarations) and the
  [".js.flow" style](#declaration-files). The styles differ in their generality
  and convenience, but share some important characteristics: both involve
  locating the declarations separately from regular code, and both use similar
  syntax.

  ## Pointing your project to declarations

  Let's start with the ".flowconfig" style of doing declarations.

  In this style, declarations (see below for examples) can be made visible to an
  entire project by putting them in files with extension `.js` in a directory,
  say `decls`, and putting the following in the `.flowconfig` of the project:

*/
// $DocIssue{not a flow file}
[libs]
// $DocIssue{not a flow file}
decls/

/*
  ## Declaring definitions that should exist at run time

  Here's a simple example, where we declare a global variable.
*/
declare var DEBUG: bool;

/*
  Other global definitions, like functions and classes, can similarly be
  declared. Note how function and method bodies are elided.
*/
declare function isLeapYear(year: string): bool;

declare class Counter {
  val: number;
  incr(): void;
}

/*
  Such declarations can be made visible to all modules in a project (see
  [above](#pointing-your-project-to-declarations)). This means that any code
  that uses these definitions in a typesafe manner will typecheck.
*/
if (isLeapYear('2016')) console.log('Yay!');

/*
  Note that it is entirely up to the programmer to ensure that declared
  definitions actually exist, and have the correct types.

  ## Mixins

  You can declare a class which mixes in 1 or more other classes with the
  `mixins` keyword. Mixing class `B` into class `A` copies `B`'s fields and
  methods into `A`. Note, however, that any fields or methods that `B` inherits
  are not copied over. Mixins are for code reuse, not for multiple inheritance.
*/

// You can mixin more than one class
declare class MyClass extends Child mixins MixinA, MixinB {}
declare class MixinA {
  a: number;
  b: number;
}
// Mixing in MixinB will NOT mix in MixinBase
declare class MixinB extends MixinBase {}
declare class MixinBase {
  c: number;
}
declare class Child extends Base {
  a: string;
  c: string;
}
declare class Base {
  b: string;
}

var c = new MyClass();
(c.a: number); // Both Child and MixinA provide `a`, so MixinA wins
(c.b: number); // The same principle holds for `b`, which Child inherits
(c.c: string); // mixins does not copy inherited properties,
               // so `c` comes from Child

/*
  ## Declaring types

  It is similarly useful to declare types. Like other declarations, type
  declarations can also be made visible to all modules in a project.
*/

/*
  Declared types include type aliases and interfaces; in fact, they share the
  same syntax as usual types, so the `declare` keyword is superfluous.
*/
declare type Response = 'yes' | 'no' | 'maybe';

declare interface Stack<T> {
  push(item: T): void;
  pop(): T;
  isEmpty(): bool;
}

/*
  ## Declaring modules

  Finally, modules can be declared as well. Like definitions that should exist
  at run time, it is up to the programmer to ensure that the declared modules
  actually exist at run time.

  Declaring a module consists of naming the module and declaring its exports. Of
  course, the exports can be variables, functions, classes, as well as type
  aliases and interfaces. Thus it is not surprising that they share exactly the
  same syntax as the declarations above, except that they are now scoped to the
  module, instead of globally.
*/
declare module Misc {
  declare var DEBUG: bool;
  declare function isLeapYear(year: string): bool;
  declare class Counter {
    val: number;
    incr(): void;
  }
  declare type Response = 'yes' | 'no' | 'maybe';
  declare interface Stack<T> {
    push(item: T): void;
    pop(): T;
    isEmpty(): bool;
  }
}

/*
  Note that a declared module should have a global name. (This can sometimes be
  a limitation; see [below](#declaration-files).) The global name could be any
  string, though: it need not be an identifier. So the following also works:
*/
declare module "fancy-pants" {
  // ...
}

/*
  A declared module would be looked up by the typechecker only when a file
  implementing that module was not found by [the resolution algorithm of the
  module system](modules.html#module-resolution), or such a file was found but
  not [checked](new-project.html#typechecking-your-files). For example, suppose
  we have the following code in a file `src/LookBeforeYouLeap.js`:
*/
// @flow
// $DocIssue{module should be found given an appropriate setup}
import { isLeapYear } from 'Misc';
if (isLeapYear('2016')) console.log('Yay!');

/*
  If the import successfully resolves to (say) a file
  `src/node_modules/Misc/index.js` with the following code, then we would get a
  Flow error, since the parameter of `isLeapYear` expects a `number`.
*/
// @flow
export function isLeapYear(year: number): bool {
  return (year % 4 == 0); // yeah, this is approximate
}

/*
  But on the other hand, if the above file doesn't exist or we remove the
  `@flow` header then we would *not* get a Flow error, since the parameter of
  `isLeapYear` in the declared module `Misc` expects a `string`.

  ## Declaration files

  Now, let's look at a more general, and sometimes more convenient, way to
  declare types for modules: the ".js.flow" style.

  The exported types of a module may be declared in a _declaration file_ with
  the `.js.flow` extension, colocated with the corresponding _implementation
  file_ with the `.js` extension. A declaration file for a module shadows a
  colocated implementation file for that module when typechecking other code
  that may depend on that module.

  For example, looking back at the file `src/LookBeforeYouLeap.js`, suppose it
  instead had the following code (note the relative-path import):
*/
// @flow
// $DocIssue{module should be found given an appropriate setup}
import { isLeapYear } from './Misc';
if (isLeapYear('2016')) console.log('Yay!');

/*
  Next, suppose that `src/Misc.js` had an incompatible implementation of
  `isLeapYear`, just as above.
*/
// @flow
export function isLeapYear(year: number): bool {
  return (year % 4 == 0); // yeah, this is approximate
}

/*
  If we now create a declaration file `src/Misc.js.flow`, the declarations in it
  will be used instead of the code in `src/Misc.js`. Let's say we have the
  following declarations in `src/Misc.js.flow`. Note that the syntax for
  declarations in a declaration file is the same as we've seen above, except
  that we also write the keyword `export`, like we would in an implementation
  file.
*/
declare export function isLeapYear(year: string): bool;

/*
  What do you think will happen? Right, the `isLeapYear` call in
  `src/LookBeforeYouLeap.js` will typecheck.

  As this example shows, declaration files must be written with care: it is up
  to the programmer to ensure they are correct, otherwise they may hide type
  errors.

  That said, declaration files provide a very convenient way to write
  specifications for modular typechecking. Sometimes, the implementation code
  may not yet be free of type errors, but we may want to move on and come back
  to fixing the type errors later. Another important use of this feature is for
  libraries, whose implementation code may be too complex to typecheck
  satisfactorily, but whose clients we still want to typecheck against
  well-defined specifications.

  ## Inlining declarations in regular code

  As noted above, declarations should be distinct from regular code. But
  sometimes, it is useful to do declarations "inline," as part of the source of
  an implementation file. **Proceed with caution!**

  The most common use is writing "work-in-progress" code while ensuring that
  your code typechecks. In the following example, say you want to finish writing
  the function `fooList` without bothering to mock up its dependencies first: a
  function `foo` that takes a `number`, and returns a `string` and a class
  `List` that has a `map` method. Easy! (Just don't forget to replace the
  declarations with proper implementations.)
*/
declare class List<T> {
  map<U>(f: (x: T) => U): List<U>;
}
declare function foo(n: number): string;

function fooList(ns: List<number>): List<string> {
  return ns.map(foo);
}
<commit_msg>add @flow comment to .js.flow style file<commit_after>/* @flow */
/*
---
id: declarations
title: Declarations
permalink: /docs/declarations.html
prev: modules.html
next: react.html
---
*/

/*
  Sometimes we just want to _declare_ the types of some definitions, so that
  code that _uses_ those definitions may be typechecked, without worrying about
  the code that _implements_ those definitions. The implementation code may
  simply not be available for typechecking (such as for JavaScript built-ins
  like `Math` or `Array`). Alternatively, the implementation code may be
  available but we may not want to typecheck it (yet). Declarations also enable
  a powerful modular approach to typechecking libraries, separating the checking
  of uses from the checking of implementations.

  As we shall see below, declarations can not only express types of definitions
  in global scope (variables, functions, classes), but also express signatures
  of modules.

  ## Declarations should be distinct from regular code

  Note that declarations are exclusively _compile-time_ entities: they are
  transpiled away, so they have no effect at run time. In fact, declarations
  without backing implementations may cause typechecked uses to break at run
  time! Thus, it is important to distinguish declaration code from regular code.

  In Flow, there are two recommended styles of doing declarations: let's call
  them the [".flowconfig"-style](#pointing-your-project-to-declarations) and the
  [".js.flow" style](#declaration-files). The styles differ in their generality
  and convenience, but share some important characteristics: both involve
  locating the declarations separately from regular code, and both use similar
  syntax.

  ## Pointing your project to declarations

  Let's start with the ".flowconfig" style of doing declarations.

  In this style, declarations (see below for examples) can be made visible to an
  entire project by putting them in files with extension `.js` in a directory,
  say `decls`, and putting the following in the `.flowconfig` of the project:

*/
// $DocIssue{not a flow file}
[libs]
// $DocIssue{not a flow file}
decls/

/*
  ## Declaring definitions that should exist at run time

  Here's a simple example, where we declare a global variable.
*/
declare var DEBUG: bool;

/*
  Other global definitions, like functions and classes, can similarly be
  declared. Note how function and method bodies are elided.
*/
declare function isLeapYear(year: string): bool;

declare class Counter {
  val: number;
  incr(): void;
}

/*
  Such declarations can be made visible to all modules in a project (see
  [above](#pointing-your-project-to-declarations)). This means that any code
  that uses these definitions in a typesafe manner will typecheck.
*/
if (isLeapYear('2016')) console.log('Yay!');

/*
  Note that it is entirely up to the programmer to ensure that declared
  definitions actually exist, and have the correct types.

  ## Mixins

  You can declare a class which mixes in 1 or more other classes with the
  `mixins` keyword. Mixing class `B` into class `A` copies `B`'s fields and
  methods into `A`. Note, however, that any fields or methods that `B` inherits
  are not copied over. Mixins are for code reuse, not for multiple inheritance.
*/

// You can mixin more than one class
declare class MyClass extends Child mixins MixinA, MixinB {}
declare class MixinA {
  a: number;
  b: number;
}
// Mixing in MixinB will NOT mix in MixinBase
declare class MixinB extends MixinBase {}
declare class MixinBase {
  c: number;
}
declare class Child extends Base {
  a: string;
  c: string;
}
declare class Base {
  b: string;
}

var c = new MyClass();
(c.a: number); // Both Child and MixinA provide `a`, so MixinA wins
(c.b: number); // The same principle holds for `b`, which Child inherits
(c.c: string); // mixins does not copy inherited properties,
               // so `c` comes from Child

/*
  ## Declaring types

  It is similarly useful to declare types. Like other declarations, type
  declarations can also be made visible to all modules in a project.
*/

/*
  Declared types include type aliases and interfaces; in fact, they share the
  same syntax as usual types, so the `declare` keyword is superfluous.
*/
declare type Response = 'yes' | 'no' | 'maybe';

declare interface Stack<T> {
  push(item: T): void;
  pop(): T;
  isEmpty(): bool;
}

/*
  ## Declaring modules

  Finally, modules can be declared as well. Like definitions that should exist
  at run time, it is up to the programmer to ensure that the declared modules
  actually exist at run time.

  Declaring a module consists of naming the module and declaring its exports. Of
  course, the exports can be variables, functions, classes, as well as type
  aliases and interfaces. Thus it is not surprising that they share exactly the
  same syntax as the declarations above, except that they are now scoped to the
  module, instead of globally.
*/
declare module Misc {
  declare var DEBUG: bool;
  declare function isLeapYear(year: string): bool;
  declare class Counter {
    val: number;
    incr(): void;
  }
  declare type Response = 'yes' | 'no' | 'maybe';
  declare interface Stack<T> {
    push(item: T): void;
    pop(): T;
    isEmpty(): bool;
  }
}

/*
  Note that a declared module should have a global name. (This can sometimes be
  a limitation; see [below](#declaration-files).) The global name could be any
  string, though: it need not be an identifier. So the following also works:
*/
declare module "fancy-pants" {
  // ...
}

/*
  A declared module would be looked up by the typechecker only when a file
  implementing that module was not found by [the resolution algorithm of the
  module system](modules.html#module-resolution), or such a file was found but
  not [checked](new-project.html#typechecking-your-files). For example, suppose
  we have the following code in a file `src/LookBeforeYouLeap.js`:
*/
// @flow
// $DocIssue{module should be found given an appropriate setup}
import { isLeapYear } from 'Misc';
if (isLeapYear('2016')) console.log('Yay!');

/*
  If the import successfully resolves to (say) a file
  `src/node_modules/Misc/index.js` with the following code, then we would get a
  Flow error, since the parameter of `isLeapYear` expects a `number`.
*/
// @flow
export function isLeapYear(year: number): bool {
  return (year % 4 == 0); // yeah, this is approximate
}

/*
  But on the other hand, if the above file doesn't exist or we remove the
  `@flow` header then we would *not* get a Flow error, since the parameter of
  `isLeapYear` in the declared module `Misc` expects a `string`.

  ## Declaration files

  Now, let's look at a more general, and sometimes more convenient, way to
  declare types for modules: the ".js.flow" style.

  The exported types of a module may be declared in a _declaration file_ with
  the `.js.flow` extension, colocated with the corresponding _implementation
  file_ with the `.js` extension. A declaration file for a module shadows a
  colocated implementation file for that module when typechecking other code
  that may depend on that module.

  For example, looking back at the file `src/LookBeforeYouLeap.js`, suppose it
  instead had the following code (note the relative-path import):
*/
// @flow
// $DocIssue{module should be found given an appropriate setup}
import { isLeapYear } from './Misc';
if (isLeapYear('2016')) console.log('Yay!');

/*
  Next, suppose that `src/Misc.js` had an incompatible implementation of
  `isLeapYear`, just as above.
*/
// @flow
export function isLeapYear(year: number): bool {
  return (year % 4 == 0); // yeah, this is approximate
}

/*
  If we now create a declaration file `src/Misc.js.flow`, the declarations in it
  will be used instead of the code in `src/Misc.js`. Let's say we have the
  following declarations in `src/Misc.js.flow`. Note that the syntax for
  declarations in a declaration file is the same as we've seen above, except
  that we also write the keyword `export`, like we would in an implementation
  file.
*/
// @flow
declare export function isLeapYear(year: string): bool;

/*
  What do you think will happen? Right, the `isLeapYear` call in
  `src/LookBeforeYouLeap.js` will typecheck.

  As this example shows, declaration files must be written with care: it is up
  to the programmer to ensure they are correct, otherwise they may hide type
  errors.

  That said, declaration files provide a very convenient way to write
  specifications for modular typechecking. Sometimes, the implementation code
  may not yet be free of type errors, but we may want to move on and come back
  to fixing the type errors later. Another important use of this feature is for
  libraries, whose implementation code may be too complex to typecheck
  satisfactorily, but whose clients we still want to typecheck against
  well-defined specifications.

  ## Inlining declarations in regular code

  As noted above, declarations should be distinct from regular code. But
  sometimes, it is useful to do declarations "inline," as part of the source of
  an implementation file. **Proceed with caution!**

  The most common use is writing "work-in-progress" code while ensuring that
  your code typechecks. In the following example, say you want to finish writing
  the function `fooList` without bothering to mock up its dependencies first: a
  function `foo` that takes a `number`, and returns a `string` and a class
  `List` that has a `map` method. Easy! (Just don't forget to replace the
  declarations with proper implementations.)
*/
declare class List<T> {
  map<U>(f: (x: T) => U): List<U>;
}
declare function foo(n: number): string;

function fooList(ns: List<number>): List<string> {
  return ns.map(foo);
}
<|endoftext|>


<commit_before>import {replaceSelectedText} from '../lib/rangy';

// This driver consumes an Observable of objects
// {element, string} and insertes string into the element
export const insertStringDriver = (insertion$) => {
  insertion$.subscribe((insertion) => {
    replaceSelectedText(insertion.element, insertion.string, "collapseToEnd");
  });

  return Object.create(null);
};
<commit_msg>trigger input event when inserting text<commit_after>import {replaceSelectedText} from '../lib/rangy';

const triggerInputEvent = (element) => {
  if ("createEvent" in document) {
    const evt = document.createEvent("MutationEvents");
    evt.initEvent("input", true, true);
    element.dispatchEvent(evt);
  } else {
    element.fireEvent("oninput");
  }
};

// This driver consumes an Observable of objects
// {element, string} and insertes string into the element
export const insertStringDriver = (insertion$) => {
  insertion$.subscribe((insertion) => {
    const element = insertion.element;
    replaceSelectedText(element, insertion.string, "collapseToEnd");
    triggerInputEvent(element);
  });

  return Object.create(null);
};
<|endoftext|>