<commit_before>/*
 eslint-disable no-param-reassign, no-underscore-dangle
*/

import { Router } from 'express';
import { ObjectId } from 'mongodb';
import expressJwt from 'express-jwt';
import { SUCCESS, UNAUTHORIZED, SERVER_FAILED } from 'nagu-validates';
import { secret, mongoUrl } from '../config';
import { getToken, isMockVersion } from '../utils';

const CeeInfoManager = require('../models/cee').default;

const cim = new CeeInfoManager(mongoUrl);
const router = new Router();

router.put('/',
    // 返回mock数据
    (req, res, next) => {
      if (isMockVersion(req)) {
        res.json({
          ret: SUCCESS,
          data: {
            _id: '592e61700000000000000000',
          },
        });
      } else next();
    },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以添加数据
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  async (req, res) => {
    const _id = await cim.insert(req.body);
    res.json({
      ret: SUCCESS,
      data: { _id },
    });
  }
);

router.get('/list/:pageIndex',
  // 返回mock数据
  (req, res, next) => {
    if (isMockVersion(req)) {
      const list = [{
        name: '张三',
        fromSchool: '通海一中',
        toSchool: '玉溪一中',
        parentName: '张二',
        homeAddress: '纳古纳家营二组',
        phone: '18909879987',
        examTypeText: '中考',
        point: 536,
      }];
      res.json({
        ret: SUCCESS,
        data: {
          list,
          totalCount: list.length,
        },
      });
    } else next();
  },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以读取列表
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  (req, res, next) => {
    req.pageIndex = parseInt(req.params.pageIndex, 10);
    req.pageSize = parseInt(req.query.pageSize || 200, 10);
    if (isNaN(req.pageIndex) || isNaN(req.pageSize)) throw new Error('pageIndex or pageSize is wrong.');
    next();
  },
  async (req, res) => {
    const list = await cim.list({
      pageSize: req.pageSize,
      pageIndex: req.pageIndex,
    });
    const totalCount = await cim.count();
    res.json({
      ret: SUCCESS,
      data: {
        list,
        totalCount,
      },
    });
  }
);

// 根据用户信息获取录取信息
router.get('/app/:appId/user/:userId',
  // 返回mock数据
  (req, res, next) => {
    if (isMockVersion(req)) {
      const data = {
        _id: '592e61700000000000000000',
        name: '张三',
        fromSchool: '通海一中',
        toSchool: '玉溪一中',
        parentName: '张二',
        homeAddress: '纳古纳家营二组',
        phone: '18909879987',
        examTypeText: '中考',
        examType: 4,
        point: 536,
        user: {
          [req.params.appId]: req.params.userId,
        },
      };
      res.json({
        ret: SUCCESS,
        data,
      });
    } else next();
  },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以读取列表
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  async (req, res) => {
    const { appId, userId } = req.params;
    const data = await cim.findByUser(appId, userId);
    res.json({
      ret: SUCCESS,
      data,
    });
  }
);

// 删除指定Id的数据
router.delete('/:iId',
  // 返回mock数据
  (req, res, next) => {
    if (isMockVersion(req)) {
      res.json({
        ret: SUCCESS,
      });
    } else next();
  },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以读取列表
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  async (req, res) => {
    const { id } = req.params;
    try {
      const _id = new ObjectId(id);
      await cim.removeById(_id);
      res.json({
        ret: SUCCESS,
      });
    } catch (e) {
      res.status(500).json({
        ret: SERVER_FAILED,
        msg: e.message,
      });
    }
  }
);

router.post('/:id',
  // 返回mock数据
  (req, res, next) => {
    if (isMockVersion(req)) {
      res.json({
        ret: SUCCESS,
        data: {
          _id: '592e61700000000000000000',
        },
      });
    } else next();
  },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以读取列表
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  async (req, res) => {
    const { id } = req.params;
    try {
      const _id = new ObjectId(id);
      await cim.updateyId({
        ...req.body,
        _id,
      });
      res.json({
        ret: SUCCESS,
        data: {
          _id,
        },
      });
    } catch (e) {
      res.status(500).json({
        ret: SERVER_FAILED,
        msg: e.message,
      });
    }
  }
);
export default router;
<commit_msg>fix errors<commit_after>/*
 eslint-disable no-param-reassign, no-underscore-dangle
*/

import { Router } from 'express';
import { ObjectId } from 'mongodb';
import expressJwt from 'express-jwt';
import { SUCCESS, UNAUTHORIZED, SERVER_FAILED } from 'nagu-validates';
import { secret, mongoUrl } from '../config';
import { getToken, isMockVersion } from '../utils';

const CeeInfoManager = require('../models/cee').default;

const cim = new CeeInfoManager(mongoUrl);
const router = new Router();

router.put('/',
    // 返回mock数据
    (req, res, next) => {
      if (isMockVersion(req)) {
        res.json({
          ret: SUCCESS,
          data: {
            _id: '592e61700000000000000000',
          },
        });
      } else next();
    },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以添加数据
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  async (req, res) => {
    const _id = await cim.insert(req.body);
    res.json({
      ret: SUCCESS,
      data: { _id },
    });
  }
);

router.get('/list/:pageIndex',
  // 返回mock数据
  (req, res, next) => {
    if (isMockVersion(req)) {
      const list = [{
        name: '张三',
        fromSchool: '通海一中',
        toSchool: '玉溪一中',
        parentName: '张二',
        homeAddress: '纳古纳家营二组',
        phone: '18909879987',
        examTypeText: '中考',
        point: 536,
      }];
      res.json({
        ret: SUCCESS,
        data: {
          list,
          totalCount: list.length,
        },
      });
    } else next();
  },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以读取列表
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  (req, res, next) => {
    req.pageIndex = parseInt(req.params.pageIndex, 10);
    req.pageSize = parseInt(req.query.pageSize || 200, 10);
    if (isNaN(req.pageIndex) || isNaN(req.pageSize)) throw new Error('pageIndex or pageSize is wrong.');
    next();
  },
  async (req, res) => {
    const list = await cim.list({
      pageSize: req.pageSize,
      pageIndex: req.pageIndex,
    });
    const totalCount = await cim.count();
    res.json({
      ret: SUCCESS,
      data: {
        list,
        totalCount,
      },
    });
  }
);

// 根据用户信息获取录取信息
router.get('/app/:appId/user/:userId',
  // 返回mock数据
  (req, res, next) => {
    if (isMockVersion(req)) {
      const data = {
        _id: '592e61700000000000000000',
        name: '张三',
        fromSchool: '通海一中',
        toSchool: '玉溪一中',
        parentName: '张二',
        homeAddress: '纳古纳家营二组',
        phone: '18909879987',
        examTypeText: '中考',
        examType: 4,
        point: 536,
        user: {
          [req.params.appId]: req.params.userId,
        },
      };
      res.json({
        ret: SUCCESS,
        data,
      });
    } else next();
  },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以读取列表
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  async (req, res) => {
    const { appId, userId } = req.params;
    const data = await cim.findByUser(appId, userId);
    res.json({
      ret: SUCCESS,
      data,
    });
  }
);

// 删除指定Id的数据
router.delete('/:iId',
  // 返回mock数据
  (req, res, next) => {
    if (isMockVersion(req)) {
      res.json({
        ret: SUCCESS,
      });
    } else next();
  },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以读取列表
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  async (req, res) => {
    const { id } = req.params;
    try {
      const _id = new ObjectId(id);
      await cim.removeById(_id);
      res.json({
        ret: SUCCESS,
      });
    } catch (e) {
      res.status(500).json({
        ret: SERVER_FAILED,
        msg: e.message,
      });
    }
  }
);

router.post('/:id',
  // 返回mock数据
  (req, res, next) => {
    if (isMockVersion(req)) {
      res.json({
        ret: SUCCESS,
        data: {
          _id: '592e61700000000000000000',
        },
      });
    } else next();
  },
  // 确保用户已登录
  expressJwt({
    secret,
    credentialsRequired: true,
    getToken,
  }),
  // 判断是否是Manager，只有这种角色可以读取列表
  (req, res, next) => {
    if (req.user.isManager) next();
    else res.send({ ret: UNAUTHORIZED, msg: 'only manager can go next.' });
  },
  async (req, res) => {
    const { id } = req.params;
    try {
      const _id = new ObjectId(id);
      await cim.updateById({
        ...req.body,
        _id,
      });
      res.json({
        ret: SUCCESS,
        data: {
          _id,
        },
      });
    } catch (e) {
      res.status(500).json({
        ret: SERVER_FAILED,
        msg: e.message,
      });
    }
  }
);
export default router;
<|endoftext|>


<commit_before>function Map() {
    this.rows = [];
    this.edge = -1;
    this.advance();
}

Map.SCALE = 25;
Map.TREE_SCALE = 8;
Map.COLD_SCALE = 16;
Map.COLD_RANGE = 256;
Map.SUPPLY_RATE = 0.01;
Map.prototype.width = 32;

Map.prototype.get = function(y) {
    if (y >= this.rows.length) {
        this.generate(y);
    }
    return this.rows[y];
};

Map.road = function(y, width) {
    var w2 = width / 2, w3 = width / 3;
    return Math.round(w3 * noise.perlin3(0.5, y / 20, 0)) + w2;
};

Map.select = function(value, x, y) {
    var tile = null;
    if (value > 0.8) {
        tile = new Tile(Tile.WATER3);
    } else if (value > 0.75) {
        tile = new Tile(Tile.WATER2);
    } else if (value > 0.7) {
        tile = new Tile(Tile.WATER1);
    } else if (value > -0.4) {
        tile = new Tile(Tile.GRASS);
    } else if (value > -0.6) {
        tile = new Tile(Tile.SOIL);
    } else if (value > -0.9) {
        tile = new Tile(Tile.DIRT);
    } else {
        tile = new Tile(Tile.SAND);
    }
    return tile;
};

Map.cold = function(x, y) {
    var cold = noise.perlin3(x / Map.COLD_SCALE, y / Map.COLD_SCALE, 1.5),
        limit = Math.atan((y - Map.COLD_RANGE) / Map.COLD_RANGE) - 0.3;
     return cold < limit;
};

Map.bselect = function(value, base, x, y) {
    if (value > 0.5) {
        return Tile.MOUNTAIN;
    } else if (value > 0.22) {
        return Tile.TREE;
    } else if (value < -0.2 && base.type === Tile.GRASS && !base.cold) {
        return Tile.TALLGRASS;
    } else {
        return null;
    }
};

