<commit_before>/**
 * Default settings
 */
window.DAYBED_SETTINGS = window.DAYBED_SETTINGS || {
    SERVER: "localhost:8000"
};

//
//  Item : a record
//
var Item = Backbone.Model.extend({
});

var ItemList = Backbone.Collection.extend({
    model: Item,

    initialize: function (definition) {
        this.definition = definition;
    },

    url: function () {
        return URI.build({hostname: window.DAYBED_SETTINGS.SERVER,
                          path: '/data/' + this.definition.id});
    },

    parse: function(response) {
        return response.data;
    },

    /**
     * Override instanciation to link with Definition instance.
     */
    _prepareModel: function() {
        var m = Backbone.Collection.prototype._prepareModel.apply(this, arguments);
        m.definition = this.definition;
        return m;
    }
});

//
//  Definition : a model
//
var Definition = Backbone.Model.extend({
    url: function () {
        return URI.build({hostname: DAYBED_SETTINGS.SERVER,
                          path: 'definitions/' + this.id});
    },

    /**
     * Backbone.forms schema for Definition forms
     */
    schema: {
        id:  { type: 'Hidden', title: '' },
        title: 'Text',
        description: 'Text',
        fields: { type: 'List', itemType: 'Object', subSchema: {
            name: { validators: ['required'] },
            description: 'Text',
            required: { type: 'Checkbox', editorAttrs: { 'checked' : 'checked' } },
            type: { type: 'Select', options: ['int', 'string', 'decimal', 'boolean',
                                              'email', 'url', 'point', 'line', 'polygon'] }
        }}
    },

    /**
     * @returns {boolean} True if *Definition* is initialized (fetched from server)
     */
    isReady: function () {
        return this.attributes.fields && this.attributes.fields.length > 0;
    },

    /**
     * Calls ``cb`` when *Definition* was fetched from server.
     * @param {function} cb
     */
    whenReady: function (cb) {
        if (this.isReady())
            cb();
        else {
            this.once('change', function () {
                this.whenReady(cb);
            }, this);
        }
    },

    /**
     * Builds a Backbone.forms schema from the *Definition* record,
     * for {Item} forms.
     * For each model field, add a Backbone.forms declaration.
     * @returns {Object}
     */
    itemSchema: function () {
        if (!this.isReady())
            throw "Definition is not ready. Fetch it first.";
        var typeMapping = {
            'int': 'Number',
            'string': 'Text',
            'boolean': 'Checkbox'
        };
        var geom = function (f) {
            return {type: 'TextArea',
                    editorAttrs: {style: 'display: none'},
                    help: f.description + ' (on map)'};
        };
        var fieldMapping = {
            'default': function (f) {
                var d = {help: f.description},
                    t = typeMapping[f.type];
                if (t) d.type = t;
                return d;
            },
            'decimal': function (f) {
                var d = fieldMapping['default'](f);
                d.editorAttrs = {pattern: '[-+]?[0-9]*\\.?[0-9]+'};
                return d;
            },
            'email': function (f) {
                var d = fieldMapping['default'](f);
                d.validators = ['required', 'email'];
                return d;
            },
            'url': function (f) {
                var d = fieldMapping['default'](f);
                d.validators = ['required', 'url'];
                return d;
            },
            'point': geom,
            'line': geom,
            'polygon': geom
        };
        var schema = {};
        // Add Backbone.Forms fields from Daybed definition
        $(this.attributes.fields).each(function (i, field) {
            var defaultschema = fieldMapping['default'],
                build = fieldMapping[field.type] || defaultschema;
            schema[field.name] = build(field);
        });
        return schema;
    },

    /**
     * Returns field names that are not of type geometry.
     * @returns {Array[string]}
     */
    mainFields: function () {
        var geomField = this.geomField();
        if (!geomField)
            return this.attributes.fields;
        return this.attributes.fields.filter(function (f) {
            return f.name != geomField.name;
        });
    },

    /**
     * Returns the first field whose type is Geometry.
     * @returns {string} ``null`` if no geometry field in *Definition*
     */
    geomField: function () {
        for (var i in this.attributes.fields) {
            var f = this.attributes.fields[i];
            if (f.type == 'point' || f.type == 'line' || f.type == 'polygon')
                return f;
        }
        return null;
    }
});

//
// FormView : Generic Backbone form
//
var FormView = Backbone.View.extend({
    model: Item,
    tagName: "div",
    className: "well",

    template: Mustache.compile('
{{ title }}
' +
                               '

' +
                               'Cancel ' +
                               'Save'),
    templateError: Mustache.compile('{{ msg }}'),

    events: {
        "click #submit": "submit",
        "click #cancel": "cancel"
    },

    initialize: function () {
        this.instance = new this.model({});
        if (!this.instance.schema && this.options.definition) {
            this.instance.definition = this.options.definition;
            this.instance.schema = this.options.definition.itemSchema();
        }
        this.form = new Backbone.Form({
            model: this.instance
        });
    },

    render: function () {
        this.$el.html(this.template(this));
        this.$('#form').html(this.form.render().el);
        this.delegateEvents();
        this.instance.on('change', this.refresh.bind(this));
        this.instance.on('sync', this.success.bind(this));
        this.instance.on('error', this.showErrors.bind(this));
        this.instance.trigger('change');
        return this;
    },

    cancel: function (e) {
        e.preventDefault();
        return false;
    },

    submit: function(e) {
        e.preventDefault();
        this.$el.find('.field-error').remove();
        this.form.commit();
        return false;
    },

    success: function (model, response, options) {
        return false;
    },

    showErrors: function (model, xhr, options) {
        try {
            var descriptions = JSON.parse(xhr.responseText);
            $(descriptions.errors).each((function (i, e) {
                var name = e.name.split('.')[0];
                this.$el.find("[name='" + name + "']")
                    .after(this.templateError({msg: e.description}));
            }).bind(this));
        }
        catch (e) {
            this.$el.html(this.templateError({msg: xhr.responseText}));
        }
    },

    /**
     * Refresh field values from instance attributes.
     */
    refresh: function () {
        for (var f in this.instance.changed) {
            if (f == 'id') continue;
            var formfield = this.$('[name='+ f + ']');
            if (formfield.length === 0)
                console.warn("Could not find form field '" + f + "'");
            formfield.val(this.instance.get(f));
        }
    }
});
<commit_msg>Move notions of geometries to daybed-map<commit_after>/**
 * Default settings
 */
window.DAYBED_SETTINGS = window.DAYBED_SETTINGS || {
    SERVER: "localhost:8000"
};

//
//  Item : a record
//
var Item = Backbone.Model.extend({
});

var ItemList = Backbone.Collection.extend({
    model: Item,

    initialize: function (definition) {
        this.definition = definition;
    },

    url: function () {
        return URI.build({hostname: window.DAYBED_SETTINGS.SERVER,
                          path: '/data/' + this.definition.id});
    },

    parse: function(response) {
        return response.data;
    },

    /**
     * Override instanciation to link with Definition instance.
     */
    _prepareModel: function() {
        var m = Backbone.Collection.prototype._prepareModel.apply(this, arguments);
        m.definition = this.definition;
        return m;
    }
});

//
//  Definition : a model
//
var Definition = Backbone.Model.extend({
    url: function () {
        return URI.build({hostname: DAYBED_SETTINGS.SERVER,
                          path: 'definitions/' + this.id});
    },

    /**
     * Backbone.forms schema for Definition forms
     */
    schema: {
        id:  { type: 'Hidden', title: '' },
        title: 'Text',
        description: 'Text',
        fields: { type: 'List', itemType: 'Object', subSchema: {
            name: { validators: ['required'] },
            description: 'Text',
            required: { type: 'Checkbox', editorAttrs: { 'checked' : 'checked' } },
            type: { type: 'Select', options: ['int', 'string', 'decimal', 'boolean',
                                              'email', 'url', 'point', 'line', 'polygon'] }
        }}
    },

    /**
     * @returns {boolean} True if *Definition* is initialized (fetched from server)
     */
    isReady: function () {
        return this.attributes.fields && this.attributes.fields.length > 0;
    },

    /**
     * Calls ``cb`` when *Definition* was fetched from server.
     * @param {function} cb
     */
    whenReady: function (cb) {
        if (this.isReady())
            cb();
        else {
            this.once('change', function () {
                this.whenReady(cb);
            }, this);
        }
    },

    /**
     * Builds a Backbone.forms schema from the *Definition* record,
     * for {Item} forms.
     * For each model field, add a Backbone.forms declaration.
     * @returns {Object}
     */
    itemSchema: function () {
        if (!this.isReady())
            throw "Definition is not ready. Fetch it first.";
        var typeMapping = {
            'int': 'Number',
            'string': 'Text',
            'boolean': 'Checkbox'
        };
        var fieldMapping = {
            'default': function (f) {
                var d = {help: f.description},
                    t = typeMapping[f.type];
                if (t) d.type = t;
                return d;
            },
            'decimal': function (f) {
                var d = fieldMapping['default'](f);
                d.editorAttrs = {pattern: '[-+]?[0-9]*\\.?[0-9]+'};
                return d;
            },
            'email': function (f) {
                var d = fieldMapping['default'](f);
                d.validators = ['required', 'email'];
                return d;
            },
            'url': function (f) {
                var d = fieldMapping['default'](f);
                d.validators = ['required', 'url'];
                return d;
            }
        };
        var schema = {};
        // Add Backbone.Forms fields from Daybed definition
        $(this.attributes.fields).each(function (i, field) {
            var defaultschema = fieldMapping['default'],
                build = fieldMapping[field.type] || defaultschema;
            schema[field.name] = build(field);
        });
        return schema;
    }
});

