<commit_before>// Timestamp, das muss man eigentlich auf der Serverseite machen,
// damit mans nicht faken kann?? Noch anschauen.
get_timestamp = function (){
	var now = new Date();
	return now.getTime();
}

hasRole = function(members, role) {
	var has = false;
	members.forEach(function(member) {
		if (member.roles.indexOf(role) !== -1) {
			has = true;
			return true;
		}
	})
	return has;
}

havingRole = function(members, role) {
	return _.reduce(members, function(ids, member) {
		if (member.roles.indexOf(role) !== -1) ids.push(member.user)
			return ids;
	}, [])
}

getMemeber = function(members, user) {
	var member = false;
	members.forEach(function(member_candidate) {
		if (member.user == user) {
			member = member_candidate
			return true; // break
		}
	})
	return member;
}

hasRoleUser = function(members, role, user) {
	var has = false;
	members.forEach(function(member) {
		if (member.user == user) {
			has = member.roles.indexOf(role) !== -1
			return true; // break
		}
	})
	return has;
}

/*************** HandleBars Helpers ***********************/

Handlebars.registerHelper("log", function(context) {
	if (window.console) console.log(context)
});

Handlebars.registerHelper("title", function() {
	var les = Array.prototype.slice.call(arguments, 0, -1)
	document.title = les.join("");
});

Handlebars.registerHelper('username', function (userid){
	console.log(userid)
	var user= Meteor.users.findOne({_id:userid});
	if(user){
		if(user.username){
			return user.username;
		}else{
			return "userid: "+user._id; // solange .username noch nix ist, haben wir nur die _id...
		}
	}else{
		if (1==1){
			console.log( userid.substr(0, 5)  == 'Anon_')  //
			return "Anonymous☔";
		}else{
			return "No_User";
		}

	}
})

Handlebars.registerHelper('dateformat', function(date) {
    // We'll need a date formatter at some point
    //if (date) return date.toDateString();

    if (date) return date.getDate()+"."+(date.getMonth()+1)+"."+date.getFullYear();
});

Handlebars.registerHelper('dateformat_withday', function(date) {
    // We'll need a date formatter at some point
    //if (date) return date.toDateString();
    horrible_date_array=["Mo","Tue","Wed","Thu","Fr","Sat","So"]; //FIXME

    if (date) return horrible_date_array[date.getDay()]+". "+date.getDate()+"."+(date.getMonth()+1)+"."+date.getFullYear();
});

Handlebars.registerHelper('dateformat_mini', function(date) {
    // We'll need a date formatter at some point
    //if (date) return date.toDateString();
    if (date) return date.getDate()+"."+(date.getMonth()+1)+".";
});

Handlebars.registerHelper('timeformat', function(date) {
    // We'll need a time formatter at some point
    //if (date) return date.toTimeString();

    if (date) return ("0"+date.getHours()).slice(-2)+":"+("0"+date.getMinutes()).slice(-2);
});

Handlebars.registerHelper('isNull', function(val) {
    return val === null
});

Handlebars.registerHelper('courseURL', function(_id) {
    var course=Courses.findOne(_id);
    var name = getSlug(course.name);
	//var name = course.name.replace(/[^\w\s]/gi, '-').replace(/[_\s]/g, '_')
	var _id = _id
	return '/course/' + _id + '/' + name;
});

//Html title attribute of participant-state-sybol in courselist
Handlebars.registerHelper('isYes', function(val) {
 	return val === 'yes'
});
Handlebars.registerHelper('isOntheway', function(val) {
 	return val === 'ontheway'
});

Handlebars.registerHelper('isAdmin', function() {
    var user = Meteor.user()
    error.log(user.isAdmin)
    return user && user.isAdmin
});

<commit_msg>first step for privacy-participant<commit_after>// Timestamp, das muss man eigentlich auf der Serverseite machen,
// damit mans nicht faken kann?? Noch anschauen.
get_timestamp = function (){
	var now = new Date();
	return now.getTime();
}

hasRole = function(members, role) {
	var has = false;
	members.forEach(function(member) {
		if (member.roles.indexOf(role) !== -1) {
			has = true;
			return true;
		}
	})
	return has;
}

havingRole = function(members, role) {
	return _.reduce(members, function(ids, member) {
		if (member.roles.indexOf(role) !== -1) ids.push(member.user)
			return ids;
	}, [])
}

getMemeber = function(members, user) {
	var member = false;
	members.forEach(function(member_candidate) {
		if (member.user == user) {
			member = member_candidate
			return true; // break
		}
	})
	return member;
}

hasRoleUser = function(members, role, user) {
	var has = false;
	members.forEach(function(member) {
		if (member.user == user) {
			has = member.roles.indexOf(role) !== -1
			return true; // break
		}
	})
	return has;
}

/*************** HandleBars Helpers ***********************/

Handlebars.registerHelper("log", function(context) {
	if (window.console) console.log(context)
});

Handlebars.registerHelper("title", function() {
	var les = Array.prototype.slice.call(arguments, 0, -1)
	document.title = les.join("");
});

Handlebars.registerHelper('username', function (userid){
	console.log(userid)
	var user= Meteor.users.findOne({_id:userid});
	if(user){
		if(user.username){
			return user.username;
		}else{
			return "userid: "+user._id; // solange .username noch nix ist, haben wir nur die _id...
		}
	}else{
		if (userid.substr(0, 5)  == 'Anon_'){
			return "Anonymous☔";
		}else{
			return "No_User";
		}

	}
})

Handlebars.registerHelper('dateformat', function(date) {
    // We'll need a date formatter at some point
    //if (date) return date.toDateString();

    if (date) return date.getDate()+"."+(date.getMonth()+1)+"."+date.getFullYear();
});

Handlebars.registerHelper('dateformat_withday', function(date) {
    // We'll need a date formatter at some point
    //if (date) return date.toDateString();
    horrible_date_array=["Mo","Tue","Wed","Thu","Fr","Sat","So"]; //FIXME

    if (date) return horrible_date_array[date.getDay()]+". "+date.getDate()+"."+(date.getMonth()+1)+"."+date.getFullYear();
});

Handlebars.registerHelper('dateformat_mini', function(date) {
    // We'll need a date formatter at some point
    //if (date) return date.toDateString();
    if (date) return date.getDate()+"."+(date.getMonth()+1)+".";
});

Handlebars.registerHelper('timeformat', function(date) {
    // We'll need a time formatter at some point
    //if (date) return date.toTimeString();

    if (date) return ("0"+date.getHours()).slice(-2)+":"+("0"+date.getMinutes()).slice(-2);
});

Handlebars.registerHelper('isNull', function(val) {
    return val === null
});

Handlebars.registerHelper('courseURL', function(_id) {
    var course=Courses.findOne(_id);
    var name = getSlug(course.name);
	//var name = course.name.replace(/[^\w\s]/gi, '-').replace(/[_\s]/g, '_')
	var _id = _id
	return '/course/' + _id + '/' + name;
});

//Html title attribute of participant-state-sybol in courselist
Handlebars.registerHelper('isYes', function(val) {
 	return val === 'yes'
});
Handlebars.registerHelper('isOntheway', function(val) {
 	return val === 'ontheway'
});

Handlebars.registerHelper('isAdmin', function() {
    var user = Meteor.user()
    error.log(user.isAdmin)
    return user && user.isAdmin
});

<|endoftext|>


<commit_before>
// Reference to the root of the Firebase database
var database = new Firebase("https://conquiz.firebaseio.com/");
// Reference to the google sheets of questions
var questionsLink = "https://spreadsheets.google.com/feeds/list/1C1POJrIlpm1R3muE0ImmI_ifxpH_aEfPP-QSyl3o2Kg/1/public/basic?alt=json-in-script&callback=JSON_CALLBACK";
var questions;

$("#upload").click(function() { // If the user clicks on the input with the id="upload"
	var name = $("#nameInput").val();
	var text = $("#messageInput").val();
	if (name.length != 0 && text.length != 0) { // Don't upload if there's no information in the textboxes
		console.log(name.length);
		console.log(text.length);

		database.push({name: name, text: text}); // Push the data onto the database

	}else { // warns user of their empty textbox
		console.log("Please input values into the textbox");
	}
});

// Get an update once the database has new data
// database.on('child_added', function(update) {
// 	questions = update.val();

// 	console.log("Successfully retrieve questions from database.");
// });

// database.on("child_added", function(update) { // Get an update once the database has new data
// 			console.log("Callback function: New data has been added to the database");
// 			var message = update.val();
// 			displayUpdate(message.name, message.text);
// });

function displayUpdate(name, text) {
	$("<div/>").text(text).prepend($("<em/>").text(name+": ")).appendTo($("#messageDiv"));
	$("#messageDiv")[0].scrollTop = $("#messageDiv")[0].scrollHeight;
};

function displayData(data){
    var rows = [];
    var cells = data.feed.entry;

    for (var i = 0; i < cells.length; i++){
        var rowObj = {};
        rowObj.timestamp = cells[i].title.$t;
        var rowCols = cells[i].content.$t.split(',');
        for (var j = 0; j < rowCols.length; j++){
            var keyVal = rowCols[j].split(':');
            rowObj[keyVal[0].trim()] = keyVal[1].trim();
        }
        rows.push(rowObj);
    }

    var raw = document.createElement('p');
    raw.innerText = JSON.stringify(rows);
    document.body.appendChild(raw);
}

$(document).ready(function(){
    $.ajax({
        url:'https://spreadsheets.google.com/feeds/list/1C1POJrIlpm1R3muE0ImmI_ifxpH_aEfPP-QSyl3o2Kg/1/public/basic?alt=json',
        success: function(data){
            displayData(data);
        }
    });
});

// One time push to update the questions on firebase
function updateDatabase() {
	$.ajax({
		url: 'https://spreadsheets.google.com/feeds/list/1C1POJrIlpm1R3muE0ImmI_ifxpH_aEfPP-QSyl3o2Kg/1/public/basic?alt=json',
		async: false,
		success: function(data) {
			console.log("success");
			questions = data['feed']['entry'];
			$.each(questions, )
			console.log(data);
		},
		onError: function() {
			console.log("Error");
		}
	});
}

updateDatabase();

console.log('LOADED BACKEND');<commit_msg>Finally made backend.js upload<commit_after>
// Reference to the root of the Firebase database
var database = new Firebase("https://conquiz.firebaseio.com/");
// Reference to the google sheets of questions
var questionsLink = "https://spreadsheets.google.com/feeds/list/1C1POJrIlpm1R3muE0ImmI_ifxpH_aEfPP-QSyl3o2Kg/1/public/basic?alt=json-in-script&callback=JSON_CALLBACK";
var questions;
var rows;

