<commit_before>function getDateFromEntry(entry) {
  return entry.date || Date.parse(entry.display_time) || Date.parse(entry.dateString);
}

var getLastGlucose = function (data) {
    data = data.filter(function(obj) {
      return obj.glucose || obj.sgv;
    }).map(function prepGlucose (obj) {
        //Support the NS sgv field to avoid having to convert in a custom way
        obj.glucose = obj.glucose || obj.sgv;
        return obj;
    });

    var now = data[0];
    var now_date = getDateFromEntry(now);
    var change;
    var last_deltas = [];
    var short_deltas = [];
    var long_deltas = [];
    var last_cal = 0;

    //console.error(now.glucose);
    for (var i=1; i < data.length; i++) {
        // if we come across a cal record, don't process any older SGVs
        if (typeof data[i] !== 'undefined' && data[i].type === "cal") {
            last_cal = i;
            break;
        }
        // only use data from the same device as the most recent BG data point
        if (typeof data[i] !== 'undefined' && data[i].glucose > 38 && data[i].device === now.device) {
            var then = data[i];
            var then_date = getDateFromEntry(then);
            var avgdelta = 0;
            var minutesago;
            if (typeof then_date !== 'undefined' && typeof now_date !== 'undefined') {
                minutesago = Math.round( (now_date - then_date) / (1000 * 60) );
                // multiply by 5 to get the same units as delta, i.e. mg/dL/5m
                change = now.glucose - then.glucose;
                avgdelta = change/minutesago * 5;
            } else { console.error("Error: date field not found: cannot calculate avgdelta"); }
            //if (i < 5) {
                //console.error(then.glucose, minutesago, avgdelta);
            //}
            // use the average of all data points in the last 2.5m for all further "now" calculations
            if (-2 < minutesago && minutesago < 2.5) {
                now.glucose = ( now.glucose + then.glucose ) / 2;
                now_date = ( now_date + then_date ) / 2;
                //console.error(then.glucose, now.glucose);
            // short_deltas are calculated from everything ~5-15 minutes ago
            } else if (2.5 < minutesago && minutesago < 17.5) {
                //console.error(minutesago, avgdelta);
                short_deltas.push(avgdelta);
                // last_deltas are calculated from everything ~5 minutes ago
                if (2.5 < minutesago && minutesago < 7.5) {
                    last_deltas.push(avgdelta);
                }
                //console.error(then.glucose, minutesago, avgdelta, last_deltas, short_deltas);
            // long_deltas are calculated from everything ~20-40 minutes ago
            } else if (17.5 < minutesago && minutesago < 42.5) {
                long_deltas.push(avgdelta);
            }
        }
    }
    var last_delta = 0;
    var short_avgdelta = 0;
    var long_avgdelta = 0;
    if (last_deltas.length > 0) {
        last_delta = last_deltas.reduce(function(a, b) { return a + b; }) / last_deltas.length;
    }
    if (short_deltas.length > 0) {
        short_avgdelta = short_deltas.reduce(function(a, b) { return a + b; }) / short_deltas.length;
    }
    if (long_deltas.length > 0) {
        long_avgdelta = long_deltas.reduce(function(a, b) { return a + b; }) / long_deltas.length;
    }

    return {
        delta: Math.round( last_delta * 100 ) / 100
        , glucose: Math.round( now.glucose * 100 ) / 100
        , noise: Math.round(now.noise)
        , short_avgdelta: Math.round( short_avgdelta * 100 ) / 100
        , long_avgdelta: Math.round( long_avgdelta * 100 ) / 100
        , date: now_date
        , last_cal: last_cal
        , device: now.device
    };
};

module.exports = getLastGlucose;
<commit_msg>ignore null glucose records (may fix #1265) (#1324)<commit_after>function getDateFromEntry(entry) {
  return entry.date || Date.parse(entry.display_time) || Date.parse(entry.dateString);
}

var getLastGlucose = function (data) {
    data = data.filter(function(obj) {
      return obj.glucose || obj.sgv;
    }).map(function prepGlucose (obj) {
        //Support the NS sgv field to avoid having to convert in a custom way
        obj.glucose = obj.glucose || obj.sgv;
        if ( obj.glucose !== null ) {
            return obj;
        }
    });

    var now = data[0];
    var now_date = getDateFromEntry(now);
    var change;
    var last_deltas = [];
    var short_deltas = [];
    var long_deltas = [];
    var last_cal = 0;

    //console.error(now.glucose);
    for (var i=1; i < data.length; i++) {
        // if we come across a cal record, don't process any older SGVs
        if (typeof data[i] !== 'undefined' && data[i].type === "cal") {
            last_cal = i;
            break;
        }
        // only use data from the same device as the most recent BG data point
        if (typeof data[i] !== 'undefined' && data[i].glucose > 38 && data[i].device === now.device) {
            var then = data[i];
            var then_date = getDateFromEntry(then);
            var avgdelta = 0;
            var minutesago;
            if (typeof then_date !== 'undefined' && typeof now_date !== 'undefined') {
                minutesago = Math.round( (now_date - then_date) / (1000 * 60) );
                // multiply by 5 to get the same units as delta, i.e. mg/dL/5m
                change = now.glucose - then.glucose;
                avgdelta = change/minutesago * 5;
            } else { console.error("Error: date field not found: cannot calculate avgdelta"); }
            //if (i < 5) {
                //console.error(then.glucose, minutesago, avgdelta);
            //}
            // use the average of all data points in the last 2.5m for all further "now" calculations
            if (-2 < minutesago && minutesago < 2.5) {
                now.glucose = ( now.glucose + then.glucose ) / 2;
                now_date = ( now_date + then_date ) / 2;
                //console.error(then.glucose, now.glucose);
            // short_deltas are calculated from everything ~5-15 minutes ago
            } else if (2.5 < minutesago && minutesago < 17.5) {
                //console.error(minutesago, avgdelta);
                short_deltas.push(avgdelta);
                // last_deltas are calculated from everything ~5 minutes ago
                if (2.5 < minutesago && minutesago < 7.5) {
                    last_deltas.push(avgdelta);
                }
                //console.error(then.glucose, minutesago, avgdelta, last_deltas, short_deltas);
            // long_deltas are calculated from everything ~20-40 minutes ago
            } else if (17.5 < minutesago && minutesago < 42.5) {
                long_deltas.push(avgdelta);
            }
        }
    }
    var last_delta = 0;
    var short_avgdelta = 0;
    var long_avgdelta = 0;
    if (last_deltas.length > 0) {
        last_delta = last_deltas.reduce(function(a, b) { return a + b; }) / last_deltas.length;
    }
    if (short_deltas.length > 0) {
        short_avgdelta = short_deltas.reduce(function(a, b) { return a + b; }) / short_deltas.length;
    }
    if (long_deltas.length > 0) {
        long_avgdelta = long_deltas.reduce(function(a, b) { return a + b; }) / long_deltas.length;
    }

    return {
        delta: Math.round( last_delta * 100 ) / 100
        , glucose: Math.round( now.glucose * 100 ) / 100
        , noise: Math.round(now.noise)
        , short_avgdelta: Math.round( short_avgdelta * 100 ) / 100
        , long_avgdelta: Math.round( long_avgdelta * 100 ) / 100
        , date: now_date
        , last_cal: last_cal
        , device: now.device
    };
};

module.exports = getLastGlucose;
<|endoftext|>


<commit_before>/* @flow */

import React, { Component, PropTypes } from 'react';
import ReactNative from 'react-native';
import shallowCompare from 'react-addons-shallow-compare';
import CTACardContainerRoom from '../../containers/CTACardContainerRoom';
import PageEmpty from '../Page/PageEmpty';
import PageLoading from '../Page/PageLoading';
import LoadingItem from '../Core/LoadingItem';
import DiscussionItem from './DiscussionItem';
import StartDiscussionButton from '../StartDiscussion/StartDiscussionButton';
import type { Thread, ThreadRel } from '../../../../lib/schemaTypes';

const {
	PixelRatio,
	Dimensions,
	StyleSheet,
	RecyclerViewBackedScrollView,
	ListView,
	View,
} = ReactNative;

const styles = StyleSheet.create({
	column: {
		paddingTop: 6,
		paddingBottom: 88,
	},

	grid: {
		flexDirection: 'row',
		flexWrap: 'wrap',
		justifyContent: 'center',
		paddingTop: 12,
		paddingBottom: 88,
	},

	columnItem: {
		overflow: 'hidden',
	},

	gridItem: {
		overflow: 'hidden',
		width: 320,
		marginHorizontal: 12,
		marginVertical: 12,
		borderLeftWidth: 1 / PixelRatio.get(),
		borderRightWidth: 1 / PixelRatio.get(),
		borderRadius: 3,
	},
});