Map.prototype.generate = function(n) {
    while (this.rows.length < n + 1) {
        var row = [], y = this.rows.length;
        var road = Map.road(y, this.width),
            lastroad = y > 0 ? this.rows[y - 1].road : road;
        row.road = road;
        var roadmin = Math.min(road, lastroad),
            roadmax = Math.max(road, lastroad);
        for (var x = 0; x < this.width; x++) {
            var tvalue = noise.simplex2(x / Map.SCALE, y / Map.SCALE),
                tile = x >= roadmin && x <= roadmax
                    ? new Tile(Tile.ROAD) : Map.select(tvalue, x, y),
                bvalue = noise.perlin2(x / Map.TREE_SCALE, y / Map.TREE_SCALE);
            tile.cold = Map.cold(x, y);
            if (!tile.type.water && tile.type !== Tile.ROAD) {
                tile.obstacle = Map.bselect(bvalue, tile, x, y);
            }
            if (!tile.obstacle && !tile.type.solid) {
                if (Math.random() < Map.SUPPLY_RATE / (tile.cold ? 2 : 1)) {
                    tile.obstacle = Tile.SUPPLIES;
                }
            }
            row.push(tile);
        }
        this.rows.push(row);
    }
};

Map.prototype.advance = function() {
    var edge = ++this.edge,
        row = this.get(edge);
    for (var x = 0; x < row.length; x++) {
        row[x].corrupted = true;
    }
};

Map.prototype.lurk = function() {
    var lurk = this.edge + 1,
        row = this.get(lurk);
    for (var x = 0; x < row.length; x++) {
        if (Math.random() < 0.1) {
            row[x].corrupted = true;
        }
    }
};

Map.prototype.isSolid = function(x, y) {
    if (y < 0) return true;
    var tile = this.get(y)[x];
    return tile == null
        || (tile.type.solid && (tile.type.water ? !tile.cold : true))
        || tile.obstacle != null && tile.obstacle.solid;
};
<commit_msg>Add animateAdvance().<commit_after>function Map() {
    this.rows = [];
    this.edge = -1;
    this.advance();
}

Map.SCALE = 25;
Map.TREE_SCALE = 8;
Map.COLD_SCALE = 16;
Map.COLD_RANGE = 256;
Map.SUPPLY_RATE = 0.01;
Map.prototype.width = 32;

Map.prototype.get = function(y) {
    if (y >= this.rows.length) {
        this.generate(y);
    }
    return this.rows[y];
};

Map.road = function(y, width) {
    var w2 = width / 2, w3 = width / 3;
    return Math.round(w3 * noise.perlin3(0.5, y / 20, 0)) + w2;
};

Map.select = function(value, x, y) {
    var tile = null;
    if (value > 0.8) {
        tile = new Tile(Tile.WATER3);
    } else if (value > 0.75) {
        tile = new Tile(Tile.WATER2);
    } else if (value > 0.7) {
        tile = new Tile(Tile.WATER1);
    } else if (value > -0.4) {
        tile = new Tile(Tile.GRASS);
    } else if (value > -0.6) {
        tile = new Tile(Tile.SOIL);
    } else if (value > -0.9) {
        tile = new Tile(Tile.DIRT);
    } else {
        tile = new Tile(Tile.SAND);
    }
    return tile;
};

Map.cold = function(x, y) {
    var cold = noise.perlin3(x / Map.COLD_SCALE, y / Map.COLD_SCALE, 1.5),
        limit = Math.atan((y - Map.COLD_RANGE) / Map.COLD_RANGE) - 0.3;
     return cold < limit;
};

Map.bselect = function(value, base, x, y) {
    if (value > 0.5) {
        return Tile.MOUNTAIN;
    } else if (value > 0.22) {
        return Tile.TREE;
    } else if (value < -0.2 && base.type === Tile.GRASS && !base.cold) {
        return Tile.TALLGRASS;
    } else {
        return null;
    }
};

Map.prototype.generate = function(n) {
    while (this.rows.length < n + 1) {
        var row = [], y = this.rows.length;
        var road = Map.road(y, this.width),
            lastroad = y > 0 ? this.rows[y - 1].road : road;
        row.road = road;
        var roadmin = Math.min(road, lastroad),
            roadmax = Math.max(road, lastroad);
        for (var x = 0; x < this.width; x++) {
            var tvalue = noise.simplex2(x / Map.SCALE, y / Map.SCALE),
                tile = x >= roadmin && x <= roadmax
                    ? new Tile(Tile.ROAD) : Map.select(tvalue, x, y),
                bvalue = noise.perlin2(x / Map.TREE_SCALE, y / Map.TREE_SCALE);
            tile.cold = Map.cold(x, y);
            if (!tile.type.water && tile.type !== Tile.ROAD) {
                tile.obstacle = Map.bselect(bvalue, tile, x, y);
            }
            if (!tile.obstacle && !tile.type.solid) {
                if (Math.random() < Map.SUPPLY_RATE / (tile.cold ? 2 : 1)) {
                    tile.obstacle = Tile.SUPPLIES;
                }
            }
            row.push(tile);
        }
        this.rows.push(row);
    }
};

Map.prototype.advance = function() {
    var edge = ++this.edge,
        row = this.get(edge);
    for (var x = 0; x < row.length; x++) {
        row[x].corrupted = true;
    }
};

Map.prototype.animateAdvance = function(n, callback) {
    if (n === 0) {
        callback();
    } else {
        this.advance();
        display.draw();
        var _this = this;
        window.setTimeout(function() {
            _this.animateAdvance(n - 1, callback);
        }, 200);
    }
};

Map.prototype.lurk = function() {
    var lurk = this.edge + 1,
        row = this.get(lurk);
    for (var x = 0; x < row.length; x++) {
        if (Math.random() < 0.1) {
            row[x].corrupted = true;
        }
    }
};

Map.prototype.isSolid = function(x, y) {
    if (y < 0) return true;
    var tile = this.get(y)[x];
    return tile == null
        || (tile.type.solid && (tile.type.water ? !tile.cold : true))
        || tile.obstacle != null && tile.obstacle.solid;
};
<|endoftext|>


<commit_before>(function( $ ){
    // This re-usable plugin displays
    // the no credit course registered message panel

    $.fn.no_courses = function(inputs) {
        var settings = $.extend({}, {
            "which_quarter_or_term" : "this quarter",
	    "present_addi_links" : true,
	    "visual": ""
        }, inputs);

        return this.each(function() {
            var source   = $("#no-courses").html();
            var template = Handlebars.compile(source);
//	    Handlebars.registerPartial("no-course-msg",
//				       $("#no-course-msg").html());
            $(this).html(template(settings));

	    if (settings.present_addi_links) {
		$("#addi_links").addi_course_links({
		    "visual": settings.visual,
		    "registered_for_the_quarter" : false });
	    }
        });
    };
}(jQuery));
<commit_msg>minor syntax change.<commit_after>(function( $ ){
    // This re-usable plugin displays
    // the no credit course registered message panel

    $.fn.no_courses = function( inputs ) {
        var settings = $.extend( {
            "which_quarter_or_term" : "this quarter",
	    "present_addi_links" : true,
	    "visual": ""
        }, inputs);

        return this.each(function() {
            var source   = $("#no-courses").html();
            var template = Handlebars.compile(source);
//	    Handlebars.registerPartial("no-course-msg",
//				       $("#no-course-msg").html());
            $(this).html(template(settings));

	    if ( settings.present_addi_links ) {
		$("#addi_links").addi_course_links({
		    "visual": settings.visual,
		    "registered_for_the_quarter" : false });
	    }
        });
    };
})( jQuery );
<|endoftext|>


<commit_before>import { Feature } from 'core/feature';
import * as toolkitHelper from 'helpers/toolkit';

export class ChangeEnterBehavior extends Feature {
  shouldInvoke() {
    return toolkitHelper.getCurrentRouteName().indexOf('account') !== -1 &&
           $('.ynab-grid-body-row.is-adding').length;
  }

  invoke() {
    const $addRow = $('.ynab-grid-body-row.is-adding');
    const $memoInput = $('.ynab-grid-cell-memo input', $addRow);
    const $outflowInput = $('.ynab-grid-cell-outflow input', $addRow);
    const $inflowInput = $('.ynab-grid-cell-inflow input', $addRow);

    if (!$memoInput[0].getAttribute('data-toolkit-save-behavior')) {
      $memoInput[0].setAttribute('data-toolkit-save-behavior', true);
      $memoInput.keydown(this.applyNewEnterBehavior);
    }

    if (!$outflowInput[0].getAttribute('data-toolkit-save-behavior')) {
      $outflowInput[0].setAttribute('data-toolkit-save-behavior', true);
      $outflowInput.keydown(this.applyNewEnterBehavior);
    }

    if (!$inflowInput[0].getAttribute('data-toolkit-save-behavior')) {
      $inflowInput[0].setAttribute('data-toolkit-save-behavior', true);
      $inflowInput.keydown(this.applyNewEnterBehavior);
    }
  }

  applyNewEnterBehavior(event) {
    if (event.keyCode === 13) {
      event.preventDefault();
      event.stopPropagation();

      const $saveButton = $('.button.button-primary:not(.button-another)');
      $saveButton.click();
    }
  }

  observe(changedNodes) {
    if (!changedNodes.has('ynab-grid-body')) return;

    if (this.shouldInvoke()) {
      this.invoke();
    }
  }
}
<commit_msg>narrowed scope of jquery selector so the save button would be "clicked" instead of the "create adjustment & finish" button when in reconcile mode.<commit_after>import { Feature } from 'core/feature';
import * as toolkitHelper from 'helpers/toolkit';

export class ChangeEnterBehavior extends Feature {
  shouldInvoke() {
    return toolkitHelper.getCurrentRouteName().indexOf('account') !== -1 &&
           $('.ynab-grid-body-row.is-adding').length;
  }