$("#upload").click(function() { // If the user clicks on the input with the id="upload"
	var name = $("#nameInput").val();
	var text = $("#messageInput").val();
	if (name.length != 0 && text.length != 0) { // Don't upload if there's no information in the textboxes
		console.log(name.length);
		console.log(text.length);

		database.push({name: name, text: text}); // Push the data onto the database

	}else { // warns user of their empty textbox
		console.log("Please input values into the textbox");
	}
});

// Get an update once the database has new data
// database.on('child_added', function(update) {
// 	questions = update.val();

// 	console.log("Successfully retrieve questions from database.");
// });

// database.on("child_added", function(update) { // Get an update once the database has new data
// 			console.log("Callback function: New data has been added to the database");
// 			var message = update.val();
// 			displayUpdate(message.name, message.text);
// });

function displayUpdate(name, text) {
	$("<div/>").text(text).prepend($("<em/>").text(name+": ")).appendTo($("#messageDiv"));
	$("#messageDiv")[0].scrollTop = $("#messageDiv")[0].scrollHeight;
};

// One time push to update the questions on firebase
function getData() {
    $.ajax({
        url:'https://spreadsheets.google.com/feeds/list/1C1POJrIlpm1R3muE0ImmI_ifxpH_aEfPP-QSyl3o2Kg/1/public/basic?alt=json',
        success: function(data){
            uploadFirebase(data);
        }
    });
}
// upload data to firebase
function uploadFirebase(data){
    var cells = data.feed.entry;
    rows = [];

    for (var i = 0; i < cells.length; i++){
        var rowObj = {};
        rowObj.timestamp = cells[i].title.$t;
        var rowCols = cells[i].content.$t.split(',');
        for (var j = 0; j < rowCols.length; j++){
            var keyVal = rowCols[j].split(':');
            rowObj[keyVal[0].trim()] = keyVal[1].trim();
        }
        rows.push(rowObj);
    }
    for (var i = 0; i < rows.length; i++) {
    	database.push({question: rows[i]['timestamp'], correct: rows[i]['correct'], wa1: rows[i]['wa1'], wa2: rows[i]['wa2'], wa3: rows[i]['wa3']});
    }
}

console.log('LOADED BACKEND');<|endoftext|>


<commit_before>import React from "react";
import { find, get, replace } from "lodash-es";
import { Col, Panel, ProgressBar, Row } from "react-bootstrap";
import { connect } from "react-redux";

import { installHMMs, fetchHmms } from "../actions";
import { Button, Flex, FlexItem } from "../../base";

class HMMInstall extends React.Component {

    componentDidUpdate (prevProps) {

        const process = this.getProcess();

        if (!process) {
            return;
        }

        if (!this.props.installed && process.progress === 1) {
            this.props.onRefresh();
        }
    }

    handleInstall = () => {
        this.props.onInstall(this.props.releaseId);
    };

    getProcess = () => {
        if (this.props.processId && this.props.processes.length) {
            const process = find(this.props.processes, ["id", this.props.processId]);
            return process || null;
        }
    };

    render () {

        if (this.props.processId && !this.props.installed) {

            const process = this.getProcess();
            const progress = process.progress * 100;
            const step = replace(process.step, "_", " ");

            const barStyle = progress === 100 ? "success" : "warning";

            return (
                <Panel>
                    <Panel.Body>
                        <Row>
                            <Col xs={10} xsOffset={1} md={6} mdOffset={3}>

Installing

                                    <ProgressBar bsStyle={barStyle} now={progress} />

                                            {step}

                            </Col>
                        </Row>
                    </Panel.Body>
                </Panel>
            );
        }

        return (
            <Panel>
                <Panel.Body>
                    <Flex justifyContent="center" style={{padding: "10px 0"}}>
                        <FlexItem>

                        </FlexItem>

                        <FlexItem>

                                No HMM data available.

                                You can download and install the offical HMM data automatically from our
                                 GitHub repository.

                            <Button icon="download" onClick={this.handleInstall}>
                                Install Official
                            </Button>
                        </FlexItem>
                    </Flex>
                </Panel.Body>
            </Panel>
        );
    }
}

const mapStateToProps = (state) => ({
    processId: get(state.hmms.status, "process.id"),
    releaseId: get(state.hmms.status, "release.id"),
    installed: !!state.hmms.status.installed,
    processes: state.processes.documents
});

const mapDispatchToProps = (dispatch) => ({

    onInstall: (releaseId) => {
        dispatch(installHMMs(`${releaseId}`));
    },

    onRefresh: () => {
        dispatch(fetchHmms());
    }

});

export default connect(mapStateToProps, mapDispatchToProps)(HMMInstall);

<commit_msg>Update componentDidUpdate check<commit_after>import React from "react";
import { find, get, replace } from "lodash-es";
import { Col, Panel, ProgressBar, Row } from "react-bootstrap";
import { connect } from "react-redux";

import { installHMMs, fetchHmms } from "../actions";
import { Button, Flex, FlexItem } from "../../base";

class HMMInstall extends React.Component {

    componentDidUpdate () {

        const process = this.getProcess();

        if (!process) {
            return;
        }

        if (!this.props.installed && process.progress === 1) {
            this.props.onRefresh();
        }
    }

    handleInstall = () => {
        this.props.onInstall(this.props.releaseId);
    };

    getProcess = () => {
        if (this.props.processId && this.props.processes.length) {
            const process = find(this.props.processes, ["id", this.props.processId]);
            return process || null;
        }
    };

    render () {

        if (this.props.processId && !this.props.installed) {

            const process = this.getProcess();
            const progress = process.progress * 100;
            const step = replace(process.step, "_", " ");

            const barStyle = progress === 100 ? "success" : "warning";

            return (
                <Panel>
                    <Panel.Body>
                        <Row>
                            <Col xs={10} xsOffset={1} md={6} mdOffset={3}>

Installing

                                    <ProgressBar bsStyle={barStyle} now={progress} />

                                            {step}

                            </Col>
                        </Row>
                    </Panel.Body>
                </Panel>
            );
        }

        return (
            <Panel>
                <Panel.Body>
                    <Flex justifyContent="center" style={{padding: "10px 0"}}>
                        <FlexItem>

                        </FlexItem>

                        <FlexItem>

                                No HMM data available.

                                You can download and install the offical HMM data automatically from our
                                 GitHub repository.

                            <Button icon="download" onClick={this.handleInstall}>
                                Install Official
                            </Button>
                        </FlexItem>
                    </Flex>
                </Panel.Body>
            </Panel>
        );
    }
}

const mapStateToProps = (state) => ({
    processId: get(state.hmms.status, "process.id"),
    releaseId: get(state.hmms.status, "release.id"),
    installed: !!state.hmms.status.installed,
    processes: state.processes.documents
});

const mapDispatchToProps = (dispatch) => ({

    onInstall: (releaseId) => {
        dispatch(installHMMs(`${releaseId}`));
    },

    onRefresh: () => {
        dispatch(fetchHmms());
    }

});

export default connect(mapStateToProps, mapDispatchToProps)(HMMInstall);

<|endoftext|>


<commit_before>'use strict';

var gui = require('./gui.js');
var _3dviz = require('./3dviz.js');
var SunCalc = require('suncalc');

var vec = [0, 0, 0];
var date = new Date();
var radius = 100;
var sunPos;

function computeDirection(date){
	sunPos = SunCalc.getPosition(date, -0.573781, 44.840484);
    var lightX = radius * Math.cos(sunPos.altitude) * Math.cos(sunPos.azimuth);
    var lightY = radius * Math.cos(sunPos.altitude) * Math.sin(sunPos.azimuth);
    var lightZ = radius * Math.tan(sunPos.altitude);
    vec = [lightX, lightY, lightZ];
    return vec;
}

module.exports = function(sunlight, ambientLight){

    function applyLightTargetAtHour(hour){
        date.setHours(hour);
        vec = computeDirection(date);
        var pos = sunlight.position;
        sunlight.target.position.set(pos.x + vec[0], pos.y + vec[1], 0);
        _3dviz.render();
    }

    applyLightTargetAtHour(gui.guiControls.hour);

    gui.hourControler.onChange(applyLightTargetAtHour);

    vec = computeDirection(date);
	return vec;
};<commit_msg>compute and update light colors depending on sun vector<commit_after>'use strict';

var gui = require('./gui.js');
var _3dviz = require('./3dviz.js');
var SunCalc = require('suncalc');
var THREE = require('three');

var vec = [0, 0, 0];
var date = new Date();
var radius = 100;
var sunPos;

var nightLightColor     = new THREE.Color(0xffffee);
var nightShadowColor    = new THREE.Color(0x000022);
var dayLightColor       = new THREE.Color(0xfcfce5);
var dayShadowColor      = new THREE.Color(0x27282f);
var tmpLight    = new THREE.Color();
var tmpShadow   = new THREE.Color();
var transitionExp = 5; // exponent of the transition curve

function computeDirection(date){
	sunPos = SunCalc.getPosition(date, -0.573781, 44.840484);
    var lightX = radius * Math.cos(sunPos.altitude) * Math.cos(sunPos.azimuth);
    var lightY = radius * Math.cos(sunPos.altitude) * Math.sin(sunPos.azimuth);
    var lightZ = radius * Math.tan(sunPos.altitude);
    vec = [lightX, lightY, lightZ];
    return vec;
}

module.exports = function(sunlight, ambientLight){

    function applyLightTargetAtHour(hour){
        date.setHours(hour);
        vec = computeDirection(date);
        var pos = sunlight.position;
        sunlight.target.position.set(pos.x + vec[0], pos.y + vec[1], 0);

        // Compute the dot product of the normalized UP and SUN vectors
        //  1 => sun right up
        //  0 => sun on the horizon
        // -1 => sun right below
        var upVector = new THREE.Vector3(0, 0, 1);
        var sunVector = new THREE.Vector3(vec[0], vec[1], vec[2]);
        sunVector.normalize();
        var dotProduct = upVector.dot(sunVector);

        // Clip to 0-1
        var fact = Math.max(0, dotProduct);

        //console.log(fact);

        // Mix day and night colors depending on sun vector
        tmpLight.setHex(dayLightColor.getHex());
        tmpShadow.setHex(dayShadowColor.getHex());

        tmpLight.lerp(nightLightColor, Math.pow(1 - fact, transitionExp));
        tmpShadow.lerp(nightShadowColor, Math.pow(1 - fact, transitionExp));

        // Update colors in scene
        sunlight.color.setHex(tmpLight.getHex());
        ambientLight.color.setHex(tmpShadow.getHex());

        _3dviz.render();
    }

    applyLightTargetAtHour(gui.guiControls.hour);

    gui.hourControler.onChange(applyLightTargetAtHour);

    vec = computeDirection(date);
	return vec;
};<|endoftext|>