type DataItem = {
	thread: Thread;
	threadrel: ?ThreadRel;
	type?: 'loading'
};

type Props = {
	user: string;
	room: string;
	data: Array<DataItem>;
	loadMore: (count: number) => void;
	onNavigate: (count: number) => void;
}

type State = {
	dataSource: ListView.DataSource
}

export default class Discussions extends Component<void, Props, State> {
	static propTypes = {
		data: PropTypes.arrayOf(PropTypes.object).isRequired,
		room: PropTypes.string.isRequired,
		user: PropTypes.string.isRequired,
		loadMore: PropTypes.func.isRequired,
		onNavigate: PropTypes.func.isRequired,
	};

	state: State = {
		dataSource: new ListView.DataSource({
			rowHasChanged: (r1, r2) => r1 !== r2,
		}),
	};

	componentWillMount() {
		this.setState({
			dataSource: this.state.dataSource.cloneWithRows(this.props.data),
		});
	}

	componentWillReceiveProps(nextProps: Props) {
		this.setState({
			dataSource: this.state.dataSource.cloneWithRows(nextProps.data),
		});
	}

	shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
		return shallowCompare(this, nextProps, nextState);
	}

	_isWide = () => {
		return Dimensions.get('window').width > 400;
	};

	_renderRow = ({ thread, threadrel, type }: DataItem) => {
		switch (type) {
		case 'loading':
			return <LoadingItem />;
		case 'cta':
			return <CTACardContainerRoom room={this.props.room} style={this._isWide() ? styles.gridItem : styles.columnItem} />;
		default:
			if (!thread) {
				return null;
			}

			if (thread.type === 'loading') {
				return <LoadingItem />;
			}

			return (
				<DiscussionItem
					key={thread.id}
					thread={thread}
					threadrel={threadrel}
					onNavigate={this.props.onNavigate}
					style={this._isWide() ? styles.gridItem : styles.columnItem}
				/>
			);
		}
	};

	_renderScrollComponent = (props: any) => {
		return <RecyclerViewBackedScrollView {...props} />;
	};

	render() {
		const {
			data,
		} = this.props;

		let placeHolder;

		if (data.length === 0) {
			placeHolder = <PageEmpty label='No discussions yet' image='sad' />;
		} else if (data.length === 1) {
			switch (data[0] && data[0].type) {
			case 'loading':
				placeHolder = <PageLoading />;
				break;
			case 'banned':
				placeHolder = <PageEmpty label="You're banned in this group" image='meh' />;
				break;
			case 'nonexistent':
				placeHolder = <PageEmpty label="This group doesn't exist" image='sad' />;
				break;
			case 'failed':
				placeHolder = <PageEmpty label='Failed to load discussions' image='sad' />;
				break;
			}
		}

		return (
			<View {...this.props}>
				{placeHolder ? placeHolder :
					<ListView
						removeClippedSubviews
						initialListSize={3}
						pageSize={3}
						renderScrollComponent={this._renderScrollComponent}
						renderRow={this._renderRow}
						onEndReached={this.props.loadMore}
						dataSource={this.state.dataSource}
						contentContainerStyle={this._isWide() ? styles.grid : styles.column}
					/>
				}

				<StartDiscussionButton
					room={this.props.room}
					onNavigate={this.props.onNavigate}
				/>
			</View>
		);
	}
}
<commit_msg>fix(ui): fix grid layout for discussions in tablets (#400)<commit_after>/* @flow */

import React, { Component, PropTypes } from 'react';
import ReactNative from 'react-native';
import shallowCompare from 'react-addons-shallow-compare';
import CTACardContainerRoom from '../../containers/CTACardContainerRoom';
import PageEmpty from '../Page/PageEmpty';
import PageLoading from '../Page/PageLoading';
import LoadingItem from '../Core/LoadingItem';
import DiscussionItem from './DiscussionItem';
import StartDiscussionButton from '../StartDiscussion/StartDiscussionButton';
import type { Thread, ThreadRel } from '../../../../lib/schemaTypes';

const {
	PixelRatio,
	Dimensions,
	StyleSheet,
	ScrollView,
	RecyclerViewBackedScrollView,
	ListView,
	View,
} = ReactNative;

const styles = StyleSheet.create({
	column: {
		paddingTop: 6,
		paddingBottom: 88,
	},

	grid: {
		flexDirection: 'row',
		flexWrap: 'wrap',
		justifyContent: 'center',
		paddingTop: 12,
		paddingBottom: 88,
	},

	columnItem: {
		overflow: 'hidden',
	},

	gridItem: {
		overflow: 'hidden',
		width: 320,
		marginHorizontal: 12,
		marginVertical: 12,
		borderLeftWidth: 1 / PixelRatio.get(),
		borderRightWidth: 1 / PixelRatio.get(),
		borderRadius: 3,
	},
});

type DataItem = {
	thread: Thread;
	threadrel: ?ThreadRel;
	type?: 'loading'
};

type Props = {
	user: string;
	room: string;
	data: Array<DataItem>;
	loadMore: (count: number) => void;
	onNavigate: (count: number) => void;
}

type State = {
	dataSource: ListView.DataSource
}

export default class Discussions extends Component<void, Props, State> {
	static propTypes = {
		data: PropTypes.arrayOf(PropTypes.object).isRequired,
		room: PropTypes.string.isRequired,
		user: PropTypes.string.isRequired,
		loadMore: PropTypes.func.isRequired,
		onNavigate: PropTypes.func.isRequired,
	};

	state: State = {
		dataSource: new ListView.DataSource({
			rowHasChanged: (r1, r2) => r1 !== r2,
		}),
	};

	componentWillMount() {
		this.setState({
			dataSource: this.state.dataSource.cloneWithRows(this.props.data),
		});
	}

	componentWillReceiveProps(nextProps: Props) {
		this.setState({
			dataSource: this.state.dataSource.cloneWithRows(nextProps.data),
		});
	}

	shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
		return shallowCompare(this, nextProps, nextState);
	}

	_isWide = () => {
		return Dimensions.get('window').width > 400;
	};

	_renderRow = ({ thread, threadrel, type }: DataItem) => {
		switch (type) {
		case 'loading':
			return <LoadingItem />;
		case 'cta':
			return <CTACardContainerRoom room={this.props.room} style={this._isWide() ? styles.gridItem : styles.columnItem} />;
		default:
			if (!thread) {
				return null;
			}

			if (thread.type === 'loading') {
				return <LoadingItem />;
			}

			return (
				<DiscussionItem
					key={thread.id}
					thread={thread}
					threadrel={threadrel}
					onNavigate={this.props.onNavigate}
					style={this._isWide() ? styles.gridItem : styles.columnItem}
				/>
			);
		}
	};

	_renderScrollComponent = (props: any) => {
		// FIXME: RecyclerViewBackedScrollView doesn't support multi-column mode
		return this._isWide() ? <ScrollView {...props} /> : <RecyclerViewBackedScrollView {...props} />;
	};

	render() {
		const {
			data,
		} = this.props;

		let placeHolder;

		if (data.length === 0) {
			placeHolder = <PageEmpty label='No discussions yet' image='sad' />;
		} else if (data.length === 1) {
			switch (data[0] && data[0].type) {
			case 'loading':
				placeHolder = <PageLoading />;
				break;
			case 'banned':
				placeHolder = <PageEmpty label="You're banned in this group" image='meh' />;
				break;
			case 'nonexistent':
				placeHolder = <PageEmpty label="This group doesn't exist" image='sad' />;
				break;
			case 'failed':
				placeHolder = <PageEmpty label='Failed to load discussions' image='sad' />;
				break;
			}
		}

		return (
			<View {...this.props}>
				{placeHolder ? placeHolder :
					<ListView
						removeClippedSubviews
						initialListSize={3}
						pageSize={3}
						renderScrollComponent={this._renderScrollComponent}
						renderRow={this._renderRow}
						onEndReached={this.props.loadMore}
						dataSource={this.state.dataSource}
						contentContainerStyle={this._isWide() ? styles.grid : styles.column}
					/>
				}

				<StartDiscussionButton
					room={this.props.room}
					onNavigate={this.props.onNavigate}
				/>
			</View>
		);
	}
}
<|endoftext|>


<commit_before>$(document).ready(function(){

    $('a[rel="popover"]').popover({
        container: 'body',
        html: true,
        trigger:'hover',
        content: function () {
            var clone = $($(this).data('popover-content')).clone(true).removeClass('hide');
            return clone;
        }
    }).click(function(e) {
        e.preventDefault();
    });

});