//
// FormView : Generic Backbone form
//
var FormView = Backbone.View.extend({
    model: Item,
    tagName: "div",
    className: "well",

    template: Mustache.compile('
{{ title }}
' +
                               '

' +
                               'Cancel ' +
                               'Save'),
    templateError: Mustache.compile('{{ msg }}'),

    events: {
        "click #submit": "submit",
        "click #cancel": "cancel"
    },

    initialize: function () {
        this.instance = new this.model({});
        if (!this.instance.schema && this.options.definition) {
            this.instance.definition = this.options.definition;
            this.instance.schema = this.options.definition.itemSchema();
        }
        this.form = new Backbone.Form({
            model: this.instance
        });
    },

    render: function () {
        this.$el.html(this.template(this));
        this.$('#form').html(this.form.render().el);
        this.delegateEvents();
        this.instance.on('change', this.refresh.bind(this));
        this.instance.on('sync', this.success.bind(this));
        this.instance.on('error', this.showErrors.bind(this));
        this.instance.trigger('change');
        return this;
    },

    cancel: function (e) {
        e.preventDefault();
        return false;
    },

    submit: function(e) {
        e.preventDefault();
        this.$el.find('.field-error').remove();
        this.form.commit();
        return false;
    },

    success: function (model, response, options) {
        return false;
    },

    showErrors: function (model, xhr, options) {
        try {
            var descriptions = JSON.parse(xhr.responseText);
            $(descriptions.errors).each((function (i, e) {
                var name = e.name.split('.')[0];
                this.$el.find("[name='" + name + "']")
                    .after(this.templateError({msg: e.description}));
            }).bind(this));
        }
        catch (e) {
            this.$el.html(this.templateError({msg: xhr.responseText}));
        }
    },

    /**
     * Refresh field values from instance attributes.
     */
    refresh: function () {
        for (var f in this.instance.changed) {
            if (f == 'id') continue;
            var formfield = this.$('[name='+ f + ']');
            if (formfield.length === 0)
                console.warn("Could not find form field '" + f + "'");
            formfield.val(this.instance.get(f));
        }
    }
});
<|endoftext|>


<commit_before>// User Welcome controller
App.UserWelcomeController = Ember.Controller.extend({

	needs : 'clusterCreate',
	// output message of create cluster script
	output_message : '',
	// flag to see if the transition is from create cluster button
	create_cluster_start : false,

	sortedclusters : [],
	column : '',
	sortdir : null,
	sortbyname : false,
	sortbystatus : false,
	sortbysize : false,
	sortbyurl : false,
	confirm : false,
	ip_of_master : '',
	sortedCollection : function() {
		// sorts content (clusters) based on properties
		return Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, {
			content : this.get('sortedclusters'),
			sortProperties : [this.get('column')],
			sortAscending : this.get('sortdir')
		});
	}.property('sortdir', 'sortbyname', 'sortbystatus', 'sortbysize', 'sortbyurl'),
	actions : {
		// sorts clusters based on selected column (name, status, size, IP)
		sortBy : function(clusters, column) {
			switch (column) {
			case 'cluster_name':
				this.set('sortbyname', !this.get('sortbyname'));
				this.set('sortdir', this.get('sortbyname'));
				break;
			case 'cluster_status':
				this.set('sortbystatus', !this.get('sortbystatus'));
				this.set('sortdir', this.get('sortbystatus'));
				break;
			case 'cluster_size':
				this.set('sortbysize', !this.get('sortbysize'));
				this.set('sortdir', this.get('sortbysize'));
				break;
			case 'master_IP':
				this.set('sortbyurl', !this.get('sortbyurl'));
				this.set('sortdir', this.get('sortbyurl'));
				break;
			}
			this.set('sortedclusters', clusters);
			this.set('column', column);
		},
		go_to_confirm : function(master_IP) {
			this.set('confirm', true);
			this.set('ip_of_master', master_IP);
			alert(master_IP);
		},
		go_to_destroy : function(master_IP) {

		},
		timer : function(status, store) {
			var that = this;
			if (Ember.isNone(this.get('timer'))) {
				this.set('timer', App.Ticker.create({
					seconds : 5,
					onTick : function() {
						var promise = store.fetch('user', 1);
						promise.then(function(user) {
							// success
							var num_records = user.get('clusters').get('length');
							var bPending = false;
							for ( i = 0; i < num_records; i++) {
								if (user.get('clusters').objectAt(i).get('cluster_status') == '2') {
									bPending = true;
									break;
								}
							}
							if (!bPending) {
								that.get('timer').stop();
								status = false;
							}
						}, function(reason) {
							console.log(reason);
						});
						return promise;
					}
				}));
			}
			if (status) {
				this.get('timer').start();
			} else {
				this.get('timer').stop();
			}
		},
	},
});
<commit_msg>fix for store being undefined if polling stops without a route transition<commit_after>// User Welcome controller
App.UserWelcomeController = Ember.Controller.extend({

	needs : 'clusterCreate',
	// output message of create cluster script
	output_message : '',
	// flag to see if the transition is from create cluster button
	create_cluster_start : false,

	sortedclusters : [],
	column : '',
	sortdir : null,
	sortbyname : false,
	sortbystatus : false,
	sortbysize : false,
	sortbyurl : false,
	confirm : false,
	ip_of_master : '',
	sortedCollection : function() {
		// sorts content (clusters) based on properties
		return Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, {
			content : this.get('sortedclusters'),
			sortProperties : [this.get('column')],
			sortAscending : this.get('sortdir')
		});
	}.property('sortdir', 'sortbyname', 'sortbystatus', 'sortbysize', 'sortbyurl'),
	actions : {
		// sorts clusters based on selected column (name, status, size, IP)
		sortBy : function(clusters, column) {
			switch (column) {
			case 'cluster_name':
				this.set('sortbyname', !this.get('sortbyname'));
				this.set('sortdir', this.get('sortbyname'));
				break;
			case 'cluster_status':
				this.set('sortbystatus', !this.get('sortbystatus'));
				this.set('sortdir', this.get('sortbystatus'));
				break;
			case 'cluster_size':
				this.set('sortbysize', !this.get('sortbysize'));
				this.set('sortdir', this.get('sortbysize'));
				break;
			case 'master_IP':
				this.set('sortbyurl', !this.get('sortbyurl'));
				this.set('sortdir', this.get('sortbyurl'));
				break;
			}
			this.set('sortedclusters', clusters);
			this.set('column', column);
		},
		go_to_confirm : function(master_IP) {
			this.set('confirm', true);
			this.set('ip_of_master', master_IP);
			alert(master_IP);
		},
		go_to_destroy : function(master_IP) {

		},
		timer : function(status, store) {
			var that = this;
			if (Ember.isNone(this.get('timer'))) {
				this.set('timer', App.Ticker.create({
					seconds : 5,
					onTick : function() {
						if (!store){
							store = this.store;
						}
						var promise = store.fetch('user', 1);
						promise.then(function(user) {
							// success
							var num_records = user.get('clusters').get('length');
							var bPending = false;
							for ( i = 0; i < num_records; i++) {
								if (user.get('clusters').objectAt(i).get('cluster_status') == '2') {
									bPending = true;
									break;
								}
							}
							if (!bPending) {
								that.get('timer').stop();
								status = false;
							}
						}, function(reason) {
							console.log(reason);
						});
						return promise;
					}
				}));
			}
			if (status) {
				this.get('timer').start();
			} else {
				this.get('timer').stop();
			}
		},
	},
});
<|endoftext|>


<commit_before>'use strict';

var m = require('mithril');
var URI = require('URIjs');
var $ = require('jquery');

var Fangorn = require('js/fangorn');
var waterbutler = require('js/waterbutler');
var $osf = require('js/osfHelpers');

function changeState(grid, item, version) {
    item.data.version = version;
    grid.updateFolder(null, item);
}

function _downloadEvent(event, item, col) {
    event.stopPropagation();
    window.location = waterbutler.buildTreeBeardDownload(item, {path: item.data.extra.fileId});
}