<commit_before>/**
* jquery.matchHeight.js master
* http://brm.io/jquery-match-height/
* License: MIT
*/

;(function($) {
    /*
    *  internal
    */

    var _previousResizeWidth = -1,
        _updateTimeout = -1;

    /*
    *  _parse
    *  value parse utility function
    */

    var _parse = function(value) {
        // parse value and convert NaN to 0
        return parseFloat(value) || 0;
    };

    /*
    *  _rows
    *  utility function returns array of jQuery selections representing each row
    *  (as displayed after float wrapping applied by browser)
    */

    var _rows = function(elements) {
        var tolerance = 1,
            $elements = $(elements),
            lastTop = null,
            rows = [];

        // group elements by their top position
        $elements.each(function(){
            var $that = $(this),
                top = $that.offset().top - _parse($that.css('margin-top')),
                lastRow = rows.length > 0 ? rows[rows.length - 1] : null;

            if (lastRow === null) {
                // first item on the row, so just push it
                rows.push($that);
            } else {
                // if the row top is the same, add to the row group
                if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {
                    rows[rows.length - 1] = lastRow.add($that);
                } else {
                    // otherwise start a new row group
                    rows.push($that);
                }
            }

            // keep track of the last row top
            lastTop = top;
        });

        return rows;
    };

    /*
    *  _parseOptions
    *  handle plugin options
    */

    var _parseOptions = function(options) {
        var opts = {
            byRow: true,
            property: 'height',
            target: null,
            remove: false
        };

        if (typeof options === 'object') {
            return $.extend(opts, options);
        }

        if (typeof options === 'boolean') {
            opts.byRow = options;
        } else if (options === 'remove') {
            opts.remove = true;
        }

        return opts;
    };

    /*
    *  matchHeight
    *  plugin definition
    */

    var matchHeight = $.fn.matchHeight = function(options) {
        var opts = _parseOptions(options);

        // handle remove
        if (opts.remove) {
            var that = this;

            // remove fixed height from all selected elements
            this.css(opts.property, '');

            // remove selected elements from all groups
            $.each(matchHeight._groups, function(key, group) {
                group.elements = group.elements.not(that);
            });

            // TODO: cleanup empty groups

            return this;
        }

        if (this.length <= 1 && !opts.target) {
            return this;
        }

        // keep track of this group so we can re-apply later on load and resize events
        matchHeight._groups.push({
            elements: this,
            options: opts
        });

        // match each element's height to the tallest element in the selection
        matchHeight._apply(this, opts);

        return this;
    };

    /*
    *  plugin global options
    */

    matchHeight._groups = [];
    matchHeight._throttle = 80;
    matchHeight._maintainScroll = false;
    matchHeight._beforeUpdate = null;
    matchHeight._afterUpdate = null;

    /*
    *  matchHeight._apply
    *  apply matchHeight to given elements
    */

    matchHeight._apply = function(elements, options) {
        var opts = _parseOptions(options),
            $elements = $(elements),
            rows = [$elements];

        // take note of scroll position
        var scrollTop = $(window).scrollTop(),
            htmlHeight = $('html').outerHeight(true);

        // get hidden parents
        var $hiddenParents = $elements.parents().filter(':hidden');

        // cache the original inline style
        $hiddenParents.each(function() {
            var $that = $(this);
            $that.data('style-cache', $that.attr('style'));
        });

        // temporarily must force hidden parents visible
        $hiddenParents.css('display', 'block');

        // get rows if using byRow, otherwise assume one row
        if (opts.byRow && !opts.target) {

            // must first force an arbitrary equal height so floating elements break evenly
            $elements.each(function() {
                var $that = $(this),
                    display = $that.css('display') === 'inline-block' ? 'inline-block' : 'block';

                // cache the original inline style
                $that.data('style-cache', $that.attr('style'));

                $that.css({
                    'display': display,
                    'padding-top': '0',
                    'padding-bottom': '0',
                    'margin-top': '0',
                    'margin-bottom': '0',
                    'border-top-width': '0',
                    'border-bottom-width': '0',
                    'height': '100px'
                });
            });

            // get the array of rows (based on element top position)
            rows = _rows($elements);

            // revert original inline styles
            $elements.each(function() {
                var $that = $(this);
                $that.attr('style', $that.data('style-cache') || '');
            });
        }

        $.each(rows, function(key, row) {
            var $row = $(row),
                targetHeight = 0;

            if (!opts.target) {
                // skip apply to rows with only one item
                if (opts.byRow && $row.length <= 1) {
                    $row.css(opts.property, '');
                    return;
                }

                // iterate the row and find the max height
                $row.each(function(){
                    var $that = $(this),
                        display = $that.css('display') === 'inline-block' ? 'inline-block' : 'block';

                    // ensure we get the correct actual height (and not a previously set height value)
                    var css = { 'display': display };
                    css[opts.property] = '';
                    $that.css(css);

                    // find the max height (including padding, but not margin)
                    if ($that.outerHeight(false) > targetHeight) {
                        targetHeight = $that.outerHeight(false);
                    }

                    // revert display block
                    $that.css('display', '');
                });
            } else {
                // if target set, use the height of the target element
                targetHeight = opts.target.outerHeight(false);
            }

            // iterate the row and apply the height to all elements
            $row.each(function(){
                var $that = $(this),
                    verticalPadding = 0;

                // don't apply to a target
                if (opts.target && $that.is(opts.target)) {
                    return;
                }

                // handle padding and border correctly (required when not using border-box)
                if ($that.css('box-sizing') !== 'border-box') {
                    verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width'));
                    verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom'));
                }

                // set the height (accounting for padding and border)
                $that.css(opts.property, targetHeight - verticalPadding);
            });
        });

        // revert hidden parents
        $hiddenParents.each(function() {
            var $that = $(this);
            $that.attr('style', $that.data('style-cache') || null);
        });

        // restore scroll position if enabled
        if (matchHeight._maintainScroll) {
            $(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true));
        }

        return this;
    };

    /*
    *  matchHeight._applyDataApi
    *  applies matchHeight to all elements with a data-match-height attribute
    */

    matchHeight._applyDataApi = function() {
        var groups = {};

        // generate groups by their groupId set by elements using data-match-height
        $('[data-match-height], [data-mh]').each(function() {
            var $this = $(this),
                groupId = $this.attr('data-mh') || $this.attr('data-match-height');

            if (groupId in groups) {
                groups[groupId] = groups[groupId].add($this);
            } else {
                groups[groupId] = $this;
            }
        });

        // apply matchHeight to each group
        $.each(groups, function() {
            this.matchHeight(true);
        });
    };

    /*
    *  matchHeight._update
    *  updates matchHeight on all current groups with their correct options
    */

    var _update = function(event) {
        if (matchHeight._beforeUpdate) {
            matchHeight._beforeUpdate(event, matchHeight._groups);
        }

        $.each(matchHeight._groups, function() {
            matchHeight._apply(this.elements, this.options);
        });

        if (matchHeight._afterUpdate) {
            matchHeight._afterUpdate(event, matchHeight._groups);
        }
    };

    matchHeight._update = function(throttle, event) {
        // prevent update if fired from a resize event
        // where the viewport width hasn't actually changed
        // fixes an event looping bug in IE8
        if (event && event.type === 'resize') {
            var windowWidth = $(window).width();
            if (windowWidth === _previousResizeWidth) {
                return;
            }
            _previousResizeWidth = windowWidth;
        }

        // throttle updates
        if (!throttle) {
            _update(event);
        } else if (_updateTimeout === -1) {
            _updateTimeout = setTimeout(function() {
                _update(event);
                _updateTimeout = -1;
            }, matchHeight._throttle);
        }
    };

    /*
    *  bind events
    */

    // apply on DOM ready event
    $(matchHeight._applyDataApi);

    // update heights on load and resize events
    $(window).bind('load', function(event) {
        matchHeight._update(false, event);
    });

    // throttled update heights on resize events
    $(window).bind('resize orientationchange', function(event) {
        matchHeight._update(true, event);
    });

})(jQuery);
<commit_msg>fix for unitless properties by forcing px, closes #64<commit_after>/**
* jquery.matchHeight.js master
* http://brm.io/jquery-match-height/
* License: MIT
*/

