<commit_before>/**
 * Created by wujichao on 16/4/19.
 */
"use strict"

const sprintf = require("sprintf-js").sprintf;
const keys = require('../config/keys');
const _ = require('lodash');
const http_request = require('./request');
const assert = require('chai').assert;
const db = require('../database');

const openid_cache = {};

module.exports = function *(next){
    const code = this.query.code || this.request.body.code;
    if (!_.isString(code)) {
        return yield *next;
    }

    // code不同账号可能是一样的 擦了...
    var openid = null;//openid_cache.code;
    if (openid) {
        console.log('hit! code ' + code + ' openid ' + openid);
    } else {
        console.log('not hit! code ' + code);

        const url = sprintf('https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code',
            keys.WECHAT_APPID, keys.WECHAT_APPSECRET, code);

        let body;
        try {
            body = yield http_request(url);
        } catch(err) {
            console.log(err);
            throw err;
        }

        console.log(body);
        openid = body.openid;
        assert(_.isObject(body) && _.isString(body.openid));

        // cache
        openid_cache.code = openid;
    }

    this.openid = openid;

    // openid 换 userid
    const request = yield db.request();
    request.input('openid', this.openid);
    const result = yield request.queryOne('select userid from wechat_bind where openid=@openid');
    if (result) {
        this.userid = result.userid;
    } else {
        // TODO: 这里做个校验 还需要重新规划下路径
        //未绑定, 理论上只有get_bind和post_bind才会未绑定
    }

    console.log('wechat web auth code '+ code + ' -> this.openid ' + this.openid + ' -> userid ' + this.userid);
    yield *next;
};<commit_msg>犯低级错误了, var d={}, code='xx', d.code == d.['code'] != d.[code]<commit_after>/**
 * Created by wujichao on 16/4/19.
 */
"use strict"

const sprintf = require("sprintf-js").sprintf;
const keys = require('../config/keys');
const _ = require('lodash');
const http_request = require('./request');
const assert = require('chai').assert;
const db = require('../database');

const openid_cache = {};

module.exports = function *(next){
    const code = this.query.code || this.request.body.code;
    if (!_.isString(code)) {
        return yield *next;
    }

    var openid = openid_cache[code];
    if (openid) {
        console.log('hit! code ' + code + ' openid ' + openid);
    } else {
        console.log('not hit! code ' + code);

        const url = sprintf('https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code',
            keys.WECHAT_APPID, keys.WECHAT_APPSECRET, code);

        let body;
        try {
            body = yield http_request(url);
        } catch(err) {
            console.log(err);
            throw err;
        }

        console.log(body);
        openid = body.openid;
        assert(_.isObject(body) && _.isString(body.openid));

        // cache
        openid_cache[code] = openid;
        console.log('get new code: ', code , 'openid: ', openid);
    }

    this.openid = openid;

    // openid 换 userid
    const request = yield db.request();
    request.input('openid', this.openid);
    const result = yield request.queryOne('select userid from wechat_bind where openid=@openid');
    if (result) {
        this.userid = result.userid;
    } else {
        // TODO: 这里做个校验 还需要重新规划下路径
        //未绑定, 理论上只有get_bind和post_bind才会未绑定
    }

    console.log('wechat web auth code '+ code + ' -> this.openid ' + this.openid + ' -> userid ' + this.userid);
    yield *next;
};<|endoftext|>


<commit_before>
////////////////////////////////////////////////////////////////////////////////
// Fixity Resolution
// converts infix lists to infix application using correct precedences.

JSHC.Fixity = {};  // Fixity module

/*
  modifies the module AST by rewriting infix lists into function applications.
*/
JSHC.Fixity.fixityResolution = function(module_ast){
//        JSHC.alert(module_ast)
    JSHC.Fixity.translateInfixLists(module_ast.body.fspace,module_ast);
};

////////////////////////////////////////////////////////////////////////////////

/*
  looks up fixity information and defaults to infixl 9 if missing.
*/
JSHC.Fixity.fixityLookup = function(info,name){

    var r = name.id.fixity;
    if( r === undefined ){
	r = {fix: "leftfix", prec: 9};
    }
    return r;
};

////////////////////////////////////////////////////////////////////////////////

/*
  takes an infix list and returns an expression using '-' and/or binary
  operators.
  throws exceptions if anything goes wrong, such as precedence errors.
 */
JSHC.Fixity.resolve = function(info,exps) {
    assert.ok( exps instanceof Array );
    for(var i=0;i<exps.length;i++){
	assert.ok(exps[i]!==undefined);
    }

    resolve_parseNeg = function(prec, fix){
	assert.ok( exps.length > 0 );
	var e0 = exps[0];
//	JSHC.alert("checking fixity of an exp:",e0)
//	alert("resolve parseNeg of: " + JSHC.showAST(e0));
	if( e0.name === "-" ){
	    if( prec >= 6 ){
		throw new JSHC.SourceError("unary minus can not occur here as outer expression has greater (>=6) precedence.");
	    }
	    exps.shift();
	    rexp = resolve_parseNeg(6, "leftfix");
	    return {name:"negate",exp:rexp,pos:e0.pos};
	} else if( e0.name === "qop" ) {
	    throw new JSHC.CompilerError("unexpected operator in precedence resolution: expected '-' or lexp, got: " + JSHC.showAST(e0));
	} else {  // some arbitrary expression
//	    alert("resolve parse: \n" + JSHC.showAST(exps) + "\n\n" + JSHC.showAST(e0));
	    exps.shift();
	    return resolve_parse(prec,fix,e0);
	}
    };

    resolve_parse = function(prec1, fix1, exp1){
	if( exps.length === 0 ){
	    return exp1;
	}
//	JSHC.alert("resolve_parse args\nprec1:",prec1,"fix1:",fix1,"\nexp1:",exp1);
	var exp2 = exps[0];
	if( exp2.name === "qop" ){
	    var exp2_fixity = JSHC.Fixity.fixityLookup(info,exp2);
	    prec2 = exp2_fixity.prec;
	    fix2 = exp2_fixity.fix;
//	    JSHC.alert("prec2:",prec2,"fix2:",fix2,"\nexp2:",exp2);

	    if( prec1 === prec2 && (fix1 !== fix2 || fix1 === "nonfix") ){
		throw new JSHC.SourceError("same precedence with non-associative operator");
	    } else if( prec1 > prec2 || (prec1 === prec2 && fix1 == "leftfix" ) ){
	        //this commented out for chained operator applications to work,
	        //i.e. 1 + 2 + 3
//		exps.unshift(exp2);
//		JSHC.alert("unshifted:",exp2,exps,"\nand returned:",exp1);
		return exp1;
	    } else {
//	    alert("resolve_parseNeg:\n\n" + "prec2: " + JSHC.showAST(prec2) + "\n\nfix2: " + JSHC.showAST(fix2));
//                JSHC.alert("before shift: ", exps);
	        exps.shift();
//	        JSHC.alert("shifted:",exps,"\nand calling parseNeg on: ", prec2, fix2)
		var rexp = resolve_parseNeg(prec2, fix2);
		//rexp = {name:"infix-app", lhs:exp1, op:exp2, rhs:rexp, pos:exp2.pos};
		rexp = {name:"application", exps:[exp2.id,exp1,rexp], pos:exp2.pos, orig:"infix"};
//		alert("FIXED INFIXEXP: \n\n" + JSHC.showAST(rexp));
		return resolve_parse(prec1, fix1, rexp);
	    }
	} else {
	    throw new JSHC.CompilerError("expected operator in precedence resolution, found: " + JSHC.showAST(exp2));
	}
    };

    return resolve_parseNeg(-1, "nonfix");
};

////////////////////////////////////////////////////////////////////////////////

/*
  given an AST and a member name, check if the sub-tree referred to by the member
  name is an infix list, and if so, replaces it by using the 'resolve' function.
*/
JSHC.Fixity.translateInfixMember = function(info, ast, member){
    assert.ok( ast !== undefined && ast.name !== undefined, "param 'ast' must be an AST" );
    assert.ok(typeof member === "string", "type of member is not string but: " + typeof member );
    if( ast[member].name === "infixexp" ){
	ast[member] = JSHC.Fixity.resolve(info, ast[member].exps);
	assert.ok( ast[member] !== undefined );
    }
};

////////////////////////////////////////////////////////////////////////////////

/*
  given an AST, check if it is an infix list, and if so, apply the 'resolve'
  function and return the result.
*/
JSHC.Fixity.translateInfixExp = function(info, ast){
//        JSHC.alert("translate:", ast)
    if( ast.name === "infixexp" ){
	return JSHC.Fixity.resolve(info, ast.exps);
    } else {
	return ast;
    }
};

////////////////////////////////////////////////////////////////////////////////

/*
  replaces all infix lists in an AST.
*/
JSHC.Fixity.translateInfixLists = function(info, ast){
    assert.ok( ast !== undefined && ast.name !== undefined, "param 'ast' must be an AST" );
//    alert("translateInfixLists: " + ast.name);
    var f = JSHC.Fixity.translateInfixLists[ast.name];
    if( f === undefined ){
	throw new Error("no definition for " + JSHC.showAST(ast) ); //+ast.name);
    }
    assert.ok( f instanceof Function, ast.name+" <: Function." )
    f(info, ast);
};

JSHC.Fixity.translateInfixLists["module"] = function(info, ast){
    // ignoring exports as there are no expressions to translate there
    JSHC.Fixity.translateInfixLists(info, ast.body);
};

JSHC.Fixity.translateInfixLists["body"] = function(info, ast){
    var i;

    // ignoring imports as there are no expressions to translate there

    for(i=0;i<ast.topdecls.length;i++){
	JSHC.Fixity.translateInfixLists(info, ast.topdecls[i]);
    }
};

JSHC.Fixity.translateInfixLists["topdecl-decl"] = function(info, ast){
    JSHC.Fixity.translateInfixLists(info, ast.decl);
};

JSHC.Fixity.translateInfixLists["topdecl-data"] = function(info, ast){
    // no expressions to translate here
};

JSHC.Fixity.translateInfixLists["decl-fun"] = function(info, ast){
    // TODO: currently nothing to do for the LHS.
    //       adding constructor operators will make infix expressions in patterns.
    JSHC.Fixity.translateInfixMember(info, ast, "rhs");
    JSHC.Fixity.translateInfixLists(info, ast.rhs);
};

JSHC.Fixity.translateInfixLists["fun-where"] = function (info,ast) {
    JSHC.Fixity.translateInfixMember(info, ast, "exp");
    JSHC.Fixity.translateInfixLists(info, ast.exp);

    for (var i = 0; i < ast.decls.length; i++) {
        JSHC.Fixity.translateInfixLists(info,ast.decls[i]);
    }
};

JSHC.Fixity.translateInfixLists["let"] = function (info,ast) {
    JSHC.Fixity.translateInfixMember(info, ast, "exp");
    JSHC.Fixity.translateInfixLists(info, ast.exp);

    for (var i = 0; i < ast.decls.length; i++) {
        JSHC.Fixity.translateInfixLists(info,ast.decls[i]);
    }
};

JSHC.Fixity.translateInfixLists["constrained-exp"] = function(info, ast){
    // no infix expressions in type signatures.

    JSHC.Fixity.translateInfixMember(info, ast, "exp");
    // handle sub-expressions afterwards
    JSHC.Fixity.translateInfixLists(info, ast.exp);
};

/*
JSHC.Fixity.translateInfixLists["infix-app"] = function(info, ast){
    JSHC.Fixity.translateInfixMember(info, ast, "lhs");
    JSHC.Fixity.translateInfixMember(info, ast, "rhs");
    // handle sub-expressions afterwards
    JSHC.Fixity.translateInfixLists(info, ast.lhs);
    JSHC.Fixity.translateInfixLists(info, ast.rhs);
};
*/