var requestMetaData = function(data={}) {
    var access_key_header = "Bearer " + getCookie("WSO2_AM_TOKEN_1"); //TODO: tmkb Depend on result from
    // promise
    var request_meta = {
        clientAuthorizations: {
            api_key: new SwaggerClient.ApiKeyAuthorization("Authorization", access_key_header, "header")
        },
        responseContentType: data['Content-Type'] || "application/json"
    };
    return request_meta;
};

var getCookie = function(name) {
    var value = "; " + document.cookie;
    var parts = value.split("; " + name + "=");
    if (parts.length == 2) return parts.pop().split(";").shift();
};

var setAuthHeader = function(swaggerClient) {
    var bearerToken = "Bearer " + getCookie("WSO2_AM_TOKEN_1");
    swaggerClient.clientAuthorizations.add("apiKey", new SwaggerClient.ApiKeyAuthorization("Authorization", bearerToken, "header"));
    swaggerClient.setHost(location.host);

};

var redirectToLogin = function (contextPath) {
    var message = "The session has expired" + ".
 You will be redirect to the login page ...";
    noty({
        text: message,
        type: 'error',
        dismissQueue: true,
        modal: true,
        progressBar: true,
        timeout: 5000,
        layout: 'top',
        theme: 'relax',
        maxVisible: 10,
        callback: {
            afterClose: function () {
                window.location = loginPageUri;
            },
        }
    });
}
<commit_msg>Removed unused JS functions.<commit_after>$(document).ready(function(){

    $('a[rel="popover"]').popover({
        container: 'body',
        html: true,
        trigger:'hover',
        content: function () {
            var clone = $($(this).data('popover-content')).clone(true).removeClass('hide');
            return clone;
        }
    }).click(function(e) {
        e.preventDefault();
    });
});

var redirectToLogin = function (contextPath) {
    var message = "The session has expired" + ".
 You will be redirect to the login page ...";
    noty({
        text: message,
        type: 'error',
        dismissQueue: true,
        modal: true,
        progressBar: true,
        timeout: 5000,
        layout: 'top',
        theme: 'relax',
        maxVisible: 10,
        callback: {
            afterClose: function () {
                window.location = loginPageUri;
            },
        }
    });
}
<|endoftext|>


<commit_before>var html = "";

document.addEventListener('keydown', handleKeypress, false);

function handleKeypress(){
	if (event.keyCode == 84){
		getSelectionHtml();
		if (html != ""){
			var site = "http://words.bighugelabs.com/api/2/e2b80f9b79a99670c738434e668ebc08/" + html + "/";
			$.get(
				site,
				function(data) {
					var res = data.match(/\|.*?\n/) +"|";
					var syns = res.split("|");
					alert(syns[2]);
				}
			);
			html = "";
		}
	}
}

function getSelectionHtml() {
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
}<commit_msg>splitter<commit_after>var html = "";

document.addEventListener('keydown', handleKeypress, false);

function handleKeypress(){
	if (event.keyCode == 84){
		getSelectionHtml();
		if (html != ""){
			var site = "http://words.bighugelabs.com/api/2/e2b80f9b79a99670c738434e668ebc08/" + html + "/";
			$.get(
				site,
				function(data) {
					var res = data.match(/\|.*?\n/) +"|";
					var syns = res.split("|");
					alert(syns[2]);
				}
			);
			html = "";
		}
	}
}

function getSelectionHtml() {
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            selected = container.innerHTML;
			html = selected.split(" ")[1];
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            selected = document.selection.createRange().htmlText;
			html = selected.split(" ")[1];
        }
    }
}<|endoftext|>


<commit_before>'use strict';

var express = require('express');
var assert = require('assert');
var RabbitClient = require('./RabbitClient');

const PORT = 8080;
const DEFAULT_NAME = 'Anonymous';

var settings = {
    client: null
};

function get (req, res) {
    assert(typeof settings.client.rpc === 'function');

    var name = req.query.name || DEFAULT_NAME;
    settings.client.rpc(name, function (err, msg) {
        if (err) {
            console.error(` [e] failed with ${err}`);
            res.send(err);
            return;
        }
        console.log(` [.] Got ${msg.content.toString()}`);
        res.send(msg.content.toString());
    });
}

function init (client) {
    assert(client instanceof RabbitClient);
    settings.client = client;

    var app = express();

    app.get('/', get);

    app.listen(PORT);
    console.log('Application is ready');
}

module.exports = init;

<commit_msg>Refactored REST Server<commit_after>'use strict';

var express = require('express');
var assert = require('assert');
var RabbitClient = require('./RabbitClient');

const PORT = 8080;
const DEFAULT_NAME = 'Anonymous';

class RestServer {
    constructor (rabbitClient) {
        assert(rabbitClient instanceof RabbitClient);
        this.rabbitClient = rabbitClient;

        var app = express();

        app.param('person_name', this.fetchPersonMiddleware);
        app.get('/', this.getAnonymous);
        app.get('/:person_name', this.getPerson);

        app.listen(PORT);
        console.log('Application is ready');
    }
    getPerson (req, res) {
        res.json({
            success: true,
            response: req.greeting
        });
    }
    getAnonymous (req, res) {
        this.findPerson(DEFAULT_NAME, (err, result) => {
            if (err) {
                res.send(err);
                return;
            }
            res.json({
                success: true,
                response: result
            });
        });
    }
    fetchPersonMiddleware (request, response, next, person_name) {
        this.findPerson(person_name, (err, result) => {
            request.greeting = result;
            return next();
        });
    }
    findPerson (name, callback) {
        this.rabbitClient.rpc(name, function (err, msg) {
            if (err) {
                console.error(` [e] failed with ${err}`);
                return callback(err);
            }
            console.log(` [.] Got ${msg.content.toString()}`);
            callback(null, msg.content.toString());
        });
    }
}

//module.exports = init;
module.exports = RestServer;

<|endoftext|>