;(function($) {
    /*
    *  internal
    */

    var _previousResizeWidth = -1,
        _updateTimeout = -1;

    /*
    *  _parse
    *  value parse utility function
    */

    var _parse = function(value) {
        // parse value and convert NaN to 0
        return parseFloat(value) || 0;
    };

    /*
    *  _rows
    *  utility function returns array of jQuery selections representing each row
    *  (as displayed after float wrapping applied by browser)
    */

    var _rows = function(elements) {
        var tolerance = 1,
            $elements = $(elements),
            lastTop = null,
            rows = [];

        // group elements by their top position
        $elements.each(function(){
            var $that = $(this),
                top = $that.offset().top - _parse($that.css('margin-top')),
                lastRow = rows.length > 0 ? rows[rows.length - 1] : null;

            if (lastRow === null) {
                // first item on the row, so just push it
                rows.push($that);
            } else {
                // if the row top is the same, add to the row group
                if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {
                    rows[rows.length - 1] = lastRow.add($that);
                } else {
                    // otherwise start a new row group
                    rows.push($that);
                }
            }

            // keep track of the last row top
            lastTop = top;
        });

        return rows;
    };

    /*
    *  _parseOptions
    *  handle plugin options
    */

    var _parseOptions = function(options) {
        var opts = {
            byRow: true,
            property: 'height',
            target: null,
            remove: false
        };

        if (typeof options === 'object') {
            return $.extend(opts, options);
        }

        if (typeof options === 'boolean') {
            opts.byRow = options;
        } else if (options === 'remove') {
            opts.remove = true;
        }

        return opts;
    };

    /*
    *  matchHeight
    *  plugin definition
    */

    var matchHeight = $.fn.matchHeight = function(options) {
        var opts = _parseOptions(options);

        // handle remove
        if (opts.remove) {
            var that = this;

            // remove fixed height from all selected elements
            this.css(opts.property, '');

            // remove selected elements from all groups
            $.each(matchHeight._groups, function(key, group) {
                group.elements = group.elements.not(that);
            });

            // TODO: cleanup empty groups

            return this;
        }

        if (this.length <= 1 && !opts.target) {
            return this;
        }

        // keep track of this group so we can re-apply later on load and resize events
        matchHeight._groups.push({
            elements: this,
            options: opts
        });

        // match each element's height to the tallest element in the selection
        matchHeight._apply(this, opts);

        return this;
    };

    /*
    *  plugin global options
    */

    matchHeight._groups = [];
    matchHeight._throttle = 80;
    matchHeight._maintainScroll = false;
    matchHeight._beforeUpdate = null;
    matchHeight._afterUpdate = null;

    /*
    *  matchHeight._apply
    *  apply matchHeight to given elements
    */

    matchHeight._apply = function(elements, options) {
        var opts = _parseOptions(options),
            $elements = $(elements),
            rows = [$elements];

        // take note of scroll position
        var scrollTop = $(window).scrollTop(),
            htmlHeight = $('html').outerHeight(true);

        // get hidden parents
        var $hiddenParents = $elements.parents().filter(':hidden');

        // cache the original inline style
        $hiddenParents.each(function() {
            var $that = $(this);
            $that.data('style-cache', $that.attr('style'));
        });

        // temporarily must force hidden parents visible
        $hiddenParents.css('display', 'block');

        // get rows if using byRow, otherwise assume one row
        if (opts.byRow && !opts.target) {

            // must first force an arbitrary equal height so floating elements break evenly
            $elements.each(function() {
                var $that = $(this),
                    display = $that.css('display') === 'inline-block' ? 'inline-block' : 'block';

                // cache the original inline style
                $that.data('style-cache', $that.attr('style'));

                $that.css({
                    'display': display,
                    'padding-top': '0',
                    'padding-bottom': '0',
                    'margin-top': '0',
                    'margin-bottom': '0',
                    'border-top-width': '0',
                    'border-bottom-width': '0',
                    'height': '100px'
                });
            });

            // get the array of rows (based on element top position)
            rows = _rows($elements);

            // revert original inline styles
            $elements.each(function() {
                var $that = $(this);
                $that.attr('style', $that.data('style-cache') || '');
            });
        }

        $.each(rows, function(key, row) {
            var $row = $(row),
                targetHeight = 0;

            if (!opts.target) {
                // skip apply to rows with only one item
                if (opts.byRow && $row.length <= 1) {
                    $row.css(opts.property, '');
                    return;
                }

                // iterate the row and find the max height
                $row.each(function(){
                    var $that = $(this),
                        display = $that.css('display') === 'inline-block' ? 'inline-block' : 'block';

                    // ensure we get the correct actual height (and not a previously set height value)
                    var css = { 'display': display };
                    css[opts.property] = '';
                    $that.css(css);

                    // find the max height (including padding, but not margin)
                    if ($that.outerHeight(false) > targetHeight) {
                        targetHeight = $that.outerHeight(false);
                    }

                    // revert display block
                    $that.css('display', '');
                });
            } else {
                // if target set, use the height of the target element
                targetHeight = opts.target.outerHeight(false);
            }

            // iterate the row and apply the height to all elements
            $row.each(function(){
                var $that = $(this),
                    verticalPadding = 0;

                // don't apply to a target
                if (opts.target && $that.is(opts.target)) {
                    return;
                }

                // handle padding and border correctly (required when not using border-box)
                if ($that.css('box-sizing') !== 'border-box') {
                    verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width'));
                    verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom'));
                }

                // set the height (accounting for padding and border)
                $that.css(opts.property, (targetHeight - verticalPadding) + 'px');
            });
        });

        // revert hidden parents
        $hiddenParents.each(function() {
            var $that = $(this);
            $that.attr('style', $that.data('style-cache') || null);
        });

        // restore scroll position if enabled
        if (matchHeight._maintainScroll) {
            $(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true));
        }

        return this;
    };

    /*
    *  matchHeight._applyDataApi
    *  applies matchHeight to all elements with a data-match-height attribute
    */

    matchHeight._applyDataApi = function() {
        var groups = {};

        // generate groups by their groupId set by elements using data-match-height
        $('[data-match-height], [data-mh]').each(function() {
            var $this = $(this),
                groupId = $this.attr('data-mh') || $this.attr('data-match-height');

            if (groupId in groups) {
                groups[groupId] = groups[groupId].add($this);
            } else {
                groups[groupId] = $this;
            }
        });

        // apply matchHeight to each group
        $.each(groups, function() {
            this.matchHeight(true);
        });
    };

    /*
    *  matchHeight._update
    *  updates matchHeight on all current groups with their correct options
    */

    var _update = function(event) {
        if (matchHeight._beforeUpdate) {
            matchHeight._beforeUpdate(event, matchHeight._groups);
        }

        $.each(matchHeight._groups, function() {
            matchHeight._apply(this.elements, this.options);
        });

        if (matchHeight._afterUpdate) {
            matchHeight._afterUpdate(event, matchHeight._groups);
        }
    };

    matchHeight._update = function(throttle, event) {
        // prevent update if fired from a resize event
        // where the viewport width hasn't actually changed
        // fixes an event looping bug in IE8
        if (event && event.type === 'resize') {
            var windowWidth = $(window).width();
            if (windowWidth === _previousResizeWidth) {
                return;
            }
            _previousResizeWidth = windowWidth;
        }

        // throttle updates
        if (!throttle) {
            _update(event);
        } else if (_updateTimeout === -1) {
            _updateTimeout = setTimeout(function() {
                _update(event);
                _updateTimeout = -1;
            }, matchHeight._throttle);
        }
    };

    /*
    *  bind events
    */

    // apply on DOM ready event
    $(matchHeight._applyDataApi);

    // update heights on load and resize events
    $(window).bind('load', function(event) {
        matchHeight._update(false, event);
    });

    // throttled update heights on resize events
    $(window).bind('resize orientationchange', function(event) {
        matchHeight._update(true, event);
    });

})(jQuery);
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Component.extend({
	cell: null,
	row: null,
  table: null,
	rowIndex: null,
  editorShown: false,
  inError: Ember.computed.notEmpty('errorMessage'),
  errorMessage: '',
  showEditorForSelectedCell: null,
  highlightedRow: null,
  highlightedColumn: null,
  selectedCellPosition: null,
  isHighlighted: Ember.computed.or('inHighlightedRow', 'inHighlightedColumn'),
  classNameBindings: [
    'cell.isEditable::protected',
    'cell.isSelected:selected',
    'isHighlighted:highlighted',
    'inError:error',
    'inError:alert',
    'inError:alert-danger'
  ],
  attributeBindings: ['tabindex'],
  tabindex: 1,

	displayableIndex: Ember.computed('position', function () {
    return this.get('position.row') + 1;
  }),

  focusIn: function () {
    if (this.get('cell.isSelected')) {
      return;
    }
    this.set('selectedCellPosition', this.get('position'));
  },

  keyDown: function (event) {
    if (event.ctrlKey) {
      if (this.get('cell.isHeader')) {
        this.keyManipulation(event);
      }
    } else if (!this.keyNavigation(event)) {
      this.startEdition();
    }
  },

  keyNavigation: function (event) {
    var mapping = {
        37: 'navigateLeft',
        38: 'navigateUp',
        39: 'navigateRight',
        40: 'navigateDown'
      },
      action = mapping[event.which];

    if (event.which === 9) {
      action = event.shiftKey ? 'navigateLeft' : 'navigateRight';
    }

    if (!Ember.isNone(action)) {
      event.preventDefault();
      this.sendAction('navigate', action);
      return true;
    }
  },

  keyManipulation: function (event) {
    var mapping, action;
    if (this.get('position.row') === -1) {
      var column_index = this.get('position.column');
      mapping = {
        45: {label: 'insertColumnAfter', index: column_index + 1},
        46: {label: 'removeColumn', index: column_index},
        37: {label: 'moveColumnLeft', index: column_index},
        39: {label: 'moveColumnRight', index: column_index}
      };
    } else {
      var row_index = this.get('position.row');
      mapping = {
        45: {label: 'insertRowAfter', index: row_index + 1},
        46: {label: 'removeRow', index: row_index},
        38: {label: 'moveRowUp', index: row_index},
        40: {label: 'moveRowDown', index: row_index}
      };
    }

    action = mapping[event.which];
    if (!Ember.isNone(action)) {
      this.sendAction('manipulate', action.label, action.index);
    }
  },

  columnIndex: Ember.computed('cell', 'row.cells.[]', function () {
    return this.get('row.cells').indexOf(this.get('cell'));
  }),

  position: Ember.computed('rowIndex', 'columnIndex', function () {
    return {
      row: this.get('rowIndex'),
      column: this.get('columnIndex')
    };
  }),

  click: function () {
    this.startEdition();
  },

  startEditionWhenAsked: Ember.on('init', Ember.observer('showEditorForSelectedCell', function () {
    Ember.run.schedule('afterRender', this, function () {
      if (this.get('cell.isSelected') && !this.get('editorShown') && this.get('showEditorForSelectedCell')) {
        this.startEdition();
        this.set('showEditorForSelectedCell', false);
      }
    });
  })),

  focusWhenSelected: Ember.on('init', Ember.observer('cell.isSelected', function () {
    Ember.run.schedule('afterRender', this, function () {
      if (Ember.isNone(this.$())) {
        return;
      }

      if (this.get('cell.isSelected') && !this.get('editorShown')) {
        this.$().focus();
      } else {
        this.$().blur();
      }
    });
  })),

  focusAfterRender: Ember.on('init', Ember.on('didInsertElement', function () {
    Ember.run.schedule('afterRender', this, function () {
      var position = this.get('position'),
        selected = this.get('selectedCellPosition');

      if (this.get('editorShown') || Ember.isNone(selected)) {
        return;
      }

      if (position.row === selected.row && position.column === selected.column) {
        this.$().focus();
      }
    });
  })),

  startEdition: function () {
    if (this.get('cell.isEditable')) {
      this.set('editorShown', true);
    }
  },

  actions: {
    navigate: function (direction) {
      this.sendAction('navigate', direction);
    },

    manipulate: function (label, index) {
      this.sendAction('manipulate', label, index);
    },

    stopEdition: function () {
      this.set('errorMessage', '');
      this.set('editorShown', false);
      this.notifyPropertyChange('cell.isSelected');
    },

    save: function (newValue, postSaveAction) {
      var self = this;

      this.validateValue(newValue).then(function (validatedNewValue) {
        if (self.get('isDestroyed')) {
          return;
        }
        self.set('cell.value', validatedNewValue);
        self.send('stopEdition');
        self.get('table').notifyPropertyChange('contentUpdated');
        if (!Ember.isNone(postSaveAction)) {
          self.sendAction('navigate', postSaveAction);
        }
      }, function (error) {
        if (self.get('isDestroyed')) {
          return;
        }
        self.set('errorMessage', error);
      });
    },

    saveOnLeave: function (newValue) {
      var self = this;

      this.validateValue(newValue).then(function (validatedNewValue) {
        if (self.get('isDestroyed')) {
          return;
        }
        self.set('cell.value', validatedNewValue);
        self.send('stopEdition');
        self.get('table').notifyPropertyChange('contentUpdated');
      }, function () {
        if (self.get('isDestroyed')) {
          return;
        }
        self.send('stopEdition');
      });
    }
  },

  validateValue: function (value) {
    var datatable = this.get('table'),
      cell = this.get('cell'),
      position = this.get('position'),
      isValid;
    isValid = datatable.validateCell(cell, position, value);
    // is it a promise? (async validation)
    if (isValid instanceof Ember.RSVP.Promise) {
      return isValid;
    // no, so it is a boolean (sync validation)
    } else if (isValid) {
      return Ember.RSVP.Promise.resolve(value);
    } else {
      return Ember.RSVP.Promise.reject("Invalid value");
    }
  },

  inHighlightedRow: Ember.computed('position', 'highlightedRow', function () {
    return this.get('position.row') === this.get('highlightedRow');
  }),

  inHighlightedColumn: Ember.computed('position', 'highlightedColumn', function () {
    return this.get('position.column') === this.get('highlightedColumn');
  }),
});<commit_msg>workaround to force sendAction to know its targetObject<commit_after>import Ember from 'ember';