// Define Fangorn Button Actions
var _dataverseItemButtons = {
    view: function (ctrl, args, children) {
        var buttons = [];
        var tb = args.treebeard;
        var item = args.item;
        function _uploadEvent(event, item, col) {
            event.stopPropagation();
            tb.dropzone.hiddenFileInput.click();
            tb.dropzoneItemCache = item;
        }
        function dataversePublish(event, item, col) {
            var both = !item.data.dataverseIsPublished;
            var url = item.data.urls.publish;
            var toPublish = both ? 'Dataverse and dataset' : 'dataset';
            var modalContent = [
                m('h3', 'Publish this ' + toPublish + '?'),
                m('p.m-md', both ? 'This dataset cannot be published until ' + item.data.dataverse + ' Dataverse is published. ' : ''),
                m('p.m-md', 'By publishing this ' + toPublish + ', all content will be made available through the Harvard Dataverse using their internal privacy settings, regardless of your OSF project settings. '),
                m('p.font-thick.m-md', both ? 'Do you want to publish this Dataverse AND this dataset?' : 'Are you sure you want to publish this dataset?')
            ];
            var modalActions = [
                m('button.btn.btn-default.m-sm', {
                    'onclick': function () {
                        tb.modal.dismiss();
                    }
                }, 'Cancel'),
                m('button.btn.btn-primary.m-sm', {
                    'onclick': function () {
                        publishDataset();
                    }
                }, 'Publish ' + toPublish)
            ];

            tb.modal.update(modalContent, modalActions);

            function publishDataset() {
                tb.modal.dismiss();
                item.notify.update('Publishing ' + toPublish, 'info', 1, 1);
                $.osf.putJSON(
                    url,
                    {'publish_both': both}
                ).done(function (data) {
                    item.notify.update();
                    var modalContent = [
                        m('p.m-md', 'Your content has been published.')
                    ];
                    var modalActions = [
                        m('button.btn.btn-primary.m-sm', {
                            'onclick': function () {
                                tb.modal.dismiss();
                            }
                        }, 'Okay')
                    ];
                    tb.modal.update(modalContent, modalActions);
                    item.data.dataverseIsPublished = true;
                    item.data.hasPublishedFiles = item.children.length > 0;
                    item.data.version = item.data.hasPublishedFiles ? 'latest-published' : 'latest';
                }).fail(function (xhr, status, error) {
                    var statusCode = xhr.responseJSON.code;
                    var message;
                    switch (statusCode) {
                    case 405:
                        message = 'Error: This dataset cannot be published until ' + item.data.dataverse + ' Dataverse is published.';
                        break;
                    case 409:
                        message = 'This dataset version has already been published.';
                        break;
                    default:
                        message = 'Error: Something went wrong when attempting to publish your dataset.';
                        Raven.captureMessage('Could not publish dataset', {
                            url: url,
                            textStatus: status,
                            error: error
                        });
                    }

                    var modalContent = [
                        m('p.m-md', message)
                    ];
                    var modalActions = [
                        m('button.btn.btn-primary.m-sm', {
                            'onclick': function () {
                                tb.modal.dismiss();
                            }
                        }, 'Okay')
                    ];
                    tb.modal.update(modalContent, modalActions);
                });
            }
        }
        if (item.data.addonFullname) {
            var options = [
                m('option', {selected: item.data.version === 'latest-published', value: 'latest-published'}, 'Published'),
                m('option', {selected: item.data.version === 'latest', value: 'latest'}, 'Draft')
            ];
            buttons.push(
                m.component(Fangorn.Components.dropdown, {
                    'label': 'Version: ',
                    onchange: function (e) {
                        changeState(tb, item, e.target.value);
                    },
                    icon: 'fa fa-external-link',
                    className: 'text-info'
                }, options)
            );
        }
        if (item.kind === 'folder' && item.data.addonFullname && item.data.version === 'latest' && item.data.permissions.edit) {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        _uploadEvent.call(tb, event, item);
                    },
                    icon: 'fa fa-upload',
                    className: 'text-success'
                }, 'Upload'),
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        dataversePublish.call(tb, event, item);
                    },
                    icon: 'fa fa-globe',
                    className: 'text-primary'
                }, 'Publish')
            );
        } else if (item.kind === 'folder' && !item.data.addonFullname) {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        _uploadEvent.call(tb, event, item);
                    },
                    icon: 'fa fa-upload',
                    className: 'text-success'
                }, 'Upload')
            );
        } else if (item.kind === 'file') {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        _downloadEvent.call(tb, event, item);
                    },
                    icon: 'fa fa-download',
                    className: 'text-primary'
                }, 'Download')
            );
            if (item.parent().data.version === 'latest' && item.data.permissions.edit) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._removeEvent.call(tb, event, [item]);
                        },
                        icon: 'fa fa-trash',
                        className: 'text-danger'
                    }, 'Delete')
                );
            }
            if (item.data.permissions && item.data.permissions.view) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function(event) {
                            gotoFile(item);
                        },
                        icon: 'fa fa-file-o',
                        className : 'text-info'
                    }, 'View'));

            }
        }
        return m('span', buttons);
    }
};

function gotoFile (item) {
    var redir = new URI(item.data.nodeUrl);
    window.location = redir
        .segment('files')
        .segment(item.data.provider)
        .segment(item.data.extra.fileId)
        .query({version: item.data.extra.datasetVersion})
        .toString();
}

function _fangornDataverseTitle(item, col) {
    var tb = this;
    var version = item.data.version === 'latest-published' ? 'Published' : 'Draft';
    if (item.data.addonFullname) {
        var contents = [m('dataverse-name', item.data.name + ' (' + version + ')')];
        if (item.data.hasPublishedFiles) {
            if (item.data.permissions.edit) {
                // Default to version in url parameters for file view page
                var urlParams = $osf.urlParams();
                if (urlParams.version && urlParams.version !== item.data.version) {
                    item.data.version = urlParams.version;
                }
            } else {
                contents.push(
                    m('span.text-muted', '[Published]')
                );
            }
        } else {
            contents.push(
                m('span.text.text-muted', '[Draft]')
            );
        }
        return m('span', contents);
    } else {
        return m('span', [
            m('dataverse-name.fg-file-links', {
                onclick: function () {
                    gotoFile(item);
                },
                'data-toggle': 'tooltip',
                title: 'View file',
                'data-placement': 'bottom'
            }, item.data.name
                )
        ]);
    }
}

function _fangornColumns(item) {
    var tb = this;
    var selectClass = '';
    if (item.data.kind === 'file' && tb.currentFileID === item.id) {
        item.css = 'fangorn-selected';
        tb.multiselected([item]);
    }
    var columns = [];
    columns.push({
        data : 'name',
        folderIcons : true,
        filter : true,
        css: selectClass,
        custom: _fangornDataverseTitle
    });

    if (tb.options.placement === 'project-files') {
        columns.push(
            {
                data: 'downloads',
                filter: false,
                css: ''
            }
        );
    }
    return columns;
}

function _fangornFolderIcons(item) {
    if (item.data.iconUrl) {
        return m('img', {
            src: item.data.iconUrl,
            style: {
                width: '16px',
                height: 'auto'
            }
        }, ' ');
    }
    return undefined;
}

function _fangornDeleteUrl(item) {
    return waterbutler.buildTreeBeardDelete(item, {full_path: item.data.path + '?' + $.param({name: item.data.name})});
}

function _fangornLazyLoad(item) {
    return waterbutler.buildTreeBeardMetadata(item, {version: item.data.version});
}

function _canDrop(item) {
    return item.data.provider &&
        item.kind === 'folder' &&
        item.data.permissions.edit &&
        item.data.version === 'latest';
}

Fangorn.config.dataverse = {
    folderIcon: _fangornFolderIcons,
    resolveDeleteUrl: _fangornDeleteUrl,
    resolveRows: _fangornColumns,
    lazyload:_fangornLazyLoad,
    canDrop: _canDrop,
    itemButtons: _dataverseItemButtons
};
<commit_msg>Add dataverse column title template for disconnected [skip ci]<commit_after>'use strict';

var m = require('mithril');
var URI = require('URIjs');
var $ = require('jquery');

var Fangorn = require('js/fangorn');
var waterbutler = require('js/waterbutler');
var $osf = require('js/osfHelpers');

function changeState(grid, item, version) {
    item.data.version = version;
    grid.updateFolder(null, item);
}

function _downloadEvent(event, item, col) {
    event.stopPropagation();
    window.location = waterbutler.buildTreeBeardDownload(item, {path: item.data.extra.fileId});
}