  invoke() {
    const $addRow = $('.ynab-grid-body-row.is-adding');
    const $memoInput = $('.ynab-grid-cell-memo input', $addRow);
    const $outflowInput = $('.ynab-grid-cell-outflow input', $addRow);
    const $inflowInput = $('.ynab-grid-cell-inflow input', $addRow);

    if (!$memoInput[0].getAttribute('data-toolkit-save-behavior')) {
      $memoInput[0].setAttribute('data-toolkit-save-behavior', true);
      $memoInput.keydown(this.applyNewEnterBehavior);
    }

    if (!$outflowInput[0].getAttribute('data-toolkit-save-behavior')) {
      $outflowInput[0].setAttribute('data-toolkit-save-behavior', true);
      $outflowInput.keydown(this.applyNewEnterBehavior);
    }

    if (!$inflowInput[0].getAttribute('data-toolkit-save-behavior')) {
      $inflowInput[0].setAttribute('data-toolkit-save-behavior', true);
      $inflowInput.keydown(this.applyNewEnterBehavior);
    }
  }

  applyNewEnterBehavior(event) {
    if (event.keyCode === 13) {
      event.preventDefault();
      event.stopPropagation();

      const $saveButton = $('.ynab-grid-actions-buttons .button.button-primary:not(.button-another)');
      $saveButton.click();
    }
  }

  observe(changedNodes) {
    if (!changedNodes.has('ynab-grid-body')) return;

    if (this.shouldInvoke()) {
      this.invoke();
    }
  }
}
<|endoftext|>


<commit_before>var CONSTANTS = window.CONSTANTS
var ActionTypes = CONSTANTS.ActionTypes
// var Dispatcher = require('../dispatcher');
var Store = require('./es6_store')

var parsedUri = parseUri(window.location) || {};
var query = parsedUri.query || {};
var currentPage = query.page || 1
var totalPages = 1

class PaginationStore extends Store {
  constructor() {
    super()

    this.dispatchToken = Dispatcher.register((action) => {
      switch (action.type) {
        case ActionTypes.PAGINATION_PAGE_CHANGED:
          _setPage(action)
          this.emitChange()
          break
        case ActionTypes.PAGINATION_TOTAL_PAGES_RECEIVE:
          _setTotalPages(action)
          this.emitChange()
          break
      }
    })
  }

  getCurrentPage() {
    return currentPage
  }

  getTotalPages() {
    return totalPages
  }
}

var store = new PaginationStore()

var dataTag = document.getElementById('PaginationStore')
if (dataTag) {
  var data = JSON.parse(dataTag.innerHTML);

  Dispatcher.dispatch({
    type: ActionTypes.PAGINATION_TOTAL_PAGES_RECEIVE,
    currentPage: data.current_page,
    totalPages: data.total_pages
  })
}

module.exports = store

function _setPage(action) {
  currentPage = action.page
}

function _setTotalPages(action) {
  totalPages = action.totalPages
}
<commit_msg>Fix pagination initialization<commit_after>var CONSTANTS = window.CONSTANTS
var ActionTypes = CONSTANTS.ActionTypes
// var Dispatcher = require('../dispatcher')
var Store = require('./es6_store')
var url = require('url')
var qs = require('qs')

var parsedUri = url.parse(window.location.toString())
var query = qs.parse(parsedUri.query || {})
var currentPage = parseInt(query.page || 1, 10)
var totalPages = 1

class PaginationStore extends Store {
  constructor() {
    super()

    this.dispatchToken = Dispatcher.register((action) => {
      switch (action.type) {
        case ActionTypes.PAGINATION_PAGE_CHANGED:
          _setPage(action)
          this.emitChange()
          break
        case ActionTypes.PAGINATION_TOTAL_PAGES_RECEIVE:
          _setTotalPages(action)
          this.emitChange()
          break
      }
    })
  }

  getCurrentPage() {
    return currentPage
  }

  getTotalPages() {
    return totalPages
  }
}

var store = new PaginationStore()

var dataTag = document.getElementById('PaginationStore')
if (dataTag) {
  var data = JSON.parse(dataTag.innerHTML)

  Dispatcher.dispatch({
    type: ActionTypes.PAGINATION_TOTAL_PAGES_RECEIVE,
    currentPage: data.current_page,
    totalPages: data.total_pages
  })
}

module.exports = store

function _setPage(action) {
  currentPage = action.page
}

function _setTotalPages(action) {
  totalPages = action.totalPages
}
<|endoftext|>


<commit_before>/**
 * Angular directive to display an interactive visualization chart to visualize events in time,
 * relaying on Almende's Timeline (http://almende.github.io/chap-links-library/timeline.html)
 * @author Gabriele Destefanis
 * @version 0.1.0
 */

'use strict';

angular.module('destegabry.timeline', [])
	.directive('timeline', function() {

		var ItemRangePopup = function(data, options) {
			links.Timeline.ItemRange.call(this, data, options);
		};

		ItemRangePopup.prototype = new links.Timeline.ItemRange();

		ItemRangePopup.prototype.updateDOM = function() {
			var divBox = this.dom;
			if (divBox) {

				divBox.className = "timeline-event timeline-event-range timeline-event-range-popup ui-widget ui-state-default";
				divBox.style.height = "22px";

				if (this.content) {
					$(divBox).tooltip({
						'placement': 'top',
						'html': true,
						'title': this.content,
						'container': 'body'
					});
				}

				if (this.isCluster) {
					links.Timeline.addClassName(divBox, 'timeline-event-cluster ui-widget-header');
				}

				if (this.className) {
					links.Timeline.addClassName(divBox, this.className);
				}
			}
		};

		return {
			restrict: 'A',
			scope: {
				model: '=timeline',
				options: '=timelineOptions',
				selection: '=timelineSelection'
			},
			link: function($scope, $element) {
				var timeline = new links.Timeline($element[0]);
				timeline.addItemType('range', ItemRangePopup);

				links.events.addListener(timeline, 'select', function() {
					$scope.selection = undefined;
					var sel = timeline.getSelection();
					if (sel[0]) {
						$scope.selection = $scope.model[sel[0].row];
					}
				});

				$scope.$watch('model', function(newVal, oldVal) {
					timeline.setData(newVal);
				});

				$scope.$watch('options', function(newVal, oldVal) {
					timeline.draw($scope.model, $scope.options);
				});

				$scope.$watch('selection', function(newVal, oldVal) {
					if (!angular.equals(newVal, oldVal)) {
						for (var i = $scope.model.length - 1; i >= 0; i--) {
							if (angular.equals($scope.model[i], newVal)) {
								timeline.setSelection([{
									row: i
								}]);
								break;
							}
						};
					}
				});
			}
		};
	});<commit_msg>Added automatic timeline resize to show all elements when model changes, refactored identation<commit_after>/**
 * Angular directive to display an interactive visualization chart to visualize events in time,
 * relaying on Almende's Timeline (http://almende.github.io/chap-links-library/timeline.html)
 * @author Gabriele Destefanis
 * @version 0.1.0
 */

'use strict';

angular.module('destegabry.timeline', [])
  .directive('timeline', function() {

    var ItemRangePopup = function(data, options) {
      links.Timeline.ItemRange.call(this, data, options);
    };

    ItemRangePopup.prototype = new links.Timeline.ItemRange();

    ItemRangePopup.prototype.updateDOM = function() {
      var divBox = this.dom;
      if (divBox) {

        divBox.className = "timeline-event timeline-event-range timeline-event-range-popup ui-widget ui-state-default";
        divBox.style.height = "22px";

        if (this.content) {
          $(divBox).tooltip({
            'placement': 'top',
            'html': true,
            'title': this.content,
            'container': 'body'
          });
        }

        if (this.isCluster) {
          links.Timeline.addClassName(divBox, 'timeline-event-cluster ui-widget-header');
        }

        if (this.className) {
          links.Timeline.addClassName(divBox, this.className);
        }
      }
    };

    return {
      restrict: 'A',
      scope: {
        model: '=timeline',
        options: '=timelineOptions',
        selection: '=timelineSelection'
      },
      link: function($scope, $element) {
        var timeline = new links.Timeline($element[0]);
        timeline.addItemType('range', ItemRangePopup);

        links.events.addListener(timeline, 'select', function() {
          $scope.selection = undefined;
          var sel = timeline.getSelection();
          if (sel[0]) {
            $scope.selection = $scope.model[sel[0].row];
          }
        });

        $scope.$watch('model', function(newVal, oldVal) {
          timeline.setData(newVal);
          timeline.setVisibleChartRangeAuto();
        });

        $scope.$watch('options', function(newVal, oldVal) {
          timeline.draw($scope.model, $scope.options);
        });

        $scope.$watch('selection', function(newVal, oldVal) {
          if (!angular.equals(newVal, oldVal)) {
            for (var i = $scope.model.length - 1; i >= 0; i--) {
              if (angular.equals($scope.model[i], newVal)) {
                timeline.setSelection([{
                  row: i
                }]);
                break;
              }
            };
          }
        });
      }
    };
  });<|endoftext|>