JSHC.Fixity.translateInfixLists["case"] = function(info, ast) {
    JSHC.Fixity.translateInfixMember(info, ast, "exp");
    JSHC.Fixity.translateInfixLists(info, ast.exp);

    for (var i = 0; i < ast.alts.length; i++) {
        JSHC.Fixity.translateInfixMember(info, ast.alts[i], "exp");
        JSHC.Fixity.translateInfixLists(info, ast.alts[i].exp);
    }
};

JSHC.Fixity.translateInfixLists["negate"] = function(info, ast){
    JSHC.Fixity.translateInfixMember(info, ast, "exp");
    JSHC.Fixity.translateInfixLists(info, ast.exp);
};

JSHC.Fixity.translateInfixLists["application"] = function(info, ast){
    var i;
//    alert("App contains: " + JSHC.showAST(ast));
    for(i=0;i<ast.exps.length;i++){
	ast.exps[i] = JSHC.Fixity.translateInfixExp(info, ast.exps[i]);
	JSHC.Fixity.translateInfixLists(info, ast.exps[i]);
    }
};

JSHC.Fixity.translateInfixLists["tuple"] = function(info, ast){
    var i;
//    alert("App contains: " + JSHC.showAST(ast));
    for(i=0;i<ast.members.length;i++){
//        JSHC.alert("translating this tuple member;", ast.members[i]);
	ast.members[i] = JSHC.Fixity.translateInfixExp(info, ast.members[i]);
//	JSHC.alert("translated this tuple member;", ast.members[i]);
	JSHC.Fixity.translateInfixLists(info, ast.members[i]);
    }
};

JSHC.Fixity.translateInfixLists["lambda"] = function(info, ast) {
    JSHC.Fixity.translateInfixMember(info, ast, "rhs");
    JSHC.Fixity.translateInfixLists(info, ast.rhs);
};