// Define Fangorn Button Actions
var _dataverseItemButtons = {
    view: function (ctrl, args, children) {
        var buttons = [];
        var tb = args.treebeard;
        var item = args.item;
        function _uploadEvent(event, item, col) {
            event.stopPropagation();
            tb.dropzone.hiddenFileInput.click();
            tb.dropzoneItemCache = item;
        }
        function dataversePublish(event, item, col) {
            var both = !item.data.dataverseIsPublished;
            var url = item.data.urls.publish;
            var toPublish = both ? 'Dataverse and dataset' : 'dataset';
            var modalContent = [
                m('h3', 'Publish this ' + toPublish + '?'),
                m('p.m-md', both ? 'This dataset cannot be published until ' + item.data.dataverse + ' Dataverse is published. ' : ''),
                m('p.m-md', 'By publishing this ' + toPublish + ', all content will be made available through the Harvard Dataverse using their internal privacy settings, regardless of your OSF project settings. '),
                m('p.font-thick.m-md', both ? 'Do you want to publish this Dataverse AND this dataset?' : 'Are you sure you want to publish this dataset?')
            ];
            var modalActions = [
                m('button.btn.btn-default.m-sm', {
                    'onclick': function () {
                        tb.modal.dismiss();
                    }
                }, 'Cancel'),
                m('button.btn.btn-primary.m-sm', {
                    'onclick': function () {
                        publishDataset();
                    }
                }, 'Publish ' + toPublish)
            ];

            tb.modal.update(modalContent, modalActions);

            function publishDataset() {
                tb.modal.dismiss();
                item.notify.update('Publishing ' + toPublish, 'info', 1, 1);
                $.osf.putJSON(
                    url,
                    {'publish_both': both}
                ).done(function (data) {
                    item.notify.update();
                    var modalContent = [
                        m('p.m-md', 'Your content has been published.')
                    ];
                    var modalActions = [
                        m('button.btn.btn-primary.m-sm', {
                            'onclick': function () {
                                tb.modal.dismiss();
                            }
                        }, 'Okay')
                    ];
                    tb.modal.update(modalContent, modalActions);
                    item.data.dataverseIsPublished = true;
                    item.data.hasPublishedFiles = item.children.length > 0;
                    item.data.version = item.data.hasPublishedFiles ? 'latest-published' : 'latest';
                }).fail(function (xhr, status, error) {
                    var statusCode = xhr.responseJSON.code;
                    var message;
                    switch (statusCode) {
                    case 405:
                        message = 'Error: This dataset cannot be published until ' + item.data.dataverse + ' Dataverse is published.';
                        break;
                    case 409:
                        message = 'This dataset version has already been published.';
                        break;
                    default:
                        message = 'Error: Something went wrong when attempting to publish your dataset.';
                        Raven.captureMessage('Could not publish dataset', {
                            url: url,
                            textStatus: status,
                            error: error
                        });
                    }

                    var modalContent = [
                        m('p.m-md', message)
                    ];
                    var modalActions = [
                        m('button.btn.btn-primary.m-sm', {
                            'onclick': function () {
                                tb.modal.dismiss();
                            }
                        }, 'Okay')
                    ];
                    tb.modal.update(modalContent, modalActions);
                });
            }
        }
        if (item.data.addonFullname) {
            var options = [
                m('option', {selected: item.data.version === 'latest-published', value: 'latest-published'}, 'Published'),
                m('option', {selected: item.data.version === 'latest', value: 'latest'}, 'Draft')
            ];
            buttons.push(
                m.component(Fangorn.Components.dropdown, {
                    'label': 'Version: ',
                    onchange: function (e) {
                        changeState(tb, item, e.target.value);
                    },
                    icon: 'fa fa-external-link',
                    className: 'text-info'
                }, options)
            );
        }
        if (item.kind === 'folder' && item.data.addonFullname && item.data.version === 'latest' && item.data.permissions.edit) {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        _uploadEvent.call(tb, event, item);
                    },
                    icon: 'fa fa-upload',
                    className: 'text-success'
                }, 'Upload'),
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        dataversePublish.call(tb, event, item);
                    },
                    icon: 'fa fa-globe',
                    className: 'text-primary'
                }, 'Publish')
            );
        } else if (item.kind === 'folder' && !item.data.addonFullname) {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        _uploadEvent.call(tb, event, item);
                    },
                    icon: 'fa fa-upload',
                    className: 'text-success'
                }, 'Upload')
            );
        } else if (item.kind === 'file') {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        _downloadEvent.call(tb, event, item);
                    },
                    icon: 'fa fa-download',
                    className: 'text-primary'
                }, 'Download')
            );
            if (item.parent().data.version === 'latest' && item.data.permissions.edit) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._removeEvent.call(tb, event, [item]);
                        },
                        icon: 'fa fa-trash',
                        className: 'text-danger'
                    }, 'Delete')
                );
            }
            if (item.data.permissions && item.data.permissions.view) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function(event) {
                            gotoFile(item);
                        },
                        icon: 'fa fa-file-o',
                        className : 'text-info'
                    }, 'View'));

            }
        }
        return m('span', buttons);
    }
};

function gotoFile (item) {
    var redir = new URI(item.data.nodeUrl);
    window.location = redir
        .segment('files')
        .segment(item.data.provider)
        .segment(item.data.extra.fileId)
        .query({version: item.data.extra.datasetVersion})
        .toString();
}

function _fangornDataverseTitle(item, col) {
    var tb = this;
    if (item.data.isAddonRoot && item.connected === false) { // as opposed to undefined, avoids unnecessary setting of this value
        return Fangorn.Utils.connectCheckTemplate.call(this, item);
    }
    var version = item.data.version === 'latest-published' ? 'Published' : 'Draft';
    if (item.data.addonFullname) {
        var contents = [m('dataverse-name', item.data.name + ' (' + version + ')')];
        if (item.data.hasPublishedFiles) {
            if (item.data.permissions.edit) {
                // Default to version in url parameters for file view page
                var urlParams = $osf.urlParams();
                if (urlParams.version && urlParams.version !== item.data.version) {
                    item.data.version = urlParams.version;
                }
            } else {
                contents.push(
                    m('span.text-muted', '[Published]')
                );
            }
        } else {
            contents.push(
                m('span.text.text-muted', '[Draft]')
            );
        }
        return m('span', contents);
    } else {
        return m('span', [
            m('dataverse-name.fg-file-links', {
                onclick: function () {
                    gotoFile(item);
                },
                'data-toggle': 'tooltip',
                title: 'View file',
                'data-placement': 'bottom'
            }, item.data.name
                )
        ]);
    }
}

function _fangornColumns(item) {
    var tb = this;
    var selectClass = '';
    if (item.data.kind === 'file' && tb.currentFileID === item.id) {
        item.css = 'fangorn-selected';
        tb.multiselected([item]);
    }
    var columns = [];
    columns.push({
        data : 'name',
        folderIcons : true,
        filter : true,
        css: selectClass,
        custom: _fangornDataverseTitle
    });

    if (tb.options.placement === 'project-files') {
        columns.push(
            {
                data: 'downloads',
                filter: false,
                css: ''
            }
        );
    }
    return columns;
}

function _fangornFolderIcons(item) {
    if (item.data.iconUrl) {
        return m('img', {
            src: item.data.iconUrl,
            style: {
                width: '16px',
                height: 'auto'
            }
        }, ' ');
    }
    return undefined;
}

function _fangornDeleteUrl(item) {
    return waterbutler.buildTreeBeardDelete(item, {full_path: item.data.path + '?' + $.param({name: item.data.name})});
}

function _fangornLazyLoad(item) {
    return waterbutler.buildTreeBeardMetadata(item, {version: item.data.version});
}

function _canDrop(item) {
    return item.data.provider &&
        item.kind === 'folder' &&
        item.data.permissions.edit &&
        item.data.version === 'latest';
}

Fangorn.config.dataverse = {
    folderIcon: _fangornFolderIcons,
    resolveDeleteUrl: _fangornDeleteUrl,
    resolveRows: _fangornColumns,
    lazyload:_fangornLazyLoad,
    canDrop: _canDrop,
    itemButtons: _dataverseItemButtons
};
<|endoftext|>


<commit_before>'use strict';

var utils = require('./Utils.js');
var mathjs = require('mathjs');

function MegaSena(ensure) {
	if (!(this instanceof MegaSena)) return new LotoFacil(ensure);
	this.name = 'Mega Sena';
	this.from = 60;
	this.choose = 6;
	this.ensure = ensure || 1;
	this.combinations = mathjs.combinations(this.from, this.choose);
	this.combinationsOfEnsurement = utils.combinacoesDeFechamento(this);
	this.probability = this.combinations / this.combinationsOfEnsurement;
	utils.validate(this);
};

MegaSena.prototype.rodar = function (progressCB) {
	return utils.rodar(this, progressCB);
};

MegaSena.prototype.info = function () {
	return utils.info(this);
};

module.exports = MegaSena;
<commit_msg>fix(MegaSena): MegaSena instance called by function would generate endless recursion loop.<commit_after>'use strict';

var utils = require('./Utils.js');
var mathjs = require('mathjs');

function MegaSena(ensure) {
	if (!(this instanceof MegaSena)) return new MegaSena(ensure);
	this.name = 'Mega Sena';
	this.from = 60;
	this.choose = 6;
	this.ensure = ensure || 1;
	this.combinations = mathjs.combinations(this.from, this.choose);
	this.combinationsOfEnsurement = utils.combinacoesDeFechamento(this);
	this.probability = this.combinations / this.combinationsOfEnsurement;
	utils.validate(this);
};