<commit_before>module.exports = function(grunt) {
	var pkg, s3, version, verParts;
	pkg = grunt.file.readJSON('package.json');
  	try {
    	s3 = grunt.file.readJSON('.s3config.json');
  	} catch(e) {
    	s3 = {};
  	}
  	verParts = pkg.version.split('.');
	version = {
		full: pkg.version,
	    major: verParts[0],
	    minor: verParts[1],
	    patch: verParts[2]
	};
  	version.majorMinor = version.major + '.' + version.minor;
  // Project configuration.
  grunt.initConfig({
    pkg: pkg,
    jshint: {
      src: {
        src: ['src/*.js'],
        options: {
        	jshintrc: '.jshintrc'
        }
      }
    },
    concat: {
    	build: {
    		src: ['src/cuepoint.js','src/core.js'],
    		dest:'build/<%= pkg.name %>.js'
    	}
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.title %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'+
        		'/*! Author: <%= pkg.author_name %> <<%= pkg.author_email %>>*/\n'
      },
      build: {
        src: 'build/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.distName %>.js'
      },
      dist: {
      	src: 'build/<%= pkg.name %>.js',
        dest: 'dist/<%= pkg.distName %>.js'
      }
    },
    s3: {
      options: s3,
      minor: {
        upload: [
          {
            src: 'build/*',
            dest: version.majorMinor+'/',
            headers: {
              'Cache-Control': 'public, max-age=2628000'
            }
          }
        ]
      },
      patch: {
        upload: [
          {
            src: 'build/*',
            dest: version.full+'/',
            headers: {
              'Cache-Control': 'public, max-age=31536000'
            }
          }
        ]
      }
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-s3');
  // Default task(s).
  grunt.registerTask('default', ['jshint', 'concat','uglify']);
  grunt.registerTask('deploy',['jshint', 'concat','uglify:dist','s3']);
};<commit_msg>Uploads only to s3 files in dist folder<commit_after>module.exports = function(grunt) {
	var pkg, s3, version, verParts;
	pkg = grunt.file.readJSON('package.json');
  	try {
    	s3 = grunt.file.readJSON('.s3config.json');
  	} catch(e) {
    	s3 = {};
  	}
  	verParts = pkg.version.split('.');
	version = {
		full: pkg.version,
	    major: verParts[0],
	    minor: verParts[1],
	    patch: verParts[2]
	};
  	version.majorMinor = version.major + '.' + version.minor;
  // Project configuration.
  grunt.initConfig({
    pkg: pkg,
    jshint: {
      src: {
        src: ['src/*.js'],
        options: {
        	jshintrc: '.jshintrc'
        }
      }
    },
    concat: {
    	build: {
    		src: ['src/cuepoint.js','src/core.js'],
    		dest:'build/<%= pkg.name %>.js'
    	}
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.title %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'+
        		'/*! Author: <%= pkg.author_name %> <<%= pkg.author_email %>>*/\n'
      },
      build: {
        src: 'build/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.distName %>.js'
      },
      dist: {
      	src: 'build/<%= pkg.name %>.js',
        dest: 'dist/<%= pkg.distName %>.js'
      }
    },
    s3: {
      options: s3,
      minor: {
        upload: [
          {
            src: 'dist/*',
            dest: version.majorMinor+'/',
            headers: {
              'Cache-Control': 'public, max-age=2628000'
            }
          }
        ]
      },
      patch: {
        upload: [
          {
            src: 'dist/*',
            dest: version.full+'/',
            headers: {
              'Cache-Control': 'public, max-age=31536000'
            }
          }
        ]
      }
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-s3');
  // Default task(s).
  grunt.registerTask('default', ['jshint', 'concat','uglify']);
  grunt.registerTask('deploy',['jshint', 'concat','uglify:dist','s3']);
};<|endoftext|>


<commit_before>/**
 * An Animator class for animating objects based on an AnimationData.
 *
 * @constructor
 * @param {THREE.Object[]} objects
 * The objects to animate.
 * @param {AnimationData} animationData
 * The AnimationData to animate with.
 */
function Animator(object, animationData) {
  EventEmitter.call(this);

  this.objects = object;
  this.data = animationData;
  this.currentTime = 0;
  this.isPlaying = false;
  this.isPaused = false;
  this.loop = 0;
  this.timeScale = 1;
  this.length = this.data.frameCount / this.data.fps;
}

Animator.prototype = Object.create(EventEmitter.prototype);

Animator.prototype.play = function (startTime, weight) {
  this.currentTime = startTime !== undefined ? startTime : 0;
  this.weight = weight !== undefined ? weight : 1;

  this.reset();

  this.isPlaying = true;
  this.isPaused = false;

  THREE.AnimationHandler.play(this);
};

Animator.prototype.pause = function() {
  this.isPaused = true;
};

Animator.prototype.unpause = function() {
  this.isPaused = false;
};

Animator.prototype.stop = function () {
  if (!this.isPlaying) {
    return;
  }

  this.isPlaying = false;
  this.isPaused = false;

  THREE.AnimationHandler.stop(this);
};

Animator.prototype.reset = function () {
  for (var h = 0, hl = this.objects.length; h < hl; h++) {
    var object = this.objects[h];

    object.matrixAutoUpdate = true;

    if (object.animatorCache === undefined) {
      object.animatorCache = {
        blending: {
          positionWeight: 0.0,
          quaternionWeight: 0.0,
          scaleWeight: 0.0
        }
      }
    }
  }
};

Animator.prototype.resetBlendWeights = function () {
  for (var h = 0, hl = this.objects.length; h < hl; h++) {
    var object = this.objects[h];

    if (object.animatorCache !== undefined) {
      object.animatorCache.blending.positionWeight = 0.0;
      object.animatorCache.blending.quaternionWeight = 0.0;
      object.animatorCache.blending.scaleWeight = 0.0;
    }
  }
};

Animator.prototype._applyChannel = function(index, type, value) {
  var object = this.objects[index];
  var blending = object.animatorCache.blending;

  object.matrixAutoUpdate = true;
  object.matrixWorldNeedsUpdate = true;

  if (type === AnimationData.CHANNEL_TYPE.Position) {
    if (blending.positionWeight === 0) {
      object.position.copy(value);
      blending.positionWeight = this.weight;
    } else {
      var proportionalWeight = this.weight / (this.weight + blending.positionWeight);
      object.position.lerp(value, proportionalWeight);
      blending.positionWeight += this.weight;
    }
  } else if (AnimationData.CHANNEL_TYPE.Rotation) {
    if (blending.quaternionWeight === 0) {
      object.quaternion.copy(value);
      blending.quaternionWeight = this.weight;
    } else {
      var proportionalWeight = this.weight / (this.weight + blending.quaternionWeight);
      object.quaternion.slerp(value, proportionalWeight);
      blending.quaternionWeight += this.weight;
    }
  } else if (AnimationData.CHANNEL_TYPE.Scale) {
    if (blending.scaleWeight === 0) {
      object.scale.copy(value);
      blending.scaleWeight = this.weight;
    } else {
      var proportionalWeight = this.weight / (this.weight + blending.scaleWeight);
      object.scale.lerp(value, proportionalWeight);
      blending.scaleWeight += this.weight;
    }
  }
};

var _SLERPER = new THREE.Quaternion();
var _V3LERPER = new THREE.Vector3();
var _V2LERPER = new THREE.Vector2();
Animator.prototype._applyChannels = function(channels, thisFrame, nextFrame, frameRatio) {
  for (var i = 0; i < channels.length; ++i) {
    var c = channels[i];

    var f0 = c.frames[thisFrame];
    var f1 = c.frames[nextFrame];
    var f = null;
    if (frameRatio === 0) {
      f = f0;
    } else {
      if (f0 instanceof THREE.Quaternion) {
        f = THREE.Quaternion.slerp(f0, f1, _SLERPER, frameRatio);
      } else if (f0 instanceof THREE.Vector3) {
        f = _V3LERPER.copy(f0).lerp(f1, frameRatio);
      } else if (f0 instanceof THREE.Vector2) {
        f = _V2LERPER.copy(f0).lerp(f1, frameRatio);
      } else if (f0 instanceof Number) {
        f = f0 * (1 - frameRatio) + f1 * frameRatio;
      } else {
        f = f0;
      }
    }
    this._applyChannel(c.index, c.type, f);
  }
};

Animator.prototype.update = function (delta) {
  if (this.isPlaying === false) return delta;

  if (!this.isPaused) {
    this.currentTime += delta * this.timeScale;

    // If this is the last frame, we have to stop at the last frame, rather
    //   then blending back towards frame 0, remove that time.
    var endTime = this.length;
    if (this.loop === 1) {
      endTime = (this.data.frameCount - 1) / this.data.fps;
    }

    if (this.currentTime >= endTime || this.currentTime < 0) {
      if (this.loop === 0 || this.loop > 1) {
        if (this.loop !== 0) {
          this.loop--;
        }

        this.currentTime %= this.length;

        if (this.currentTime < 0) {
          this.currentTime += this.length;
        }

        this.reset();
        this.emit('restart');
      } else {
        var timeConsumed = endTime - this.currentTime;
        this.currentTime = endTime;
        this.pause();
        this.emit('finish');
        return delta - timeConsumed;
      }
    }
  }

  if (this.weight === 0) {
    return 0.0;
  }

  var thisFrame = Math.floor(this.currentTime * this.data.fps);
  // TODO: THIS SHOULD NOT BE NEEDED
  if (thisFrame >= this.data.frameCount) {
    thisFrame = this.data.frameCount - 1;
  }
  var nextFrame = thisFrame + 1;
  if (nextFrame >= this.data.frameCount) {
    if (this.loop) {
      nextFrame -= this.data.frameCount;
    } else {
      nextFrame = thisFrame;
    }
  }

  var frameRatio = ( this.currentTime - (thisFrame / this.data.fps) ) / (1 / this.data.fps);
  this._applyChannels(this.data.channels, thisFrame, nextFrame, frameRatio);

  return 0.0;
};

module.exports = Animator;
<commit_msg>Stop Animator from being added to AnimationHandler twice.<commit_after>/**
 * An Animator class for animating objects based on an AnimationData.
 *
 * @constructor
 * @param {THREE.Object[]} objects
 * The objects to animate.
 * @param {AnimationData} animationData
 * The AnimationData to animate with.
 */
function Animator(object, animationData) {
  EventEmitter.call(this);

  this.objects = object;
  this.data = animationData;
  this.currentTime = 0;
  this.isPlaying = false;
  this.isPaused = false;
  this.loop = 0;
  this.timeScale = 1;
  this.length = this.data.frameCount / this.data.fps;
}

Animator.prototype = Object.create(EventEmitter.prototype);

Animator.prototype.play = function (startTime, weight) {
  if (this.isPlaying) {
    this.stop();
  }

  this.currentTime = startTime !== undefined ? startTime : 0;
  this.weight = weight !== undefined ? weight : 1;

  this.reset();

  this.isPlaying = true;

  THREE.AnimationHandler.play(this);
};

Animator.prototype.pause = function() {
  this.isPaused = true;
};

Animator.prototype.unpause = function() {
  this.isPaused = false;
};

Animator.prototype.stop = function () {
  if (!this.isPlaying) {
    return;
  }

  this.isPlaying = false;
  this.isPaused = false;

  THREE.AnimationHandler.stop(this);
};

Animator.prototype.reset = function () {
  for (var h = 0, hl = this.objects.length; h < hl; h++) {
    var object = this.objects[h];

    object.matrixAutoUpdate = true;

    if (object.animatorCache === undefined) {
      object.animatorCache = {
        blending: {
          positionWeight: 0.0,
          quaternionWeight: 0.0,
          scaleWeight: 0.0
        }
      }
    }
  }
};

Animator.prototype.resetBlendWeights = function () {
  for (var h = 0, hl = this.objects.length; h < hl; h++) {
    var object = this.objects[h];

    if (object.animatorCache !== undefined) {
      object.animatorCache.blending.positionWeight = 0.0;
      object.animatorCache.blending.quaternionWeight = 0.0;
      object.animatorCache.blending.scaleWeight = 0.0;
    }
  }
};

Animator.prototype._applyChannel = function(index, type, value) {
  var object = this.objects[index];
  var blending = object.animatorCache.blending;

  object.matrixAutoUpdate = true;
  object.matrixWorldNeedsUpdate = true;

  if (type === AnimationData.CHANNEL_TYPE.Position) {
    if (blending.positionWeight === 0) {
      object.position.copy(value);
      blending.positionWeight = this.weight;
    } else {
      var proportionalWeight = this.weight / (this.weight + blending.positionWeight);
      object.position.lerp(value, proportionalWeight);
      blending.positionWeight += this.weight;
    }
  } else if (AnimationData.CHANNEL_TYPE.Rotation) {
    if (blending.quaternionWeight === 0) {
      object.quaternion.copy(value);
      blending.quaternionWeight = this.weight;
    } else {
      var proportionalWeight = this.weight / (this.weight + blending.quaternionWeight);
      object.quaternion.slerp(value, proportionalWeight);
      blending.quaternionWeight += this.weight;
    }
  } else if (AnimationData.CHANNEL_TYPE.Scale) {
    if (blending.scaleWeight === 0) {
      object.scale.copy(value);
      blending.scaleWeight = this.weight;
    } else {
      var proportionalWeight = this.weight / (this.weight + blending.scaleWeight);
      object.scale.lerp(value, proportionalWeight);
      blending.scaleWeight += this.weight;
    }
  }
};

var _SLERPER = new THREE.Quaternion();
var _V3LERPER = new THREE.Vector3();
var _V2LERPER = new THREE.Vector2();
Animator.prototype._applyChannels = function(channels, thisFrame, nextFrame, frameRatio) {
  for (var i = 0; i < channels.length; ++i) {
    var c = channels[i];

    var f0 = c.frames[thisFrame];
    var f1 = c.frames[nextFrame];
    var f = null;
    if (frameRatio === 0) {
      f = f0;
    } else {
      if (f0 instanceof THREE.Quaternion) {
        f = THREE.Quaternion.slerp(f0, f1, _SLERPER, frameRatio);
      } else if (f0 instanceof THREE.Vector3) {
        f = _V3LERPER.copy(f0).lerp(f1, frameRatio);
      } else if (f0 instanceof THREE.Vector2) {
        f = _V2LERPER.copy(f0).lerp(f1, frameRatio);
      } else if (f0 instanceof Number) {
        f = f0 * (1 - frameRatio) + f1 * frameRatio;
      } else {
        f = f0;
      }
    }
    this._applyChannel(c.index, c.type, f);
  }
};

Animator.prototype.update = function (delta) {
  if (this.isPlaying === false) return delta;

  if (!this.isPaused) {
    this.currentTime += delta * this.timeScale;

    // If this is the last frame, we have to stop at the last frame, rather
    //   then blending back towards frame 0, remove that time.
    var endTime = this.length;
    if (this.loop === 1) {
      endTime = (this.data.frameCount - 1) / this.data.fps;
    }

    if (this.currentTime >= endTime || this.currentTime < 0) {
      if (this.loop === 0 || this.loop > 1) {
        if (this.loop !== 0) {
          this.loop--;
        }

        this.currentTime %= this.length;

        if (this.currentTime < 0) {
          this.currentTime += this.length;
        }

        this.reset();
        this.emit('restart');
      } else {
        var timeConsumed = endTime - this.currentTime;
        this.currentTime = endTime;
        this.pause();
        this.emit('finish');
        return delta - timeConsumed;
      }
    }
  }

  if (this.weight === 0) {
    return 0.0;
  }

  var thisFrame = Math.floor(this.currentTime * this.data.fps);
  // TODO: THIS SHOULD NOT BE NEEDED
  if (thisFrame >= this.data.frameCount) {
    thisFrame = this.data.frameCount - 1;
  }
  var nextFrame = thisFrame + 1;
  if (nextFrame >= this.data.frameCount) {
    if (this.loop) {
      nextFrame -= this.data.frameCount;
    } else {
      nextFrame = thisFrame;
    }
  }

  var frameRatio = ( this.currentTime - (thisFrame / this.data.fps) ) / (1 / this.data.fps);
  this._applyChannels(this.data.channels, thisFrame, nextFrame, frameRatio);

  return 0.0;
};

module.exports = Animator;
<|endoftext|>


<commit_before>'use strict';

module.exports = function (grunt) {

    require('load-grunt-tasks')(grunt);

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        project: {
            app: 'app',
            assets: '<%= project.app %>/assets',
            scss: '<%= project.assets %>/sass/app.scss',
            tmp: '.tmp',
            dist: 'dist'
        },

        clean: {
            dist: [
                '<%= project.dist %>/assets/',
                '<%= project.dist %>/bower_components/',
                '<%= project.dist %>/components/',
                '<%= project.dist %>/js/',
                '<%= project.dist %>/templates/',
                '<%= project.dist %>/index.html'
            ],
            tmp: ['<%= project.tmp %>/']
        },

        copy: {
            prod: {
                files: [
                    {
                        cwd: '<%= project.assets %>/css/',
                        expand: true,
                        src: ['**.*'],
                        dest: '<%= project.dist %>/assets/css/'
                    },
                    {
                        cwd: '<%= project.app %>/',
                        expand: true,
                        src: ['**/*.html'],
                        dest: '<%= project.dist %>/'
                    },
                    {
                        src: '<%= project.app %>/components/config/config.json',
                        dest: '<%= project.dist %>/components/config/config.json'
                    },
                    {
                        src: '<%= project.app %>/components/config/developmentConfig.json',
                        dest: '<%= project.dist %>/components/config/developmentConfig.json'
                    },
                    {
                        src: '<%= project.app %>/index.html',
                        dest: '<%= project.dist %>/index.html'
                    }
                ]
            },
        },

        sass: {
            dev: {
                options: {
                    style: 'expanded',
                    compass: false
                },
                files: {
                    '<%= project.assets %>/css/app.css': '<%= project.scss %>'
                }
            }
        },

        jshint: { // configure the task
            options: {
                node: true,
                loopfunc: true,
                globals: {
                    document: true,
                    angular: true,
                    $: true,
                    describe: true,
                    it: true,
                    expect: true,
                    beforeEach: true,
                    inject: true
                },
                force: true
            },
            all: [
                'karma.conf.js',
                'Gruntfile.js',
                '<%= project.app %>/app.js',
                '<%= project.app %>/**/*.js',
                '!<%= project.app %>/bower_components/**',
            ]
        },

        useminPrepare: {
            html: {
                src: ['<%= project.app %>/index.html']
            },
            options: {
                dest: '<%= project.dist %>/'
            }
        },

        usemin: {
            html: '<%= project.dist %>/index.html'
        },

        concat: {
            generated: {
                // Will be generated with usemin:html
                nonull: true
            }
        },

        cssmin: {
            generated: {
                // Will be generated with usemin:html
                nonull: true
            }
        },

        // Minify and concatenate bansho in one file
        uglify: {
            generated: {
                // Will be generated with usemin:html
                nonull: true
            },
            options: {
                mangle: true
            }
        },

        watch: {
            development: {
                files: [
                    '<%= project.app %>/**/*.js',
                    '<%= project.app %>/**/*.html',
                    '<%= project.assets %>/sass/{,*/}*.{scss,sass}'
                ],
                tasks: ['sass:dev', 'jshint:all']
            },
            staging: {
                files: [
                    '<%= project.app %>/**/*.js',
                    '<%= project.app %>/**/*.html',
                    '<%= project.assets %>/sass/{,*/}*.{scss,sass}'
                ],
                tasks: ['production']
            },
            options: {
                livereload: true
            }
        }
    });

    grunt.registerTask('default', ['development']);

    grunt.registerTask('development', [
        'sass',
        'jshint:all',
        'watch:development'
    ]);

    grunt.registerTask('staging', [
        'production',
        'watch:development'
    ]);

    grunt.registerTask('production', [
        'clean',
        'sass',
        'copy:prod' ,
        'useminPrepare:html',
        'concat:generated',
        'uglify:generated',
        'cssmin:generated',
        'usemin:html'
    ]);
};
<commit_msg>Fix dist generation<commit_after>'use strict';

module.exports = function (grunt) {

    require('load-grunt-tasks')(grunt);

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        project: {
            app: 'app',
            assets: '<%= project.app %>/assets',
            scss: '<%= project.assets %>/sass/app.scss',
            tmp: '.tmp',
            dist: 'dist'
        },

        clean: {
            dist: [
                '<%= project.dist %>/assets/',
                '<%= project.dist %>/bower_components/',
                '<%= project.dist %>/components/',
                '<%= project.dist %>/js/',
                '<%= project.dist %>/templates/',
                '<%= project.dist %>/index.html'
            ],
            tmp: ['<%= project.tmp %>/']
        },

        copy: {
            prod: {
                files: [
                    {
                        cwd: '<%= project.assets %>/css/',
                        expand: true,
                        src: ['**.*'],
                        dest: '<%= project.dist %>/assets/css/'
                    },
                    {
                        cwd: '<%= project.assets %>/images/',
                        expand: true,
                        src: ['**.*'],
                        dest: '<%= project.dist %>/assets/images/'
                    },
                    {
                        cwd: '<%= project.app %>/',
                        expand: true,
                        src: ['**/*.html'],
                        dest: '<%= project.dist %>/'
                    },
                    {
                        src: '<%= project.app %>/components/config/config.json',
                        dest: '<%= project.dist %>/components/config/config.json'
                    },
                    {
                        src: '<%= project.app %>/components/config/developmentConfig.json',
                        dest: '<%= project.dist %>/components/config/developmentConfig.json'
                    },
                    {
                        src: '<%= project.app %>/index.html',
                        dest: '<%= project.dist %>/index.html'
                    }
                ]
            },
        },

        sass: {
            dev: {
                options: {
                    style: 'expanded',
                    compass: false
                },
                files: {
                    '<%= project.assets %>/css/app.css': '<%= project.scss %>'
                }
            }
        },

        jshint: { // configure the task
            options: {
                node: true,
                loopfunc: true,
                globals: {
                    document: true,
                    angular: true,
                    $: true,
                    describe: true,
                    it: true,
                    expect: true,
                    beforeEach: true,
                    inject: true
                },
                force: true
            },
            all: [
                'karma.conf.js',
                'Gruntfile.js',
                '<%= project.app %>/app.js',
                '<%= project.app %>/**/*.js',
                '!<%= project.app %>/bower_components/**',
            ]
        },

        useminPrepare: {
            html: {
                src: ['<%= project.app %>/index.html']
            },
            options: {
                dest: '<%= project.dist %>/'
            }
        },

        usemin: {
            html: '<%= project.dist %>/index.html'
        },

        concat: {
            generated: {
                // Will be generated with usemin:html
                nonull: true
            }
        },

        cssmin: {
            generated: {
                // Will be generated with usemin:html
                nonull: true
            }
        },

        // Minify and concatenate bansho in one file
        uglify: {
            generated: {
                // Will be generated with usemin:html
                nonull: true
            },
            options: {
                mangle: true
            }
        },

        watch: {
            development: {
                files: [
                    '<%= project.app %>/**/*.js',
                    '<%= project.app %>/**/*.html',
                    '<%= project.assets %>/sass/{,*/}*.{scss,sass}'
                ],
                tasks: ['sass:dev', 'jshint:all']
            },
            staging: {
                files: [
                    '<%= project.app %>/**/*.js',
                    '<%= project.app %>/**/*.html',
                    '<%= project.assets %>/sass/{,*/}*.{scss,sass}'
                ],
                tasks: ['production']
            },
            options: {
                livereload: true
            }
        }
    });

    grunt.registerTask('default', ['development']);

    grunt.registerTask('development', [
        'sass',
        'jshint:all',
        'watch:development'
    ]);

    grunt.registerTask('staging', [
        'production',
        'watch:development'
    ]);

    grunt.registerTask('production', [
        'clean',
        'sass',
        'copy:prod' ,
        'useminPrepare:html',
        'concat:generated',
        'uglify:generated',
        'cssmin:generated',
        'usemin:html'
    ]);
};
<|endoftext|>