<commit_before>module.exports = {

	//---------------------------------------------------------------------
	// Action Name
	//
	// This is the name of the action displayed in the editor.
	//---------------------------------------------------------------------

	name: "Store Member Data List",

	//---------------------------------------------------------------------
	// Action Section
	//
	// This is the section the action will fall into.
	//---------------------------------------------------------------------

	section: "Member Control",

	//---------------------------------------------------------------------
	// DBM Mods Manager Variables (Optional but nice to have!)
	//
	// These are variables that DBM Mods Manager uses to show information
	// about the mods for people to see in the list.
	//---------------------------------------------------------------------

	// Who made the mod (If not set, defaults to "DBM Mods")
	author: "Two",

	// The version of the mod (Defaults to 1.0.0)
	version: "1.9.4", //Added in 1.9.4

	// A short description to show on the mod line for this mod (Must be on a single line)
	short_description: "This mod allows you to grab the members from a dataname then sort/dont sort it and/or use a result limit.",
	long_description: "While using this mod you can grab the members tag from a dataname that are stored in 'players.json'. You can use these members to sort their datas/dont sort and/or use a result limit. This mod can be used to make a leaderboard without MySQL or any other SQL Database.",

	// If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods

	//---------------------------------------------------------------------
	//---------------------------------------------------------------------
	// Action Subtitle
	//
	// This function generates the subtitle displayed next to the name.
	//---------------------------------------------------------------------

	subtitle: function (data) {
		return `${[(data.dataName)]}`
	},

	//---------------------------------------------------------------------
	// Action Storage Function
	//
	// Stores the relevant variable info for the editor.
	//---------------------------------------------------------------------

	variableStorage: function (data, varType) {
		const type = parseInt(data.storage);
		if (type !== varType) return;
		return ([data.varName2, 'Array']);
	},

	//---------------------------------------------------------------------
	// Action Fields
	//
	// These are the fields for the action. These fields are customized
	// by creating elements with corresponding IDs in the HTML. These
	// are also the names of the fields stored in the action's JSON data.
	//---------------------------------------------------------------------

	fields: ["debu", "numbefst2", "numbefst", "numbefstselect", "sort", "start", "middle", "end", "getresults", "dataName", "varName2", "storage"],

	//---------------------------------------------------------------------
	// Command HTML
	//
	// This function returns a string containing the HTML used for
	// editting actions.
	//
	// The "isEvent" parameter will be true if this action is being used
	// for an event. Due to their nature, events lack certain information,
	// so edit the HTML to reflect this.
	//
	// The "data" parameter stores constants for select elements to use.
	// Each is an array: index 0 for commands, index 1 for events.
	// The names are: sendTargets, members, roles, channels,
	//                messages, servers, variables
	//---------------------------------------------------------------------

	html: function (isEvent, data) {
		return `

		Data Name:

		<input id="dataName" class="round" type="text">

      Number before start
<select id="numbefstselect" class="round" style="width:33%" onchange="glob.onChange1(this)">
<option value="1" >No</option>
<option value="2"selected>Yes</option>
</select>

Char after Number:

<input id="numbefst2" class="round" type="text" value=")">

	Start:

	<select id="start" class="round" style="width:33%">
	<option value="result" >Result</option>
	<option value="username"selected>Username</option>
	</select>

		Middle:

		<input id="middle" style="width:80%"  class="round" type="text" value="-">
		</input>

	End:

	<select id="end" class="round" style="width:100%">

	<option value="result" selected>Result</option>
	<option value="username">Username</option>
	</select>

   <select id="sort" class="round" style="width: 90%;">
   <option value="0" selected>Don't Sort</option>
   <option value="1" selected>Sort from Descending</option>
   <option value="2">Sort from Ascending</option>
</select>

	Result Limit:
	<input id="getresults" class="round" type="text" placeholder="If blank it gets all results.">

	Store In:

	<select id="storage" class="round">
		${data.variables[1]}
	</select>

	Variable Name:

	<input id="varName2" class="round" type="text">

<select id="debu" class="round" style="width: 90%;">
<option value="0" selected>Debug</option>
<option value="1" selected>Don't Debug</option>

</select>

`
	},

	//---------------------------------------------------------------------
	// Action Editor Init Code
	//
	// When the HTML is first applied to the action editor, this code
	// is also run. This helps add modifications or setup reactionary
	// functions for the DOM elements.
	//---------------------------------------------------------------------

	init: function () {
		const {
			glob,
			document
		} = this;
		glob.onChange1 = function(event) {
			const value = parseInt(event.value);
			const dom = document.getElementById('numbefst');

			if(value == 1) {
				dom.style.display = 'none';

			} else if(value == 2) {

				dom.style.display = null;
			}

		}
		glob.onChange1(document.getElementById('numbefstselect'));
	},

	//---------------------------------------------------------------------
	// Action Bot Function
	//
	// This is the function for the action within the Bot's Action class.
	// Keep in mind event calls won't have access to the "msg" parameter,
	// so be sure to provide checks for variable existance.
	//---------------------------------------------------------------------

	action: function (cache) {
		var _this = this;
		const data = cache.actions[cache.index];
		var msg = cache.msg
		const type = parseInt(data.member);
		const varName = this.evalMessage(data.varName, cache);
		const storage = parseInt(data.storage);
		const varName2 = this.evalMessage(data.varName2, cache);
		const st = this.evalMessage(data.start, cache)
		const mid = this.evalMessage(data.middle, cache)
		const selectionsnum = parseInt(data.numbefstselect);

		const en = this.evalMessage(data.end, cache)
		const sort = parseInt(data.sort);
		const debug = parseInt(data.debu);
		const WrexMODS = this.getWrexMods(); // as always.

		var Discord = WrexMODS.require('discord.js');
		var fastsort = WrexMODS.require('fast-sort');
		var client = new Discord.Client();
		const {
			JSONPath
		} = WrexMODS.require('jsonpath-plus');
		fs = require('fs')
		var file = fs.readFileSync("./data/players.json", 'utf8');

		if (file) {
			var dataName = this.evalMessage(data.dataName, cache);
			dataName = '[' + "'" + dataName + "'" + ']'

			const isAdd = Boolean(data.changeType === "1");
			let val = this.evalMessage(data.value, cache);
			var list2 = []
			var list = []
			var list4 = []
			var list5 = []

			if (val !== undefined) {
				var file = JSON.parse(file)
				try {
					var list = []
					var result = JSONPath({
						path: '$.[?(@' + dataName + ' || @' + dataName + ' > -9999999999999999999999999999999999999999999999999999999)]*~',
						json: file
					});
					var pull = result;

					function sortNumber(a, b) {
						return b - a;
					}
					for (var i = 0; i < result.length; i++) {

						var result2 = JSONPath({
							path: '$.' + result[i] + dataName,
							json: file
						});

						try {

							var user = msg.guild.members.get(result[i]);

							tag = user.user.tag

							var name2 = "'" + "name" + "'";
							var id = "'" + "id" + "'";
							var tag2 = "" + tag + "";
							var res2 = "" + result2 + "";

							list.push({
								id: tag2,
								name2: res2
							});

						} catch (err) {
							switch (debug) {
								case 0:
								console.log(err)
								break;
								case 1:
								break;
							}

						}
					}
					switch (sort) {
						case 1:
							result = fastsort(list).desc(u => parseInt(u.name2));
							break;
						case 2:

							result = fastsort(list).asc(u => parseInt(u.name2));
							break;
						case 0:
							result = list
							break;
					}
                   console.log(result)
					var result2 = JSON.stringify(result)

					var getres = parseInt(this.evalMessage(data.getresults, cache));

					if (!getres) {

						getres = result.length;
					}

					for (var i = 0; i < getres; i++) {
						var result2 = JSON.stringify(list[i])

						try {
							var file = JSON.parse(result2)

							var res = JSONPath({
								path: '$..name2',
								json: file
							});
							var res2 = JSONPath({
								path: '$..id',
								json: file
							});

							var username = res2
							var result = res

							eval(' ' + st + ' ');
							var middle = " " + mid + " "
							eval(' ' + en + ' ');
							var username = res2
							var result = res
							var en2 = eval(en);
							var st2 = eval(st);
							list5.push("easter egg :eyes:")
							switch (selectionsnum) {
								case 1:

									list2.push(st2 + middle + en2 + '\n')
									break;
								case 2:

									var num = list5.length;
									var numbef = this.evalMessage(data.numbefst2, cache)
									list2.push(num + numbef + " " + st2 + middle + en2 + '\n')
									break;
							}

						} catch (err) {
							switch (debug) {
								case 0:
								console.log(err)
								break;
								case 1:
								break;
							}
						}

						list4 = list2.join('')

					}

					_this.storeValue(list4, storage, varName2, cache)
					_this.callNextAction(cache);
				} catch (err) {
					switch (debug) {
						case 0:
						console.log(err)
						break;
						case 1:
						break;
					}
				}

			}
		}

	},

	//---------------------------------------------------------------------
	// Action Bot Mod
	//
	// Upon initialization of the bot, this code is run. Using the bot's
	// DBM namespace, one can add/modify existing functions if necessary.
	// In order to reduce conflictions between mods, be sure to alias
	// functions you wish to overwrite.
	//---------------------------------------------------------------------

	mod: function (DBM) {}

}; // End of module
<commit_msg>Removed annoying console.log<commit_after>module.exports = {

	//---------------------------------------------------------------------
	// Action Name
	//
	// This is the name of the action displayed in the editor.
	//---------------------------------------------------------------------

	name: "Store Member Data List",

	//---------------------------------------------------------------------
	// Action Section
	//
	// This is the section the action will fall into.
	//---------------------------------------------------------------------

	section: "Member Control",

	//---------------------------------------------------------------------
	// DBM Mods Manager Variables (Optional but nice to have!)
	//
	// These are variables that DBM Mods Manager uses to show information
	// about the mods for people to see in the list.
	//---------------------------------------------------------------------

	// Who made the mod (If not set, defaults to "DBM Mods")
	author: "Two",

	// The version of the mod (Defaults to 1.0.0)
	version: "1.9.4", //Added in 1.9.4

	// A short description to show on the mod line for this mod (Must be on a single line)
	short_description: "This mod allows you to grab the members from a dataname then sort/dont sort it and/or use a result limit.",
	long_description: "While using this mod you can grab the members tag from a dataname that are stored in 'players.json'. You can use these members to sort their datas/dont sort and/or use a result limit. This mod can be used to make a leaderboard without MySQL or any other SQL Database.",

	// If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods

	//---------------------------------------------------------------------
	//---------------------------------------------------------------------
	// Action Subtitle
	//
	// This function generates the subtitle displayed next to the name.
	//---------------------------------------------------------------------

	subtitle: function (data) {
		return `${[(data.dataName)]}`
	},

	//---------------------------------------------------------------------
	// Action Storage Function
	//
	// Stores the relevant variable info for the editor.
	//---------------------------------------------------------------------

	variableStorage: function (data, varType) {
		const type = parseInt(data.storage);
		if (type !== varType) return;
		return ([data.varName2, 'Array']);
	},

	//---------------------------------------------------------------------
	// Action Fields
	//
	// These are the fields for the action. These fields are customized
	// by creating elements with corresponding IDs in the HTML. These
	// are also the names of the fields stored in the action's JSON data.
	//---------------------------------------------------------------------

	fields: ["debu", "numbefst2", "numbefst", "numbefstselect", "sort", "start", "middle", "end", "getresults", "dataName", "varName2", "storage"],

	//---------------------------------------------------------------------
	// Command HTML
	//
	// This function returns a string containing the HTML used for
	// editting actions.
	//
	// The "isEvent" parameter will be true if this action is being used
	// for an event. Due to their nature, events lack certain information,
	// so edit the HTML to reflect this.
	//
	// The "data" parameter stores constants for select elements to use.
	// Each is an array: index 0 for commands, index 1 for events.
	// The names are: sendTargets, members, roles, channels,
	//                messages, servers, variables
	//---------------------------------------------------------------------

	html: function (isEvent, data) {
		return `

		Data Name:

		<input id="dataName" class="round" type="text">

      Number before start
<select id="numbefstselect" class="round" style="width:33%" onchange="glob.onChange1(this)">
<option value="1" >No</option>
<option value="2"selected>Yes</option>
</select>

Char after Number:

<input id="numbefst2" class="round" type="text" value=")">

	Start:

	<select id="start" class="round" style="width:33%">
	<option value="result" >Result</option>
	<option value="username"selected>Username</option>
	</select>

		Middle:

		<input id="middle" style="width:80%"  class="round" type="text" value="-">
		</input>

	End:

	<select id="end" class="round" style="width:100%">

	<option value="result" selected>Result</option>
	<option value="username">Username</option>
	</select>

   <select id="sort" class="round" style="width: 90%;">
   <option value="0" selected>Don't Sort</option>
   <option value="1" selected>Sort from Descending</option>
   <option value="2">Sort from Ascending</option>
</select>

	Result Limit:
	<input id="getresults" class="round" type="text" placeholder="If blank it gets all results.">

	Store In:

	<select id="storage" class="round">
		${data.variables[1]}
	</select>

	Variable Name:

	<input id="varName2" class="round" type="text">

<select id="debu" class="round" style="width: 90%;">
<option value="0" selected>Debug</option>
<option value="1" selected>Don't Debug</option>

</select>

`
	},

	//---------------------------------------------------------------------
	// Action Editor Init Code
	//
	// When the HTML is first applied to the action editor, this code
	// is also run. This helps add modifications or setup reactionary
	// functions for the DOM elements.
	//---------------------------------------------------------------------

	init: function () {
		const {
			glob,
			document
		} = this;
		glob.onChange1 = function(event) {
			const value = parseInt(event.value);
			const dom = document.getElementById('numbefst');

			if(value == 1) {
				dom.style.display = 'none';

			} else if(value == 2) {

				dom.style.display = null;
			}

		}
		glob.onChange1(document.getElementById('numbefstselect'));
	},

	//---------------------------------------------------------------------
	// Action Bot Function
	//
	// This is the function for the action within the Bot's Action class.
	// Keep in mind event calls won't have access to the "msg" parameter,
	// so be sure to provide checks for variable existance.
	//---------------------------------------------------------------------

	action: function (cache) {
		var _this = this;
		const data = cache.actions[cache.index];
		var msg = cache.msg
		const type = parseInt(data.member);
		const varName = this.evalMessage(data.varName, cache);
		const storage = parseInt(data.storage);
		const varName2 = this.evalMessage(data.varName2, cache);
		const st = this.evalMessage(data.start, cache)
		const mid = this.evalMessage(data.middle, cache)
		const selectionsnum = parseInt(data.numbefstselect);

		const en = this.evalMessage(data.end, cache)
		const sort = parseInt(data.sort);
		const debug = parseInt(data.debu);
		const WrexMODS = this.getWrexMods(); // as always.

		var Discord = WrexMODS.require('discord.js');
		var fastsort = WrexMODS.require('fast-sort');
		var client = new Discord.Client();
		const {
			JSONPath
		} = WrexMODS.require('jsonpath-plus');
		fs = require('fs')
		var file = fs.readFileSync("./data/players.json", 'utf8');

		if (file) {
			var dataName = this.evalMessage(data.dataName, cache);
			dataName = '[' + "'" + dataName + "'" + ']'

			const isAdd = Boolean(data.changeType === "1");
			let val = this.evalMessage(data.value, cache);
			var list2 = []
			var list = []
			var list4 = []
			var list5 = []

			if (val !== undefined) {
				var file = JSON.parse(file)
				try {
					var list = []
					var result = JSONPath({
						path: '$.[?(@' + dataName + ' || @' + dataName + ' > -9999999999999999999999999999999999999999999999999999999)]*~',
						json: file
					});
					var pull = result;

					function sortNumber(a, b) {
						return b - a;
					}
					for (var i = 0; i < result.length; i++) {

						var result2 = JSONPath({
							path: '$.' + result[i] + dataName,
							json: file
						});

						try {

							var user = msg.guild.members.get(result[i]);

							tag = user.user.tag

							var name2 = "'" + "name" + "'";
							var id = "'" + "id" + "'";
							var tag2 = "" + tag + "";
							var res2 = "" + result2 + "";

							list.push({
								id: tag2,
								name2: res2
							});

						} catch (err) {
							switch (debug) {
								case 0:
								console.log(err)
								break;
								case 1:
								break;
							}

						}
					}
					switch (sort) {
						case 1:
							result = fastsort(list).desc(u => parseInt(u.name2));
							break;
						case 2:

							result = fastsort(list).asc(u => parseInt(u.name2));
							break;
						case 0:
							result = list
							break;
					}

					var result2 = JSON.stringify(result)

					var getres = parseInt(this.evalMessage(data.getresults, cache));

					if (!getres) {

						getres = result.length;
					}

					for (var i = 0; i < getres; i++) {
						var result2 = JSON.stringify(list[i])

						try {
							var file = JSON.parse(result2)

							var res = JSONPath({
								path: '$..name2',
								json: file
							});
							var res2 = JSONPath({
								path: '$..id',
								json: file
							});

							var username = res2
							var result = res

							eval(' ' + st + ' ');
							var middle = " " + mid + " "
							eval(' ' + en + ' ');
							var username = res2
							var result = res
							var en2 = eval(en);
							var st2 = eval(st);
							list5.push("easter egg :eyes:")
							switch (selectionsnum) {
								case 1:

									list2.push(st2 + middle + en2 + '\n')
									break;
								case 2:

									var num = list5.length;
									var numbef = this.evalMessage(data.numbefst2, cache)
									list2.push(num + numbef + " " + st2 + middle + en2 + '\n')
									break;
							}

						} catch (err) {
							switch (debug) {
								case 0:
								console.log(err)
								break;
								case 1:
								break;
							}
						}

						list4 = list2.join('')

					}

					_this.storeValue(list4, storage, varName2, cache)
					_this.callNextAction(cache);
				} catch (err) {
					switch (debug) {
						case 0:
						console.log(err)
						break;
						case 1:
						break;
					}
				}

			}
		}

	},

	//---------------------------------------------------------------------
	// Action Bot Mod
	//
	// Upon initialization of the bot, this code is run. Using the bot's
	// DBM namespace, one can add/modify existing functions if necessary.
	// In order to reduce conflictions between mods, be sure to alias
	// functions you wish to overwrite.
	//---------------------------------------------------------------------

	mod: function (DBM) {}

}; // End of module
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'react-flexbox-grid';