MegaSena.prototype.rodar = function (progressCB) {
	return utils.rodar(this, progressCB);
};

MegaSena.prototype.info = function () {
	return utils.info(this);
};

module.exports = MegaSena;
<|endoftext|>


<commit_before>export default class PersonCategoryFilterDropdownDirective {
    static factory(PersonCategoryService, AuthService) {
        return {
            restrict: 'E',
            require: '^ngModel',
            template: `

                    <input class="form-control" ng-model="filterIndicator" ng-click="toggleEditor()" readonly>

                                 ({{clubName}})
                                <fls-editable-tree id="personCategories"
                                                   data="{nodes: masterdata.personCategories}"
                                                   edit-mode="false"></fls-editable-tree>

                        <button class="btn btn-default pull-right" style="margin-top: 10px;" ng-click="toggleEditor()" translate="OK"></button>
                        <button class="btn btn-default pull-left" style="margin-top: 10px;margin-right: 5px;" ng-click="reset()" translate="ALL"></button>
                        <button class="btn btn-default pull-left" style="margin-top: 10px;margin-right: 5px;" ng-click="selectNone()" translate="NONE"></button>
                        <button class="btn btn-default pull-left" style="margin-top: 10px;margin-right: 5px;" ng-click="invert()" translate="INVERT"></button>

            `,
            scope: {
                ngModel: '=',
                field: '@'
            },
            link: function (scope, element, attrs, modelCtrl) {
                function updateViewValue() {
                    modelCtrl.$setViewValue(scope.masterdata.personCategories.filter(node => node.selected).map(node => node.PersonCategoryId));
                }

                scope.masterdata = {
                    personCategories: []
                };
                PersonCategoryService.loadPersonCategories().then((result) => {
                    scope.masterdata.personCategories = Object.assign([], result);
                    scope.reset();

                    updateViewValue();
                });
                scope.clubName = AuthService.getUser().myClub.ClubName;

                scope.toggleEditor = () => {
                    updateViewValue();
                    scope.editorVisible = !scope.editorVisible;
                };

                scope.reset = () => {
                    scope.masterdata.personCategories.forEach(node => {
                        node.selected = true;
                    });
                };

                scope.selectNone = () => {
                    scope.masterdata.personCategories.forEach(node => {
                        node.selected = false;
                    });
                };

                scope.invert = () => {
                    scope.masterdata.personCategories.forEach(node => {
                        node.selected = !node.selected;
                    });
                };
            }
        };
    };
}
<commit_msg>#165 implemented filter indicator<commit_after>import {FlightStateMapper} from "../../flights/FlightsServices";

export default class PersonCategoryFilterDropdownDirective {
    static factory(PersonCategoryService, AuthService) {
        return {
            restrict: 'E',
            require: '^ngModel',
            template: `

                    <input class="form-control" ng-model="filterIndicator" ng-click="toggleEditor()" readonly>

                                 ({{clubName}})
                                <fls-editable-tree id="personCategories"
                                                   data="{nodes: masterdata.personCategories}"
                                                   edit-mode="false"></fls-editable-tree>

                        <button class="btn btn-default pull-right" style="margin-top: 10px;" ng-click="toggleEditor()" translate="OK"></button>
                        <button class="btn btn-default pull-left" style="margin-top: 10px;margin-right: 5px;" ng-click="reset()" translate="ALL"></button>
                        <button class="btn btn-default pull-left" style="margin-top: 10px;margin-right: 5px;" ng-click="selectNone()" translate="NONE"></button>
                        <button class="btn btn-default pull-left" style="margin-top: 10px;margin-right: 5px;" ng-click="invert()" translate="INVERT"></button>

            `,
            scope: {
                ngModel: '=',
                field: '@'
            },
            link: function (scope, element, attrs, modelCtrl) {
                function updateViewValue() {
                    modelCtrl.$setViewValue(scope.masterdata.personCategories.filter(node => node.selected).map(node => node.PersonCategoryId));
                    scope.filterIndicator = scope.masterdata.personCategories.filter(node => !node.selected).length > 0 ? "*" : "";
                }

                if (scope.ngModel) {
                    scope.masterdata = {
                        personCategories: scope.ngModel
                    };
                } else {
                    scope.masterdata = {
                        personCategories: []
                    };
                    PersonCategoryService.loadPersonCategories().then((result) => {
                        scope.masterdata.personCategories = Object.assign([], result);
                        scope.reset();

                        updateViewValue();
                    });
                }

                scope.clubName = AuthService.getUser().myClub.ClubName;

                scope.toggleEditor = () => {
                    updateViewValue();
                    scope.editorVisible = !scope.editorVisible;
                };

                scope.reset = () => {
                    scope.masterdata.personCategories.forEach(node => {
                        node.selected = true;
                    });
                };

                scope.selectNone = () => {
                    scope.masterdata.personCategories.forEach(node => {
                        node.selected = false;
                    });
                };

                scope.invert = () => {
                    scope.masterdata.personCategories.forEach(node => {
                        node.selected = !node.selected;
                    });
                };
            }
        };
    }
    ;
}
<|endoftext|>


<commit_before>/* global Log, Module, moment, config */
/* Magic Mirror
 * Module: MMM-NetworkScanner
 *
 * By Ian Perrin http://ianperrin.com
 * MIT Licensed.
 */