<commit_before>/*
 * redis.js: Redis storage engine for nconf configuration(s)
 *
 * (C) 2011, Charlie Robbins
 *
 */

var async = require('async'),
    redis = require('redis'),
    nconf = require('nconf'),
    Memory = require('./memory').Memory;

//
// ### function Redis (options)
// #### @options {Object} Options for this instance
// Constructor function for the Redis nconf store which maintains
// a nested Redis key structure based on key delimiters `:`.
//
// e.g.
//     my:nested:key, 'value'
//       namespace:keys        ==> ['my']
//       namespace:nested:keys ==> ['key']
//       namespace:nested:key  ==> 'value'
//
var Redis = exports.Redis = function (options) {
  options        = options || {};
  this.type      = 'redis';
  this.namespace = options.namespace || 'nconf';
  this.host      = options.host || 'localhost';
  this.port      = options.port || 6379;
  this.ttl       = options.ttl  || 60 * 60 * 1000;
  this.cache     = new Memory();
  this.redis     = redis.createClient(options.port, options.host);

  if (options.auth) {
    this.redis.auth(options.auth);
  }

  // Suppress errors from the Redis client
  this.redis.on('error', function (err) {
    require('eyes').inspect(err);
  });
};

//
// ### function get (key, callback)
// #### @key {string} Key to retrieve for this instance.
// #### @callback {function} Continuation to respond to when complete.
// Retrieves the value for the specified key (if any).
//
Redis.prototype.get = function (key, callback) {
  var self    = this,
      result  = {},
      now     = Date.now(),
      mtime   = this.cache.mtimes[key],
      fullKey = nconf.key(this.namespace, key);

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  //
  // If the key exists in the cache and the ttl is less than
  // the value set for this instance, return from the cache.
  //
  if (mtime && now - mtime < this.ttl) {
    return callback(null, this.cache.get(key));
  }

  //
  // Get the set of all children keys for the `key` supplied. If the value
  // to be returned is an Object, this list will not be empty.
  //
  this.redis.smembers(nconf.key(fullKey, 'keys'), function (err, keys) {
    function addValue (source, next) {
      self.get(nconf.key(key, source), function (err, value) {
        if (err) {
          return next(err);
        }

        result[source] = value;
        next();
      });
    }

    if (keys && keys.length > 0) {
      //
      // If the value to be retrieved is an Object, recursively attempt
      // to get the value from redis. Here we use a recursive call to `this.get`
      // to support nested Object keys.
      //
      async.forEach(keys, addValue, function (err) {
        if (err) {
          return callback(err);
        }

        self.cache.set(key, result);
        callback(null, result);
      })
    }
    else {
      //
      // If there are no keys, then the value to be retrieved is a literal
      // and we can simply return the value from redis directly.
      //
      self.redis.get(fullKey, function (err, value) {
        if (err) {
          return callback(err);
        }

        result = JSON.parse(value);
        if (result) {
          self.cache.set(key, result);
        }

        callback(null, result);
      });
    }
  });
};