export default Ember.Component.extend({
	cell: null,
	row: null,
  table: null,
	rowIndex: null,
  editorShown: false,
  inError: Ember.computed.notEmpty('errorMessage'),
  errorMessage: '',
  showEditorForSelectedCell: null,
  highlightedRow: null,
  highlightedColumn: null,
  selectedCellPosition: null,
  isHighlighted: Ember.computed.or('inHighlightedRow', 'inHighlightedColumn'),
  classNameBindings: [
    'cell.isEditable::protected',
    'cell.isSelected:selected',
    'isHighlighted:highlighted',
    'inError:error',
    'inError:alert',
    'inError:alert-danger'
  ],
  attributeBindings: ['tabindex'],
  tabindex: 1,

	displayableIndex: Ember.computed('position', function () {
    return this.get('position.row') + 1;
  }),

  focusIn: function () {
    if (this.get('cell.isSelected')) {
      return;
    }
    this.set('selectedCellPosition', this.get('position'));
  },

  keyDown: function (event) {
    if (event.ctrlKey) {
      if (this.get('cell.isHeader')) {
        this.keyManipulation(event);
      }
    } else if (!this.keyNavigation(event)) {
      this.startEdition();
    }
  },

  keyNavigation: function (event) {
    var mapping = {
        37: 'navigateLeft',
        38: 'navigateUp',
        39: 'navigateRight',
        40: 'navigateDown'
      },
      action = mapping[event.which];

    if (event.which === 9) {
      action = event.shiftKey ? 'navigateLeft' : 'navigateRight';
    }

    if (!Ember.isNone(action)) {
      event.preventDefault();
      this.sendAction('navigate', action);
      return true;
    }
  },

  keyManipulation: function (event) {
    var mapping, action;
    if (this.get('position.row') === -1) {
      var column_index = this.get('position.column');
      mapping = {
        45: {label: 'insertColumnAfter', index: column_index + 1},
        46: {label: 'removeColumn', index: column_index},
        37: {label: 'moveColumnLeft', index: column_index},
        39: {label: 'moveColumnRight', index: column_index}
      };
    } else {
      var row_index = this.get('position.row');
      mapping = {
        45: {label: 'insertRowAfter', index: row_index + 1},
        46: {label: 'removeRow', index: row_index},
        38: {label: 'moveRowUp', index: row_index},
        40: {label: 'moveRowDown', index: row_index}
      };
    }

    action = mapping[event.which];
    if (!Ember.isNone(action)) {
      this.sendAction('manipulate', action.label, action.index);
    }
  },

  columnIndex: Ember.computed('cell', 'row.cells.[]', function () {
    return this.get('row.cells').indexOf(this.get('cell'));
  }),

  position: Ember.computed('rowIndex', 'columnIndex', function () {
    return {
      row: this.get('rowIndex'),
      column: this.get('columnIndex')
    };
  }),

  click: function () {
    this.startEdition();
  },

  startEditionWhenAsked: Ember.on('init', Ember.observer('showEditorForSelectedCell', function () {
    Ember.run.schedule('afterRender', this, function () {
      if (this.get('cell.isSelected') && !this.get('editorShown') && this.get('showEditorForSelectedCell')) {
        this.startEdition();
        this.set('showEditorForSelectedCell', false);
      }
    });
  })),

  focusWhenSelected: Ember.on('init', Ember.observer('cell.isSelected', function () {
    Ember.run.schedule('afterRender', this, function () {
      if (Ember.isNone(this.$())) {
        return;
      }

      if (this.get('cell.isSelected') && !this.get('editorShown')) {
        this.$().focus();
      } else {
        this.$().blur();
      }
    });
  })),

  focusAfterRender: Ember.on('init', Ember.on('didInsertElement', function () {
    Ember.run.schedule('afterRender', this, function () {
      var position = this.get('position'),
        selected = this.get('selectedCellPosition');

      if (this.get('editorShown') || Ember.isNone(selected)) {
        return;
      }

      if (position.row === selected.row && position.column === selected.column) {
        this.$().focus();
      }
    });
  })),

  startEdition: function () {
    if (this.get('cell.isEditable')) {
      this.set('editorShown', true);
    }
  },

  actions: {
    navigate: function (direction) {
      this.sendAction('navigate', direction);
    },

    manipulate: function (label, index) {
      this.sendAction('manipulate', label, index);
    },

    stopEdition: function () {
      this.set('errorMessage', '');
      this.set('editorShown', false);
      this.notifyPropertyChange('cell.isSelected');
    },

    save: function (newValue, postSaveAction) {
      var self = this;

      self.get('targetObject'); // to force self.sendAction to know targetObject - bug ember ?
      this.validateValue(newValue).then(function (validatedNewValue) {
        if (self.get('isDestroyed')) {
          return;
        }
        self.set('cell.value', validatedNewValue);
        self.send('stopEdition');
        self.get('table').notifyPropertyChange('contentUpdated');
        if (!Ember.isNone(postSaveAction)) {
          self.sendAction('navigate', postSaveAction);
        }
      }, function (error) {
        if (self.get('isDestroyed')) {
          return;
        }
        self.set('errorMessage', error);
      });
    },

    saveOnLeave: function (newValue) {
      var self = this;

      this.validateValue(newValue).then(function (validatedNewValue) {
        if (self.get('isDestroyed')) {
          return;
        }
        self.set('cell.value', validatedNewValue);
        self.send('stopEdition');
        self.get('table').notifyPropertyChange('contentUpdated');
      }, function () {
        if (self.get('isDestroyed')) {
          return;
        }
        self.send('stopEdition');
      });
    }
  },

  validateValue: function (value) {
    var datatable = this.get('table'),
      cell = this.get('cell'),
      position = this.get('position'),
      isValid;
    isValid = datatable.validateCell(cell, position, value);
    // is it a promise? (async validation)
    if (isValid instanceof Ember.RSVP.Promise) {
      return isValid;
    // no, so it is a boolean (sync validation)
    } else if (isValid) {
      return Ember.RSVP.Promise.resolve(value);
    } else {
      return Ember.RSVP.Promise.reject("Invalid value");
    }
  },

  inHighlightedRow: Ember.computed('position', 'highlightedRow', function () {
    return this.get('position.row') === this.get('highlightedRow');
  }),

  inHighlightedColumn: Ember.computed('position', 'highlightedColumn', function () {
    return this.get('position.column') === this.get('highlightedColumn');
  }),
});<|endoftext|>


<commit_before>// @flow
import SweetLoader, { phaseInModulePathRegexp } from './sweet-loader';
import { readFileSync } from 'fs';
import { dirname } from 'path';
import resolve from 'resolve';
import vm from 'vm';
import Store from './store';

export default class NodeLoader extends SweetLoader {
  extensions: ?string[];

  constructor(baseDir: string, extensions?: string[]) {
    super(baseDir);
    this.extensions = extensions;
  }

  normalize(name: string, refererName?: string, refererAddress?: string) {
    let normName = super.normalize(name, refererName, refererAddress);
    let match = normName.match(phaseInModulePathRegexp);
    if (match && match.length >= 3) {
      let resolvedName = resolve.sync(match[1], {
        basedir: refererName ? dirname(refererName) : this.baseDir,
        extensions: this.extensions ? this.extensions : [ '.js' ]
      });
      return `${resolvedName}:${match[2]}`;
    }
    throw new Error(`Module ${name} is missing phase information`);
  }

  fetch({name, address, metadata}: {name: string, address: {path: string, phase: number}, metadata: {}}) {
    let src = this.sourceCache.get(address.path);
    if (src != null) {
      return src;
    } else {
      src = readFileSync(address.path, 'utf8');
      this.sourceCache.set(address.path, src);
      return src;
    }
  }

  freshStore() {
    return new Store(vm.createContext());
  }

  eval(source: string, store: Store) {
    return vm.runInContext(source, store.getBackingObject());
  }
}<commit_msg>Add console/process to global in macro fixes #603<commit_after>// @flow
import SweetLoader, { phaseInModulePathRegexp } from './sweet-loader';
import { readFileSync } from 'fs';
import { dirname } from 'path';
import resolve from 'resolve';
import vm from 'vm';
import Store from './store';

export default class NodeLoader extends SweetLoader {
  extensions: ?string[];

  constructor(baseDir: string, extensions?: string[]) {
    super(baseDir);
    this.extensions = extensions;
  }

  normalize(name: string, refererName?: string, refererAddress?: string) {
    let normName = super.normalize(name, refererName, refererAddress);
    let match = normName.match(phaseInModulePathRegexp);
    if (match && match.length >= 3) {
      let resolvedName = resolve.sync(match[1], {
        basedir: refererName ? dirname(refererName) : this.baseDir,
        extensions: this.extensions ? this.extensions : [ '.js' ]
      });
      return `${resolvedName}:${match[2]}`;
    }
    throw new Error(`Module ${name} is missing phase information`);
  }

  fetch({name, address, metadata}: {name: string, address: {path: string, phase: number}, metadata: {}}) {
    let src = this.sourceCache.get(address.path);
    if (src != null) {
      return src;
    } else {
      src = readFileSync(address.path, 'utf8');
      this.sourceCache.set(address.path, src);
      return src;
    }
  }