Module.register("MMM-NetworkScanner",{

     // Default module config.
    defaults: {
        devices: [],                    // an array of device objects e.g. { macAddress: "aa:bb:cc:11:22:33", name: "DEVICE-NAME", icon: "FONT-AWESOME-ICON"}
        showUnknown: true,              // shows devices found on the network even if not specified in the 'devices' option
        showOffline: true,              // shows devices specified in the 'devices' option even when offline
        keepAlive: 180,                 // how long (in seconds) a device should be considered 'alive' since it was last found on the network
        updateInterval: 10,             // how often (in seconds) the module should scan the network

//        residents: [],
        residents: ["Ben"],
        occupiedCMD: {notification: 'TEST', payload: {action: 'occupiedCMD'}},
        vacantCMD:   {notification: 'TEST', payload: {action: 'vacantCMD'}},
        debug: true,
    },

    // Subclass start method.
    start: function() {
        Log.info("Starting module: " + this.name);

        // variable for if anyone is home
        this.occupied = true;

        // variable for list of IP addresses
        this.IPAddresses = []
        for (var i=0; i<this.config.devices.length; i++) {
           var device = this.config.devices[i];
           if ("ipAddress" in device) {
               this.IPAddresses.push(device);
           };
        };

        moment.locale(config.language);
        this.scanNetwork();
    },

    // Subclass getStyles method.
    getStyles: function() {
        return ['font-awesome.css'];
    },

    // Subclass getScripts method.
    getScripts: function() {
        return ["moment.js"];
    },

    // Subclass socketNotificationReceived method.
    socketNotificationReceived: function(notification, payload) {
        Log.info(this.name + " received a notification: " + notification);

        if (notification === 'IP_ADDRESS') {

            for (var i=0; i < this.config.devices.length; i++) {
               var device = this.config.devices[i];
               if ("ipAddress" in device) {
                  if (payload.name === device.name) {
                     device.online = payload.online;
                     return;
                  };
               };
            };
        };

        if (notification === 'MAC_ADDRESSES') {
            // No action if data is the same
            if (JSON.stringify(this.networkDevices) === JSON.stringify(payload))  {
                return;
            };

            // Build device status list
            this.networkDevices = [];
            for (var i = 0; i < payload.length - 1; i++) {

                var device = this.getDeviceByMacAddress(payload[i]);
                if (device) {
                    device.online = true;
                    device.lastSeen = moment();
                    this.networkDevices.push(device);
                }
            };

            // Add offline known devices
            if (this.config.showOffline) {
                for (var d = 0; d < this.config.devices.length; d++) {
                    var device = this.config.devices[d];

                    // Make sure we are using a device with a mac address
                    if ("macAddress" in device) {

                       for(var n = 0; n < this.networkDevices.length; n++){
                           if( this.networkDevices[n].macAddress.toUpperCase() === device.macAddress.toUpperCase()) {
                               n = -1;
                               break;
                           }
                       }

                       if (n != -1) {
                           if (device.lastSeen) {
                               device.online = (moment().diff(device.lastSeen, 'seconds') < this.config.keepAlive);
                               Log.info (this.name + " is keeping alive " + device.name + ". Last seen " + device.lastSeen.fromNow());
                           } else {
                               device.online = false;
                           }
                           this.networkDevices.push(device);
                       }
                   } else if ("ipAddress" in device) {
                     // Keep the device alive incase of temporary loss
//                        if (!device.online) {
//                           if (device.lastSeen) {
//                               device.online = (moment().diff(device.lastSeen, 'seconds') < this.config.keepAlive);
//                               Log.info (this.name + " is keeping alive " + device.name + ". Last seen " + device.lastSeen.fromNow());
//                           } else {
//                              device.online = false;
//                           }
                           this.networkDevices.push(device);
//                       }
                   };
                };
            };

            // Sort list by known device names, then unknown device mac addresses
            this.networkDevices.sort(function(a, b) {
                var stringA = (a.name ? "_" + a.name : a.macAddress);
                var stringB = (b.name ? "_" + b.name : b.macAddress);

                return stringA.localeCompare(stringB);
            });

            // Send notification if user status has changed
            if (this.config.residents.length > 0) {

               var self = this;
               var updatedOccupied = false;
               var residents = this.config.residents;

               Array.prototype.contains = function(element){
                  return this.indexOf(element) > -1;
               };

               var anyoneHome = 0;

               for (var i=0; i<this.networkDevices.length; i++) {
                  device = this.networkDevices[i];
                  var resident = residents.contains(device.name);
                  if (resident) {
                     anyoneHome = anyoneHome + device.online;
                  }
               };

               console.log("# people home: ",anyoneHome);
               console.log("Was occupied? ", this.occupied);

               if (anyoneHome > 0) {
                  if (this.occupied==false) {
                     console.log("Someone has come home");
                     var command = this.config.occupiedCMD;
                     this.sendNotification(command.notification, command.payload);
                     this.occupied=true;
                  }
               } else {
                  if (this.occupied==true) {
                     console.log("Everyone has left home");
                     var command = this.config.vacantCMD;
                     this.sendNotification(command.notification, command.payload);
                     this.occupied=false;
                  }
               }

            };

            this.updateDom();
            return;
        };
    },

    // Override dom generator.
    getDom: function() {
        //Log.info(this.name + " is updating the DOM");
        var wrapper = document.createElement("div");
        wrapper.classList.add("small");

        // Display a loading message
        if (!this.networkDevices) {
            wrapper.innerHTML = this.translate("LOADING");
            return wrapper;
        }

        // Display device status
        var deviceList = document.createElement("ul");
        deviceList.classList.add("fa-ul");
        for (var i = 0; i < this.networkDevices.length; i++) {
            var device = this.networkDevices[i];
            if (device) {

                // device list item
                var deviceItem = document.createElement("li");
                var deviceOnline = (device.online ? "bright" : "dimmed");
                deviceItem.classList.add(deviceOnline);

                // Icon
                var icon =  document.createElement("i");
                icon.classList.add("fa-li", "fa", "fa-" + (device.icon ? device.icon : "question"));
                deviceItem.appendChild(icon);

                // Name
                deviceItem.innerHTML += (device.name ? device.name: device.macAddress) ;

                deviceList.appendChild(deviceItem);

            } else {
                Log.info("Online, but ignoring: '" + this.networkDevices[i] + "'");
            }
        }
        if(deviceList.hasChildNodes()) {
            wrapper.appendChild(deviceList);
        } else {
            // Display no devices online message
            wrapper.innerHTML = this.translate("NO DEVICES ONLINE");
        }

        return wrapper;
    },

    scanNetwork: function() {
        var self = this;
        var devices = this.config.devices;
        this.sendSocketNotification('SCAN_NETWORK', devices);
        setInterval(function() {
            self.sendSocketNotification('SCAN_NETWORK', devices);
        }, this.config.updateInterval * 1000);
        return;
    },

    getDeviceByMacAddress: function(macAddress) {

        // Find first device with matching macAddress
        for (var i = 0; i < this.config.devices.length; i++) {
            var device = this.config.devices[i];
            if ("macAddress" in device) {
               if (macAddress.toUpperCase() === device.macAddress.toUpperCase()){
                   return device;
               }
           }
        }

        // Return macAddress (if showing unknown) or null
        if (this.config.showUnknown) {
            return {macAddress: macAddress};
        } else {
            return null;
        }
    },

});

<commit_msg>Made jslint complient<commit_after>/* global Log, Module, moment, config */
/* Magic Mirror
 * Module: MMM-NetworkScanner
 *
 * By Ian Perrin http://ianperrin.com
 * MIT Licensed.
 */

var Module, Log, moment, config, Log, moment, document;

Module.register("MMM-NetworkScanner", {

     // Default module config.
    defaults: {
        devices: [],                    // an array of device objects e.g. { macAddress: "aa:bb:cc:11:22:33", name: "DEVICE-NAME", icon: "FONT-AWESOME-ICON"}
        showUnknown: true,              // shows devices found on the network even if not specified in the 'devices' option
        showOffline: true,              // shows devices specified in the 'devices' option even when offline
        keepAlive: 30,                 // how long (in seconds) a device should be considered 'alive' since it was last found on the network
        updateInterval: 10,             // how often (in seconds) the module should scan the network

        residents: [],
//        residents: ["Ben"],
        occupiedCMD: {notification: 'TEST', payload: {action: 'occupiedCMD'}},
        vacantCMD:   {notification: 'TEST', payload: {action: 'vacantCMD'}},
        debug: true,
    },

    // Subclass start method.
    start: function () {
        Log.info("Starting module: " + this.name);

        // variable for if anyone is home
        this.occupied = true;

        // variable for list of IP addresses
        this.IPAddresses = [];
        this.config.devices.forEach(function (device) {
//        for (var i=0; i<this.config.devices.length; i++) {
//           var device = this.config.devices[i];
            if (device.hasOwnProperty("ipAddress")) {
                this.IPAddresses.push(device);
            }
        });

        moment.locale(config.language);
        this.scanNetwork();
    },

    // Subclass getStyles method.
    getStyles: function () {
        return ['font-awesome.css'];
    },

    // Subclass getScripts method.
    getScripts: function () {
        return ["moment.js"];
    },

    // Subclass socketNotificationReceived method.
    socketNotificationReceived: function (notification, payload) {
        Log.info(this.name + " received a notification: " + notification);

        if (notification === 'IP_ADDRESS') {

            this.config.devices.forEach(function (device) {
//            for (var i=0; i < this.config.devices.length; i++) {
//               var device = this.config.devices[i];
                if (device.hasOwnProperty("ipAddress")) {
                    if (payload.name === device.name) {
                        device.online = payload.online;
                        return;
                    }
                }
            });
        }

        if (notification === 'MAC_ADDRESSES') {
            // No action if data is the same
            if (JSON.stringify(this.networkDevices) === JSON.stringify(payload)) {
                return;
            }

            // Build device status list
            var self = this;
            this.networkDevices = [];
            payload.forEach(function (item) {
//            for (var i = 0; i < payload.length - 1; i++) {
//                var item = payload[i]
                var device = self.getDeviceByMacAddress(item);
                if (device) {
                    device.online = true;
                    device.lastSeen = moment();
                    self.networkDevices.push(device);
                }
            });

            // Add offline known devices
            if (this.config.showOffline) {
                this.config.devices.forEach(function (device) {
//                for (var d = 0; d < this.config.devices.length; d++) {
//                    var device = this.config.devices[d];

                    // Make sure we are using a device with a mac address
                    if (device.hasOwnProperty("macAddress")) {

                        this.networkDevices.forEach(function (networkDevice) {
//                        for (var n = 0; n < this.networkDevices.length; n++){
//                            var networkDevice = networkDevices[n];

                            // Find if the device is a known device
                            if (networkDevice.macAddress.toUpperCase() === device.macAddress.toUpperCase()) {
                                if (device.lastSeen) {
                                    device.online = (moment().diff(device.lastSeen, 'seconds') < this.config.keepAlive);
                                    Log.info(this.name + " is keeping alive " + device.name + ". Last seen " + device.lastSeen.fromNow());
                                } else {
                                    device.online = false;
                                }
                                this.networkDevices.push(device);
                            }
                        });

                    } else if (device.hasOwnProperty("ipAddress")) {
                     // Keep the device alive incase of temporary loss
                        if (!device.online) {
                            if (device.lastSeen) {
                                device.online = (moment().diff(device.lastSeen, 'seconds') < this.config.keepAlive);
                                Log.info(this.name + " is keeping alive " + device.name + ". Last seen " + device.lastSeen.fromNow());
                            } else {
                                device.online = false;
                            }
                            this.networkDevices.push(device);
                        }
                    }
                });
            }

            // Sort list by known device names, then unknown device mac addresses
            this.networkDevices.sort(function (a, b) {
                var stringA, stringB;
                stringA = (a.name ? "_" + a.name : a.macAddress);
                stringB = (b.name ? "_" + b.name : b.macAddress);

                return stringA.localeCompare(stringB);
            });

            // Send notification if user status has changed
            if (this.config.residents.length > 0) {

                var self = this;
                var anyoneHome, command;
                anyoneHome = 0;

                Array.prototype.contains = function (element) {
                    return this.indexOf(element) > -1;
                };

                this.networkDevices.forEach(function (device) {
//                for (var i=0; i<this.networkDevices.length; i++) {
//                    device = this.networkDevices[i];
                    if (this.config.residents.contains(device.name)) {
                        anyoneHome = anyoneHome + device.online;
                    }
                });

                console.log("# people home: ", anyoneHome);
                console.log("Was occupied? ", this.occupied);

                if (anyoneHome > 0) {
                    if (this.occupied === false) {
                        console.log("Someone has come home");
                        command = this.config.occupiedCMD;
                        self.sendNotification(command.notification, command.payload, this.config.name);
                        this.occupied = true;
                    }
                } else {
                    if (this.occupied === true) {
                        console.log("Everyone has left home");
                        command = this.config.vacantCMD;
                        self.sendNotification(command.notification, command.payload, this.config.name);
                        this.occupied = false;
                    }
                }
            }

            this.updateDom();
            return;

        }

    },

    // Override dom generator.
    getDom: function () {
        //Log.info(this.name + " is updating the DOM");
        var wrapper, deviceList, icon, deviceItem, deviceOnline;
        wrapper = document.createElement("div");

        wrapper.classList.add("small");

        // Display a loading message
        if (!this.networkDevices) {
            wrapper.innerHTML = this.translate("LOADING");
            return wrapper;
        }

        // Display device status
        deviceList = document.createElement("ul");
        deviceList.classList.add("fa-ul");
        this.networkDevices.forEach(function (device) {
//        for (var i = 0; i < this.networkDevices.length; i++) {
//            var device = this.networkDevices[i];
            if (device) {

                // Add device items if they don't exist.
                if (!device.hasOwnProperty("icon")) {
                    device.icon = "question";
                }
                if (!device.hasOwnProperty("name")) {
                    if (device.hasOwnProperty("macAddress")) {
                        device.name = device.macAddress;
                    } else if (device.hasOwnProperty("ipAddress")) {
                        device.name = device.ipAddress;
                    } else {
                        device.name = "Unknown";
                    }
                }

                // device list item
                deviceItem = document.createElement("li");
                deviceOnline = (device.online ? "bright" : "dimmed");
                deviceItem.classList.add(deviceOnline);

                // Icon
                icon =  document.createElement("i");
                icon.classList.add("fa-li", "fa", "fa-" + device.icon);
                deviceItem.appendChild(icon);

                // Name
                deviceItem.innerHTML += device.name;

                deviceList.appendChild(deviceItem);

            } else {
                Log.info("Online, but ignoring: '" + device + "'");
            }
        });
        if (deviceList.hasChildNodes()) {
            wrapper.appendChild(deviceList);
        } else {
            // Display no devices online message
            wrapper.innerHTML = this.translate("NO DEVICES ONLINE");
        }

        return wrapper;
    },

    scanNetwork: function () {
        var devices;
        var self = this;
        devices = this.config.devices;
        this.sendSocketNotification('SCAN_NETWORK', devices);
        setInterval(function () {
            self.sendSocketNotification('SCAN_NETWORK', devices);
        }, this.config.updateInterval * 1000);
        return;
    },

    getDeviceByMacAddress: function (macAddress) {

        // Find first device with matching macAddress
        this.config.devices.forEach(function (device) {
//        for (var i = 0; i < this.config.devices.length; i++) {
//            var device = this.config.devices[i];
            if (device.hasOwnProperty("macAddress")) {
                if (macAddress.toUpperCase() === device.macAddress.toUpperCase()) {
                    return device;
                }
            }
        });

        // Return macAddress (if showing unknown) or null
        if (this.config.showUnknown) {
            return {macAddress: macAddress};
        }
    }

});