//
// ### function set (key, value, callback)
// #### @key {string} Key to set in this instance
// #### @value {literal|Object} Value for the specified key
// #### @callback {function} Continuation to respond to when complete.
// Sets the `value` for the specified `key` in this instance.
//
Redis.prototype.set = function (key, value, callback) {
  var self = this,
      path = nconf.path(key);

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  function addKey (partial, next) {
    var index  = path.indexOf(partial),
        base   = [self.namespace].concat(path.slice(0, index)),
        parent = nconf.key.apply(null, base.concat(['keys']));

    self.redis.sadd(parent, partial, next);
  };

  //
  // Iterate over the entire key path and add each key to the
  // parent key-set if it doesn't exist already.
  //
  async.forEach(path, addKey, function (err) {
    if (err) {
      return callback(err);
    }

    var fullKey = nconf.key(self.namespace, key);

    if (!Array.isArray(value) && typeof value === 'object') {
      //
      // If the value is an `Object` (and not an `Array`) then
      // nest into the value and set the child keys appropriately.
      // This is done for efficient lookup when setting Object keys.
      // (i.e. If you set and Object then wish to later retrieve only a
      // member of that Object, the entire Object need not be retrieved).
      //
      self._setObject(fullKey, value, callback);
    }
    else {
      //
      // If the value is a simple literal (or an `Array`) then JSON
      // stringify it and put it into Redis.
      //
      value = JSON.stringify(value);
      self.cache.set(key, value);
      self.redis.set(fullKey, value, callback);
    }
  });
};

//
// ### function clear (key, callback)
// #### @key {string} Key to remove from this instance
// #### @callback {function} Continuation to respond to when complete.
// Removes the value for the specified `key` from this instance.
//
Redis.prototype.clear = function (key, callback) {
  var self    = this,
      result  = {},
      path    = [this.namespace].concat(nconf.path(key)),
      last    = path.pop(),
      fullKey = nconf.key(this.namespace, key);

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  //
  // Clear the key from the cache for this instance
  //
  this.cache.clear(key);

  //
  // Remove the `key` from the parent set of keys.
  //
  this.redis.srem(nconf.key.apply(null, path.concat(['keys'])), last, function (err) {
    //
    // Remove the value from redis by iterating over the set of keys (if any)
    // and deleting each value. If no keys, then just delete the simple literal.
    //
    self.redis.smembers(nconf.key(fullKey, 'keys'), function (err, keys) {
      function removeValue (child, next) {
        //
        // Recursively call `self.clear` here to ensure we remove any
        // nested Objects completely from this instance.
        //
        self.clear(nconf.key(key, child), next);
      }

      if (keys && keys.length > 0) {
        //
        // If there are child keys then iterate over them,
        // removing each child along the way.
        //
        async.forEach(keys, removeValue, callback);
      }
      else {
        //
        // Otherwise if this is just a simple literal, then
        // simply remove it from Redis directly.
        //
        self.redis.del(fullKey, callback);
      }
    });
  });
};

//
// ### function save (value, callback)
// #### @value {Object} Config object to set for this instance
// #### @callback {function} Continuation to respond to when complete.
// Removes any existing configuration settings that may exist in this
// instance and then adds all key-value pairs in `value`.
//
Redis.prototype.save = function (value, callback) {
  if (Array.isArray(value) || typeof value !== 'object') {
    return callback(new Error('`value` to be saved must be an object.'));
  }

  var self = this,
      keys = Object.keys(value);

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  //
  // Clear all existing keys associated with this instance.
  //
  this.reset(function (err) {
    if (err) {
      return callback(err);
    }

    //
    // Iterate over the keys in the new value, setting each of them.
    //
    async.forEach(keys, function (key, next) {
      self.set(key, value[key], next);
    }, callback);
  });
};

//
// ### function load (callback)
// #### @callback {function} Continuation to respond to when complete.
// Responds with an Object representing all keys associated in this instance.
//
Redis.prototype.load = function (callback) {
  var self   = this,
      result = {};

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  this.redis.smembers(nconf.key(this.namespace, 'keys'), function (err, keys) {
    if (err) {
      return callback(err);
    }

    function addValue (key, next) {
      self.get(key, function (err, value) {
        if (err) {
          return next(err);
        }

        result[key] = value;
        next();
      });
    }

    async.forEach(keys, addValue, function (err) {
      return err ? callback(err) : callback(null, result);
    });
  });
};

//
// ### function reset (callback)
// #### @callback {function} Continuation to respond to when complete.
// Clears all keys associated with this instance.
//
Redis.prototype.reset = function (callback) {
  var self = this;

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  //
  // Get the list of of top-level keys, then clear each of them
  //
  this.redis.smembers(nconf.key(this.namespace, 'keys'), function (err, existing) {
    if (err) {
      return callback(err);
    }

    async.forEach(existing, function (key, next) {
      self.clear(key, next);
    }, callback);
  });
};

//
// ### @private function _setObject (key, value, callback)
// #### @key {string} Key to set in this instance
// #### @value {Object} Value for the specified key
// #### @callback {function} Continuation to respond to when complete.
// Internal helper function for setting all keys of a nested object.
//
Redis.prototype._setObject = function (key, value, callback) {
  var self = this,
      keys = Object.keys(value);

  function addValue (child, next) {
    //
    // Add the child key to the parent key-set, then set the value.
    // Recursively call `_setObject` in the event of nested Object(s).
    //
    self.redis.sadd(nconf.key(key, 'keys'), child, function (err) {
      if (err) {
        return next(err);
      }

      var fullKey = nconf.key(key, child),
          childValue = value[child];

      if (!Array.isArray(childValue) && typeof childValue === 'object') {
        self._setObject(fullKey, childValue, next);
      }
      else {
        childValue = JSON.stringify(childValue);
        self.redis.set(fullKey, childValue, next);
      }
    });
  }

  //
  // Iterate over the keys of the Object and set the appropriate values.
  //
  async.forEach(keys, addValue, function (err) {
    return err ? callback(err) : callback();
  });
};<commit_msg>[fix] Dont allow `async.forEach` to be called on undefined or null arrays<commit_after>/*
 * redis.js: Redis storage engine for nconf configuration(s)
 *
 * (C) 2011, Charlie Robbins
 *
 */