export class RenderPatronGroupLastUpdated extends React.Component {
  static propTypes = {
    mutator: PropTypes.shape({
      updatedBy: PropTypes.shape({
        GET: PropTypes.func,
      }),
    }).isRequired,
  };

  static defaultProps = {};

  static manifest = Object.freeze({
    updatedBy: {
      type: 'okapi',
      path: 'users/!{item.metadata.updatedByUserId}',
    }
  });

  constructor(props) {
    super(props);
    this.state = {};
  }

  ready() {
    return this.props.resources.updatedBy && this.props.resources.updatedBy.hasLoaded;
  }

  getLastUpdated() {
    return this.ready() ? this.buildValue(this.props.resources.updatedBy.records[0], this.props.item) : undefined;
  }

  formatDate(date) {
    const year = date.getFullYear();
    const month = date.getMonth();
    const day = date.getDate();
    return [year, month < 10 ? "0" + month : month, day < 10 ? "0" + day : day].join("-")
  }

  buildValue(user, group) {
    let date = new Date(group.metadata.updatedDate);
    return this.formatDate(date) + " by " +
      user.personal.lastName + ", " +
      user.personal.firstName;
  }

  render() {
    return (<Col key={this.props.key} xs>{this.getLastUpdated()}</Col>);
  }
}
<commit_msg>some more minor cleanup<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'react-flexbox-grid';