<|endoftext|>


<commit_before>'use strict';

var Home = React.createClass({
    displayName: 'Home',

    render: function render() {
        var socials = [{ link: 'https://github.com/aligos', icon: 'github' }, { link: 'http://linkedin.com/in/aligos', icon: 'linkedin' }, { link: 'https://speakerdeck.com/aligos', icon: 'slideshare' }, { link: 'http://twitter.com/aligos', icon: 'twitter' }, { link: 'http://facebook.com/matt.aligos', icon: 'facebook' }];
        return React.createElement(
            'div',
            { className: 'about' },
            React.createElement('img', { {src: 'img/header.png'}, { className: 'gue'} }),
            React.createElement(
                'h1',
                { className: 'jumbo-title' },
                'I create web & mobile apps.'
            ),
            React.createElement(
                'p',
                { className: 'jumbo-desc' },
                'Aligos - JavaScript Fans'
            ),
            React.createElement(
                'div',
                { className: 'social' },
                socials.map(function (item) {
                    return React.createElement(
                        'a',
                        { href: item.link },
                        React.createElement('i', { className: 'fa fa-' + item.icon })
                    );
                })
            )
        );
    }
});
<commit_msg>Update home.js<commit_after>'use strict';

var Home = React.createClass({
    displayName: 'Home',

    render: function render() {
        var socials = [{ link: 'https://github.com/aligos', icon: 'github' }, { link: 'http://linkedin.com/in/aligos', icon: 'linkedin' }, { link: 'https://speakerdeck.com/aligos', icon: 'slideshare' }, { link: 'http://twitter.com/aligos', icon: 'twitter' }, { link: 'http://facebook.com/matt.aligos', icon: 'facebook' }];
        return React.createElement(
            'div',
            { className: 'about' },
            React.createElement('img', { className: 'gue'}, { src: 'img/header.png' }),
            React.createElement(
                'h1',
                { className: 'jumbo-title' },
                'I create web & mobile apps.'
            ),
            React.createElement(
                'p',
                { className: 'jumbo-desc' },
                'Aligos - JavaScript Fans'
            ),
            React.createElement(
                'div',
                { className: 'social' },
                socials.map(function (item) {
                    return React.createElement(
                        'a',
                        { href: item.link },
                        React.createElement('i', { className: 'fa fa-' + item.icon })
                    );
                })
            )
        );
    }
});
<|endoftext|>


<commit_before>'use strict';

/**
 * Dependencies.
 */

var babelify = require('babelify');
var browserify = require('browserify');
var watchify = require('watchify');
var envify = require('envify');
var source = require('vinyl-source-stream');
var envc = require('envc')();
var gulp = require('gulp');
var gwatch = require('gulp-watch');
var gutil = require('gulp-util')
var html = require('gulp-minify-html');
var json = require('gulp-jsonminify');
var sass = require('gulp-sass');
var ignore = require('gulp-ignore');
var rimraf = require('rimraf');
var imagemin = require('gulp-imagemin');
var uglify = require('gulp-uglify');
var plumber = require('gulp-plumber');
var buffer = require('vinyl-buffer');
var bourbon = require('node-bourbon');
var neat = require('node-neat');
var fs = require('fs');
var mocha = require('gulp-spawn-mocha');
var jest = require('jest-cli');
var harmonize = require('harmonize')();
var requiredVars = fs.readFileSync('.env.assert', 'utf8').split('\n');
var env = process.env;
var NODE_ENV = env.NODE_ENV || 'development';
var assertEnv = require('assert-env')(requiredVars.filter(function(key) {
  return !!key;
}));

/**
 * Arguments.
 */

var argv = gutil.env;

/**
 * File patterns.
 */

var patterns = {
  html: 'src/**/*.html',
  img: 'src/**/*.{png,svg,ico}',
  css: 'src/**/*.{scss,css}',
  locales: 'src/_locales/**/*.json',
  vendor: 'vendor/**/**'
};

/**
 * Root dest.
 */

var dest = 'build' || argv.build;

/**
 * JavaScript bundles.
 */

var bundles = [
  { entry: './src/apps/popup/main.js', out: 'apps/popup/main.js' },
  { entry: './src/apps/background/main.js', out: 'apps/background/main.js' },
  { entry: './src/apps/content/main.js', out: 'apps/content/main.js' },
  { entry: './src/apps/tabs/main.js', out: 'apps/tabs/main.js' },
  { entry: './src/apps/options/main.js', out: 'apps/options/main.js' }
];

/**
 * Return a gulp-watch or noop, based on
 * the `--watch` flag.
 *
 * @return {Stream}
 * @private
 */

function watch(pattern) {
  return argv.watch ? gwatch(pattern) : gutil.noop();
}

/**
 * Build the JavaScript bundles.
 */

gulp.task('js', function() {
  bundles.forEach(function(bundle) {
    var bundler = browserify({
      entries: [bundle.entry],
      transform: [envify, babelify],
      debug: true,
      cache: {},
      packageCache: {},
      fullPaths: true
    });

    var update = function() {
      bundler.bundle()
        .pipe(source(bundle.out))
        .pipe(buffer())
        .pipe(gulp.dest(dest));
    };

    if (argv.watch) {
      bundler = watchify(bundler);
      bundler.on('update', update);
    }

    update();
  });
});

/**
 * Minify the HTML files.
 */

gulp.task('html', function() {
  return gulp.src(patterns.html)
    .pipe(watch(patterns.html))
    .pipe(html())
    .pipe(gulp.dest(dest));
});