var async = require('async'),
    redis = require('redis'),
    nconf = require('nconf'),
    Memory = require('./memory').Memory;

//
// ### function Redis (options)
// #### @options {Object} Options for this instance
// Constructor function for the Redis nconf store which maintains
// a nested Redis key structure based on key delimiters `:`.
//
// e.g.
//     my:nested:key, 'value'
//       namespace:keys        ==> ['my']
//       namespace:nested:keys ==> ['key']
//       namespace:nested:key  ==> 'value'
//
var Redis = exports.Redis = function (options) {
  options        = options || {};
  this.type      = 'redis';
  this.namespace = options.namespace || 'nconf';
  this.host      = options.host || 'localhost';
  this.port      = options.port || 6379;
  this.ttl       = options.ttl  || 60 * 60 * 1000;
  this.cache     = new Memory();
  this.redis     = redis.createClient(options.port, options.host);

  if (options.auth) {
    this.redis.auth(options.auth);
  }

  // Suppress errors from the Redis client
  this.redis.on('error', function (err) {
    require('eyes').inspect(err);
  });
};

//
// ### function get (key, callback)
// #### @key {string} Key to retrieve for this instance.
// #### @callback {function} Continuation to respond to when complete.
// Retrieves the value for the specified key (if any).
//
Redis.prototype.get = function (key, callback) {
  var self    = this,
      result  = {},
      now     = Date.now(),
      mtime   = this.cache.mtimes[key],
      fullKey = nconf.key(this.namespace, key);

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  //
  // If the key exists in the cache and the ttl is less than
  // the value set for this instance, return from the cache.
  //
  if (mtime && now - mtime < this.ttl) {
    return callback(null, this.cache.get(key));
  }

  //
  // Get the set of all children keys for the `key` supplied. If the value
  // to be returned is an Object, this list will not be empty.
  //
  this.redis.smembers(nconf.key(fullKey, 'keys'), function (err, keys) {
    function addValue (source, next) {
      self.get(nconf.key(key, source), function (err, value) {
        if (err) {
          return next(err);
        }

        result[source] = value;
        next();
      });
    }

    if (keys && keys.length > 0) {
      //
      // If the value to be retrieved is an Object, recursively attempt
      // to get the value from redis. Here we use a recursive call to `this.get`
      // to support nested Object keys.
      //
      async.forEach(keys, addValue, function (err) {
        if (err) {
          return callback(err);
        }

        self.cache.set(key, result);
        callback(null, result);
      })
    }
    else {
      //
      // If there are no keys, then the value to be retrieved is a literal
      // and we can simply return the value from redis directly.
      //
      self.redis.get(fullKey, function (err, value) {
        if (err) {
          return callback(err);
        }

        result = JSON.parse(value);
        if (result) {
          self.cache.set(key, result);
        }

        callback(null, result);
      });
    }
  });
};

//
// ### function set (key, value, callback)
// #### @key {string} Key to set in this instance
// #### @value {literal|Object} Value for the specified key
// #### @callback {function} Continuation to respond to when complete.
// Sets the `value` for the specified `key` in this instance.
//
Redis.prototype.set = function (key, value, callback) {
  var self = this,
      path = nconf.path(key);

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  function addKey (partial, next) {
    var index  = path.indexOf(partial),
        base   = [self.namespace].concat(path.slice(0, index)),
        parent = nconf.key.apply(null, base.concat(['keys']));

    self.redis.sadd(parent, partial, next);
  };

  //
  // Iterate over the entire key path and add each key to the
  // parent key-set if it doesn't exist already.
  //
  async.forEach(path, addKey, function (err) {
    if (err) {
      return callback(err);
    }

    var fullKey = nconf.key(self.namespace, key);

    if (!Array.isArray(value) && typeof value === 'object') {
      //
      // If the value is an `Object` (and not an `Array`) then
      // nest into the value and set the child keys appropriately.
      // This is done for efficient lookup when setting Object keys.
      // (i.e. If you set and Object then wish to later retrieve only a
      // member of that Object, the entire Object need not be retrieved).
      //
      self._setObject(fullKey, value, callback);
    }
    else {
      //
      // If the value is a simple literal (or an `Array`) then JSON
      // stringify it and put it into Redis.
      //
      value = JSON.stringify(value);
      self.cache.set(key, value);
      self.redis.set(fullKey, value, callback);
    }
  });
};

//
// ### function clear (key, callback)
// #### @key {string} Key to remove from this instance
// #### @callback {function} Continuation to respond to when complete.
// Removes the value for the specified `key` from this instance.
//
Redis.prototype.clear = function (key, callback) {
  var self    = this,
      result  = {},
      path    = [this.namespace].concat(nconf.path(key)),
      last    = path.pop(),
      fullKey = nconf.key(this.namespace, key);

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  //
  // Clear the key from the cache for this instance
  //
  this.cache.clear(key);

  //
  // Remove the `key` from the parent set of keys.
  //
  this.redis.srem(nconf.key.apply(null, path.concat(['keys'])), last, function (err) {
    //
    // Remove the value from redis by iterating over the set of keys (if any)
    // and deleting each value. If no keys, then just delete the simple literal.
    //
    self.redis.smembers(nconf.key(fullKey, 'keys'), function (err, keys) {
      function removeValue (child, next) {
        //
        // Recursively call `self.clear` here to ensure we remove any
        // nested Objects completely from this instance.
        //
        self.clear(nconf.key(key, child), next);
      }

      if (keys && keys.length > 0) {
        //
        // If there are child keys then iterate over them,
        // removing each child along the way.
        //
        async.forEach(keys, removeValue, callback);
      }
      else {
        //
        // Otherwise if this is just a simple literal, then
        // simply remove it from Redis directly.
        //
        self.redis.del(fullKey, callback);
      }
    });
  });
};

//
// ### function save (value, callback)
// #### @value {Object} Config object to set for this instance
// #### @callback {function} Continuation to respond to when complete.
// Removes any existing configuration settings that may exist in this
// instance and then adds all key-value pairs in `value`.
//
Redis.prototype.save = function (value, callback) {
  if (Array.isArray(value) || typeof value !== 'object') {
    return callback(new Error('`value` to be saved must be an object.'));
  }

  var self = this,
      keys = Object.keys(value);

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  //
  // Clear all existing keys associated with this instance.
  //
  this.reset(function (err) {
    if (err) {
      return callback(err);
    }

    //
    // Iterate over the keys in the new value, setting each of them.
    //
    async.forEach(keys, function (key, next) {
      self.set(key, value[key], next);
    }, callback);
  });
};

//
// ### function load (callback)
// #### @callback {function} Continuation to respond to when complete.
// Responds with an Object representing all keys associated in this instance.
//
Redis.prototype.load = function (callback) {
  var self   = this,
      result = {};

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  this.redis.smembers(nconf.key(this.namespace, 'keys'), function (err, keys) {
    if (err) {
      return callback(err);
    }

    function addValue (key, next) {
      self.get(key, function (err, value) {
        if (err) {
          return next(err);
        }

        result[key] = value;
        next();
      });
    }

    keys = keys || [];
    async.forEach(keys, addValue, function (err) {
      return err ? callback(err) : callback(null, result);
    });
  });
};

//
// ### function reset (callback)
// #### @callback {function} Continuation to respond to when complete.
// Clears all keys associated with this instance.
//
Redis.prototype.reset = function (callback) {
  var self = this;

  // Set the callback if not provided for "fire and forget"
  callback = callback || function () { };

  //
  // Get the list of of top-level keys, then clear each of them
  //
  this.redis.smembers(nconf.key(this.namespace, 'keys'), function (err, existing) {
    if (err) {
      return callback(err);
    }

    existing = existing || [];
    async.forEach(existing, function (key, next) {
      self.clear(key, next);
    }, callback);
  });
};

//
// ### @private function _setObject (key, value, callback)
// #### @key {string} Key to set in this instance
// #### @value {Object} Value for the specified key
// #### @callback {function} Continuation to respond to when complete.
// Internal helper function for setting all keys of a nested object.
//
Redis.prototype._setObject = function (key, value, callback) {
  var self = this,
      keys = Object.keys(value);

  function addValue (child, next) {
    //
    // Add the child key to the parent key-set, then set the value.
    // Recursively call `_setObject` in the event of nested Object(s).
    //
    self.redis.sadd(nconf.key(key, 'keys'), child, function (err) {
      if (err) {
        return next(err);
      }

      var fullKey = nconf.key(key, child),
          childValue = value[child];

      if (!Array.isArray(childValue) && typeof childValue === 'object') {
        self._setObject(fullKey, childValue, next);
      }
      else {
        childValue = JSON.stringify(childValue);
        self.redis.set(fullKey, childValue, next);
      }
    });
  }

  //
  // Iterate over the keys of the Object and set the appropriate values.
  //
  async.forEach(keys, addValue, function (err) {
    return err ? callback(err) : callback();
  });
};<|endoftext|>


<commit_before>'use strict';
var path = require('path');
var gulp = require('gulp');
var eslint = require('gulp-eslint');
var mocha = require('gulp-mocha');
var istanbul = require('gulp-istanbul');
var nsp = require('gulp-nsp');
var coveralls = require('gulp-coveralls');

gulp.task('static', function() {
  return gulp.src('src/**/*.js')
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failAfterError());
});

gulp.task('nsp', function(cb) {
  nsp({package: path.join(__dirname, 'package.json')}, cb);
});

var sources = ['src/index.js', 'src/adapters/postgres.js'];

if (!process.env.CI) {
  sources.push('src/adapters/mssql.js');
}

gulp.task('pre-test', function() {
  return gulp.src(sources)
    .pipe(istanbul({includeUntested: true}))
    .pipe(istanbul.hookRequire());
});

gulp.task('test', ['pre-test'], function(cb) {
  var error;
  gulp.src('test/index.js')
    .pipe(mocha({reporter: 'spec', timeout: 15000}))
    .on('error', function(e) {
      error = e;
      cb(error);
    })
    .pipe(istanbul.writeReports({
      reporters: ['json', 'text', 'text-summary', 'lcov']
    }))
    .on('end', function() {
      if (!error) cb();
    });
});