JSHC.Fixity.translateInfixLists["varname"] = function(info, ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["dacon"] = function(info, ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["integer-lit"] = function(info, ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["qop"] = function(info, ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["fixity"] = function(info, ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["type-signature"] = function(info, ast){
    // nothing
};

////////////////////////////////////////////////////////////////////////////////
<commit_msg>fixity: cleanup. remove old info map<commit_after>
////////////////////////////////////////////////////////////////////////////////
// Fixity Resolution
// converts infix lists to infix application using correct precedences.

JSHC.Fixity = {};  // Fixity module

/*
  modifies the module AST by rewriting infix lists into function applications.
*/
JSHC.Fixity.fixityResolution = function(module_ast){
//        JSHC.alert(module_ast)
    JSHC.Fixity.translateInfixLists(module_ast);
};

////////////////////////////////////////////////////////////////////////////////

/*
  looks up fixity information and defaults to infixl 9 if missing.
*/
JSHC.Fixity.fixityLookup = function(name){

    var r = name.id.fixity;
    if( r === undefined ){
	r = {fix: "leftfix", prec: 9};
    }
    return r;
};

////////////////////////////////////////////////////////////////////////////////

/*
  takes an infix list and returns an expression using '-' and/or binary
  operators.
  throws exceptions if anything goes wrong, such as precedence errors.
 */
JSHC.Fixity.resolve = function(exps) {
    assert.ok( exps instanceof Array );
    for(var i=0;i<exps.length;i++){
	assert.ok(exps[i]!==undefined);
    }

    resolve_parseNeg = function(prec, fix){
	assert.ok( exps.length > 0 );
	var e0 = exps[0];
//	JSHC.alert("checking fixity of an exp:",e0)
//	alert("resolve parseNeg of: " + JSHC.showAST(e0));
	if( e0.name === "-" ){
	    if( prec >= 6 ){
		throw new JSHC.SourceError("unary minus can not occur here as outer expression has greater (>=6) precedence.");
	    }
	    exps.shift();
	    rexp = resolve_parseNeg(6, "leftfix");
	    return {name:"negate",exp:rexp,pos:e0.pos};
	} else if( e0.name === "qop" ) {
	    throw new JSHC.CompilerError("unexpected operator in precedence resolution: expected '-' or lexp, got: " + JSHC.showAST(e0));
	} else {  // some arbitrary expression
//	    alert("resolve parse: \n" + JSHC.showAST(exps) + "\n\n" + JSHC.showAST(e0));
	    exps.shift();
	    return resolve_parse(prec,fix,e0);
	}
    };

    resolve_parse = function(prec1, fix1, exp1){
	if( exps.length === 0 ){
	    return exp1;
	}
//	JSHC.alert("resolve_parse args\nprec1:",prec1,"fix1:",fix1,"\nexp1:",exp1);
	var exp2 = exps[0];
	if( exp2.name === "qop" ){
	    var exp2_fixity = JSHC.Fixity.fixityLookup(exp2);
	    prec2 = exp2_fixity.prec;
	    fix2 = exp2_fixity.fix;
//	    JSHC.alert("prec2:",prec2,"fix2:",fix2,"\nexp2:",exp2);

	    if( prec1 === prec2 && (fix1 !== fix2 || fix1 === "nonfix") ){
		throw new JSHC.SourceError("same precedence with non-associative operator");
	    } else if( prec1 > prec2 || (prec1 === prec2 && fix1 == "leftfix" ) ){
	        //this commented out for chained operator applications to work,
	        //i.e. 1 + 2 + 3
//		exps.unshift(exp2);
//		JSHC.alert("unshifted:",exp2,exps,"\nand returned:",exp1);
		return exp1;
	    } else {
//	    alert("resolve_parseNeg:\n\n" + "prec2: " + JSHC.showAST(prec2) + "\n\nfix2: " + JSHC.showAST(fix2));
//                JSHC.alert("before shift: ", exps);
	        exps.shift();
//	        JSHC.alert("shifted:",exps,"\nand calling parseNeg on: ", prec2, fix2)
		var rexp = resolve_parseNeg(prec2, fix2);
		//rexp = {name:"infix-app", lhs:exp1, op:exp2, rhs:rexp, pos:exp2.pos};
		rexp = {name:"application", exps:[exp2.id,exp1,rexp], pos:exp2.pos, orig:"infix"};
//		alert("FIXED INFIXEXP: \n\n" + JSHC.showAST(rexp));
		return resolve_parse(prec1, fix1, rexp);
	    }
	} else {
	    throw new JSHC.CompilerError("expected operator in precedence resolution, found: " + JSHC.showAST(exp2));
	}
    };

    return resolve_parseNeg(-1, "nonfix");
};

////////////////////////////////////////////////////////////////////////////////

/*
  given an AST and a member name, check if the sub-tree referred to by the member
  name is an infix list, and if so, replaces it by using the 'resolve' function.
*/
JSHC.Fixity.translateInfixMember = function(ast, member){
    assert.ok( ast !== undefined && ast.name !== undefined, "param 'ast' must be an AST" );
    assert.ok(typeof member === "string", "type of member is not string but: " + typeof member );
    if( ast[member].name === "infixexp" ){
	ast[member] = JSHC.Fixity.resolve(ast[member].exps);
	assert.ok( ast[member] !== undefined );
    }
};

////////////////////////////////////////////////////////////////////////////////

/*
  given an AST, check if it is an infix list, and if so, apply the 'resolve'
  function and return the result.
*/
JSHC.Fixity.translateInfixExp = function(ast){
//        JSHC.alert("translate:", ast)
    if( ast.name === "infixexp" ){
	return JSHC.Fixity.resolve(ast.exps);
    } else {
	return ast;
    }
};

////////////////////////////////////////////////////////////////////////////////

/*
  replaces all infix lists in an AST.
*/
JSHC.Fixity.translateInfixLists = function(ast){
    assert.ok( ast !== undefined && ast.name !== undefined, "param 'ast' must be an AST" );
//    alert("translateInfixLists: " + ast.name);
    var f = JSHC.Fixity.translateInfixLists[ast.name];
    if( f === undefined ){
	throw new Error("no definition for " + JSHC.showAST(ast) ); //+ast.name);
    }
    assert.ok( f instanceof Function, ast.name+" <: Function." )
    f(ast);
};

JSHC.Fixity.translateInfixLists["module"] = function(ast){
    // ignoring exports as there are no expressions to translate there
    JSHC.Fixity.translateInfixLists(ast.body);
};

JSHC.Fixity.translateInfixLists["body"] = function(ast){
    var i;

    // ignoring imports as there are no expressions to translate there

    for(i=0;i<ast.topdecls.length;i++){
	JSHC.Fixity.translateInfixLists(ast.topdecls[i]);
    }
};

JSHC.Fixity.translateInfixLists["topdecl-decl"] = function(ast){
    JSHC.Fixity.translateInfixLists(ast.decl);
};

JSHC.Fixity.translateInfixLists["topdecl-data"] = function(ast){
    // no expressions to translate here
};

JSHC.Fixity.translateInfixLists["decl-fun"] = function(ast){
    // TODO: currently nothing to do for the LHS.
    //       adding constructor operators will make infix expressions in patterns.
    JSHC.Fixity.translateInfixMember(ast, "rhs");
    JSHC.Fixity.translateInfixLists(ast.rhs);
};

JSHC.Fixity.translateInfixLists["fun-where"] = function (ast) {
    JSHC.Fixity.translateInfixMember(ast, "exp");
    JSHC.Fixity.translateInfixLists(ast.exp);

    for (var i = 0; i < ast.decls.length; i++) {
        JSHC.Fixity.translateInfixLists(ast.decls[i]);
    }
};

JSHC.Fixity.translateInfixLists["let"] = function (ast) {
    JSHC.Fixity.translateInfixMember(ast, "exp");
    JSHC.Fixity.translateInfixLists(ast.exp);

    for (var i = 0; i < ast.decls.length; i++) {
        JSHC.Fixity.translateInfixLists(ast.decls[i]);
    }
};

JSHC.Fixity.translateInfixLists["constrained-exp"] = function(ast){
    // no infix expressions in type signatures.

    JSHC.Fixity.translateInfixMember(ast, "exp");
    // handle sub-expressions afterwards
    JSHC.Fixity.translateInfixLists(ast.exp);
};

/*
JSHC.Fixity.translateInfixLists["infix-app"] = function(ast){
    JSHC.Fixity.translateInfixMember(ast, "lhs");
    JSHC.Fixity.translateInfixMember(ast, "rhs");
    // handle sub-expressions afterwards
    JSHC.Fixity.translateInfixLists(ast.lhs);
    JSHC.Fixity.translateInfixLists(ast.rhs);
};
*/

JSHC.Fixity.translateInfixLists["case"] = function(ast) {
    JSHC.Fixity.translateInfixMember(ast, "exp");
    JSHC.Fixity.translateInfixLists(ast.exp);

    for (var i = 0; i < ast.alts.length; i++) {
        JSHC.Fixity.translateInfixMember(ast.alts[i], "exp");
        JSHC.Fixity.translateInfixLists(ast.alts[i].exp);
    }
};

JSHC.Fixity.translateInfixLists["negate"] = function(ast){
    JSHC.Fixity.translateInfixMember(ast, "exp");
    JSHC.Fixity.translateInfixLists(ast.exp);
};

JSHC.Fixity.translateInfixLists["application"] = function(ast){
    var i;
//    alert("App contains: " + JSHC.showAST(ast));
    for(i=0;i<ast.exps.length;i++){
	ast.exps[i] = JSHC.Fixity.translateInfixExp(ast.exps[i]);
	JSHC.Fixity.translateInfixLists(ast.exps[i]);
    }
};

JSHC.Fixity.translateInfixLists["tuple"] = function(ast){
    var i;
//    alert("App contains: " + JSHC.showAST(ast));
    for(i=0;i<ast.members.length;i++){
//        JSHC.alert("translating this tuple member;", ast.members[i]);
	ast.members[i] = JSHC.Fixity.translateInfixExp(ast.members[i]);
//	JSHC.alert("translated this tuple member;", ast.members[i]);
	JSHC.Fixity.translateInfixLists(ast.members[i]);
    }
};

JSHC.Fixity.translateInfixLists["lambda"] = function(ast) {
    JSHC.Fixity.translateInfixMember(ast, "rhs");
    JSHC.Fixity.translateInfixLists(ast.rhs);
};

JSHC.Fixity.translateInfixLists["varname"] = function(ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["dacon"] = function(ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["integer-lit"] = function(ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["qop"] = function(ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["fixity"] = function(ast){
    // nothing
};

JSHC.Fixity.translateInfixLists["type-signature"] = function(ast){
    // nothing
};

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>// Load our dependencies
var spritesmithEngineTest = require('spritesmith-engine-test');
var pixelsmith = require('../');

// Run our test
spritesmithEngineTest.run({
  engine: pixelsmith,
  engineName: 'pixelsmith'
});

// TODO: Should we test png, jpeg, and gif support?
<commit_msg>Defined custom tests for jpeg and gif<commit_after>// Load our dependencies
var spritesmithEngineTest = require('spritesmith-engine-test');
var pixelsmith = require('../');

// Run our test
// DEV: This covers png and jpeg inputs
spritesmithEngineTest.run({
  engine: pixelsmith,
  engineName: 'pixelsmith'
});

// Define custom tests
var spritesmithUtils = spritesmithEngineTest.spritesmithUtils;
describe('pixelsmith', function () {
  describe('working with multiple images', function () {
    describe('outputting a jpeg image', function () {
      // Render a jpeg image
      var multipleImages = spritesmithEngineTest.config.multipleImages;
      spritesmithUtils.interpretImages(pixelsmith, multipleImages.filepaths);
      spritesmithUtils.renderCanvas({
        engine: pixelsmith,
        width: multipleImages.width,
        height: multipleImages.height,
        coordinateArr: multipleImages.coordinateArr,
        exportParams: {
          format: 'jpeg'
        }
      });

      // Allow for debugging
      if (process.env.TEST_DEBUG) {
        spritesmithUtils.debugResult('debug.jpg');
      }

      it.only('outputs a jpeg image', function () {
        // TOOD: Complete me
      });
    });

    describe.skip('outputting a gif image', function () {
      it('outputs a gif image', function () {
        // TOOD: Complete me
      });
    });
  });
});
<|endoftext|>


<commit_before>var App = Ember.Application.create({
  rootElement: '#builds-application'
});

App.Router.map(function() {
  this.route('release');
  this.route('beta');
  this.route('canary');
  this.route('tagged');
});

App.Router.reopen({
  notifyGoogleAnalytics: function() {
    var url = this.get('url');

    // Add a slash if neccesary
    if (!/^\//.test(url)){ url = '/' + url; }

    _gaq.push(['_trackPageview', '/builds' + url]);
  }.on('didTransition')
});

App.CopyClipboardComponent = Ember.Component.extend({
  tagName: 'span',
  hasFlash: ZeroClipboard.detectFlashSupport(),

  didInsertElement: function () {
    var clip = new ZeroClipboard(this.$('button'), {
      // This would normally be a relative path
      moviePath: "/images/ZeroClipboard.swf",

      trustedDomains: ["*"],
      allowScriptAccess: "always"
    });

    clip.on('mousedown', function(client, e) {
      Em.run.later(this, function() {
        $(this).removeClass('loading');
        $(this).removeAttr('disabled');
      }, 1000);
      Em.run.next(this, function() {
        $(this).addClass('loading');
        $(this).attr('disabled', 'disabled');
      });
    });

    this.$('input').on('click', function() {
      $(this).select();
    });
  }
});

App.S3Bucket = Ember.Object.extend({
  files: [],
  isLoading: false,

  // Setup these as default values.
  // They can be overridden on create.
  queryUseSSL: true,
  objectUseSSL: false,
  delimiter: '/',
  bucket: 'builds.emberjs.com',
  endpoint: 's3.amazonaws.com',

  delimiterParameter: function(){
    var delimiter = this.getWithDefault('delimiter','').toString();
    return (delimiter) ? 'delimiter=' + delimiter : '';
  }.property('delimiter'),

  markerParameter: function(){
    return 'marker=' + this.getWithDefault('marker','').toString();
  }.property('marker'),

  maxKeysParameter: function(){
    return 'max-keys=' + this.getWithDefault('maxKeys','').toString();
  }.property('maxKeys'),

  prefixParameter: function(){
    return 'prefix=' + this.getWithDefault('prefix','').toString();
  }.property('prefix'),

  queryProtocol: function() {
    return this.get('queryUseSSL') ? 'https://' : 'http://';
  }.property('queryUseSSL'),

  queryBaseUrl: function(){
    return this.get('queryProtocol') + this.get('endpoint') + '/' + this.get('bucket')
  }.property('queryProtocol', 'endpoint', 'bucket'),

  objectProtocol: function() {
    return this.get('objectUseSSL') ? 'https://' : 'http://';
  }.property('objectUseSSL'),

  objectBaseUrl: function(){
    return this.get('objectProtocol') + this.get('bucket');
  }.property('objectProtocol', 'bucket'),

  queryParams: function(){
    return this.get('delimiterParameter')  + '&' +
      this.get('markerParameter')     + '&' +
      this.get('maxKeysParameter')    + '&' +
      this.get('prefixParameter');
  }.property('delimiterParameter','markerParameter','maxKeysParameter','prefixParameter'),

  queryUrl: function(){
    return this.get('queryBaseUrl') + '?' + this.get('queryParams');
  }.property('queryBaseUrl','queryParams'),

  filesPresent: function(){
    return this.get('files').length;
  }.property('files.@each'),

  filterFiles: function(filter){
    var files = this.get('files');

    return files.filter(function(e) {
      return e.get('name').indexOf(filter + '.') !== -1;
    });
  },

  load: function(){
    var self = this,
    baseUrl = this.get('objectBaseUrl');

    this.set('isLoading', true);
    Ember.$.get(this.get('queryUrl'), function(data){
      self.set('isLoading', false);
      self.set('response', data);

      var contents = data.getElementsByTagName('Contents'),
      length   = contents.length,
      files    = [];

      for(var i = 0; i < length; i++) {
        var size = contents[i].getElementsByTagName('Size')[0].firstChild.data,
        name = contents[i].getElementsByTagName('Key')[0].firstChild.data,
        lastModified = new Date(contents[i].getElementsByTagName('LastModified')[0].firstChild.data);

        files.push(
          App.S3File.create({
          name: name,
          size: size,
          lastModified: lastModified,
          relativePath: name,
          baseUrl: baseUrl
        })
        );
      }

      self.set('files', files.sort(function(a,b){
        return b.lastModified - a.lastModified;
      }));
    });
  }.observes('queryUrl').on('init')
});

App.S3File = Ember.Object.extend({
  scriptTag: function(){
    var escapedURL = Handlebars.Utils.escapeExpression(this.get('url'));

    return new Handlebars.SafeString('<script src="' + escapedURL + '"></script>').toString();
  }.property('url'),

  url: function(){
    return this.get('baseUrl') + '/' + this.get('relativePath');
  }.property('baseUrl', 'relativePath')
});

App.Project = Ember.Object.extend();

App.Project.reopenClass({
  FIXTURES:
    [ {
      projectName: 'Ember',
      projectFilter: 'ember',
      projectRepo: 'emberjs/ember.js',
      channel: "tagged"
    }, {
      projectName: 'Ember Data',
      projectFilter: 'ember-data',
      projectRepo: 'emberjs/data',
      channel: "tagged"
    }, {
      projectName: "Ember",
      projectFilter: "ember",
      projectRepo: 'emberjs/ember.js',
      initialVersion: "1.7.0",
      initialReleaseDate: "2014-08-19",
      lastRelease: "1.7.0",
      futureVersion: "1.7.1",
      channel: "release",
      date: "2014-8-19",
      changelogPath: "CHANGELOG.md"
    }, {
      projectName: "Ember",
      projectFilter: "ember",
      projectRepo: 'emberjs/ember.js',
      lastRelease: "1.8.0-beta.1",
      futureVersion: "1.8.0-beta.2",
      finalVersion: '1.8.0',
      channel: "beta",
      cycleEstimatedFinishDate: '2014-10-03',
      date: "2014-08-22",
      nextDate: "2014-08-29",
      changelogPath: "CHANGELOG.md"
    }, {
      projectName: "Ember Data",
      projectFilter: "ember-data",
      projectRepo: 'emberjs/data',
      lastRelease: "1.0.0-beta.9",
      futureVersion: "1.0.0-beta.10",
      channel: "beta",
      date: "2014-08-18",
      changelogPath: "CHANGELOG.md"
    }, {
      projectName: "Ember",
      projectFilter: "ember",
      projectRepo: 'emberjs/ember.js',
      channel: "canary",
    }, {
      projectName: "Ember Data",
      projectFilter: "ember-data",
      projectRepo: 'emberjs/data',
      channel: "canary",
    }],

  all: function(channel){
    var projects;

    if (channel)
      projects = this.FIXTURES.filterBy('channel', channel);
    else
      projects = this.FIXTURES;

    return projects.map(function(obj) {
      return App.Project.create(obj);
    });
  },

  find: function(channel, name) {
    var allProjects = this.all(channel);

    if (!name)
      return allProjects;
    else
      return allProjects.filterBy('projectName', name);
  }
});

App.BuildCategoryMixin = Ember.Mixin.create({
  renderTemplate: function() {
    this.render('build-list');
  }
});

App.ApplicationController = Ember.ObjectController.extend({
  isIndexActive: function(){
    return this.isActiveChannel('index');
  }.property('currentRouteName'),

  isTaggedActive: function(){
    return this.isActiveChannel('tagged');
  }.property('currentRouteName'),

  isChannelsActive: function(){
    var self = this;
    return !['index','tagged'].some(function(name){ return name === self.get('currentRouteName'); })
  }.property('currentRouteName'),

  isReleaseActive: function(){
    return this.isActiveChannel('release');
  }.property('currentRouteName'),

  isBetaActive: function(){
    return this.isActiveChannel('beta');
  }.property('currentRouteName'),

  isCanaryActive: function(){
    return this.isActiveChannel('canary');
  }.property('currentRouteName'),

  isActiveChannel: function(channel){
    return this.get('currentRouteName').indexOf(channel) !== -1;
  }
});

App.ProjectsMixin = Ember.Mixin.create({
  projects: function(){
    var projects = App.Project.find(this.get('channel')),
        bucket   = this.get('model'),
        self = this;

    projects.forEach(function(project){
      if (project.channel === 'beta'){
        project.isEmberBeta = project.projectName === 'Ember';

        [1,2,3,4,5].forEach(function(increment){
          var versionParts = project.lastRelease.split('.');
          var currentBetaNumber = parseInt(versionParts[versionParts.length - 1], 10);
          project['beta' + increment + 'Completed'] = increment <= currentBetaNumber;
          project['isBeta' + increment] = increment === currentBetaNumber;
        });

        var release = App.Project.find('release', project.projectName)[0];

        // no releases exist for ember-data (yet)
        if (release) {
          project.lastStableVersion = release.initialVersion;
          project.lastStableDate = release.initialReleaseDate;
        }
      }

      project.files = bucket.filterFiles(project.projectFilter);
      project.description = self.description(project);
      project.lastReleaseDebugUrl = self.lastReleaseUrl(project.projectFilter, project.channel, project.lastRelease, '.js');
      project.lastReleaseProdUrl  = self.lastReleaseUrl(project.projectFilter, project.channel, project.lastRelease, '.prod.js');
      project.lastReleaseMinUrl   = self.lastReleaseUrl(project.projectFilter, project.channel, project.lastRelease, '.min.js');

      if (project.channel === 'canary')
        project.lastRelease = 'latest';
      else if (project.changelog !== 'false')
        project.lastReleaseChangelogUrl   = 'https://github.com/' + project.projectRepo + '/blob/v' + project.lastRelease + '/' + project.changelogPath;
    });

    return projects;
  }.property('channel', 'model'),

  description: function(project){
    var lastRelease = project.lastRelease,
        futureVersion = project.futureVersion,
        value;

    if (this.get('channel') === 'tagged') {
      value = '';
    } else if (lastRelease) {
      value = 'The builds listed below are incremental improvements made since ' + lastRelease + ' and may become ' + futureVersion + '.'
    } else if (futureVersion) {
      value = 'The builds listed below are not based on a tagged release. Upon the next release cycle they will become ' + futureVersion + '.';
    } else {
      value = 'The builds listed below are based on the most recent development.';
    }

    return new Handlebars.SafeString(value);
  },

  lastReleaseUrl: function(project, channel, lastRelease, extension){
    if (channel === 'canary')
      return 'http://builds.emberjs.com/canary/' + project + extension;
    else
      return 'http://builds.emberjs.com/tags/v' + lastRelease + '/' + project + extension;
  }

});

App.CanaryRoute = Ember.Route.extend(App.BuildCategoryMixin, {
  model: function() {
    return App.S3Bucket.create({title: 'Canary Builds', prefix: 'canary/' });
  }
});

App.CanaryController = Ember.ObjectController.extend(App.ProjectsMixin, {
  templateName: 'buildList',
  channel: 'canary'
});

App.BetaRoute = Ember.Route.extend(App.BuildCategoryMixin, {
  model: function() {
    return App.S3Bucket.create({title: 'Beta Builds', prefix: 'beta/'});
  }
});

App.BetaController = Ember.ObjectController.extend(App.ProjectsMixin, {
  templateName: 'buildList',
  channel: 'beta'
});

App.ReleaseRoute = Ember.Route.extend(App.BuildCategoryMixin, {
  model: function() {
    return App.S3Bucket.create({title: 'Release Builds', prefix: 'release/'});
  }
});

App.ReleaseController = Ember.ObjectController.extend(App.ProjectsMixin, {
  templateName: 'buildList',
  channel: 'release'
});

App.TaggedRoute = Ember.Route.extend(App.BuildCategoryMixin, {
  model: function() {
    var bucket = App.S3Bucket.create({
      title: 'Tagged Release Builds',
      prefix: 'tags/',
      delimiter: '',
    });
    return bucket;
  }
});

App.TaggedController = Ember.ObjectController.extend(App.ProjectsMixin, {
  channel: 'tagged'
});
/*
 * Handlebars Helpers
 */
Ember.Handlebars.helper('format-bytes', function(bytes){
  return (bytes / 1024).toFixed(2) + ' KB';
});

Ember.Handlebars.helper('format-date-time', function(date, format, options) {
  if (!options) {
    options = format;
    format = null;
  }

  if (format){
    return moment(date).format(format);
  } else {
    return moment(date).fromNow();
  }
});

Ember.Handlebars.helper('isHiDPIScreen', function() {
  return window.getDevicePixelRatio() > 1;
});
<commit_msg>Update link to Ember Data beta.10 at /builds<commit_after>var App = Ember.Application.create({
  rootElement: '#builds-application'
});

App.Router.map(function() {
  this.route('release');
  this.route('beta');
  this.route('canary');
  this.route('tagged');
});

App.Router.reopen({
  notifyGoogleAnalytics: function() {
    var url = this.get('url');

    // Add a slash if neccesary
    if (!/^\//.test(url)){ url = '/' + url; }

    _gaq.push(['_trackPageview', '/builds' + url]);
  }.on('didTransition')
});

App.CopyClipboardComponent = Ember.Component.extend({
  tagName: 'span',
  hasFlash: ZeroClipboard.detectFlashSupport(),

  didInsertElement: function () {
    var clip = new ZeroClipboard(this.$('button'), {
      // This would normally be a relative path
      moviePath: "/images/ZeroClipboard.swf",

      trustedDomains: ["*"],
      allowScriptAccess: "always"
    });

    clip.on('mousedown', function(client, e) {
      Em.run.later(this, function() {
        $(this).removeClass('loading');
        $(this).removeAttr('disabled');
      }, 1000);
      Em.run.next(this, function() {
        $(this).addClass('loading');
        $(this).attr('disabled', 'disabled');
      });
    });

    this.$('input').on('click', function() {
      $(this).select();
    });
  }
});

App.S3Bucket = Ember.Object.extend({
  files: [],
  isLoading: false,

  // Setup these as default values.
  // They can be overridden on create.
  queryUseSSL: true,
  objectUseSSL: false,
  delimiter: '/',
  bucket: 'builds.emberjs.com',
  endpoint: 's3.amazonaws.com',

  delimiterParameter: function(){
    var delimiter = this.getWithDefault('delimiter','').toString();
    return (delimiter) ? 'delimiter=' + delimiter : '';
  }.property('delimiter'),

  markerParameter: function(){
    return 'marker=' + this.getWithDefault('marker','').toString();
  }.property('marker'),

  maxKeysParameter: function(){
    return 'max-keys=' + this.getWithDefault('maxKeys','').toString();
  }.property('maxKeys'),

  prefixParameter: function(){
    return 'prefix=' + this.getWithDefault('prefix','').toString();
  }.property('prefix'),

  queryProtocol: function() {
    return this.get('queryUseSSL') ? 'https://' : 'http://';
  }.property('queryUseSSL'),

  queryBaseUrl: function(){
    return this.get('queryProtocol') + this.get('endpoint') + '/' + this.get('bucket')
  }.property('queryProtocol', 'endpoint', 'bucket'),

  objectProtocol: function() {
    return this.get('objectUseSSL') ? 'https://' : 'http://';
  }.property('objectUseSSL'),

  objectBaseUrl: function(){
    return this.get('objectProtocol') + this.get('bucket');
  }.property('objectProtocol', 'bucket'),

  queryParams: function(){
    return this.get('delimiterParameter')  + '&' +
      this.get('markerParameter')     + '&' +
      this.get('maxKeysParameter')    + '&' +
      this.get('prefixParameter');
  }.property('delimiterParameter','markerParameter','maxKeysParameter','prefixParameter'),

  queryUrl: function(){
    return this.get('queryBaseUrl') + '?' + this.get('queryParams');
  }.property('queryBaseUrl','queryParams'),

  filesPresent: function(){
    return this.get('files').length;
  }.property('files.@each'),

  filterFiles: function(filter){
    var files = this.get('files');

    return files.filter(function(e) {
      return e.get('name').indexOf(filter + '.') !== -1;
    });
  },

  load: function(){
    var self = this,
    baseUrl = this.get('objectBaseUrl');

    this.set('isLoading', true);
    Ember.$.get(this.get('queryUrl'), function(data){
      self.set('isLoading', false);
      self.set('response', data);

      var contents = data.getElementsByTagName('Contents'),
      length   = contents.length,
      files    = [];

      for(var i = 0; i < length; i++) {
        var size = contents[i].getElementsByTagName('Size')[0].firstChild.data,
        name = contents[i].getElementsByTagName('Key')[0].firstChild.data,
        lastModified = new Date(contents[i].getElementsByTagName('LastModified')[0].firstChild.data);

        files.push(
          App.S3File.create({
          name: name,
          size: size,
          lastModified: lastModified,
          relativePath: name,
          baseUrl: baseUrl
        })
        );
      }

      self.set('files', files.sort(function(a,b){
        return b.lastModified - a.lastModified;
      }));
    });
  }.observes('queryUrl').on('init')
});

App.S3File = Ember.Object.extend({
  scriptTag: function(){
    var escapedURL = Handlebars.Utils.escapeExpression(this.get('url'));

    return new Handlebars.SafeString('<script src="' + escapedURL + '"></script>').toString();
  }.property('url'),

  url: function(){
    return this.get('baseUrl') + '/' + this.get('relativePath');
  }.property('baseUrl', 'relativePath')
});

App.Project = Ember.Object.extend();

App.Project.reopenClass({
  FIXTURES:
    [ {
      projectName: 'Ember',
      projectFilter: 'ember',
      projectRepo: 'emberjs/ember.js',
      channel: "tagged"
    }, {
      projectName: 'Ember Data',
      projectFilter: 'ember-data',
      projectRepo: 'emberjs/data',
      channel: "tagged"
    }, {
      projectName: "Ember",
      projectFilter: "ember",
      projectRepo: 'emberjs/ember.js',
      initialVersion: "1.7.0",
      initialReleaseDate: "2014-08-19",
      lastRelease: "1.7.0",
      futureVersion: "1.7.1",
      channel: "release",
      date: "2014-8-19",
      changelogPath: "CHANGELOG.md"
    }, {
      projectName: "Ember",
      projectFilter: "ember",
      projectRepo: 'emberjs/ember.js',
      lastRelease: "1.8.0-beta.1",
      futureVersion: "1.8.0-beta.2",
      finalVersion: '1.8.0',
      channel: "beta",
      cycleEstimatedFinishDate: '2014-10-03',
      date: "2014-08-22",
      nextDate: "2014-08-29",
      changelogPath: "CHANGELOG.md"
    }, {
      projectName: "Ember Data",
      projectFilter: "ember-data",
      projectRepo: 'emberjs/data',
      lastRelease: "1.0.0-beta.10",
      futureVersion: "1.0.0-beta.11",
      channel: "beta",
      date: "2014-09-09",
      changelogPath: "CHANGELOG.md"
    }, {
      projectName: "Ember",
      projectFilter: "ember",
      projectRepo: 'emberjs/ember.js',
      channel: "canary",
    }, {
      projectName: "Ember Data",
      projectFilter: "ember-data",
      projectRepo: 'emberjs/data',
      channel: "canary",
    }],

  all: function(channel){
    var projects;

    if (channel)
      projects = this.FIXTURES.filterBy('channel', channel);
    else
      projects = this.FIXTURES;

    return projects.map(function(obj) {
      return App.Project.create(obj);
    });
  },

  find: function(channel, name) {
    var allProjects = this.all(channel);

    if (!name)
      return allProjects;
    else
      return allProjects.filterBy('projectName', name);
  }
});

App.BuildCategoryMixin = Ember.Mixin.create({
  renderTemplate: function() {
    this.render('build-list');
  }
});

App.ApplicationController = Ember.ObjectController.extend({
  isIndexActive: function(){
    return this.isActiveChannel('index');
  }.property('currentRouteName'),

  isTaggedActive: function(){
    return this.isActiveChannel('tagged');
  }.property('currentRouteName'),

  isChannelsActive: function(){
    var self = this;
    return !['index','tagged'].some(function(name){ return name === self.get('currentRouteName'); })
  }.property('currentRouteName'),

  isReleaseActive: function(){
    return this.isActiveChannel('release');
  }.property('currentRouteName'),

  isBetaActive: function(){
    return this.isActiveChannel('beta');
  }.property('currentRouteName'),

  isCanaryActive: function(){
    return this.isActiveChannel('canary');
  }.property('currentRouteName'),

  isActiveChannel: function(channel){
    return this.get('currentRouteName').indexOf(channel) !== -1;
  }
});

App.ProjectsMixin = Ember.Mixin.create({
  projects: function(){
    var projects = App.Project.find(this.get('channel')),
        bucket   = this.get('model'),
        self = this;

    projects.forEach(function(project){
      if (project.channel === 'beta'){
        project.isEmberBeta = project.projectName === 'Ember';

        [1,2,3,4,5].forEach(function(increment){
          var versionParts = project.lastRelease.split('.');
          var currentBetaNumber = parseInt(versionParts[versionParts.length - 1], 10);
          project['beta' + increment + 'Completed'] = increment <= currentBetaNumber;
          project['isBeta' + increment] = increment === currentBetaNumber;
        });

        var release = App.Project.find('release', project.projectName)[0];

        // no releases exist for ember-data (yet)
        if (release) {
          project.lastStableVersion = release.initialVersion;
          project.lastStableDate = release.initialReleaseDate;
        }
      }

      project.files = bucket.filterFiles(project.projectFilter);
      project.description = self.description(project);
      project.lastReleaseDebugUrl = self.lastReleaseUrl(project.projectFilter, project.channel, project.lastRelease, '.js');
      project.lastReleaseProdUrl  = self.lastReleaseUrl(project.projectFilter, project.channel, project.lastRelease, '.prod.js');
      project.lastReleaseMinUrl   = self.lastReleaseUrl(project.projectFilter, project.channel, project.lastRelease, '.min.js');

      if (project.channel === 'canary')
        project.lastRelease = 'latest';
      else if (project.changelog !== 'false')
        project.lastReleaseChangelogUrl   = 'https://github.com/' + project.projectRepo + '/blob/v' + project.lastRelease + '/' + project.changelogPath;
    });

    return projects;
  }.property('channel', 'model'),

  description: function(project){
    var lastRelease = project.lastRelease,
        futureVersion = project.futureVersion,
        value;

    if (this.get('channel') === 'tagged') {
      value = '';
    } else if (lastRelease) {
      value = 'The builds listed below are incremental improvements made since ' + lastRelease + ' and may become ' + futureVersion + '.'
    } else if (futureVersion) {
      value = 'The builds listed below are not based on a tagged release. Upon the next release cycle they will become ' + futureVersion + '.';
    } else {
      value = 'The builds listed below are based on the most recent development.';
    }

    return new Handlebars.SafeString(value);
  },

  lastReleaseUrl: function(project, channel, lastRelease, extension){
    if (channel === 'canary')
      return 'http://builds.emberjs.com/canary/' + project + extension;
    else
      return 'http://builds.emberjs.com/tags/v' + lastRelease + '/' + project + extension;
  }

});

App.CanaryRoute = Ember.Route.extend(App.BuildCategoryMixin, {
  model: function() {
    return App.S3Bucket.create({title: 'Canary Builds', prefix: 'canary/' });
  }
});

App.CanaryController = Ember.ObjectController.extend(App.ProjectsMixin, {
  templateName: 'buildList',
  channel: 'canary'
});

App.BetaRoute = Ember.Route.extend(App.BuildCategoryMixin, {
  model: function() {
    return App.S3Bucket.create({title: 'Beta Builds', prefix: 'beta/'});
  }
});

App.BetaController = Ember.ObjectController.extend(App.ProjectsMixin, {
  templateName: 'buildList',
  channel: 'beta'
});

App.ReleaseRoute = Ember.Route.extend(App.BuildCategoryMixin, {
  model: function() {
    return App.S3Bucket.create({title: 'Release Builds', prefix: 'release/'});
  }
});

App.ReleaseController = Ember.ObjectController.extend(App.ProjectsMixin, {
  templateName: 'buildList',
  channel: 'release'
});

App.TaggedRoute = Ember.Route.extend(App.BuildCategoryMixin, {
  model: function() {
    var bucket = App.S3Bucket.create({
      title: 'Tagged Release Builds',
      prefix: 'tags/',
      delimiter: '',
    });
    return bucket;
  }
});

App.TaggedController = Ember.ObjectController.extend(App.ProjectsMixin, {
  channel: 'tagged'
});
/*
 * Handlebars Helpers
 */
Ember.Handlebars.helper('format-bytes', function(bytes){
  return (bytes / 1024).toFixed(2) + ' KB';
});

Ember.Handlebars.helper('format-date-time', function(date, format, options) {
  if (!options) {
    options = format;
    format = null;
  }

  if (format){
    return moment(date).format(format);
  } else {
    return moment(date).fromNow();
  }
});

Ember.Handlebars.helper('isHiDPIScreen', function() {
  return window.getDevicePixelRatio() > 1;
});
<|endoftext|>


<commit_before>var gulp = require('gulp');
var typescript = require('gulp-typescript');
var merge2 = require('merge2');
var concat = require('gulp-concat');
var runsequence = require('run-sequence');
var zip = require('gulp-zip');
var replace = require('gulp-replace');
var markdown = require('gulp-markdown');
var pug = require('gulp-pug');
var webserver = require('gulp-webserver');

//ライブラリのドキュメント作成
var typedocModule = require("typedoc");

typedocModule.converter.GitHubPlugin.prototype.onEndResolve = function (context) {
    var _this = this;
    var project = context.project;
    var destBaseUrl = null;
    project.files.forEach(function (sourceFile) {
        var repository = _this.getRepository(sourceFile.fullFileName);
        if (repository) {
            var srcUrl = repository.getGitHubURL(sourceFile.fullFileName);
            destBaseUrl = [
                'https://github.com',
                repository.gitHubUser,
                repository.gitHubProject,
                'blob',
                'master',
                'framework',
                ''
            ].join('/');
            sourceFile.url = destBaseUrl+sourceFile.fileName;
        }
    });
    for (var key in project.reflections) {
        var reflection = project.reflections[key];
        if (reflection.sources)
            reflection.sources.forEach(function (source) {
                if(destBaseUrl !== null){
                    source.file.url = destBaseUrl+source.file.fileName;
                }
                if (source.file && source.file.url) {
                    source.url = source.file.url + '#L' + source.line;
                }
            });
    }
};

var typedoc = require("gulp-typedoc");
gulp.task('createDoc',function(){
	return gulp
		.src(['./framework/**/**.ts'])
		.pipe(typedoc({
			// TypeScript options (see typescript docs)
			module: "commonjs",
			target: "es5",
			includeDeclarations: false,
			mode:"file",
			entryPoint :"Rf.ETS.FrameWork",
			// Output options (see typedoc docs)
			out: "./starter/doc",

			// TypeDoc options (see typedoc docs)
			name: "efs-framework",
			ignoreCompilerErrors: false,
			//version: false,
		}))
	;
});

//スーパークラスのビルド
var header = require('gulp-header');
var pkg = require('./package.json');
var banner = [
  "/* ",
  " * <%= pkg.name %> <%= pkg.version %>",
  " * <%= pkg.url %>",
  " * <%= pkg.license %>",
  " * ",
  " * Copyright (C) 2016 <%= pkg.author %>",
  " */",
  "",
].join('\n');

var buildBasesProject = typescript.createProject('./framework/tsconfig.json', { sortOutput: true });
gulp.task('_beforeBuildBases',function(){
	var result = gulp.src(["./framework/**/*.ts"])
      .pipe(typescript(buildBasesProject));

    return merge2[
    result.pipe(typescript.filter(
        buildBasesProject
        ,{referencedFrom: ['compileEntry.ts']}
    ))
    //result.js
    .pipe(concat('ets-framework.js'))
    .pipe(header(banner, {
      pkg: pkg,
    }))
    .pipe(gulp.dest('./build'))
    .pipe(gulp.dest('./assets/js'))
    ,
    //dts
    result.dts
    .pipe(concat('ets-framework.d.ts'))
    .pipe(gulp.dest('./temp'))
    ];
});

gulp.task('buildBases',['_beforeBuildBases'], function () {
    return gulp.src(['./framework/typings/*.d.ts','./temp/ets-framework.d.ts'])
            .pipe(concat('ets-framework.d.ts'))
            .pipe(gulp.dest('./typings'))
            .pipe(gulp.dest('./build'));
});

//実装例のビルド
gulp.task('buildExamples', function () {
    return merge2(
            [
                gulp.src(['./example/ImageSpriteSample/*.ts','./typings/ets-framework.d.ts'])
                    .pipe(typescript('./example/ImageSpriteSample/tsconfig.json')).js
                    .pipe(gulp.dest('./build/ImageSpriteSample')),

                gulp.src(['./example/LoginSample/*.ts','./typings/ets-framework.d.ts'])
                    .pipe(typescript('./example/LoginSample/tsconfig.json')).js
                    .pipe(gulp.dest('./build/LoginSample')),

                gulp.src(['./example/2DRPGMapSample/*.ts','./typings/ets-framework.d.ts'])
                    .pipe(typescript('./example/2DRPGMapSample/tsconfig.json')).js
                    .pipe(gulp.dest('./build/2DRPGMapSample')),

                gulp.src(['./example/template/*.ts','./typings/ets-framework.d.ts'])
                    .pipe(typescript('./example/template/tsconfig.json')).js
                    .pipe(gulp.dest('./build/template')),

                gulp.src(['./example/UseEnchantDtsOnly/*.ts','./framework/typings/enchant.d.ts'])
                    .pipe(typescript('./example/UseEnchantDtsOnly/tsconfig.json')).js
                    .pipe(gulp.dest('./build/UseEnchantDtsOnly'))
            ]
    );
});

//スターターの作成
gulp.task('CreateStarter',['_CreateStarterZip'],function () {
});

//0.node_modulesフォルダの削除
var del = require('del');
gulp.task('_CreateStarterRemoveFiles', function () {
return del([
    './starter/node_modules'
    ,'./starter/**/node_modules'
  ]);
});

//1.スターターの作成準備(ファイルコピー)
gulp.task('_CreateStarterCopyFiles',['_CreateStarterRemoveFiles'], function () {
    return merge2(
            [
                //starter/simpleへコピー
                gulp.src([
                    './framework/typings/enchant.d.ts'
                ])
                .pipe(gulp.dest('./starter/simple/typings')),

                gulp.src([
                    './assets/resources/*.*'
                ])
                .pipe(gulp.dest('./starter/simple/assets/resources')),

                gulp.src([
                    './assets/js/enchant.js' ,
                    './assets/js/plugins/extendMap.enchant.js'
                ])
                .pipe(gulp.dest('./starter/simple/assets/js')),

                gulp.src([
                    './example/UseEnchantDtsOnly/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/simple')),

                //starter/use-framework/ImageSpriteSampleへコピー
                gulp.src([
                    './typings/ets-framework.d.ts',
                    './assets/**/*.*'
                ],{base:'./'})
                .pipe(gulp.dest('./starter/use-framework/ImageSpriteSample')),

                gulp.src([
                    './example/ImageSpriteSample/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/use-framework/ImageSpriteSample')),

                //starter/use-framework/LoginSampleへコピー
                gulp.src([
                    './typings/ets-framework.d.ts',
                    './assets/js/**/*.*'
                ],{base:'./'})
                .pipe(gulp.dest('./starter/use-framework/LoginSample')),
                gulp.src([
                    './example/LoginSample/assets/**/*.*'
                ],{base:'./example/LoginSample/'})
                .pipe(gulp.dest('./starter/use-framework/LoginSample')),

                gulp.src([
                    './example/LoginSample/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/use-framework/LoginSample')),

                //starter/use-framework/2DRPGMapSampleへコピー
                gulp.src([
                    './typings/ets-framework.d.ts',
                    './assets/js/**/*.*'
                ],{base:'./'})
                .pipe(gulp.dest('./starter/use-framework/2DRPGMapSample')),
                gulp.src([
                    './example/2DRPGMapSample/assets/**/*.*'
                ],{base:'./example/2DRPGMapSample'})
                .pipe(gulp.dest('./starter/use-framework/2DRPGMapSample')),

                gulp.src([
                    './example/2DRPGMapSample/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/use-framework/2DRPGMapSample')),

                //starter/use-framework/templateへコピー
                gulp.src([
                    './typings/ets-framework.d.ts',
                    './assets/js/**/*.*'
                ],{base:'./'})
                .pipe(gulp.dest('./starter/use-framework/template')),

                gulp.src([
                    './example/template/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/use-framework/template'))
            ]
    );
});

//2.スターターの作成準備(リソースパスの修正)
gulp.task('_CreateStarterReplacePath',['_CreateStarterCopyFiles'], function () {
    return gulp.src(['./starter/**/*.ts','!./starter/**/*.d.ts'],{base:'./starter'})
        .pipe(replace('../../assets/resources/','./assets/resources/'))
        .pipe(gulp.dest('./starter'));
});

//3.スターターの作成準備(ビルド)
gulp.task('_CreateStarterBuild',['_CreateStarterReplacePath'], function () {
    return merge2(
        [
            //TypeScriptのビルド
            gulp.src(['./starter/simple/**/*.ts'])
            .pipe(typescript('./starter/simple/tsconfig.json')).js
            .pipe(gulp.dest('./starter/simple')),

            gulp.src(['./starter/use-framework/ImageSpriteSample/**/*.ts'])
            .pipe(typescript('./starter/use-framework/ImageSpriteSample/tsconfig.json')).js
            .pipe(gulp.dest('./starter/use-framework/ImageSpriteSample')),

            gulp.src(['./starter/use-framework/LoginSample/**/*.ts'])
            .pipe(typescript('./starter/use-framework/LoginSample/tsconfig.json')).js
            .pipe(gulp.dest('./starter/use-framework/LoginSample')),

            gulp.src(['./starter/use-framework/2DRPGMapSample/**/*.ts'])
            .pipe(typescript('./starter/use-framework/2DRPGMapSample/tsconfig.json')).js
            .pipe(gulp.dest('./starter/use-framework/2DRPGMapSample')),

            gulp.src(['./starter/use-framework/template/**/*.ts'])
            .pipe(typescript('./starter/use-framework/template/tsconfig.json')).js
            .pipe(gulp.dest('./starter/use-framework/template'))
        ]
    );
});

//4.readme.mdをhtmlタグに変換
gulp.task('_CreateStarterConvertMD',['_CreateStarterBuild'], function () {
    return gulp.src('./starter/README.md')
        .pipe(markdown())
        .pipe(gulp.dest('./temp'));
});

//5.変換したhtmlタグをベースにHTMLを作成
gulp.task('_CreateStarterCreateHTML',['_CreateStarterConvertMD'], function () {
  return gulp.src('./pug-files/*.pug')
    .pipe(pug({
      pretty: true
    }))
    .pipe(gulp.dest('./starter'));
});

//6.スターターの作成準備(zip圧縮)
gulp.task('_CreateStarterZip',['_CreateStarterCreateHTML'], function () {
    return  gulp.src(['./starter/**/*'],{base:'./starter'})
            .pipe(zip('starter.zip'))
            .pipe(gulp.dest('./'))
});

//デフォルト
gulp.task('default',['buildBases'], function () {
    runsequence('buildExamples');
});

gulp.task('startServer', function() {
  webStream = gulp.src('./').pipe(webserver());
});
<commit_msg>スターターキットのサンプル「simple」のextendMap.enchant.jsの設置場所を変更<commit_after>var gulp = require('gulp');
var typescript = require('gulp-typescript');
var merge2 = require('merge2');
var concat = require('gulp-concat');
var runsequence = require('run-sequence');
var zip = require('gulp-zip');
var replace = require('gulp-replace');
var markdown = require('gulp-markdown');
var pug = require('gulp-pug');
var webserver = require('gulp-webserver');

//ライブラリのドキュメント作成
var typedocModule = require("typedoc");

typedocModule.converter.GitHubPlugin.prototype.onEndResolve = function (context) {
    var _this = this;
    var project = context.project;
    var destBaseUrl = null;
    project.files.forEach(function (sourceFile) {
        var repository = _this.getRepository(sourceFile.fullFileName);
        if (repository) {
            var srcUrl = repository.getGitHubURL(sourceFile.fullFileName);
            destBaseUrl = [
                'https://github.com',
                repository.gitHubUser,
                repository.gitHubProject,
                'blob',
                'master',
                'framework',
                ''
            ].join('/');
            sourceFile.url = destBaseUrl+sourceFile.fileName;
        }
    });
    for (var key in project.reflections) {
        var reflection = project.reflections[key];
        if (reflection.sources)
            reflection.sources.forEach(function (source) {
                if(destBaseUrl !== null){
                    source.file.url = destBaseUrl+source.file.fileName;
                }
                if (source.file && source.file.url) {
                    source.url = source.file.url + '#L' + source.line;
                }
            });
    }
};

var typedoc = require("gulp-typedoc");
gulp.task('createDoc',function(){
	return gulp
		.src(['./framework/**/**.ts'])
		.pipe(typedoc({
			// TypeScript options (see typescript docs)
			module: "commonjs",
			target: "es5",
			includeDeclarations: false,
			mode:"file",
			entryPoint :"Rf.ETS.FrameWork",
			// Output options (see typedoc docs)
			out: "./starter/doc",

			// TypeDoc options (see typedoc docs)
			name: "efs-framework",
			ignoreCompilerErrors: false,
			//version: false,
		}))
	;
});

//スーパークラスのビルド
var header = require('gulp-header');
var pkg = require('./package.json');
var banner = [
  "/* ",
  " * <%= pkg.name %> <%= pkg.version %>",
  " * <%= pkg.url %>",
  " * <%= pkg.license %>",
  " * ",
  " * Copyright (C) 2016 <%= pkg.author %>",
  " */",
  "",
].join('\n');

var buildBasesProject = typescript.createProject('./framework/tsconfig.json', { sortOutput: true });
gulp.task('_beforeBuildBases',function(){
	var result = gulp.src(["./framework/**/*.ts"])
      .pipe(typescript(buildBasesProject));

    return merge2[
    result.pipe(typescript.filter(
        buildBasesProject
        ,{referencedFrom: ['compileEntry.ts']}
    ))
    //result.js
    .pipe(concat('ets-framework.js'))
    .pipe(header(banner, {
      pkg: pkg,
    }))
    .pipe(gulp.dest('./build'))
    .pipe(gulp.dest('./assets/js'))
    ,
    //dts
    result.dts
    .pipe(concat('ets-framework.d.ts'))
    .pipe(gulp.dest('./temp'))
    ];
});

gulp.task('buildBases',['_beforeBuildBases'], function () {
    return gulp.src(['./framework/typings/*.d.ts','./temp/ets-framework.d.ts'])
            .pipe(concat('ets-framework.d.ts'))
            .pipe(gulp.dest('./typings'))
            .pipe(gulp.dest('./build'));
});

//実装例のビルド
gulp.task('buildExamples', function () {
    return merge2(
            [
                gulp.src(['./example/ImageSpriteSample/*.ts','./typings/ets-framework.d.ts'])
                    .pipe(typescript('./example/ImageSpriteSample/tsconfig.json')).js
                    .pipe(gulp.dest('./build/ImageSpriteSample')),

                gulp.src(['./example/LoginSample/*.ts','./typings/ets-framework.d.ts'])
                    .pipe(typescript('./example/LoginSample/tsconfig.json')).js
                    .pipe(gulp.dest('./build/LoginSample')),

                gulp.src(['./example/2DRPGMapSample/*.ts','./typings/ets-framework.d.ts'])
                    .pipe(typescript('./example/2DRPGMapSample/tsconfig.json')).js
                    .pipe(gulp.dest('./build/2DRPGMapSample')),

                gulp.src(['./example/template/*.ts','./typings/ets-framework.d.ts'])
                    .pipe(typescript('./example/template/tsconfig.json')).js
                    .pipe(gulp.dest('./build/template')),

                gulp.src(['./example/UseEnchantDtsOnly/*.ts','./framework/typings/enchant.d.ts'])
                    .pipe(typescript('./example/UseEnchantDtsOnly/tsconfig.json')).js
                    .pipe(gulp.dest('./build/UseEnchantDtsOnly'))
            ]
    );
});

//スターターの作成
gulp.task('CreateStarter',['_CreateStarterZip'],function () {
});

//0.node_modulesフォルダの削除
var del = require('del');
gulp.task('_CreateStarterRemoveFiles', function () {
return del([
    './starter/node_modules'
    ,'./starter/**/node_modules'
  ]);
});

//1.スターターの作成準備(ファイルコピー)
gulp.task('_CreateStarterCopyFiles',['_CreateStarterRemoveFiles'], function () {
    return merge2(
            [
                //starter/simpleへコピー
                gulp.src([
                    './framework/typings/enchant.d.ts'
                ])
                .pipe(gulp.dest('./starter/simple/typings')),

                gulp.src([
                    './assets/resources/*.*'
                ])
                .pipe(gulp.dest('./starter/simple/assets/resources')),

                gulp.src([
                    './assets/js/enchant.js' ,
                    './assets/js/plugins/extendMap.enchant.js'
                ],{base:'./assets/js'})
                .pipe(gulp.dest('./starter/simple/assets/js')),

                gulp.src([
                    './example/UseEnchantDtsOnly/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/simple')),

                //starter/use-framework/ImageSpriteSampleへコピー
                gulp.src([
                    './typings/ets-framework.d.ts',
                    './assets/**/*.*'
                ],{base:'./'})
                .pipe(gulp.dest('./starter/use-framework/ImageSpriteSample')),

                gulp.src([
                    './example/ImageSpriteSample/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/use-framework/ImageSpriteSample')),

                //starter/use-framework/LoginSampleへコピー
                gulp.src([
                    './typings/ets-framework.d.ts',
                    './assets/js/**/*.*'
                ],{base:'./'})
                .pipe(gulp.dest('./starter/use-framework/LoginSample')),
                gulp.src([
                    './example/LoginSample/assets/**/*.*'
                ],{base:'./example/LoginSample/'})
                .pipe(gulp.dest('./starter/use-framework/LoginSample')),

                gulp.src([
                    './example/LoginSample/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/use-framework/LoginSample')),

                //starter/use-framework/2DRPGMapSampleへコピー
                gulp.src([
                    './typings/ets-framework.d.ts',
                    './assets/js/**/*.*'
                ],{base:'./'})
                .pipe(gulp.dest('./starter/use-framework/2DRPGMapSample')),
                gulp.src([
                    './example/2DRPGMapSample/assets/**/*.*'
                ],{base:'./example/2DRPGMapSample'})
                .pipe(gulp.dest('./starter/use-framework/2DRPGMapSample')),

                gulp.src([
                    './example/2DRPGMapSample/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/use-framework/2DRPGMapSample')),

                //starter/use-framework/templateへコピー
                gulp.src([
                    './typings/ets-framework.d.ts',
                    './assets/js/**/*.*'
                ],{base:'./'})
                .pipe(gulp.dest('./starter/use-framework/template')),

                gulp.src([
                    './example/template/**/*.ts'
                ])
                .pipe(gulp.dest('./starter/use-framework/template'))
            ]
    );
});

//2.スターターの作成準備(リソースパスの修正)
gulp.task('_CreateStarterReplacePath',['_CreateStarterCopyFiles'], function () {
    return gulp.src(['./starter/**/*.ts','!./starter/**/*.d.ts'],{base:'./starter'})
        .pipe(replace('../../assets/resources/','./assets/resources/'))
        .pipe(gulp.dest('./starter'));
});

//3.スターターの作成準備(ビルド)
gulp.task('_CreateStarterBuild',['_CreateStarterReplacePath'], function () {
    return merge2(
        [
            //TypeScriptのビルド
            gulp.src(['./starter/simple/**/*.ts'])
            .pipe(typescript('./starter/simple/tsconfig.json')).js
            .pipe(gulp.dest('./starter/simple')),

            gulp.src(['./starter/use-framework/ImageSpriteSample/**/*.ts'])
            .pipe(typescript('./starter/use-framework/ImageSpriteSample/tsconfig.json')).js
            .pipe(gulp.dest('./starter/use-framework/ImageSpriteSample')),

            gulp.src(['./starter/use-framework/LoginSample/**/*.ts'])
            .pipe(typescript('./starter/use-framework/LoginSample/tsconfig.json')).js
            .pipe(gulp.dest('./starter/use-framework/LoginSample')),

            gulp.src(['./starter/use-framework/2DRPGMapSample/**/*.ts'])
            .pipe(typescript('./starter/use-framework/2DRPGMapSample/tsconfig.json')).js
            .pipe(gulp.dest('./starter/use-framework/2DRPGMapSample')),

            gulp.src(['./starter/use-framework/template/**/*.ts'])
            .pipe(typescript('./starter/use-framework/template/tsconfig.json')).js
            .pipe(gulp.dest('./starter/use-framework/template'))
        ]
    );
});

//4.readme.mdをhtmlタグに変換
gulp.task('_CreateStarterConvertMD',['_CreateStarterBuild'], function () {
    return gulp.src('./starter/README.md')
        .pipe(markdown())
        .pipe(gulp.dest('./temp'));
});

//5.変換したhtmlタグをベースにHTMLを作成
gulp.task('_CreateStarterCreateHTML',['_CreateStarterConvertMD'], function () {
  return gulp.src('./pug-files/*.pug')
    .pipe(pug({
      pretty: true
    }))
    .pipe(gulp.dest('./starter'));
});

//6.スターターの作成準備(zip圧縮)
gulp.task('_CreateStarterZip',['_CreateStarterCreateHTML'], function () {
    return  gulp.src(['./starter/**/*'],{base:'./starter'})
            .pipe(zip('starter.zip'))
            .pipe(gulp.dest('./'))
});

//デフォルト
gulp.task('default',['buildBases'], function () {
    runsequence('buildExamples');
});

gulp.task('startServer', function() {
  webStream = gulp.src('./').pipe(webserver());
});
<|endoftext|>


<commit_before>var branches = new Vue({
  el: '#branches',
  data: {
    payload: [],
    count: 0
  },
  methods: {
    load_branches: function(){
      this.make_gh_call();
    },
    make_gh_call: function() {
      vt = this;
      auth_data = this.creds().username + ":" + this.creds().token;
      jQuery.ajax
      ({
        type: "GET",
        url: "https://api.github.com/repos/" + this.creds().org + "/"+ this.creds().repo +"/branches",
        dataType: 'json',
        headers: {"Authorization": "Basic " + btoa(auth_data)},
        success: function (data){
          vt.payload = vt.buildBranches(data, vt.payload);
        },
        error: function() {
          alert('error');
        }
       });
    },

    creds: function() {
      return github_details();
    },

    buildBranches: function (data, payload) {
      payload = [];
      $.each(data, function (_, v) {
        name = v.name;
        isStale = '',
        status = ''
        payload.push({
          name: name,
          isStale: isStale,
          status: status
        });
      });
      return payload;
    }
  },
  watch: {
    payload: function() {
      this.count = this.payload.length;
    }
  }
});

$(document).ready(function () {
  setTimeout(function(){
    branches.load_branches();
  },2000);
});
<commit_msg>add the followup calls<commit_after>var branches = new Vue({
  el: '#branches',
  data: {
    payload: [],
    count: 0
  },
  methods: {
    load_branches: function(){
      this.make_gh_call();
    },
    make_gh_call: function() {
      vt = this;
      auth_data = this.creds().username + ":" + this.creds().token;
      jQuery.ajax
      ({
        type: "GET",
        url: "https://api.github.com/repos/" + this.creds().org + "/"+ this.creds().repo +"/branches",
        dataType: 'json',
        headers: {"Authorization": "Basic " + btoa(auth_data)},
        success: function (data){
          vt.payload = vt.buildBranches(data, vt.payload);
        },
        error: function() {
          alert('error');
        }
       });
    },

    buildBranches: function (data, payload) {
      vt = this;
      payload = [];
      $.each(data, function (_, v) {
        name = v.name;
        isStale = '';
        status = 'fetching';
        branch = { name: name,
                   isStale: isStale,
                   status: status
                 };
        payload.push(branch);
        vt.fetch_gh_age(branch);
      });
      return payload;
    },

    fetch_gh_age: function(branch) {
      vt = this;
      auth_data = this.creds().username + ":" + this.creds().token;
      jQuery.ajax
      ({
        type: "GET",
        url: "https://api.github.com/repos/" + this.creds().org + "/"+ this.creds().repo +"/branches/" + branch.name,
        dataType: 'json',
        headers: {"Authorization": "Basic " + btoa(auth_data)},
        success: function (data){
          vt.updateStale(data, branch);
          vt.fetch_gh_status(data, branch);
        },
        error: function() {
          alert('error');
        }
       });
    },

    updateStale: function(data, branch) {
      lastCommit = data.commit.commit.committer.date;
      lastCommitDate = new Date(lastCommit);
      today = new Date();
      daysOld = (today - lastCommitDate) / 1000 / 60 / 60 / 24;
      branch.isStale = daysOld > 14;
    },

    fetch_gh_status: function(data, branch) {
      vt = this;
      url = data.commit.url;
      auth_data = this.creds().username + ":" + this.creds().token;
      jQuery.ajax
      ({
        type: "GET",
        url: url + "/statuses",
        dataType: 'json',
        headers: {"Authorization": "Basic " + btoa(auth_data)},
        success: function (data){
          vt.updateStatus(data, branch);
        },
        error: function() {
          alert('error');
        }
       });
    },

    updateStatus: function(data, branch) {
      if(data.length > 0) {
        branch.status = data[0].state;
      }
    },

    creds: function() {
      return github_details();
    },

  },
  watch: {
    payload: function() {
      this.count = this.payload.length;
    }
  }
});

$(document).ready(function () {
  setTimeout(function(){
    branches.load_branches();
  },2000);
});
<|endoftext|>


<commit_before>// (function () {
  // return

//= require "../vendor/jshint/jshint"
var jshint = function () {
  var source = editors.javascript.editor.getCode();
  var ok = JSHINT(source);

  return ok ? true : JSHINT.data();
};

var detailsSupport = 'open' in document.createElement('details');

// yeah, this is happening. Fucking IE...sheesh.
var html = $.browser.msie && $.browser.version < 9 ? '

warnings
' : 'warnings';

var $error = $(html).appendTo('#source .javascript').hide();

$error.find('.summary').click(function () {
  if (!detailsSupport) {
    $(this).nextAll().toggle();
    $error[0].open = !$error[0].open;
  }
  // trigger a resize after the click has completed and the details is close
  setTimeout(function () {
    $document.trigger('sizeeditors');
  }, 10);
});

if (!detailsSupport) {
  $error[0].open = false;
}

// modify JSHINT to only return errors that are of value (to me, for displaying)
JSHINT._data = JSHINT.data;
JSHINT.data = function (onlyErrors) {
  var data = JSHINT._data(),
      errors = [];

  if (onlyErrors && data.errors) {
    for (var i = 0; i < data.errors.length; i++) {
      if (data.errors[i] !== null && data.errors[i].evidence) { // ignore JSHINT just quitting
        errors.push(data.errors[i]);
      } else if (data.errors[i] !== null && data.errors[i].reason.indexOf('Stopping') === 0) {
        errors.push('Fatal errors, unable to continue');
      }
    }
    return {
      errors: errors
    };
  } else {
    data.errors = [];
    return data;
  }
};

$error.delegate('li', 'click', function () {
  var errors = JSHINT.data(true).errors;
  if (errors.length) {
    var i = $error.find('li').index(this);
    if (errors[i].reason) {
      editors.javascript.editor.setSelection({ line: errors[i].line - 1, ch: 0 }, { line: errors[i].line - 1 });
      editors.javascript.editor.focus();
    }
    // var line = editors.javascript.nthLine(errors[0].line);
    // editors.javascript.jumpToLine(line);
    // editors.javascript.selectLines(line, 0, editors.javascript.nthLine(errors[0].line + 1), 0);
    return false;
  }
});

var checkForErrors = function () {
  // exit if the javascript panel isn't visible
  if (!editors.javascript.visible) return;

  var hint = jshint(),
      jshintErrors = JSHINT.data(true),
      errors = '',
      visible = $error.is(':visible');

  if (hint === true && visible) {
    $error.hide();
    $document.trigger('sizeeditors');
  } else if (jshintErrors.errors.length) {
    var html = ['
'],
        errors = jshintErrors.errors;
    for (var i = 0; i < errors.length; i++) {
      if (typeof errors[i] == 'string') {
        html.push(errors[i]);
      } else {
        html.push('Line ' + errors[i].line + ': ' + errors[i].evidence + ' --- ' + errors[i].reason);
      }
    }

    html = html.join('
') + '
';

    $error.find('.summary').text(jshintErrors.errors.length == 1 ? '1 warning' : jshintErrors.errors.length + ' warnings');
    $error.find('ol').remove();

    if (!detailsSupport && $error[0].open == false) html = $(html).hide();

    $error.append(html).show();
    $document.trigger('sizeeditors');
  }
};

$(document).bind('codeChange', throttle(checkForErrors, 1000));
$(document).bind('jsbinReady', checkForErrors);

// })();
<commit_msg>Allow settings to disable jshint<commit_after>// (function () {
  // return

//= require "../vendor/jshint/jshint"
var jshint = function () {
  var source = editors.javascript.editor.getCode();
  var ok = JSHINT(source);

  return ok ? true : JSHINT.data();
};

var detailsSupport = 'open' in document.createElement('details');

// yeah, this is happening. Fucking IE...sheesh.
var html = $.browser.msie && $.browser.version < 9 ? '

warnings
' : 'warnings';

var $error = $(html).appendTo('#source .javascript').hide();

$error.find('.summary').click(function () {
  if (!detailsSupport) {
    $(this).nextAll().toggle();
    $error[0].open = !$error[0].open;
  }
  // trigger a resize after the click has completed and the details is close
  setTimeout(function () {
    $document.trigger('sizeeditors');
  }, 10);
});

if (!detailsSupport) {
  $error[0].open = false;
}

// modify JSHINT to only return errors that are of value (to me, for displaying)
JSHINT._data = JSHINT.data;
JSHINT.data = function (onlyErrors) {
  var data = JSHINT._data(),
      errors = [];

  if (onlyErrors && data.errors) {
    for (var i = 0; i < data.errors.length; i++) {
      if (data.errors[i] !== null && data.errors[i].evidence) { // ignore JSHINT just quitting
        errors.push(data.errors[i]);
      } else if (data.errors[i] !== null && data.errors[i].reason.indexOf('Stopping') === 0) {
        errors.push('Fatal errors, unable to continue');
      }
    }
    return {
      errors: errors
    };
  } else {
    data.errors = [];
    return data;
  }
};

$error.delegate('li', 'click', function () {
  var errors = JSHINT.data(true).errors;
  if (errors.length) {
    var i = $error.find('li').index(this);
    if (errors[i].reason) {
      editors.javascript.editor.setSelection({ line: errors[i].line - 1, ch: 0 }, { line: errors[i].line - 1 });
      editors.javascript.editor.focus();
    }
    // var line = editors.javascript.nthLine(errors[0].line);
    // editors.javascript.jumpToLine(line);
    // editors.javascript.selectLines(line, 0, editors.javascript.nthLine(errors[0].line + 1), 0);
    return false;
  }
});

var checkForErrors = function () {
  // exit if the javascript panel isn't visible
  if (!editors.javascript.visible) return;

  var hint = jshint(),
      jshintErrors = JSHINT.data(true),
      errors = '',
      visible = $error.is(':visible');

  if (hint === true && visible) {
    $error.hide();
    $document.trigger('sizeeditors');
  } else if (jshintErrors.errors.length) {
    var html = ['
'],
        errors = jshintErrors.errors;
    for (var i = 0; i < errors.length; i++) {
      if (typeof errors[i] == 'string') {
        html.push(errors[i]);
      } else {
        html.push('Line ' + errors[i].line + ': ' + errors[i].evidence + ' --- ' + errors[i].reason);
      }
    }

    html = html.join('
') + '
';

    $error.find('.summary').text(jshintErrors.errors.length == 1 ? '1 warning' : jshintErrors.errors.length + ' warnings');
    $error.find('ol').remove();

    if (!detailsSupport && $error[0].open == false) html = $(html).hide();

    $error.append(html).show();
    $document.trigger('sizeeditors');
  }
};

if (jsbin.settings.jshint === true || jsbin.settings.jshint === undefined) {
  $(document).bind('codeChange', throttle(checkForErrors, 1000));
  $(document).bind('jsbinReady', checkForErrors);
}

// })();
<|endoftext|>


<commit_before>Vue.use(VueMaterial);
const app = new Vue({
    el: "#app",
    data: {
        loglevel: "INFO",
        title: "Liquid Radio",
        notSupportedMessage: "Your browser does not support audio streams, please update.",
        repoLink: "https://github.com/Trikolon/cfp-radio",
        version: "0.1",
        stream: {
            play: false,
            type: "audio/mpeg",
            src: "http://s45.myradiostream.com:12036/listen.mp3",
            title: "Liquid Radio",
            offline: false,
            el: "streamEl"
        },
        twitterFeed: {
            profile: "https://twitter.com/thecoffeepanda",
            theme: "dark"
        },
        notification: {
            message: "",
            duration: 4000,
            position: "top center",
            el: "notification-bar"
        }
    },
    watch: {
        "stream.play": function (state) {
            this.updatePlayState(state);
        },
        "stream.offline": function (state) {
            if (state) {
                this.stream.play = false;
            }
        }
    },
    mounted: function () {
        let audioEl = this.$refs[this.stream.el];

        audioEl.addEventListener("play", () => {
           this.stream.play = true;
        });
        audioEl.addEventListener("pause", () => {
            this.stream.play = false;
        });
        audioEl.addEventListener("stalled", () => {
            this.notify("Stream stalled, check your connection.");
        });
        //Attach error handler to audio stream element
        audioEl.addEventListener("error", this.streamError);
    },
    methods: {
        /**
         * Toggles visibility of left side navigation
         */
        toggleNav: function() {
            this.$refs.nav.toggle();
        },
        /**
         * Trigger play or pause for audio el depending on state.
         * @param state - true if play, false if pause.
         */
        updatePlayState: function (state) {
            const el = this.$refs[this.stream.el];
            log.debug("play state changed to", state);
            if (state) {
                el.play();
                log.debug("started stream");
                this.notify("Now playing " + this.stream.title, 2000);
            }
            else {
                el.pause();
                log.debug("stopped stream");
            }
        },
        /**
         * Reloads audio element to catch up in stream.
         */
        catchUp: function () {
            const el = this.$refs[this.stream.el];
            el.load();
            if (this.stream.play) {
                this.updatePlayState(true);
            }
            else {
                this.stream.play = true;
            }
            this.stream.offline = false;
        },
        streamError: function (e) {
            log.error("Error in stream", e);
            let msg = "Error: ";
            switch (e.target.error.code) {
                case e.target.error.MEDIA_ERR_ABORTED:
                    msg += "Playback aborted by user.";
                    break;
                case e.target.error.MEDIA_ERR_NETWORK:
                    msg += "Network error. Check your connection.";
                    break;
                case e.target.error.MEDIA_ERR_DECODE:
                    msg += "Decoding error.";
                    break;
                case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
                    msg += "Stream offline.";
                    break;
                default:
                    msg += "Unknown error";
                    break;
            }
            this.stream.offline = true;
            this.notify(msg);
        },
        /**
         * Shows notification
         * @param message - Text for notification.
         * @param duration - Duration of visibility.
         */
        notify: function (message, duration) {
            const el = this.$refs[this.notification.el];
            if (duration) {
                this.notification.duration = duration;
            }
            this.notification.message = message;
            el.open();
        }
    }
});
log.setDefaultLevel(app.loglevel);<commit_msg>moved notification bar to bottom<commit_after>Vue.use(VueMaterial);
const app = new Vue({
    el: "#app",
    data: {
        loglevel: "INFO",
        title: "Liquid Radio",
        notSupportedMessage: "Your browser does not support audio streams, please update.",
        repoLink: "https://github.com/Trikolon/cfp-radio",
        version: "0.1",
        stream: {
            play: false,
            type: "audio/mpeg",
            src: "http://s45.myradiostream.com:12036/listen.mp3",
            title: "Liquid Radio",
            offline: false,
            el: "streamEl"
        },
        twitterFeed: {
            profile: "https://twitter.com/thecoffeepanda",
            theme: "dark"
        },
        notification: {
            message: "",
            duration: 4000,
            position: "bottom center",
            el: "notification-bar"
        }
    },
    watch: {
        "stream.play": function (state) {
            this.updatePlayState(state);
        },
        "stream.offline": function (state) {
            if (state) {
                this.stream.play = false;
            }
        }
    },
    mounted: function () {
        let audioEl = this.$refs[this.stream.el];

        audioEl.addEventListener("play", () => {
           this.stream.play = true;
        });
        audioEl.addEventListener("pause", () => {
            this.stream.play = false;
        });
        audioEl.addEventListener("stalled", () => {
            this.notify("Stream stalled, check your connection.");
        });
        //Attach error handler to audio stream element
        audioEl.addEventListener("error", this.streamError);
    },
    methods: {
        /**
         * Toggles visibility of left side navigation
         */
        toggleNav: function() {
            this.$refs.nav.toggle();
        },
        /**
         * Trigger play or pause for audio el depending on state.
         * @param state - true if play, false if pause.
         */
        updatePlayState: function (state) {
            const el = this.$refs[this.stream.el];
            log.debug("play state changed to", state);
            if (state) {
                el.play();
                log.debug("started stream");
                this.notify("Now playing " + this.stream.title, 2000);
            }
            else {
                el.pause();
                log.debug("stopped stream");
            }
        },
        /**
         * Reloads audio element to catch up in stream.
         */
        catchUp: function () {
            const el = this.$refs[this.stream.el];
            el.load();
            if (this.stream.play) {
                this.updatePlayState(true);
            }
            else {
                this.stream.play = true;
            }
            this.stream.offline = false;
        },
        streamError: function (e) {
            log.error("Error in stream", e);
            let msg = "Error: ";
            switch (e.target.error.code) {
                case e.target.error.MEDIA_ERR_ABORTED:
                    msg += "Playback aborted by user.";
                    break;
                case e.target.error.MEDIA_ERR_NETWORK:
                    msg += "Network error. Check your connection.";
                    break;
                case e.target.error.MEDIA_ERR_DECODE:
                    msg += "Decoding error.";
                    break;
                case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
                    msg += "Stream offline.";
                    break;
                default:
                    msg += "Unknown error";
                    break;
            }
            this.stream.offline = true;
            this.notify(msg);
        },
        /**
         * Shows notification
         * @param message - Text for notification.
         * @param duration - Duration of visibility.
         */
        notify: function (message, duration) {
            const el = this.$refs[this.notification.el];
            if (duration) {
                this.notification.duration = duration;
            }
            this.notification.message = message;
            el.open();
        }
    }
});
log.setDefaultLevel(app.loglevel);<|endoftext|>


<commit_before>define(['require', 'app', 'angular', 'ngRoute', 'authentication'], function(require, app, angular) { 'use strict';

    var baseUrl = require.toUrl('');

    app.provider('extendedRoute', ["$routeProvider", function($routeProvider) {

        var __when = $routeProvider.when.bind($routeProvider);

        //============================================================
        //
        //
        //============================================================
        function new_when(path, route) {

            var templateUrl = route.templateUrl;
            var templateModule;

            if(templateUrl) {

                if(templateUrl.indexOf('/')!==0) {
                    route.templateUrl = baseUrl + templateUrl;
                    templateModule  = changeExtension(templateUrl, '');
                }
                else {
                    templateModule = changeExtension(templateUrl, '.js');
                }
            }

            var ext = { resolve: route.resolve || {} };

            if(!route.controller && route.resolveController && typeof(route.resolveController)=="string")
                templateModule = route.resolveController;

            if(!route.controller && route.resolveController) {
                ext.controller         = proxy;
                ext.resolve.controller = resolveController(templateModule);
            }

            if(route.resolveUser) {
                ext.resolve.user = resolveUser();
            }

            return __when(path, angular.extend(route, ext));
        }

        //********************************************************************************
        //********************************************************************************
        //********************************************************************************
        //********************************************************************************

        function changeExtension(path, ext) {

            return path.replace(/(\.[a-z0-9]+$)/gi, ext);
        }

        //============================================================
        //
        //
        //============================================================
        function proxy($injector, $scope, $route, controller) {

            if(!controller)
                return;

            var locals = angular.extend($route.current.locals, { $scope: $scope });

            return $injector.invoke(controller, undefined, locals);
        }
        proxy.$inject = ['$injector', '$scope', '$route', 'controller'];

        //============================================================
        //
        //
        //============================================================
        function resolveUser() {
            return ['$q', '$rootScope', 'authentication', function($q, $rootScope, authentication) {
                return $q.when(authentication.getUser()).then(function (user) {
                    $rootScope.user = user;
                    return user;
                });
            }];
        }

        //============================================================
        //
        //
        //============================================================
        function resolveController(controllerModule) {

            return ['$q', function($q) {

                var deferred = $q.defer();

                require([controllerModule], function (module) {
                    deferred.resolve(module);
                }, function(){
                    deferred.reject("controller not found: " + controllerModule);
                });

                return deferred.promise;
            }];
        }

        return angular.extend($routeProvider, { when: new_when });
    }]);
});
<commit_msg>Use `instantiate` instead of `invoke` for controller<commit_after>define(['require', 'app', 'angular', 'ngRoute', 'authentication'], function(require, app, angular) { 'use strict';

    var baseUrl = require.toUrl('');

    app.provider('extendedRoute', ["$routeProvider", function($routeProvider) {

        var __when = $routeProvider.when.bind($routeProvider);

        //============================================================
        //
        //
        //============================================================
        function new_when(path, route) {

            var templateUrl = route.templateUrl;
            var templateModule;

            if(templateUrl) {

                if(templateUrl.indexOf('/')!==0) {
                    route.templateUrl = baseUrl + templateUrl;
                    templateModule  = changeExtension(templateUrl, '');
                }
                else {
                    templateModule = changeExtension(templateUrl, '.js');
                }
            }

            var ext = { resolve: route.resolve || {} };

            if(!route.controller && route.resolveController && typeof(route.resolveController)=="string")
                templateModule = route.resolveController;

            if(!route.controller && route.resolveController) {
                ext.controller         = proxy;
                ext.resolve.controller = resolveController(templateModule);
            }

            if(route.resolveUser) {
                ext.resolve.user = resolveUser();
            }

            return __when(path, angular.extend(route, ext));
        }

        //********************************************************************************
        //********************************************************************************
        //********************************************************************************
        //********************************************************************************

        function changeExtension(path, ext) {

            return path.replace(/(\.[a-z0-9]+$)/gi, ext);
        }

        //============================================================
        //
        //
        //============================================================
        function proxy($injector, $scope, $route, controller) {

            if(!controller)
                return;

            var locals = angular.extend($route.current.locals, { $scope: $scope });

            return $injector.instantiate(controller, locals);
        }
        proxy.$inject = ['$injector', '$scope', '$route', 'controller'];

        //============================================================
        //
        //
        //============================================================
        function resolveUser() {
            return ['$q', '$rootScope', 'authentication', function($q, $rootScope, authentication) {
                return $q.when(authentication.getUser()).then(function (user) {
                    $rootScope.user = user;
                    return user;
                });
            }];
        }

        //============================================================
        //
        //
        //============================================================
        function resolveController(controllerModule) {

            return ['$q', function($q) {

                var deferred = $q.defer();

                require([controllerModule], function (module) {
                    deferred.resolve(module);
                }, function(){
                    deferred.reject("controller not found: " + controllerModule);
                });

                return deferred.promise;
            }];
        }

        return angular.extend($routeProvider, { when: new_when });
    }]);
});
<|endoftext|>