// Concat modules and export them as an app. (function(root) { // All our modules will use global require. (function() { // app.coffee root.require.register('burnchart/src/app.js', function(exports, require, module) { var App, Header, el, key, mediator, route, router, _i, _len, _ref; _ref = ['utils/mixins', 'models/projects']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { key = _ref[_i]; require("./" + key); } Header = require('./views/header'); mediator = require('./modules/mediator'); el = '#page'; route = function(page, req, evt) { var Page; document.title = 'BurnChart: GitHub Burndown Chart as a Service'; Page = require("./views/pages/" + page); return new Page({ el: el, 'data': { 'route': req.params } }); }; router = { '': _.partial(route, 'index'), 'project/add': _.partial(route, 'addProject'), 'chart/:owner/:name/:milestone': _.partial(route, 'showChart'), 'reset': function() { mediator.fire('!projects/clear'); return window.location.hash = '#'; } }; App = Ractive.extend({ 'template': require('./templates/layout'), 'components': { Header: Header }, init: function() { return Grapnel.listen(router); } }); module.exports = new App(); }); // config.json root.require.register('burnchart/src/models/config.js', function(exports, require, module) { module.exports = { "firebase": "burnchart", "provider": "github", "fields": { "milestone": [ "closed_issues", "created_at", "description", "due_on", "number", "open_issues", "title", "updated_at" ] } }; }); // projects.coffee root.require.register('burnchart/src/models/projects.js', function(exports, require, module) { var Model, config, date, mediator, request, user; mediator = require('../modules/mediator'); request = require('../modules/request'); Model = require('../utils/model'); date = require('../utils/date'); config = require('./config'); user = require('./user'); module.exports = new Model({ 'data': { 'list': [] }, init: function() { var _this = this; localforage.getItem('projects', function(projects) { if (projects == null) { projects = []; } return async.each(projects, function(project, cb) { return mediator.fire('!projects/add', project); }, function(err) { if (err) { throw err; } }); }); this.observe('list', function(projects) { return localforage.setItem('projects', projects); }); mediator.on('!projects/add', function(repo, done) { return request.allMilestones(repo, function(err, res) { var milestones; if (err) { return done(err); } milestones = _.pluckMany(res, config.fields.milestone); _this.push('list', _.merge(repo, { milestones: milestones })); return done(); }); }); return mediator.on('!projects/clear', function() { return _this.set('list', []); }); } }); }); // user.coffee root.require.register('burnchart/src/models/user.js', function(exports, require, module) { var Model, mediator; mediator = require('../modules/mediator'); Model = require('../utils/model'); module.exports = new Model({ 'data': { 'provider': "local", 'id': "0", 'uid': "local:0", 'token': null } }); }); // firebase.coffee root.require.register('burnchart/src/modules/firebase.js', function(exports, require, module) { var Class, config, user; config = require('../models/config'); user = require('../models/user'); Class = (function() { function Class() { var _this = this; this.client = new Firebase("https://" + config.firebase + ".firebaseio.com"); this.auth = new FirebaseSimpleLogin(this.client, function(err, obj) { if (err || !obj) { return _this.authCb(err); } return user.set(obj); }); } Class.prototype.authCb = function() {}; Class.prototype.login = function(cb) { if (!this.client) { return cb('Client is not setup'); } this.authCb = cb; return this.auth.login(config.provider, { 'rememberMe': true, 'scope': 'public_repo' }); }; Class.prototype.logout = function() { var _ref; if ((_ref = this.auth) != null) { _ref.logout; } return user.reset(); }; return Class; })(); module.exports = new Class(); }); // mediator.coffee root.require.register('burnchart/src/modules/mediator.js', function(exports, require, module) { module.exports = new Ractive(); }); // request.coffee root.require.register('burnchart/src/modules/request.js', function(exports, require, module) { var defaults, error, headers, request, response, user; user = require('../models/user'); superagent.parse = { 'application/json': function(res) { var e; try { return JSON.parse(res); } catch (_error) { e = _error; return {}; } } }; defaults = { 'github': { 'host': 'api.github.com', 'protocol': 'https' } }; module.exports = { 'repo': function(repo, cb) { var data; data = _.defaults({ 'protocol': repo.protocol, 'host': repo.host, 'path': "/repos/" + repo.owner + "/" + repo.name, 'headers': headers(user.get('token')) }, defaults.github); return request(data, cb); }, 'allMilestones': function(repo, cb) { var data; data = _.defaults({ 'protocol': repo.protocol, 'host': repo.host, 'path': "/repos/" + repo.owner + "/" + repo.name + "/milestones", 'query': { 'state': 'open', 'sort': 'due_date', 'direction': 'asc' }, 'headers': headers(user.get('token')) }, defaults.github); return request(data, cb); }, 'oneMilestone': function(repo, number, cb) { return request({ 'protocol': repo.protocol, 'host': repo.host, 'path': "/repos/" + repo.owner + "/" + repo.name + "/milestones/" + number, 'query': { 'state': 'open', 'sort': 'due_date', 'direction': 'asc' }, 'headers': headers(user.get('token')) }, cb); }, 'allIssues': function(repo, query, cb) { return request({ 'protocol': repo.protocol, 'host': repo.host, 'path': "/repos/" + repo.owner + "/" + repo.name + "/issues", 'query': _.extend(query, { 'per_page': '100' }), 'headers': headers(user.get('token')) }, cb); } }; request = function(_arg, cb) { var exited, headers, host, k, path, protocol, q, query, req, timeout, v; protocol = _arg.protocol, host = _arg.host, path = _arg.path, query = _arg.query, headers = _arg.headers; exited = false; q = query ? '?' + ((function() { var _results; _results = []; for (k in query) { v = query[k]; _results.push("" + k + "=" + v); } return _results; })()).join('&') : ''; req = superagent.get("" + protocol + "://" + host + path + q); for (k in headers) { v = headers[k]; req.set(k, v); } timeout = setTimeout(function() { exited = true; return cb('Request has timed out'); }, 1e4); return req.end(function(err, data) { if (exited) { return; } exited = true; clearTimeout(timeout); return response(err, data, cb); }); }; response = function(err, data, cb) { var _ref; if (err) { return cb(error(err)); } if (data.statusType !== 2) { if ((data != null ? (_ref = data.body) != null ? _ref.message : void 0 : void 0) != null) { return cb(data.body.message); } return cb(data.error.message); } return cb(null, data.body); }; headers = function(token) { var h; h = _.extend({}, { 'Content-Type': 'application/json', 'Accept': 'application/vnd.github.v3' }); if (token != null) { h.Authorization = "token " + token; } return h; }; error = function(err) { var message; switch (false) { case !_.isString(err): message = err; break; case !_.isArray(err): message = err[1]; break; case !(_.isObject(err) && _.isString(err.message)): message = err.message; } if (!message) { try { message = JSON.stringify(err); } catch (_error) { message = err.toString(); } } return message; }; }); // header.mustache root.require.register('burnchart/src/templates/header.js', function(exports, require, module) { module.exports = ["
Not sure where to start? Just add a demo repo to see a chart. There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable.
","The one where we deliver all that we promised.
","{{owner}}/{{name}} | ",""," {{ title }}"," | ",""," "," {{Math.floor(format.progress(closed_issues, open_issues))}}%"," due {{format.fromNow(due_on)}}"," "," "," "," "," | ","