export class RenderPatronGroupLastUpdated extends React.Component {
  static propTypes = {
    mutator: PropTypes.shape({
      updatedBy: PropTypes.shape({
        GET: PropTypes.func,
      }),
    }).isRequired,
  };

  static defaultProps = {};

  static manifest = Object.freeze({
    updatedBy: {
      type: 'okapi',
      path: 'users/!{item.metadata.updatedByUserId}',
    }
  });

  constructor(props) {
    super(props);
    this.state = {};
  }

  ready() {
    return this.props.resources.updatedBy && this.props.resources.updatedBy.hasLoaded;
  }

  getLastUpdated() {
    return this.ready() ? this.buildValue(this.props.resources.updatedBy.records[0], this.props.item) : undefined;
  }

  buildValue(user, group) {
    let date = new Date(group.metadata.updatedDate);
    return this.formatDate(date) + " by " +
      user.personal.lastName + ", " +
      user.personal.firstName;
  }

  formatDate(date) {
    const year = date.getFullYear();
    const month = date.getMonth();
    const day = date.getDate();
    return [year, month < 10 ? "0" + month : month, day < 10 ? "0" + day : day].join("-")
  }

  render() {
    return (<Col key={this.props.key} xs>{this.getLastUpdated()}</Col>);
  }
}
<|endoftext|>


<commit_before>var Channel = Backbone.Model.extend();

var Channels = Backbone.Collection.extend({
  model: Channel
});

var ActiveChannel = Backbone.View.extend({
  tagName: "div",
  className: "active-channel",
  template: '
{{content}}
',

  render: function() {
    this.$el.html(this.template.replace("{{content}}", this.model.attributes["data"]));
    $("#main-data").first.html($this.$el.html);
  },

  initialize: function() {
    this.listenTo(this.model, "change", this.render);
    this.render();
  }

});

var ChannelTab = Backbone.View.extend({

  tagName: "li",

  className: "",

  template: '{{name}}',

  render: function() {
    this.$el.html(this.template.replace("{{name}}", this.model.attributes["name"]));
    return this;
  },

  select: function() {
    // Callback to inspect this node goes here
  },

  events: {
    "click .nav":          "select"
  },

  install: function() {
    $('#channels-content')[0].appendChild(this.el);
  },

  initialize: function() {
    this.listenTo(this.model, "change", this.render);
    this.render();
    this.install();
  }

});

groundstation_channels = new Channels();
groundstation_channels.url = '/channels';
<commit_msg>Fix broken click handler<commit_after>var Channel = Backbone.Model.extend();

var Channels = Backbone.Collection.extend({
  model: Channel
});

var ActiveChannel = Backbone.View.extend({
  tagName: "div",
  className: "active-channel",
  template: '
{{content}}
',

  render: function() {
    this.$el.html(this.template.replace("{{content}}", this.model.attributes["data"]));
    $("#main-data").first.html($this.$el.html);
  },

  initialize: function() {
    this.listenTo(this.model, "change", this.render);
    this.render();
  }

});

var ChannelTab = Backbone.View.extend({

  tagName: "li",

  className: "",

  template: '{{name}}',

  render: function() {
    this.$el.html(this.template.replace("{{name}}", this.model.attributes["name"]));
    return this;
  },

  select: function() {
    // Callback to inspect this node goes here
  },

  events: {
    "click .select":          "select"
  },

  install: function() {
    $('#channels-content')[0].appendChild(this.el);
  },

  initialize: function() {
    this.listenTo(this.model, "change", this.render);
    this.render();
    this.install();
  }

});

groundstation_channels = new Channels();
groundstation_channels.url = '/channels';
<|endoftext|>