/**
 * Copy vendor files.
 */

gulp.task('vendor', function() {
  return gulp.src(patterns.vendor)
    .pipe(watch(patterns.vendor))
    .pipe(gulp.dest(dest + '/vendor'));
});

/**
 * Minify the locale files.
 */

gulp.task('locales', function() {
  return gulp.src(patterns.locales)
    .pipe(watch(patterns.locales))
    .pipe(json())
    .pipe(gulp.dest(dest + '/_locales/'));
});

/**
 * Modify the manifest file.
 */

gulp.task('manifest', function(done) {
  var manifest = require('./src/manifest.json');

  switch (NODE_ENV) {
    case 'development':
      manifest.name = '[dev] ProductHunt';
      break;
    case 'staging':
      manifest.name = '[staging] ProductHunt';
      break;
  }

  fs.writeFile(dest + '/manifest.json', JSON.stringify(manifest), done);
});

/**
 * Compile the scss files.
 */

gulp.task('scss', function() {
  var paths = neat.includePaths.concat(['./src']);

  return gulp.src(patterns.css)
    .pipe(plumber())
    .pipe(watch(patterns.css))
    .pipe(sass({
      imagePath: 'chrome-extension://' + env.EXTENSION_ID,
      includePaths: paths
    }))
    .pipe(gulp.dest(dest));
});

/**
 * Optimize the images.
 */

gulp.task('img', function() {
  return gulp.src(patterns.img)
    .pipe(watch(patterns.img))
    .pipe(imagemin())
    .pipe(gulp.dest(dest));
});

/**
 * Run the end to end tests.
 */

gulp.task('test-acceptance', ['build'], function () {
  return gulp.src(['test/*.test.js'], { read: false })
    .pipe(mocha({ r: 'test/setup.js', timeout: 10000 }));
});

/**
 * Run all unit tests.
 */

gulp.task('test-unit', function(done) {
  var options = {
    config: {
      rootDir: __dirname,
      testPathDirs: [__dirname + '/src'],
      scriptPreprocessor: __dirname + '/node_modules/babel-jest/index.js',
      setupEnvScriptFile: __dirname + '/jest/env.js',
      setupTestFrameworkScriptFile: __dirname + '/jest/setup.js'
    }
  };

  jest.runCLI(options, __dirname, function(success) {
    done();
  });
});

/**
 * Clean the build folder.
 */

gulp.task('clean', function() {
  [
    dest + '/_locales',
    dest + '/apps',
    dest + '/common',
    dest + '/vendor',
    dest + '/manifest.json'
  ].forEach(function(dir) {
    rimraf.sync(dir)
  });
});

/**
 * Tests.
 */

gulp.task('test', ['test-acceptance', 'test-unit']);

/**
 * Build all.
 */

gulp.task('build', [
  'clean',
  'js',
  'html',
  'locales',
  'manifest',
  'scss',
  'img',
  'vendor'
]);
<commit_msg>Enable verbose mode for gulp-watch<commit_after>'use strict';

/**
 * Dependencies.
 */

var babelify = require('babelify');
var browserify = require('browserify');
var watchify = require('watchify');
var envify = require('envify');
var source = require('vinyl-source-stream');
var envc = require('envc')();
var gulp = require('gulp');
var gwatch = require('gulp-watch');
var gutil = require('gulp-util')
var html = require('gulp-minify-html');
var json = require('gulp-jsonminify');
var sass = require('gulp-sass');
var ignore = require('gulp-ignore');
var rimraf = require('rimraf');
var imagemin = require('gulp-imagemin');
var uglify = require('gulp-uglify');
var plumber = require('gulp-plumber');
var buffer = require('vinyl-buffer');
var bourbon = require('node-bourbon');
var neat = require('node-neat');
var fs = require('fs');
var mocha = require('gulp-spawn-mocha');
var jest = require('jest-cli');
var harmonize = require('harmonize')();
var requiredVars = fs.readFileSync('.env.assert', 'utf8').split('\n');
var env = process.env;
var NODE_ENV = env.NODE_ENV || 'development';
var assertEnv = require('assert-env')(requiredVars.filter(function(key) {
  return !!key;
}));

/**
 * Arguments.
 */

var argv = gutil.env;

/**
 * File patterns.
 */

var patterns = {
  html: 'src/**/*.html',
  img: 'src/**/*.{png,svg,ico}',
  css: 'src/**/*.{scss,css}',
  locales: 'src/_locales/**/*.json',
  vendor: 'vendor/**/**'
};

/**
 * Root dest.
 */

var dest = 'build' || argv.build;

/**
 * JavaScript bundles.
 */

var bundles = [
  { entry: './src/apps/popup/main.js', out: 'apps/popup/main.js' },
  { entry: './src/apps/background/main.js', out: 'apps/background/main.js' },
  { entry: './src/apps/content/main.js', out: 'apps/content/main.js' },
  { entry: './src/apps/tabs/main.js', out: 'apps/tabs/main.js' },
  { entry: './src/apps/options/main.js', out: 'apps/options/main.js' }
];

/**
 * Return a gulp-watch or noop, based on
 * the `--watch` flag.
 *
 * @return {Stream}
 * @private
 */

function watch(pattern) {
  return argv.watch ? gwatch(pattern, { verbose: true }) : gutil.noop();
}

/**
 * Build the JavaScript bundles.
 */

gulp.task('js', function() {
  bundles.forEach(function(bundle) {
    var bundler = browserify({
      entries: [bundle.entry],
      transform: [envify, babelify],
      debug: true,
      cache: {},
      packageCache: {},
      fullPaths: true
    });

    var update = function() {
      bundler.bundle()
        .pipe(source(bundle.out))
        .pipe(buffer())
        .pipe(gulp.dest(dest));
    };

    if (argv.watch) {
      bundler = watchify(bundler);
      bundler.on('update', update);
    }

    update();
  });
});

/**
 * Minify the HTML files.
 */

gulp.task('html', function() {
  return gulp.src(patterns.html)
    .pipe(watch(patterns.html))
    .pipe(html())
    .pipe(gulp.dest(dest));
});

/**
 * Copy vendor files.
 */

gulp.task('vendor', function() {
  return gulp.src(patterns.vendor)
    .pipe(watch(patterns.vendor))
    .pipe(gulp.dest(dest + '/vendor'));
});

/**
 * Minify the locale files.
 */

gulp.task('locales', function() {
  return gulp.src(patterns.locales)
    .pipe(watch(patterns.locales))
    .pipe(json())
    .pipe(gulp.dest(dest + '/_locales/'));
});

/**
 * Modify the manifest file.
 */

gulp.task('manifest', function(done) {
  var manifest = require('./src/manifest.json');

  switch (NODE_ENV) {
    case 'development':
      manifest.name = '[dev] ProductHunt';
      break;
    case 'staging':
      manifest.name = '[staging] ProductHunt';
      break;
  }

  fs.writeFile(dest + '/manifest.json', JSON.stringify(manifest), done);
});

/**
 * Compile the scss files.
 */

gulp.task('scss', function() {
  var paths = neat.includePaths.concat(['./src']);

  return gulp.src(patterns.css)
    .pipe(plumber())
    .pipe(watch(patterns.css))
    .pipe(sass({
      imagePath: 'chrome-extension://' + env.EXTENSION_ID,
      includePaths: paths
    }))
    .pipe(gulp.dest(dest));
});

/**
 * Optimize the images.
 */

gulp.task('img', function() {
  return gulp.src(patterns.img)
    .pipe(watch(patterns.img))
    .pipe(imagemin())
    .pipe(gulp.dest(dest));
});

/**
 * Run the end to end tests.
 */

gulp.task('test-acceptance', ['build'], function () {
  return gulp.src(['test/*.test.js'], { read: false })
    .pipe(mocha({ r: 'test/setup.js', timeout: 10000 }));
});

/**
 * Run all unit tests.
 */

gulp.task('test-unit', function(done) {
  var options = {
    config: {
      rootDir: __dirname,
      testPathDirs: [__dirname + '/src'],
      scriptPreprocessor: __dirname + '/node_modules/babel-jest/index.js',
      setupEnvScriptFile: __dirname + '/jest/env.js',
      setupTestFrameworkScriptFile: __dirname + '/jest/setup.js'
    }
  };

  jest.runCLI(options, __dirname, function(success) {
    done();
  });
});

/**
 * Clean the build folder.
 */

gulp.task('clean', function() {
  [
    dest + '/_locales',
    dest + '/apps',
    dest + '/common',
    dest + '/vendor',
    dest + '/manifest.json'
  ].forEach(function(dir) {
    rimraf.sync(dir)
  });
});

/**
 * Tests.
 */

gulp.task('test', ['test-acceptance', 'test-unit']);

/**
 * Build all.
 */

gulp.task('build', [
  'clean',
  'js',
  'html',
  'locales',
  'manifest',
  'scss',
  'img',
  'vendor'
]);
<|endoftext|>