gulp.task('coveralls', ['test'], function() {
  if (!process.env.CI) {
    return;
  }

  return gulp.src(path.join(__dirname, 'coverage/lcov.info'))
    .pipe(coveralls());
});

gulp.task('prepublish', ['nsp']);
gulp.task('default', ['static', 'test', 'coveralls']);
<commit_msg>Better get out at first error<commit_after>'use strict';
var path = require('path');
var gulp = require('gulp');
var eslint = require('gulp-eslint');
var mocha = require('gulp-mocha');
var istanbul = require('gulp-istanbul');
var nsp = require('gulp-nsp');
var coveralls = require('gulp-coveralls');

gulp.task('static', function() {
  return gulp.src('src/**/*.js')
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failAfterError());
});

gulp.task('nsp', function(cb) {
  nsp({package: path.join(__dirname, 'package.json')}, cb);
});

var sources = ['src/index.js', 'src/adapters/postgres.js'];

if (!process.env.CI) {
  sources.push('src/adapters/mssql.js');
}

gulp.task('pre-test', function() {
  return gulp.src(sources)
    .pipe(istanbul({includeUntested: true}))
    .pipe(istanbul.hookRequire());
});

gulp.task('test', ['pre-test'], function(cb) {
  var error;
  gulp.src('test/index.js')
    .pipe(mocha({reporter: 'spec', bail: true, timeout: 15000}))
    .on('error', function(e) {
      error = e;
      cb(error);
    })
    .pipe(istanbul.writeReports({
      reporters: ['json', 'text', 'text-summary', 'lcov']
    }))
    .on('end', function() {
      if (!error) cb();
    });
});

gulp.task('coveralls', ['test'], function() {
  if (!process.env.CI) {
    return;
  }

  return gulp.src(path.join(__dirname, 'coverage/lcov.info'))
    .pipe(coveralls());
});

gulp.task('prepublish', ['nsp']);
gulp.task('default', ['static', 'test', 'coveralls']);
<|endoftext|>


<commit_before>const { createPrompt, useState, useKeypress } = require('@inquirer/core/hooks');
const { usePrefix } = require('@inquirer/core/lib/prefix');
const { isEnterKey, isBackspaceKey } = require('@inquirer/core/lib/key');
const chalk = require('chalk');

module.exports = createPrompt((config, done) => {
  const [status, setStatus] = useState('pending');
  const [defaultValue, setDefaultValue] = useState(config.default);
  const [errorMsg, setError] = useState();
  const [value, setValue] = useState('');

  const isLoading = status === 'loading';
  const prefix = usePrefix(isLoading);

  useKeypress(async (key, rl) => {
    // Ignore keypress while our prompt is doing other processing.
    if (status !== 'pending') {
      return;
    }

    if (isEnterKey(key)) {
      const answer = value || defaultValue || '';
      setStatus('loading');
      const isValid = await config.validate(answer);
      if (isValid === true) {
        setValue(answer);
        setStatus('done');
        done(answer);
      } else {
        // TODO: Can we keep the value after validation failure?
        // `rl.line = value` works but it looses the cursor position.
        setValue('');
        setError(isValid || 'You must provide a valid value');
        setStatus('pending');
      }
    } else if (isBackspaceKey(key) && !value) {
      setDefaultValue(undefined);
    } else {
      setValue(rl.line);
      setError(undefined);
    }
  });

  const message = chalk.bold(config.message);
  let formattedValue = value;
  if (typeof config.transformer === 'function') {
    formattedValue = config.transformer(value, { isFinal: status === 'done' });
  } else if (status === 'done') {
    formattedValue = chalk.cyan(value);
  }

  let defaultStr = '';
  if (defaultValue && status !== 'done' && !value) {
    defaultStr = chalk.dim(` (${defaultValue})`);
  }

  let error = '';
  if (errorMsg) {
    error = chalk.red(`> ${errorMsg}`);
  }

  return [`${prefix} ${message}${defaultStr} ${formattedValue}`, error];
});
<commit_msg>Fix input prompt final answer formatting<commit_after>const { createPrompt, useState, useKeypress } = require('@inquirer/core/hooks');
const { usePrefix } = require('@inquirer/core/lib/prefix');
const { isEnterKey, isBackspaceKey } = require('@inquirer/core/lib/key');
const chalk = require('chalk');

module.exports = createPrompt((config, done) => {
  const [status, setStatus] = useState('pending');
  const [defaultValue, setDefaultValue] = useState(config.default);
  const [errorMsg, setError] = useState();
  const [value, setValue] = useState('');

  const isLoading = status === 'loading';
  const prefix = usePrefix(isLoading);

  useKeypress(async (key, rl) => {
    // Ignore keypress while our prompt is doing other processing.
    if (status !== 'pending') {
      return;
    }

    if (isEnterKey(key)) {
      const answer = value || defaultValue || '';
      setStatus('loading');
      const isValid = await config.validate(answer);
      if (isValid === true) {
        setValue(answer);
        setStatus('done');
        done(answer);
      } else {
        // TODO: Can we keep the value after validation failure?
        // `rl.line = value` works but it looses the cursor position.
        setValue('');
        setError(isValid || 'You must provide a valid value');
        setStatus('pending');
      }
    } else if (isBackspaceKey(key) && !value) {
      setDefaultValue(undefined);
    } else {
      setValue(rl.line);
      setError(undefined);
    }
  });

  const message = chalk.bold(config.message);
  let formattedValue = value;
  if (typeof config.transformer === 'function') {
    formattedValue = config.transformer(value, { isFinal: status === 'done' });
  }
  if (status === 'done') {
    formattedValue = chalk.cyan(formattedValue);
  }

  let defaultStr = '';
  if (defaultValue && status !== 'done' && !value) {
    defaultStr = chalk.dim(` (${defaultValue})`);
  }

  let error = '';
  if (errorMsg) {
    error = chalk.red(`> ${errorMsg}`);
  }

  return [`${prefix} ${message}${defaultStr} ${formattedValue}`, error];
});
<|endoftext|>


<commit_before>/**
 * Constructor for googleLayers widget which controls the display options of the plugin.
 * @constructor
 * @param {GEPlugin} plugin Reference to the google earth plugin instance.
 * @param {HTMLFormElement} options The form that controls options. See GEOptions
 * @param {HTMLFormElement} layers The form that controls which layers are displayed. See layer reference
 */
lingcod.map.googleLayers = function(ge, options_form, layers_form){
    this.layers = $(layers_form);
    this.options = $(options_form);
    this.get = ge;
    var self = this;
    $(this.layers).find('input').click(function(){
        self.updateLayers()
    });

    $(this.options).find('input').click(function(){
        self.updateOptions()
    });

    this.updateLayers();
    this.updateOptions();
}

/**
 * Looks at the layers form and updates the map to match form values
 */
lingcod.map.googleLayers.prototype.updateLayers = function(){
    this.layers.find('input').each(function(){
        ge.getLayerRoot().enableLayerById(ge[$(this).attr('name')], $(this).attr('checked'));
    });
};

/**
 * Looks at the options form and updates the map to match form values. The
 * name of the input element should match the setXVisibility function on
 * ge.getOptions();.
 * for example:
 *
 *      <input name="setGridVisibility" />
 */
lingcod.map.googleLayers.prototype.updateOptions = function(){
    var options = ge.getOptions();
    this.options.find('input').each(function(){
        var $input = $(this);
        var name = $input.attr('name');
        if(name != 'nav' && name != 'sun'){
            options[name](this.checked);
        }
    });

    if(this.options.find('input[name="nav"]').length){
        if (this.options.find('input[name="nav"]:checked').length) {
            ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);
        }else{
            ge.getNavigationControl().setVisibility(ge.VISIBILITY_HIDE);
        }
    }

    if(this.options.find('input[name="sun"]').length){
        if(this.options.find('input[name="sun"]:checked').length){
            ge.getSun().setVisibility(true);
        }else{
            ge.getSun().setVisibility(false);
        }
    }
};

/**
 * Unbinds all event listeners.
 */
lingcod.map.googleLayers.prototype.destroy = function(){
    $(this.layers).find('input').unbind('click');
    $(this.options).find('input').unbind('click');
}<commit_msg>added trailing commas.<commit_after>/**
 * Constructor for googleLayers widget which controls the display options of the plugin.
 * @constructor
 * @param {GEPlugin} plugin Reference to the google earth plugin instance.
 * @param {HTMLFormElement} options The form that controls options. See GEOptions
 * @param {HTMLFormElement} layers The form that controls which layers are displayed. See layer reference
 */
lingcod.map.googleLayers = function(ge, options_form, layers_form){
    this.layers = $(layers_form);
    this.options = $(options_form);
    this.get = ge;
    var self = this;
    $(this.layers).find('input').click(function(){
        self.updateLayers();
    });

    $(this.options).find('input').click(function(){
        self.updateOptions();
    });

    this.updateLayers();
    this.updateOptions();
}

/**
 * Looks at the layers form and updates the map to match form values
 */
lingcod.map.googleLayers.prototype.updateLayers = function(){
    this.layers.find('input').each(function(){
        ge.getLayerRoot().enableLayerById(ge[$(this).attr('name')], $(this).attr('checked'));
    });
};

/**
 * Looks at the options form and updates the map to match form values. The
 * name of the input element should match the setXVisibility function on
 * ge.getOptions();.
 * for example:
 *
 *      <input name="setGridVisibility" />
 */
lingcod.map.googleLayers.prototype.updateOptions = function(){
    var options = ge.getOptions();
    this.options.find('input').each(function(){
        var $input = $(this);
        var name = $input.attr('name');
        if(name != 'nav' && name != 'sun'){
            options[name](this.checked);
        }
    });

    if(this.options.find('input[name="nav"]').length){
        if (this.options.find('input[name="nav"]:checked').length) {
            ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);
        }else{
            ge.getNavigationControl().setVisibility(ge.VISIBILITY_HIDE);
        }
    }

    if(this.options.find('input[name="sun"]').length){
        if(this.options.find('input[name="sun"]:checked').length){
            ge.getSun().setVisibility(true);
        }else{
            ge.getSun().setVisibility(false);
        }
    }
};

/**
 * Unbinds all event listeners.
 */
lingcod.map.googleLayers.prototype.destroy = function(){
    $(this.layers).find('input').unbind('click');
    $(this.options).find('input').unbind('click');
}<|endoftext|>