<commit_before>module.exports = function(sails) {

	/**
	 * Module dependencies.
	 */

	var _ = require('lodash'),
		util = require('sails-util');

	/**
	 * Expose hook definition
	 */

	return {

    SECURITY_LEVEL_NORMAL: 0,
    SECURITY_LEVEL_HIGH: 1,
    SECURITY_LEVEL_VERYHIGH: 2,

		defaults: {
			cors: {
				origin: '*',
				credentials: true,
				methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
				headers: 'content-type',
				exposeHeaders: '',
        securityLevel: 0,
			}
		},

		initialize: function(cb) {

			sails.on('router:before', function () {

				// If we're setting CORS on all routes by default, set up a universal route for it here.
				// CORS can still be turned off for specific routes by setting "cors:false"
				if (sails.config.cors.allRoutes === true) {
          sails.router.bind('/*', sendHeaders(), 'all', {_middlewareType: 'CORS HOOK: sendHeaders'});
				}
        // Otherwise clear all the headers by default
        else {
          sails.router.bind('/*', clearHeaders, 'all', {_middlewareType: 'CORS HOOK: clearHeaders'});
        }

        var optionsRouteConfigs = {};

				// Loop through all configured routes, looking for CORS options
				_.each(sails.config.routes, function(config, route) {

          var routeInfo = sails.util.detectVerb(route);
          var path = routeInfo.original.toLowerCase();
          var verb = routeInfo.verb.toLowerCase();

					if (!_.isUndefined(config.cors)) {

            optionsRouteConfigs[path] = optionsRouteConfigs[path] || {"default": sails.config.cors};

						// If cors is set to "true", and we're not doing all routes by default, set
						// the CORS headers for this route using the default origin
						if (config.cors === true) {
              // Use the default CORS config for this path on an OPTIONS request
              optionsRouteConfigs[path][verb || "default"] = sails.config.cors;
              if (!sails.config.cors.allRoutes) {
							 sails.router.bind(route, sendHeaders(), null);
              }
						}

            // If cors is set to "false", clear the CORS headers for this route
            else if (config.cors === false) {
              // Clear headers on an OPTIONS request for this path
              optionsRouteConfigs[path][verb || "default"] = "clear";
              sails.router.bind(route, clearHeaders, null, {_middlewareType: 'CORS HOOK: clearHeaders'});
              return;
            }

						// Else if cors is set to a string, use that has the origin
						else if (typeof config.cors === "string") {
              optionsRouteConfigs[path][verb || "default"] = _.extend({origin: config.cors},{methods: verb});
							sails.router.bind(route, sendHeaders({origin:config.cors}), null);
						}

						// Else if cors is an object, use that as the config
						else if (_.isPlainObject(config.cors)) {
              // If the route has a verb, it shouldn't have a "methods" CORS setting
              if (routeInfo.verb && config.cors.methods) {
                sails.log.warn("Ignoring 'methods' CORS setting for route "+route+" because it has a verb specified.");
                config.cors.methods = verb;
              }
              optionsRouteConfigs[path][verb || "default"] = config.cors;
							sails.router.bind(route, sendHeaders(config.cors), null);
						}

						// Otherwise throw a warning
						else {
							sails.log.warn("Invalid CORS settings for route "+route);
						}

					}

				});

        _.each(optionsRouteConfigs, function(config, path) {
          sails.router.bind("options "+path, sendHeaders(config, true), null, {_middlewareType: 'CORS HOOK: preflight'});
        });

        // IF SECURITY_LEVEL > "normal"--don't process requests from disallowed origins
        //
        // We can't just rely on the browser implementing "access-control-allow-origin" correctly;
        // we need to make sure that if a request is made from an origin that isn't whitelisted,
        // that we don't end up processing that request.
        if (sails.config.cors.securityLevel > sails.hooks.cors.SECURITY_LEVEL_NORMAL) {
          sails.router.bind('/*', function(req, res, next) {

            // If it's a cross-origin request, and the access-control-allow-origin header doesn't match
            // the origin header, then we don't approve of this origin and shouldn't continue
            // with this request.
            if (!sails.util.isSameOrigin(req, sails.config.cors.securityLevel == sails.hooks.cors.SECURITY_LEVEL_VERYHIGH) && res.get('Access-Control-Allow-Origin') != req.headers.origin) {
              return res.forbidden();
            }
            return next();
          }, null, {_middlewareType: 'CORS HOOK: catchall'});
        }

			});

			cb();

		}

	};

	function sendHeaders(_routeCorsConfig, isOptionsRoute) {

		if (!_routeCorsConfig) {
			_routeCorsConfig = {};
		}
		var _sendHeaders = function(req, res, next) {
      var routeCorsConfig;
      // If this is an options route handler, pull the config to use based on the method
      // that would be used in the follow-on request
      if (isOptionsRoute) {
        var method = (req.headers['access-control-request-method'] || '').toLowerCase() || "default";
        routeCorsConfig = _routeCorsConfig[method];
        if (routeCorsConfig == 'clear') {
          return clearHeaders(req, res, next);
        }
      }
      // Otherwise just use the config that was passed down
      else {
        routeCorsConfig = _routeCorsConfig;
      }
      // If we have an origin header...
			if (req.headers && req.headers.origin) {

				// Get the allowed origins
				var origins = (routeCorsConfig.origin || sails.config.cors.origin).split(',');

				// Match the origin of the request against the allowed origins
				var foundOrigin = false;
				_.every(origins, function(origin) {

					origin = origin.trim();
					// If we find a whitelisted origin, send the Access-Control-Allow-Origin header
					// to greenlight the request.
					if (origin == req.headers.origin || origin == "*") {
						res.set('Access-Control-Allow-Origin', req.headers.origin);
						foundOrigin = true;
						return false;
					}
					return true;
				});

				if (!foundOrigin) {
          // For HTTP requests, set the Access-Control-Allow-Origin header to '', which the browser will
          // interpret as, "no way Jose."
					res.set('Access-Control-Allow-Origin', '');
				}

        // Determine whether or not to allow cookies to be passed cross-origin
				res.set('Access-Control-Allow-Credentials', !_.isUndefined(routeCorsConfig.credentials) ? routeCorsConfig.credentials : sails.config.cors.credentials);

	// This header lets a server whitelist headers that browsers are allowed to access
        res.set('Access-Control-Expose-Headers', !_.isUndefined(routeCorsConfig.exposeHeaders) ? routeCorsConfig.exposeHeaders : sails.config.cors.exposeHeaders);

        // Handle preflight requests
				if (req.method == "OPTIONS") {
					res.set('Access-Control-Allow-Methods', !_.isUndefined(routeCorsConfig.methods) ? routeCorsConfig.methods : sails.config.cors.methods);
					res.set('Access-Control-Allow-Headers', !_.isUndefined(routeCorsConfig.headers) ? routeCorsConfig.headers : sails.config.cors.headers);
				}

			}

			next();

		};

    _sendHeaders._middlewareType = "CORS HOOK: sendHeaders";
    return _sendHeaders;

	}

	function clearHeaders(req, res, next) {
		// If we can set headers (i.e. it's not a socket request), do so.
		if (res.set) {
			res.set('Access-Control-Allow-Origin', '');
			res.set('Access-Control-Allow-Credentials', '');
			res.set('Access-Control-Allow-Methods', '');
			res.set('Access-Control-Allow-Headers', '');
			res.set('Access-Control-Expose-Headers', '');
		}

		next();

	}

};
<commit_msg>Autoformat file.<commit_after>module.exports = function(sails) {

  /**
   * Module dependencies.
   */

  var _ = require('lodash'),
    util = require('sails-util');

  /**
   * Expose hook definition
   */

  return {

    SECURITY_LEVEL_NORMAL: 0,
    SECURITY_LEVEL_HIGH: 1,
    SECURITY_LEVEL_VERYHIGH: 2,

    defaults: {
      cors: {
        origin: '*',
        credentials: true,
        methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
        headers: 'content-type',
        exposeHeaders: '',
        securityLevel: 0,
      }
    },

    initialize: function(cb) {

      sails.on('router:before', function () {

        // If we're setting CORS on all routes by default, set up a universal route for it here.
        // CORS can still be turned off for specific routes by setting "cors:false"
        if (sails.config.cors.allRoutes === true) {
          sails.router.bind('/*', sendHeaders(), 'all', {_middlewareType: 'CORS HOOK: sendHeaders'});
        }
        // Otherwise clear all the headers by default
        else {
          sails.router.bind('/*', clearHeaders, 'all', {_middlewareType: 'CORS HOOK: clearHeaders'});
        }

        var optionsRouteConfigs = {};

        // Loop through all configured routes, looking for CORS options
        _.each(sails.config.routes, function(config, route) {

          var routeInfo = sails.util.detectVerb(route);
          var path = routeInfo.original.toLowerCase();
          var verb = routeInfo.verb.toLowerCase();

          if (!_.isUndefined(config.cors)) {

            optionsRouteConfigs[path] = optionsRouteConfigs[path] || {"default": sails.config.cors};

            // If cors is set to "true", and we're not doing all routes by default, set
            // the CORS headers for this route using the default origin
            if (config.cors === true) {
              // Use the default CORS config for this path on an OPTIONS request
              optionsRouteConfigs[path][verb || "default"] = sails.config.cors;
              if (!sails.config.cors.allRoutes) {
               sails.router.bind(route, sendHeaders(), null);
              }
            }

            // If cors is set to "false", clear the CORS headers for this route
            else if (config.cors === false) {
              // Clear headers on an OPTIONS request for this path
              optionsRouteConfigs[path][verb || "default"] = "clear";
              sails.router.bind(route, clearHeaders, null, {_middlewareType: 'CORS HOOK: clearHeaders'});
              return;
            }

            // Else if cors is set to a string, use that has the origin
            else if (typeof config.cors === "string") {
              optionsRouteConfigs[path][verb || "default"] = _.extend({origin: config.cors},{methods: verb});
              sails.router.bind(route, sendHeaders({origin:config.cors}), null);
            }

            // Else if cors is an object, use that as the config
            else if (_.isPlainObject(config.cors)) {
              // If the route has a verb, it shouldn't have a "methods" CORS setting
              if (routeInfo.verb && config.cors.methods) {
                sails.log.warn("Ignoring 'methods' CORS setting for route "+route+" because it has a verb specified.");
                config.cors.methods = verb;
              }
              optionsRouteConfigs[path][verb || "default"] = config.cors;
              sails.router.bind(route, sendHeaders(config.cors), null);
            }

            // Otherwise throw a warning
            else {
              sails.log.warn("Invalid CORS settings for route "+route);
            }

          }

        });

        _.each(optionsRouteConfigs, function(config, path) {
          sails.router.bind("options "+path, sendHeaders(config, true), null, {_middlewareType: 'CORS HOOK: preflight'});
        });

        // IF SECURITY_LEVEL > "normal"--don't process requests from disallowed origins
        //
        // We can't just rely on the browser implementing "access-control-allow-origin" correctly;
        // we need to make sure that if a request is made from an origin that isn't whitelisted,
        // that we don't end up processing that request.
        if (sails.config.cors.securityLevel > sails.hooks.cors.SECURITY_LEVEL_NORMAL) {
          sails.router.bind('/*', function(req, res, next) {

            // If it's a cross-origin request, and the access-control-allow-origin header doesn't match
            // the origin header, then we don't approve of this origin and shouldn't continue
            // with this request.
            if (!sails.util.isSameOrigin(req, sails.config.cors.securityLevel == sails.hooks.cors.SECURITY_LEVEL_VERYHIGH) && res.get('Access-Control-Allow-Origin') != req.headers.origin) {
              return res.forbidden();
            }
            return next();
          }, null, {_middlewareType: 'CORS HOOK: catchall'});
        }

      });

      cb();

    }

  };

  function sendHeaders(_routeCorsConfig, isOptionsRoute) {

    if (!_routeCorsConfig) {
      _routeCorsConfig = {};
    }
    var _sendHeaders = function(req, res, next) {
      var routeCorsConfig;
      // If this is an options route handler, pull the config to use based on the method
      // that would be used in the follow-on request
      if (isOptionsRoute) {
        var method = (req.headers['access-control-request-method'] || '').toLowerCase() || "default";
        routeCorsConfig = _routeCorsConfig[method];
        if (routeCorsConfig == 'clear') {
          return clearHeaders(req, res, next);
        }
      }
      // Otherwise just use the config that was passed down
      else {
        routeCorsConfig = _routeCorsConfig;
      }
      // If we have an origin header...
      if (req.headers && req.headers.origin) {

        // Get the allowed origins
        var origins = (routeCorsConfig.origin || sails.config.cors.origin).split(',');

        // Match the origin of the request against the allowed origins
        var foundOrigin = false;
        _.every(origins, function(origin) {

          origin = origin.trim();
          // If we find a whitelisted origin, send the Access-Control-Allow-Origin header
          // to greenlight the request.
          if (origin == req.headers.origin || origin == "*") {
            res.set('Access-Control-Allow-Origin', req.headers.origin);
            foundOrigin = true;
            return false;
          }
          return true;
        });

        if (!foundOrigin) {
          // For HTTP requests, set the Access-Control-Allow-Origin header to '', which the browser will
          // interpret as, "no way Jose."
          res.set('Access-Control-Allow-Origin', '');
        }

        // Determine whether or not to allow cookies to be passed cross-origin
        res.set('Access-Control-Allow-Credentials', !_.isUndefined(routeCorsConfig.credentials) ? routeCorsConfig.credentials : sails.config.cors.credentials);

        // This header lets a server whitelist headers that browsers are allowed to access
        res.set('Access-Control-Expose-Headers', !_.isUndefined(routeCorsConfig.exposeHeaders) ? routeCorsConfig.exposeHeaders : sails.config.cors.exposeHeaders);

        // Handle preflight requests
        if (req.method == "OPTIONS") {
          res.set('Access-Control-Allow-Methods', !_.isUndefined(routeCorsConfig.methods) ? routeCorsConfig.methods : sails.config.cors.methods);
          res.set('Access-Control-Allow-Headers', !_.isUndefined(routeCorsConfig.headers) ? routeCorsConfig.headers : sails.config.cors.headers);
        }

      }

      next();

    };

    _sendHeaders._middlewareType = "CORS HOOK: sendHeaders";
    return _sendHeaders;

  }

  function clearHeaders(req, res, next) {
    // If we can set headers (i.e. it's not a socket request), do so.
    if (res.set) {
      res.set('Access-Control-Allow-Origin', '');
      res.set('Access-Control-Allow-Credentials', '');
      res.set('Access-Control-Allow-Methods', '');
      res.set('Access-Control-Allow-Headers', '');
      res.set('Access-Control-Expose-Headers', '');
    }

    next();

  }

};
<|endoftext|>