  freshStore() {
    let sandbox = {
      process: global.process,
      console: global.console
    };
    return new Store(vm.createContext(sandbox));
  }

  eval(source: string, store: Store) {
    return vm.runInContext(source, store.getBackingObject());
  }
}
<|endoftext|>


<commit_before>define([
    'jquery',
    'knockout',
    'bootstrap-datepicker'
], function ($, ko) {
    ko.bindingHandlers.datepicker = {
        init: function(element, valueAccessor, allBindingsAccessor) {
          //initialize datepicker with some optional options
          var options = allBindingsAccessor().datepickerOptions || {};
          var value = valueAccessor();
          var widget = $(element).datepicker(options).data("datepicker");
          if (typeof value() === 'string') {
              var dateValue = new Date(value());
              value(dateValue);
              widget.setDate(dateValue);
          }

          //when a user changes the date, update the view model
          ko.utils.registerEventHandler(element, "changeDate", function(event) {
                 var value = valueAccessor();
                 if (ko.isObservable(value)) {
                     value(event.date);
                 }
          });
        },
        update: function(element, valueAccessor)   {
            var widget = $(element).data("datepicker");
             //when the view model is updated, update the widget
            if (widget) {
                widget.date = ko.utils.unwrapObservable(valueAccessor());
                widget.setValue();
            }
        }
    };

    return ko.bindingHandlers.datepicker;
});
<commit_msg>re: #463<commit_after>define([
    'jquery',
    'knockout',
    'bootstrap-datepicker'
], function ($, ko) {
    /**
    * A knockout.js binding for the jQuery UI datepicker, passes datepickerOptions
    * data-bind property to the datepicker on init
    * @constructor
    * @name datepicker
    */
    ko.bindingHandlers.datepicker = {
        init: function(element, valueAccessor, allBindingsAccessor) {
          //initialize datepicker with some optional options
          var options = allBindingsAccessor().datepickerOptions || {};
          var value = valueAccessor();
          var widget = $(element).datepicker(options).data("datepicker");
          if (typeof value() === 'string') {
              var dateValue = new Date(value());
              value(dateValue);
              widget.setDate(dateValue);
          }

          //when a user changes the date, update the view model
          ko.utils.registerEventHandler(element, "changeDate", function(event) {
                 var value = valueAccessor();
                 if (ko.isObservable(value)) {
                     value(event.date);
                 }
          });
        },
        update: function(element, valueAccessor)   {
            var widget = $(element).data("datepicker");
             //when the view model is updated, update the widget
            if (widget) {
                widget.date = ko.utils.unwrapObservable(valueAccessor());
                widget.setValue();
            }
        }
    };

    return ko.bindingHandlers.datepicker;
});
<|endoftext|>


<commit_before>/*jslint node: true, indent: 4 */
'use strict';
var async = require('async');
var discourse,
    conf;

exports.description = 'Issue Likes to all posts in a thread';

exports.configuration = {
    enabled: false,
    follow: false,
    binge: false,
    bingeHour: 23,
    bingeMinute: 30,
    topic: 1000
};

exports.name = 'AutoLikes';

exports.priority = 0;

exports.version = '1.13.0';

function format(str, dict) {
    for (var name in dict) {
        str = str.replace(new RegExp('%' + name + '%', 'g'), dict[name]);
    }
    return str;
}

function binge(callback) {
        if (typeof conf.topic === 'number') {
        innerBinge(conf.topic, callback);
    } else {
        async.each(conf.topic, function(topic, next){
            return innerBinge(topic, next);
        }, callback);
    }
}

function innerBinge(topic, callback){
    var msg = 'Liking /t/%TOPIC%/%POST% by @%USER%';
    discourse.getAllPosts(topic, function (posts, next) {
        var likeables = posts.filter(function (x) {
            var action = x.actions_summary.filter(function (y) {
                return y.id === 2;
            });
            return action && action[0].can_act;
        });
        async.each(likeables, function (post, flow) {
            discourse.log(format(msg, {
                'TOPIC': post.topic_id,
                'POST': post.post_number,
                'USER': post.username
            }));
            discourse.postAction('like', post.id, function (err, resp) {
                flow(err || resp.statusCode === 429);
            });
        }, next);
    }, function () {
        callback();
    });
}

function scheduleBinges() {
    async.forever(function (cb) {
        var now = new Date(),
            utc = new Date(),
            hours,
            minutes;
        utc.setUTCHours(conf.bingeHour);
        utc.setUTCMinutes(conf.bingeMinute);
        utc.setUTCSeconds(0);
        utc.setMilliseconds(0);
        now = now.getTime();
        utc = utc.getTime();
        if (now > utc) {
            // add a day if scheduling after 23:40 UTC
            utc += 24 * 60 * 60 * 1000;
        }
        minutes = Math.ceil(((utc - now) / 1000) / 60);
        hours = Math.floor(minutes / 60);
        minutes = minutes % 60;
        discourse.log('Like Binge scheduled for ' + hours + 'h' +
            minutes + 'm from now');
        setTimeout(function () {
            binge(cb);
        }, utc - now);
    });
}

exports.onMessage = function onMessage(message, post, callback) {
    if (message.data && message.data.type === 'created') {
        if (post) {
            discourse.log('Liking Post /t/' + post.topic_id +
                '/' + post.post_number + ' by @' + post.username);
        } else {
            discourse.log('Liking Post #' + message.data.id);
        }
        discourse.postAction('like', message.data.id, callback);
    } else {
        callback();
    }
};

exports.registerListeners = function registerListeners(callback) {
    if (conf.enabled && conf.follow) {
        if (typeof conf.topic === 'number') {
            callback(null, ['/topic/' + conf.topic]);
        } else {
            callback(null, conf.topic.map(function (v) {
                return '/topic/' + v;
            }));
        }
    } else {
        callback();
    }
};

exports.begin = function begin(browser, config) {
    conf = config.modules[exports.name];
    discourse = browser;
    if (conf.enabled && conf.binge) {
        scheduleBinges();
    }
};
<commit_msg>Accalia format things right.....<commit_after>/*jslint node: true, indent: 4 */
'use strict';
var async = require('async');
var discourse,
    conf;

exports.description = 'Issue Likes to all posts in a thread';

exports.configuration = {
    enabled: false,
    follow: false,
    binge: false,
    bingeHour: 23,
    bingeMinute: 30,
    topic: 1000
};

exports.name = 'AutoLikes';

exports.priority = 0;

exports.version = '1.13.0';

function format(str, dict) {
    for (var name in dict) {
        str = str.replace(new RegExp('%' + name + '%', 'g'), dict[name]);
    }
    return str;
}

function binge(callback) {
    if (typeof conf.topic === 'number') {
        innerBinge(conf.topic, callback);
    } else {
        async.each(conf.topic, function (topic, next) {
            return innerBinge(topic, next);
        }, callback);
    }
}

function innerBinge(topic, callback) {
    var msg = 'Liking /t/%TOPIC%/%POST% by @%USER%';
    discourse.getAllPosts(topic, function (posts, next) {
        var likeables = posts.filter(function (x) {
            var action = x.actions_summary.filter(function (y) {
                return y.id === 2;
            });
            return action && action[0].can_act;
        });
        async.each(likeables, function (post, flow) {
            discourse.log(format(msg, {
                'TOPIC': post.topic_id,
                'POST': post.post_number,
                'USER': post.username
            }));
            discourse.postAction('like', post.id, function (err, resp) {
                flow(err || resp.statusCode === 429);
            });
        }, next);
    }, function () {
        callback();
    });
}

function scheduleBinges() {
    async.forever(function (cb) {
        var now = new Date(),
            utc = new Date(),
            hours,
            minutes;
        utc.setUTCHours(conf.bingeHour);
        utc.setUTCMinutes(conf.bingeMinute);
        utc.setUTCSeconds(0);
        utc.setMilliseconds(0);
        now = now.getTime();
        utc = utc.getTime();
        if (now > utc) {
            // add a day if scheduling after 23:40 UTC
            utc += 24 * 60 * 60 * 1000;
        }
        minutes = Math.ceil(((utc - now) / 1000) / 60);
        hours = Math.floor(minutes / 60);
        minutes = minutes % 60;
        discourse.log('Like Binge scheduled for ' + hours + 'h' +
            minutes + 'm from now');
        setTimeout(function () {
            binge(cb);
        }, utc - now);
    });
}

exports.onMessage = function onMessage(message, post, callback) {
    if (message.data && message.data.type === 'created') {
        if (post) {
            discourse.log('Liking Post /t/' + post.topic_id +
                '/' + post.post_number + ' by @' + post.username);
        } else {
            discourse.log('Liking Post #' + message.data.id);
        }
        discourse.postAction('like', message.data.id, callback);
    } else {
        callback();
    }
};

exports.registerListeners = function registerListeners(callback) {
    if (conf.enabled && conf.follow) {
        if (typeof conf.topic === 'number') {
            callback(null, ['/topic/' + conf.topic]);
        } else {
            callback(null, conf.topic.map(function (v) {
                return '/topic/' + v;
            }));
        }
    } else {
        callback();
    }
};

exports.begin = function begin(browser, config) {
    conf = config.modules[exports.name];
    discourse = browser;
    if (conf.enabled && conf.binge) {
        scheduleBinges();
    }
};
<|endoftext|>