<commit_before>/*

TODO check the pending not 200 requests (seen with node-static, but check also http operation requests)

*/
require('./api');
var M = process.mono;
var http = require('http');
var WebSocketServer = require('ws').Server;
var parse = require('url').parse;
var route = require(M.config.paths.SERVER_ROOT + 'router');
var send = require(M.config.paths.SERVER_ROOT + 'send');

// check event access and if event and miid exists
function getCachedMiid (miid, event) {

    miid = M.cache.miids.get(miid);

    if (miid && miid.mono.access[event] && miid.listeners(event).length > 0) {
        return miid;
    }
    return null;
}

// handle http request
function requestHandler (req, res) {

    var url = parse(req.url, true);
    var path = url.pathname.replace(/\/$|^\//g, "").split("/", 42);

    if (path[0] == M.config.coreKey) {

        if (path.length < 3) {
            return send.httpError(req, res, 400, new Error('Invalid operation url.'));
        }

        // if no operation was found in the request URL
        if (!path[1] || !path[2]) {
            return send.httpError(req, res, 400, new Error('Missing module instance ID or operation name.'));
        }

        // get cached miid and check access
        var miid = getCachedMiid(path[1], path[2]);

        // check if miid an operation exists
        if (miid) {
            var operation = miid.clone();
            operation.link = {
                req: req,
                res: res,
                path: path.slice(3),
                query: url.query,
                pathname: url.pathname,
                event: path[2],
                send: send.link
            };

            // set a empty response header object
            operation.link.res.headers = {};

            // emit operation
            operation.emit(path[2]);
            req.resume();

        } else {
            return send.httpError(req, res, 404, new Error('Miid or operation not found.'));
        }

    } else {
        route(url.pathname, req, res);
        req.resume();
    }
}

function connectionHandler (ws) {

    // listen to messages
    ws.on('message', function (data) {

        // parse data
        try {
            data = JSON.parse(data.toString());
            data[0] = data[0].split(':');

            // check message integrity
            if (!data[0][0] || !data[0][1]) {
                throw new Error('Bad message');
            }
        } catch (err) {
            return send.wsError(ws, err);
        }

        // get miid from cache and check access
        var miid = getCachedMiid(data[0][0], data[0][1]);

        // check if miid and event exists
        if (miid) {
            // mono ws protocoll: ["miid:event:msgid","err","data"]
            var message = miid.clone();
            message.link = {
                ws: ws,
                event: data[0][1],
                miid: data[0][0],
                send: send.message
            };

            if (data[0][2]) {
                message.link.id = data[0][2];
            }

            // emit event
            message.emit(message.link.event, data[1], data[2]);

        } else {
            send.wsError(ws, new Error('Miid or event not found'));
        }
    });
}

// start http server
M.http = http.createServer(function (req, res) {

    // plug http middleware functionality
    if (M.listeners('request').length) {
        M.emit('request', req, res, requestHandler);
    } else {

        // add public role to request
        req.session = {};
        req.session[M.config.session.role] = M.config.session.publicRole;

        // handle http request
        requestHandler(req, res);
    }

});

// start ws server
M.ws = new WebSocketServer({server: M.http});
M.ws.on('connection', function(ws) {

    // plug ws middleware functionality
    if (M.listeners('connection').length) {
        M.emit('connection', ws, connectionHandler);
    } else {

        // add public role to websocket
        ws.session = {};
        ws.session[M.config.session.role] = M.config.session.publicRole;

        // handle ws connection
        connectionHandler(ws);
    }
});

// start listen and write app id to stdout
M.on('ready', function () {
    M.http.listen(M.config.port, M.config.host, function () {
        process.stdout.write(M.config.id);
    });
});
<commit_msg>server should pass arguments for request or connection handler<commit_after>/*

TODO check the pending not 200 requests (seen with node-static, but check also http operation requests)

*/
require('./api');
var M = process.mono;
var http = require('http');
var WebSocketServer = require('ws').Server;
var parse = require('url').parse;
var route = require(M.config.paths.SERVER_ROOT + 'router');
var send = require(M.config.paths.SERVER_ROOT + 'send');

// check event access and if event and miid exists
function getCachedMiid (miid, event) {

    miid = M.cache.miids.get(miid);

    if (miid && miid.mono.access[event] && miid.listeners(event).length > 0) {
        return miid;
    }
    return null;
}

// handle http request
function requestHandler (req, res) {

    var url = parse(req.url, true);
    var path = url.pathname.replace(/\/$|^\//g, "").split("/", 42);

    if (path[0] == M.config.coreKey) {

        if (path.length < 3) {
            return send.httpError(req, res, 400, new Error('Invalid operation url.'));
        }

        // if no operation was found in the request URL
        if (!path[1] || !path[2]) {
            return send.httpError(req, res, 400, new Error('Missing module instance ID or operation name.'));
        }

        // get cached miid and check access
        var miid = getCachedMiid(path[1], path[2]);

        // check if miid an operation exists
        if (miid) {
            var operation = miid.clone();
            operation.link = {
                req: req,
                res: res,
                path: path.slice(3),
                query: url.query,
                pathname: url.pathname,
                event: path[2],
                send: send.link
            };

            // set a empty response header object
            operation.link.res.headers = {};

            // emit operation
            operation.emit(path[2]);
            req.resume();

        } else {
            return send.httpError(req, res, 404, new Error('Miid or operation not found.'));
        }

    } else {
        route(url.pathname, req, res);
        req.resume();
    }
}

function connectionHandler (ws) {

    // listen to messages
    ws.on('message', function (data) {

        // parse data
        try {
            data = JSON.parse(data.toString());
            data[0] = data[0].split(':');

            // check message integrity
            if (!data[0][0] || !data[0][1]) {
                throw new Error('Bad message');
            }
        } catch (err) {
            return send.wsError(ws, err);
        }

        // get miid from cache and check access
        var miid = getCachedMiid(data[0][0], data[0][1]);

        // check if miid and event exists
        if (miid) {
            // mono ws protocoll: ["miid:event:msgid","err","data"]
            var message = miid.clone();
            message.link = {
                ws: ws,
                event: data[0][1],
                miid: data[0][0],
                send: send.message
            };

            if (data[0][2]) {
                message.link.id = data[0][2];
            }

            // emit event
            message.emit(message.link.event, data[1], data[2]);

        } else {
            send.wsError(ws, new Error('Miid or event not found'));
        }
    });
}

// start http server
M.http = http.createServer(function (req, res) {

    // plug http middleware functionality
    if (M.listeners('request').length) {
        M.emit('request', req, res, function () {
            requestHandler(req, res);
        });
    } else {

        // add public role to request
        req.session = {};
        req.session[M.config.session.role] = M.config.session.publicRole;

        // handle http request
        requestHandler(req, res);
    }

});

// start ws server
M.ws = new WebSocketServer({server: M.http});
M.ws.on('connection', function(ws) {

    // plug ws middleware functionality
    if (M.listeners('connection').length) {
        M.emit('connection', ws, function () {
            connectionHandler(ws);
        });
    } else {

        // add public role to websocket
        ws.session = {};
        ws.session[M.config.session.role] = M.config.session.publicRole;

        // handle ws connection
        connectionHandler(ws);
    }
});

// start listen and write app id to stdout
M.on('ready', function () {
    M.http.listen(M.config.port, M.config.host, function () {
        process.stdout.write(M.config.id);
    });
});
<|endoftext|>