<commit_before>;(function() {
  'use strict'

  /**
   *  Chainable wrapper class.
   *
   *  This is the core of the entire plugin system and typically you extend
   *  functionality by adding methods to the prototype of this function.
   *
   *  However a plugin may also add static methods to the main function,
   *  see the `create` plugin for an example of adding static methods.
   *
   *  This implementation targets modern browsers (IE9+) and requires that
   *  the array methods `isArray`, `forEach` and `filter` are available,
   *  for older browsers you will need to include polyfills.
   *
   *  @param el A selector, DOM element, array of elements or Air instance.
   *  @param context The context element for a selector.
   */
  function Air(el, context) {
    if(typeof context === 'string') {
      context = document.querySelector(context);
    }
    context = context || document;
    this.dom = typeof el === 'string' ? context.querySelectorAll(el) : el;
    if(el instanceof Air) {
      this.dom = el.dom.slice(0);
    }else if(!Array.isArray(el)) {
      if(this.dom instanceof NodeList) {
        this.dom = Array.prototype.slice.call(this.dom);
      }else{
        this.dom = (el instanceof Element || el instanceof Window) ? [el] : [];
      }
    }

    // undocumented shortcut to Array.prototype.slice
    this.slice = Array.prototype.slice;
  }

  var proto = Air.prototype;

  /**
   *  Get the number of wrapped DOM elements.
   */
  Object.defineProperty(
    proto, 'length', {get: function(){return this.dom.length}});

  /**
   *  Get the DOM element at the specified index.
   */
  proto.get = function get(index) {
    if(index === undefined) { return this.dom };
    return this.dom[index];
  }

  /**
   *  Iterate the encapsulated DOM elements.
   */
  proto.each = function each(cb) {
    this.dom.forEach(cb);
    return this;
  }

  /**
   *  Main function, see the documentation for the `Air` class.
   */
  function air(el, context) {
    return new Air(el, context);
  }

  /**
   *  Static plugin method.
   *
   *  @param plugins Array of plugin functions.
   */
  function plugin(plugins) {
    var z;
    for(z in plugins) {
      if(typeof plugins[z] === 'function') {
        plugins[z].call(proto);
      // assume object style declaration
      }else{
        plugins[z].plugin.call(proto, plugins[z].conf);
      }
    }
  }

  // main plugin method
  air.plugin = proto.plugin = plugin;

  // expose class reference
  air.Air = Air;

  module.exports = proto.air = air;
})();
<commit_msg>Fix window test.<commit_after>;(function() {
  'use strict'

  /**
   *  Chainable wrapper class.
   *
   *  This is the core of the entire plugin system and typically you extend
   *  functionality by adding methods to the prototype of this function.
   *
   *  However a plugin may also add static methods to the main function,
   *  see the `create` plugin for an example of adding static methods.
   *
   *  This implementation targets modern browsers (IE9+) and requires that
   *  the array methods `isArray`, `forEach` and `filter` are available,
   *  for older browsers you will need to include polyfills.
   *
   *  @param el A selector, DOM element, array of elements or Air instance.
   *  @param context The context element for a selector.
   */
  function Air(el, context) {
    if(typeof context === 'string') {
      context = document.querySelector(context);
    }
    context = context || document;
    this.dom = typeof el === 'string' ? context.querySelectorAll(el) : el;
    if(el instanceof Air) {
      this.dom = el.dom.slice(0);
    }else if(!Array.isArray(el)) {
      if(this.dom instanceof NodeList) {
        this.dom = Array.prototype.slice.call(this.dom);
      }else{
        this.dom = (el instanceof Element || el === window) ? [el] : [];
      }
    }

    // undocumented shortcut to Array.prototype.slice
    this.slice = Array.prototype.slice;
  }

  var proto = Air.prototype;

  /**
   *  Get the number of wrapped DOM elements.
   */
  Object.defineProperty(
    proto, 'length', {get: function(){return this.dom.length}});

  /**
   *  Get the DOM element at the specified index.
   */
  proto.get = function get(index) {
    if(index === undefined) { return this.dom };
    return this.dom[index];
  }

  /**
   *  Iterate the encapsulated DOM elements.
   */
  proto.each = function each(cb) {
    this.dom.forEach(cb);
    return this;
  }

  /**
   *  Main function, see the documentation for the `Air` class.
   */
  function air(el, context) {
    return new Air(el, context);
  }

  /**
   *  Static plugin method.
   *
   *  @param plugins Array of plugin functions.
   */
  function plugin(plugins) {
    var z;
    for(z in plugins) {
      if(typeof plugins[z] === 'function') {
        plugins[z].call(proto);
      // assume object style declaration
      }else{
        plugins[z].plugin.call(proto, plugins[z].conf);
      }
    }
  }

  // main plugin method
  air.plugin = proto.plugin = plugin;

  // expose class reference
  air.Air = Air;

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


<commit_before>import deIndent from 'de-indent';
import htmlMinifier from 'html-minifier';
import parse5 from 'parse5';
import validateTemplate from 'vue-template-validator';
import { relative } from 'path';
import MagicString from 'magic-string';

/**
 * Check the lang attribute of a parse5 node.
 *
 * @param {Node|*} node
 * @return {String|undefined}
 */
function checkLang(node) {
    if (node.attrs) {
        let i = node.attrs.length;
        while (i--) {
            const attr = node.attrs[i];
            if (attr.name === 'lang') {
                return attr.value;
            }
        }
    }
    return undefined;
}

/**
 * Pad content with empty lines to get correct line number in errors.
 *
 * @param content
 * @returns {string}
 */
function padContent(content) {
    return content
          .split(/\r?\n/g)
          .map(() => '')
          .join('\n');
}

/**
 * Wrap code inside a with statement inside a function
 * This is necessary for Vue 2 template compilation
 *
 * @param {string} code
 * @returns {string}
 */
function wrapRenderFunction(code) {
    // Replace with(this) by something that works on strict mode
    // https://github.com/vuejs/vue-template-es2015-compiler/blob/master/index.js
    code = code.replace(/with\(this\)/g, "if(window.__VUE_WITH_STATEMENT__)");
    return `function(){${code}}`;
}

/**
 * Only support for es5 modules
 *
 * @param script
 * @param render
 * @param lang
 * @returns {string}
 */
function injectRender(script, render, lang) {
    if (['js', 'babel'].indexOf(lang.toLowerCase()) > -1) {
        const matches = /(export default[^{]*\{)/g.exec(script);
        if (matches) {
            return script.split(matches[1])
                  .join(`${matches[1]}` +
                        `render: ${wrapRenderFunction(render.render)},` +
                        'staticRenderFns: [' +
                        `${render.staticRenderFns.map(wrapRenderFunction).join(',')}],`
                  );
        }
    }
    throw new Error('[rollup-plugin-vue] could not find place to inject template in script.');
}

/**
 * @param script
 * @param template
 * @param lang
 * @returns {string}
 */
function injectTemplate(script, template, lang) {
    if (['js', 'babel'].indexOf(lang.toLowerCase()) > -1) {
        const matches = /(export default[^{]*\{)/g.exec(script);
        if (matches) {
            return script.split(matches[1])
                  .join(`${matches[1]} template: ${JSON.stringify(template)},`);
        }
    }
    throw new Error('[rollup-plugin-vue] could not find place to inject template in script.');
}

/**
 * Compile template: DeIndent and minify html.
 * @param {Node} node
 * @param {string} filePath
 * @param {string} content
 * @param {*} options
 */
function processTemplate(node, filePath, content, options) {
    const template = deIndent(parse5.serialize(node.content));
    const warnings = validateTemplate(node.content, content);
    if (warnings) {
        const relativePath = relative(process.cwd(), filePath);
        warnings.forEach((msg) => {
            console.warn(`\n Warning in ${relativePath}:\n ${msg}`);
        });
    }
    return htmlMinifier.minify(template, options.htmlMinifier);
}

/**
 * @param {Node|ASTNode} node
 * @param {string} filePath
 * @param {string} content
 * @param templateOrRender
 */
function processScript(node, filePath, content, templateOrRender) {
    const lang = checkLang(node) || 'js';
    const { template, render } = templateOrRender;
    let script = parse5.serialize(node);

    // pad the script to ensure correct line number for syntax errors
    const location = content.indexOf(script);
    const before = padContent(content.slice(0, location));
    script = before + script;

    const map = new MagicString(script);

    if (template) {
        script = injectTemplate(script, template, lang);
    } else if (render) {
        script = injectRender(script, render, lang);
    }
    script = deIndent(script);

    return {
        code: script,
        map,
    };
}

export default function vueTransform(code, filePath, options) {
    // 1. Parse the file into an HTML tree
    const fragment = parse5.parseFragment(code, { locationInfo: true });

    // 2. Walk through the top level nodes and check for their types
    const nodes = {};
    for (let i = fragment.childNodes.length - 1; i >= 0; i--) {
        nodes[fragment.childNodes[i].nodeName] = fragment.childNodes[i];
    }

    // 3. Don't touch files that don't look like Vue components
    if (!nodes.script) {
        throw new Error('There must be at least one script tag or one' +
              ' template tag per *.vue file.');
    }

    // 4. Process template
    const template = nodes.template
        ? processTemplate(nodes.template, filePath, code, options)
        : undefined;
    let js;
    if (options.compileTemplate) {
        /* eslint-disable */
        const render = template ? require('vue-template-compiler').compile(template) : undefined;
        /* eslint-enable */
        js = processScript(nodes.script, filePath, code, { render });
    } else {
        js = processScript(nodes.script, filePath, code, { template });
    }

    // 5. Process script & style
    return {
        js: js.code,
        map: js.map,
        css: nodes.style && {
            content: parse5.serialize(nodes.style),
            lang: checkLang(nodes.style),
        },
    };
}
<commit_msg>Fix lint<commit_after>import deIndent from 'de-indent';
import htmlMinifier from 'html-minifier';
import parse5 from 'parse5';
import validateTemplate from 'vue-template-validator';
import { relative } from 'path';
import MagicString from 'magic-string';

/**
 * Check the lang attribute of a parse5 node.
 *
 * @param {Node|*} node
 * @return {String|undefined}
 */
function checkLang(node) {
    if (node.attrs) {
        let i = node.attrs.length;
        while (i--) {
            const attr = node.attrs[i];
            if (attr.name === 'lang') {
                return attr.value;
            }
        }
    }
    return undefined;
}

/**
 * Pad content with empty lines to get correct line number in errors.
 *
 * @param content
 * @returns {string}
 */
function padContent(content) {
    return content
          .split(/\r?\n/g)
          .map(() => '')
          .join('\n');
}

/**
 * Wrap code inside a with statement inside a function
 * This is necessary for Vue 2 template compilation
 *
 * @param {string} code
 * @returns {string}
 */
function wrapRenderFunction(code) {
    // Replace with(this) by something that works on strict mode
    // https://github.com/vuejs/vue-template-es2015-compiler/blob/master/index.js
    code = code.replace(/with\(this\)/g, 'if(window.__VUE_WITH_STATEMENT__)');
    return `function(){${code}}`;
}

/**
 * Only support for es5 modules
 *
 * @param script
 * @param render
 * @param lang
 * @returns {string}
 */
function injectRender(script, render, lang) {
    if (['js', 'babel'].indexOf(lang.toLowerCase()) > -1) {
        const matches = /(export default[^{]*\{)/g.exec(script);
        if (matches) {
            return script.split(matches[1])
                  .join(`${matches[1]}` +
                        `render: ${wrapRenderFunction(render.render)},` +
                        'staticRenderFns: [' +
                        `${render.staticRenderFns.map(wrapRenderFunction).join(',')}],`
                  );
        }
    }
    throw new Error('[rollup-plugin-vue] could not find place to inject template in script.');
}

/**
 * @param script
 * @param template
 * @param lang
 * @returns {string}
 */
function injectTemplate(script, template, lang) {
    if (['js', 'babel'].indexOf(lang.toLowerCase()) > -1) {
        const matches = /(export default[^{]*\{)/g.exec(script);
        if (matches) {
            return script.split(matches[1])
                  .join(`${matches[1]} template: ${JSON.stringify(template)},`);
        }
    }
    throw new Error('[rollup-plugin-vue] could not find place to inject template in script.');
}

/**
 * Compile template: DeIndent and minify html.
 * @param {Node} node
 * @param {string} filePath
 * @param {string} content
 * @param {*} options
 */
function processTemplate(node, filePath, content, options) {
    const template = deIndent(parse5.serialize(node.content));
    const warnings = validateTemplate(node.content, content);
    if (warnings) {
        const relativePath = relative(process.cwd(), filePath);
        warnings.forEach((msg) => {
            console.warn(`\n Warning in ${relativePath}:\n ${msg}`);
        });
    }
    return htmlMinifier.minify(template, options.htmlMinifier);
}

/**
 * @param {Node|ASTNode} node
 * @param {string} filePath
 * @param {string} content
 * @param templateOrRender
 */
function processScript(node, filePath, content, templateOrRender) {
    const lang = checkLang(node) || 'js';
    const { template, render } = templateOrRender;
    let script = parse5.serialize(node);

    // pad the script to ensure correct line number for syntax errors
    const location = content.indexOf(script);
    const before = padContent(content.slice(0, location));
    script = before + script;

    const map = new MagicString(script);

    if (template) {
        script = injectTemplate(script, template, lang);
    } else if (render) {
        script = injectRender(script, render, lang);
    }
    script = deIndent(script);

    return {
        code: script,
        map,
    };
}

export default function vueTransform(code, filePath, options) {
    // 1. Parse the file into an HTML tree
    const fragment = parse5.parseFragment(code, { locationInfo: true });

    // 2. Walk through the top level nodes and check for their types
    const nodes = {};
    for (let i = fragment.childNodes.length - 1; i >= 0; i--) {
        nodes[fragment.childNodes[i].nodeName] = fragment.childNodes[i];
    }

    // 3. Don't touch files that don't look like Vue components
    if (!nodes.script) {
        throw new Error('There must be at least one script tag or one' +
              ' template tag per *.vue file.');
    }

    // 4. Process template
    const template = nodes.template
        ? processTemplate(nodes.template, filePath, code, options)
        : undefined;
    let js;
    if (options.compileTemplate) {
        /* eslint-disable */
        const render = template ? require('vue-template-compiler').compile(template) : undefined;
        /* eslint-enable */
        js = processScript(nodes.script, filePath, code, { render });
    } else {
        js = processScript(nodes.script, filePath, code, { template });
    }

    // 5. Process script & style
    return {
        js: js.code,
        map: js.map,
        css: nodes.style && {
            content: parse5.serialize(nodes.style),
            lang: checkLang(nodes.style),
        },
    };
}
<|endoftext|>


<commit_before>/*
 * clean.js - Clean only the bots messages.
 *
 * Contributed by Ovyerus
 */

exports.commands = [
    'clean'
];

exports.clean = {
    desc: "Clean up the bot's messages.",
    main: (bot, ctx) => {
        return new Promise((resolve, reject) => {
            ctx.msg.channel.purge(100, m => m.author.id === bot.user.id).then(amt => {
                return ctx.msg.channel.createMessage(`Cleaned \`${amt}\``);
            }).then(resolve).catch(reject);
        });
    }
};<commit_msg>fixed clean<commit_after>/*
 * clean.js - Clean only the bots messages.
 *
 * Contributed by Ovyerus
 */

exports.commands = [
    'clean'
];

exports.clean = {
    desc: 'clean messages created by the bot itself',
    main: (bot,ctx) => {
        return new Promise((resolve,reject) => {
            ctx.msg.channel.getMessages(100).then(msgs => {
                let delet = [];
                msgs.forEach(m => delet.push(m.delete()));
                return Promise.all(delet);
            });
        });
    }
};

<|endoftext|>


<commit_before>"use strict";
var exec = require('cordova/exec');

function PinnedHTTPS(expectedFingerprint){
	if (typeof expectedFingerprint != 'string') throw new TypeError('expectedFingerprint must be a string');
	expectedFingerprint = expectedFingerprint.trim().replace(' ', '').toLowerCase();
	if (!isSHA1(expectedFingerprint)) throw new TypeError('invalid expectedFingerprint. Must be an SHA1 fingerprint');
	this.fingerprint = expectedFingerprint
}

PinnedHTTPS.prototype.get = function(url, callback){
	if (typeof url != 'string') throw new TypeError('url must be a string');
	if (typeof callback != 'function') throw new TypeError('callback must be a function');

	cordova.exec(responseHandler, errorHandler, 'get', [url, this.fingerprint]);

	function responseHandler(responseObj){
		callback(null, responseObj);
	}
	function errorHandler(errObj){
		callback(errObj);
	}
};

PinnedHTTPS.prototype.request = function(options, callback){
	if (typeof options != 'object') throw new TypeError('options must be an object');
	if (typeof callback != 'function') throw new TypeError('callback must be a function');

	//Checking the mandatory fields of options
	if (typeof options.host != 'string') throw new TypeError('options.host must be a defined string');
	if (typeof options.port == 'number'){
		if (!(options.port > 0 && Math.floor(options.port) == options.port)) throw new TypeError('when defined, port must be a stricly positive integer');
	} else options.port = 443;
	if (options.method){
		if (typeof options.method != 'string') throw new TypeError('when defined, options.method must be a string');
	} else options.method = 'get';
	if (options.headers){
		if (typeof options.headers != 'object') throw new TypeError('when defined, options.headers must be an object');
		var headerKeys = Object.keys(options.headers);
		for (var i = 0; i < headerKeys.length; i++){
			var currentHeaderType = typeof options.headers[headerKeys[i]];
			if (!(currentHeaderType == 'string' || currentHeaderType == 'number' || currentHeaderType == 'boolean')) throw new TypeError('when defined, options.headers must contain either strings, numbers or booleans');
		}
	}

	cordova.exec(responseHandler, errorHandler, 'req', [JSON.stringify(options), this.fingerprint]);

	function responseHandler(responseObj){
		callback(null, responseObj);
	}
	function errorHandler(errObj){
		callback(errObj);
	}
}

module.exports = PinnedHTTPS;

function isSHA1(s){
	return (typeof s == 'string' && s.length == 40 && /^([a-f]|[0-9])+$/i.test(s));
}
<commit_msg>Forgot an argument<commit_after>"use strict";
var exec = require('cordova/exec');

function PinnedHTTPS(expectedFingerprint){
	if (typeof expectedFingerprint != 'string') throw new TypeError('expectedFingerprint must be a string');
	expectedFingerprint = expectedFingerprint.trim().replace(/ +/g, '').toLowerCase();
	console.log('Expected fingerprint: ' + expectedFingerprint);
	if (!isSHA1(expectedFingerprint)) throw new TypeError('invalid expectedFingerprint. Must be an SHA1 fingerprint');
	this.fingerprint = expectedFingerprint
}

PinnedHTTPS.prototype.get = function(url, callback){
	if (typeof url != 'string') throw new TypeError('url must be a string');
	if (typeof callback != 'function') throw new TypeError('callback must be a function');

	cordova.exec(responseHandler, errorHandler, 'PinnedHTTPS', 'get', [url, this.fingerprint]);

	function responseHandler(responseObj){
		callback(null, responseObj);
	}
	function errorHandler(errObj){
		callback(errObj);
	}
};

PinnedHTTPS.prototype.request = function(options, callback){
	if (typeof options != 'object') throw new TypeError('options must be an object');
	if (typeof callback != 'function') throw new TypeError('callback must be a function');

	//Checking the mandatory fields of options
	if (typeof options.host != 'string') throw new TypeError('options.host must be a defined string');
	if (typeof options.port == 'number'){
		if (!(options.port > 0 && Math.floor(options.port) == options.port)) throw new TypeError('when defined, port must be a stricly positive integer');
	} else options.port = 443;
	if (options.method){
		if (typeof options.method != 'string') throw new TypeError('when defined, options.method must be a string');
	} else options.method = 'get';
	if (options.headers){
		if (typeof options.headers != 'object') throw new TypeError('when defined, options.headers must be an object');
		var headerKeys = Object.keys(options.headers);
		for (var i = 0; i < headerKeys.length; i++){
			var currentHeaderType = typeof options.headers[headerKeys[i]];
			if (!(currentHeaderType == 'string' || currentHeaderType == 'number' || currentHeaderType == 'boolean')) throw new TypeError('when defined, options.headers must contain either strings, numbers or booleans');
		}
	}

	cordova.exec(responseHandler, errorHandler, 'PinnedHTTPS', 'req', [JSON.stringify(options), this.fingerprint]);

	function responseHandler(responseObj){
		callback(null, responseObj);
	}
	function errorHandler(errObj){
		callback(errObj);
	}
}

module.exports = PinnedHTTPS;

function isSHA1(s){
	return (typeof s == 'string' && s.length == 40 && /^([a-f]|[0-9])+$/i.test(s));
}
<|endoftext|>


<commit_before>'use strict';

const http = require('http');

let request = {};

request.get = function(url) {
  return new Promise((resolve, reject) => {
    let req = http.get(url, (res) => {
      if (res.statusCode == 400) {
        reject(new Error(`GET request to ${url} failed, status: ${res.statusCode}`));
      }

      let body = [];

      res.on('data', (chunk) => body.push(chunk));
      res.on('end', () => resolve(body.join('')));
    });

    req.on('error', (err) => reject(err));
  });
};

module.exports = request;<commit_msg>Create post request helper<commit_after>'use strict';

const http = require('http');

let request = {};

request.get = function(url) {
  return new Promise((resolve, reject) => {
    let req = http.get(url, (res) => {
      if ([400, 401, 03, 404].includes(res.statusCode)) {
        reject(new Error(`GET request to ${url} failed, status: ${res.statusCode}`));
      }

      let body = [];

      res.on('data', (chunk) => body.push(chunk));
      res.on('end', () => resolve(body.join('')));
    });

    req.on('error', (err) => reject(err));
  });
};

request.post = function(options, data) {
  return new Promise((resolve, reject) => {
    let req = http.request(options, (res) => {
      res.setEncoding('utf8');
      console.log(`STATUS: ${res.statusCode}`);
      console.log(`HEADERS: ${JSON.stringify(res.headers)}`);

      let body = [];

      res.on('data', (chunk) => body.push(chunk));
      res.on('end', () => resolve(body.join('')));
    });

    req.on('error', (err) => reject(err));
    req.write(data);
    req.end();
  });
};

module.exports = request;<|endoftext|>