<commit_before>/**
 * Copyright 2017, Google, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

var errorHandler;

if (process.env.NODE_ENV === 'production') {
  require('@google/cloud-trace').start();
  errorHandler = require('@google/cloud-errors').start();
}

if (process.env.GCLOUD_PROJECT) {
  require('@google-cloud/debug-agent').start();
}

var path = require('path');
var express = require('express');
var bodyParser = require('body-parser');
var google = require('googleapis');
var youtube = google.youtube('v3');

var app = express();

app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));

app.get('/data.json', function (req, res, next) {
  youtube.search.list({
    part: 'snippet',
    type: 'video',
    q: 'google+cardboard+video+3d',
    auth: process.env.API_KEY
  }, function (err, result) {
    if (err) {
      return next(err);
    }
    res.json(result);
  });
});

app.get('/search', function (req, res, next) {
  youtube.search.list({
    part: 'snippet',
    type: 'video',
    q: req.query.q
  }, function (err, result) {
    if (err) {
      return next(new Error('Search error!'));
    }
    res.json(result);
  });
});

app.use('*', function (req, res) {
  return res.sendFile(path.join(__dirname, 'public/index.html'));
});

// Basic error logger/handler
app.use(function (err, req, res, next) {
  res.status(500).send(err.message || 'Something broke!');
  next(err || new Error('Something broke!'));
});
if (process.env.NODE_ENV === 'production') {
  app.use(errorHandler.express);
}

if (module === require.main) {
  // Start the server
  var server = app.listen(process.env.port || 8080, function () {
    var port = server.address().port;

    console.log('App listening on port %s', port);
    console.log('Press Ctrl+C to quit.');
  });
}

module.exports = app;
<commit_msg>tesst<commit_after>/**
 * Copyright 2017, Google, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

var errorHandler;

if (process.env.NODE_ENV === 'production') {
  require('@google/cloud-trace').start();
  errorHandler = require('@google/cloud-errors').start();
}

if (process.env.GCLOUD_PROJECT) {
  require('@google-cloud/debug-agent').start();
}

var path = require('path');
var express = require('express');
var bodyParser = require('body-parser');
var google = require('googleapis');
var youtube = google.youtube('v3');

var app = express();

app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'src')));

app.get('/data.json', function (req, res, next) {
  youtube.search.list({
    part: 'snippet',
    type: 'video',
    q: 'google+cardboard+video+3d',
    auth: process.env.API_KEY
  }, function (err, result) {
    if (err) {
      return next(err);
    }
    res.json(result);
  });
});

app.get('/search', function (req, res, next) {
  youtube.search.list({
    part: 'snippet',
    type: 'video',
    q: req.query.q
  }, function (err, result) {
    if (err) {
      return next(new Error('Search error!'));
    }
    res.json(result);
  });
});

app.use('*', function (req, res) {
  return res.sendFile(path.join(__dirname, 'src/index.html'));
});

// Basic error logger/handler
app.use(function (err, req, res, next) {
  res.status(500).send(err.message || 'Something broke!');
  next(err || new Error('Something broke!'));
});
if (process.env.NODE_ENV === 'production') {
  app.use(errorHandler.express);
}

if (module === require.main) {
  // Start the server
  var server = app.listen(process.env.port || 8080, function () {
    var port = server.address().port;

    console.log('App listening on port %s', port);
    console.log('Press Ctrl+C to quit.');
  });
}

module.exports = app;
<|endoftext|>


<commit_before>/**
 * webpack-espower-loader - Power Assert instrumentor for webpack.
 *
 * https://github.com/power-assert-js/webpack-espower-loader
 *
 * Copyright (c) 2015 Kenta Mori
 * Licensed under the MIT license.
 *   https://github.com/power-assert-js/webpack-espower-loader/blob/master/LICENSE
 */
'use strict';

var convert = require('convert-source-map');
var espower = require('espower-source');
var extend = require('xtend');

module.exports = function(jsCode, inMap) {
  var filepath = this.resourcePath;
  var options = this.options.espower;
  if (inMap) {
    options = extend(options, {
      sourceMap: inMap,
    });
  }
  var poweredCodeWithMap = espower(jsCode, filepath, options);
  var outMap = convert.fromSource(poweredCodeWithMap);
  this.callback(null, convert.removeComments(poweredCodeWithMap), outMap.toObject());
};

<commit_msg>[add] webpack cacheable flag<commit_after>/**
 * webpack-espower-loader - Power Assert instrumentor for webpack.
 *
 * https://github.com/power-assert-js/webpack-espower-loader
 *
 * Copyright (c) 2015 Kenta Mori
 * Licensed under the MIT license.
 *   https://github.com/power-assert-js/webpack-espower-loader/blob/master/LICENSE
 */
'use strict';

var convert = require('convert-source-map');
var espower = require('espower-source');
var extend = require('xtend');

module.exports = function(jsCode, inMap) {
  var filepath = this.resourcePath;
  var options = this.options.espower;
  if (inMap) {
    options = extend(options, {
      sourceMap: inMap,
    });
  }
  if (this.cacheable) {
    this.cacheable();
  }
  var poweredCodeWithMap = espower(jsCode, filepath, options);
  var outMap = convert.fromSource(poweredCodeWithMap);
  this.callback(null, convert.removeComments(poweredCodeWithMap), outMap.toObject());
};

<|endoftext|>


<commit_before>function MainController($scope, $modal, Users, Merchants, Shops, localStorageService, $location) {
  if (!$scope.me) $scope.me = {displayName: '未登录'};
  $scope.hideMainMenu = false;
  $scope.switchMainMenu = function () {
    $scope.hideMainMenu = !$scope.hideMainMenu;
  };

  $scope.views = [
    {name: "控制面板", icon: "fa fa-dashboard", path: "views/analysis/dashboard.html"},
    {name: "营业报表", icon: "fa fa-bullseye", path: "views/analysis/dailyReport/dayBillReportAnalysis.html", submenus: [
      {name: "日报", icon: "fa fa-cny", path: "views/analysis/dailyReport/dayBillReportAnalysis.html"},
      {name: "周报", icon: "fa fa-dollar", path: "views/analysis/dailyReport/dayBillReportAnalysis.html"},
      {name: "月报", icon: "fa fa-gbp", path: "views/analysis/dailyReport/dayBillReportAnalysis.html"}
    ]},
    {name: "统计分析", icon: "fa fa-bar-chart-o", path: "views/analysis/salesAnalysis.html", submenus: [
      {name: "销售统计", icon: "fa fa-bar-chart-o", path: "views/analysis/salesAnalysis.html"},
      {name: "进货统计", icon: "fa fa-truck", path: "views/analysis/skusAnalysis.html"}
    ]},
    {name: "营业流水", icon: "fa fa-bars", path: "views/deals/index.html", submenus: [
      {name: "销售流水", icon: "fa fa-shopping-cart", path: "views/deals/index.html"},
      {name: "退货流水", icon: "fa fa-exchange", path: "views/returns/index.html"},
      {name: "储值流水", icon: "fa fa-rmb", path: "views/bills/index.html"},
      {name: "订单流水", icon: "fa fa-pencil-square", path: "views/orders/index.html"}
    ]},
    {name: "会员管理", icon: "fa fa-group", path: "views/members/index.html", submenus: [
      {name: "会员清单", icon: "fa fa-group", path: "views/members/index.html"},
      {name: "积分记录", icon: "fa fa-gift", path: "views/points/index.html"}
    ]},
    {name: "品类管理", icon: "fa fa-barcode", path: "views/item/index.html", submenus: [
      {name: "商品管理", icon: "fa fa-barcode", path: "views/item/index.html"},
      {name: "标签管理", icon: "fa fa-tags", path: "views/tags/index.html"}
    ]},
    {name: "商户管理", icon: "fa fa-building-o", path: "views/merchant/index.html", submenus:[
      {name: "当前商户", icon: "fa fa-cog", path: "views/merchant/index.html"},
      {name: "门店管理", icon: "fa fa-home", path: "views/shop/index.html"},
      {name: "员工管理", icon: "fa fa-users", path: "views/employee/index.html"},
      {name: "库存记录", icon: "fa fa-truck", path: "views/skus/index.html"},
      {name: "设备管理", icon: "fa fa-tablet", path: "views/devices/index.html"}
    ]}
  ];
  $scope.trackListPage = {};
  $scope.currentView = $scope.views[0];
  $scope.mapCurrentView = function () { // 获得父节点与子节点的map，用于导航栏使用
    var views = $scope.views;
    $scope.mapForViewName = [];
    for (var v = 0; v < views.length; v++) {
      if (views[v].submenus) {
        var c = views[v];
        c.submenus.forEach(function (i) {
          var obj = {};
          obj[c.name] = i.name;
          $scope.mapForViewName.push(obj);
        });
      }
    }
  };
  $scope.mapCurrentView();

  $scope.selectView = function (view) {
    if (view.submenus) {
      return;
    }
    $scope.currentView = view;
    $scope.trackListPage.activeView = 'views/basicList.html';
    for (var v = 0; v < $scope.mapForViewName.length; v++) {
      var i = $scope.mapForViewName[v];
      var key = Object.keys(i)[0];
      if (i[key] == $scope.currentView.name) {
        $scope.currentViewParentName = key; // 获得currentView的父节点
        return;
      }
    }
  };

  $scope.selectViewByPath = function (path) {
    $scope.views.some(function (view) {
      if (view.path === path) {
        $scope.currentView = view
        return true
      } else {
        return view.submenus.some(function (submenu) {
          if (submenu.path === path) {
            $scope.currentView = submenu
            console.log(submenu, path)
            return true
          } else {
            return false
          }
        });
      }
    });
  };
  $scope.currentMerchant = {
    merchant:{}
  };
  $scope.currentShowShop = {
    shop:{}
  };
  $scope.allShop = [];
  $scope.allMerchant = [];
  $scope.init = function () {
    Users.me(function (me) {
      if (!me.id) { // 用户会话不存在则重定向到登录界面
        $location.path('/home');
        return;
      }
      $scope.me = me;
      Merchants.query({'owner.id':me.id}, function (merchants) {
        var index = 0;
        var localStrage = localStorageService.get('localStorageCurrentMerchant');
        if (localStrage && localStrage.id) {
          var localID = localStrage.id || '';
          if (localID) {
            merchants.forEach(function (merchant, i) {
              if (merchant.id == localID) {
                index = i;
                return;
              }
            })
          }
        }
        $scope.currentMerchant.merchant = merchants[index];
        $scope.allMerchant = merchants;
      });
    }, function () {
      $scope.me = {displayName: '未登录'};
    })
  }
  $scope.showOp = function (index) {
    $scope.currentIndex = index;
  };
  $scope.$watch('currentMerchant.merchant', function () {
    if ($scope.currentMerchant.merchant['id']) {
      var obj = {
        merchantID:$scope.currentMerchant.merchant.id,
        $limit:100
      };
      obj.status = JSON.stringify({$ne: 'removed'})
      Shops.query(obj, function (shops) {
        $scope.currentShowShop.shop = shops[0] || {id:'0'};
        $scope.allShop = shops || [{id:'0'}];
      });
    }
  })

  $scope.showTwoDimensionalCode = function () {
    $modal.open({
      templateUrl: 'TwoDimensionalCode.html'
    })
  }

  $scope.patternForIdcard = /(^\d{15}$)|(^\d{17}([0-9]|X)$)/;
  $scope.patternForTelephone = /^(([0\+]\d{2,3})?(0\d{2,3}))?(\d{7,8})((\d{3,}))?$/;
  $scope.patternForPhone = /^1\d{10}$/;
  $scope.patternForEmail = /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/;
};
<commit_msg>Fixed 商户查询前端限定为100以内<commit_after>function MainController($scope, $modal, Users, Merchants, Shops, localStorageService, $location) {
  if (!$scope.me) $scope.me = {displayName: '未登录'};
  $scope.hideMainMenu = false;
  $scope.switchMainMenu = function () {
    $scope.hideMainMenu = !$scope.hideMainMenu;
  };

  $scope.views = [
    {name: "控制面板", icon: "fa fa-dashboard", path: "views/analysis/dashboard.html"},
    {name: "营业报表", icon: "fa fa-bullseye", path: "views/analysis/dailyReport/dayBillReportAnalysis.html", submenus: [
      {name: "日报", icon: "fa fa-cny", path: "views/analysis/dailyReport/dayBillReportAnalysis.html"},
      {name: "周报", icon: "fa fa-dollar", path: "views/analysis/dailyReport/dayBillReportAnalysis.html"},
      {name: "月报", icon: "fa fa-gbp", path: "views/analysis/dailyReport/dayBillReportAnalysis.html"}
    ]},
    {name: "统计分析", icon: "fa fa-bar-chart-o", path: "views/analysis/salesAnalysis.html", submenus: [
      {name: "销售统计", icon: "fa fa-bar-chart-o", path: "views/analysis/salesAnalysis.html"},
      {name: "进货统计", icon: "fa fa-truck", path: "views/analysis/skusAnalysis.html"}
    ]},
    {name: "营业流水", icon: "fa fa-bars", path: "views/deals/index.html", submenus: [
      {name: "销售流水", icon: "fa fa-shopping-cart", path: "views/deals/index.html"},
      {name: "退货流水", icon: "fa fa-exchange", path: "views/returns/index.html"},
      {name: "储值流水", icon: "fa fa-rmb", path: "views/bills/index.html"},
      {name: "订单流水", icon: "fa fa-pencil-square", path: "views/orders/index.html"}
    ]},
    {name: "会员管理", icon: "fa fa-group", path: "views/members/index.html", submenus: [
      {name: "会员清单", icon: "fa fa-group", path: "views/members/index.html"},
      {name: "积分记录", icon: "fa fa-gift", path: "views/points/index.html"}
    ]},
    {name: "品类管理", icon: "fa fa-barcode", path: "views/item/index.html", submenus: [
      {name: "商品管理", icon: "fa fa-barcode", path: "views/item/index.html"},
      {name: "标签管理", icon: "fa fa-tags", path: "views/tags/index.html"}
    ]},
    {name: "商户管理", icon: "fa fa-building-o", path: "views/merchant/index.html", submenus:[
      {name: "当前商户", icon: "fa fa-cog", path: "views/merchant/index.html"},
      {name: "门店管理", icon: "fa fa-home", path: "views/shop/index.html"},
      {name: "员工管理", icon: "fa fa-users", path: "views/employee/index.html"},
      {name: "库存记录", icon: "fa fa-truck", path: "views/skus/index.html"},
      {name: "设备管理", icon: "fa fa-tablet", path: "views/devices/index.html"}
    ]}
  ];
  $scope.trackListPage = {};
  $scope.currentView = $scope.views[0];
  $scope.mapCurrentView = function () { // 获得父节点与子节点的map，用于导航栏使用
    var views = $scope.views;
    $scope.mapForViewName = [];
    for (var v = 0; v < views.length; v++) {
      if (views[v].submenus) {
        var c = views[v];
        c.submenus.forEach(function (i) {
          var obj = {};
          obj[c.name] = i.name;
          $scope.mapForViewName.push(obj);
        });
      }
    }
  };
  $scope.mapCurrentView();

  $scope.selectView = function (view) {
    if (view.submenus) {
      return;
    }
    $scope.currentView = view;
    $scope.trackListPage.activeView = 'views/basicList.html';
    for (var v = 0; v < $scope.mapForViewName.length; v++) {
      var i = $scope.mapForViewName[v];
      var key = Object.keys(i)[0];
      if (i[key] == $scope.currentView.name) {
        $scope.currentViewParentName = key; // 获得currentView的父节点
        return;
      }
    }
  };

  $scope.selectViewByPath = function (path) {
    $scope.views.some(function (view) {
      if (view.path === path) {
        $scope.currentView = view
        return true
      } else {
        return view.submenus.some(function (submenu) {
          if (submenu.path === path) {
            $scope.currentView = submenu
            console.log(submenu, path)
            return true
          } else {
            return false
          }
        });
      }
    });
  };
  $scope.currentMerchant = {
    merchant:{}
  };
  $scope.currentShowShop = {
    shop:{}
  };
  $scope.allShop = [];
  $scope.allMerchant = [];
  $scope.init = function () {
    Users.me(function (me) {
      if (!me.id) { // 用户会话不存在则重定向到登录界面
        $location.path('/home');
        return;
      }
      $scope.me = me;
      Merchants.query({'owner.id':me.id, '$limit':100}, function (merchants) {
        var index = 0;
        var localStrage = localStorageService.get('localStorageCurrentMerchant');
        if (localStrage && localStrage.id) {
          var localID = localStrage.id || '';
          if (localID) {
            merchants.forEach(function (merchant, i) {
              if (merchant.id == localID) {
                index = i;
                return;
              }
            })
          }
        }
        $scope.currentMerchant.merchant = merchants[index];
        $scope.allMerchant = merchants;
      });
    }, function () {
      $scope.me = {displayName: '未登录'};
    })
  }
  $scope.showOp = function (index) {
    $scope.currentIndex = index;
  };
  $scope.$watch('currentMerchant.merchant', function () {
    if ($scope.currentMerchant.merchant['id']) {
      var obj = {
        merchantID:$scope.currentMerchant.merchant.id,
        $limit:100
      };
      obj.status = JSON.stringify({$ne: 'removed'})
      Shops.query(obj, function (shops) {
        $scope.currentShowShop.shop = shops[0] || {id:'0'};
        $scope.allShop = shops || [{id:'0'}];
      });
    }
  })

  $scope.showTwoDimensionalCode = function () {
    $modal.open({
      templateUrl: 'TwoDimensionalCode.html'
    })
  }

  $scope.patternForIdcard = /(^\d{15}$)|(^\d{17}([0-9]|X)$)/;
  $scope.patternForTelephone = /^(([0\+]\d{2,3})?(0\d{2,3}))?(\d{7,8})((\d{3,}))?$/;
  $scope.patternForPhone = /^1\d{10}$/;
  $scope.patternForEmail = /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/;
};
<|endoftext|>


<commit_before>'use strict';

var path    =  require('path')
  , fs      =  require('fs')
  , mkdirp  =  require('mkdirp')
  , runnel  =  require('runnel')
  , sinless =  require('sinless')
  , Emitter =  require('events').EventEmitter
  , format  =  require('util').format
  , inspect =  require('util').inspect
  , HOME    =  path.join(__dirname, 'test', 'fixtures', 'home') // process.env.HOME
  ;

function copy(srcFile, tgtFile, cb) {
  var readStream = fs.createReadStream(srcFile)
    , writeStream = fs.createWriteStream(tgtFile);

  writeStream
    .on('close', cb)
    .on('error', cb);

  readStream
    .on('error', cb);

  readStream.pipe(writeStream);
}

function copyDefaultConfig(defaultConfig, configFile, cb) {
  copy(defaultConfig, configFile, function (err) {
    cb(err, configFile);
  });
}

function mkconfigDir (configFile, cb) {
  // does nothing if dir already exists
  var dir = path.dirname(configFile);
  mkdirp(dir, function (err) {
    cb(err, configFile);
  });
}

function resolvePath (p) {
  if (!p) return HOME;

  var isFullPath = p === path.resolve(p);

  // by default place the config dir inside the user's home
  return isFullPath ? p : path.join(HOME, p);
}

function defaultLoad (p) {
  return require(p);
}

function defaultSerialize (config) {
  return 'module.exports = ' + inspect(config)
}

function noConfigFound (configFile) {
  return {};
}

function noop (config) {
  return config;
}
function writeConfig (configFile, config, cb) {
  fs.writeFile(configFile, config, 'utf8', function (err) {
    cb(err, configFile);
  });
}

/**
 *
 * Possible workflows:
 *
 *  config exists:
 *    - mkdir
 *    - load config
 *    - edit loaded config
 *    - serialize edited config
 *    - write config
 *
 *  config doesn't exist and default config is given:
 *    - mkdir
 *    - copy default config
 *    - load copied config
 *    - edit loaded config
 *    - serialize edited config
 *    - write config
 *
 *  config doesn't exist and no default config is given:
 *    - mkdir
 *    - edit config starting from scratch (null)
 *    - serialize edited config
 *    - write config
 *
 * @name
 * @function
 * @return void
 */
var go = module.exports = function (opts, cb) {
  opts = opts || {};

  var events = new Emitter();

  function emit (name, arg) {
    return sinless(function (passthru) {
      if (!arg) arg = passthru;
      events.emit(name, arg, passthru);
      return passthru;
    });
  }

  var configDir     =  resolvePath(opts.configDir)
    , configFile    =  path.join(configDir, opts.configFile)
    ;

  var defaultConfig =  opts.defaultConfig     || null
    , serialize     =  sinless(opts.serialize || defaultSerialize)
    , edit          =  sinless(opts.edit      || noop)
    , notfound      =  sinless(noConfigFound)
    ;

  var load = sinless(opts.load || defaultLoad);

  var tasks = [
      runnel.seed(configFile)
    , mkconfigDir
    , emit('created-configdir', configDir)
  ];

  fs.exists(configFile, function (exists) {
    if (!exists) {
      if (defaultConfig) {
        // config didn't exist but we were supplied a default config
        tasks = tasks.concat(
          [ copyDefaultConfig.bind(null, defaultConfig)
          , emit('copied-default', defaultConfig)
          , load
          , emit('loaded-config')
          ]
        );
      } else {
        // config didn't exist and we were not given a default config
        tasks = tasks.concat(
          [ notfound
          , emit('notfound-config')
          ]
        );
      }
    } else {
      // config existed
      tasks = tasks.concat(
        [ load
        , emit('loaded-config')
        ]
      );
    }

    tasks = tasks.concat(
      [ edit
      , emit('edited-config')
      , serialize
      , emit('serialized-config')
      , writeConfig.bind(null, configFile)
      , emit('wrote-config')
      , cb
      ]
    )

    runnel(tasks);
  });

  return events;
};
<commit_msg>no longer emitting edited when no edit is supplied<commit_after>'use strict';

var path    =  require('path')
  , fs      =  require('fs')
  , mkdirp  =  require('mkdirp')
  , runnel  =  require('runnel')
  , sinless =  require('sinless')
  , Emitter =  require('events').EventEmitter
  , format  =  require('util').format
  , inspect =  require('util').inspect
  , HOME    =  path.join(__dirname, 'test', 'fixtures', 'home') // process.env.HOME
  ;

function copy(srcFile, tgtFile, cb) {
  var readStream = fs.createReadStream(srcFile)
    , writeStream = fs.createWriteStream(tgtFile);

  writeStream
    .on('close', cb)
    .on('error', cb);

  readStream
    .on('error', cb);

  readStream.pipe(writeStream);
}

function copyDefaultConfig(defaultConfig, configFile, cb) {
  copy(defaultConfig, configFile, function (err) {
    cb(err, configFile);
  });
}

function mkconfigDir (configFile, cb) {
  // does nothing if dir already exists
  var dir = path.dirname(configFile);
  mkdirp(dir, function (err) {
    cb(err, configFile);
  });
}

function resolvePath (p) {
  if (!p) return HOME;

  var isFullPath = p === path.resolve(p);

  // by default place the config dir inside the user's home
  return isFullPath ? p : path.join(HOME, p);
}

function defaultLoad (p) {
  return require(p);
}

function defaultSerialize (config) {
  return 'module.exports = ' + inspect(config)
}

function noConfigFound (configFile) {
  return {};
}

function writeConfig (configFile, config, cb) {
  fs.writeFile(configFile, config, 'utf8', function (err) {
    cb(err, configFile);
  });
}

/**
 *
 * Possible workflows:
 *
 *  config exists:
 *    - mkdir
 *    - load config
 *    - edit loaded config
 *    - serialize edited config
 *    - write config
 *
 *  config doesn't exist and default config is given:
 *    - mkdir
 *    - copy default config
 *    - load copied config
 *    - edit loaded config
 *    - serialize edited config
 *    - write config
 *
 *  config doesn't exist and no default config is given:
 *    - mkdir
 *    - edit config starting from scratch (null)
 *    - serialize edited config
 *    - write config
 *
 * @name
 * @function
 * @return void
 */
var go = module.exports = function (opts, cb) {
  opts = opts || {};

  var events = new Emitter();

  function emit (name, arg) {
    return sinless(function (passthru) {
      if (!arg) arg = passthru;
      events.emit(name, arg, passthru);
      return passthru;
    });
  }

  var configDir     =  resolvePath(opts.configDir)
    , configFile    =  path.join(configDir, opts.configFile)
    ;

  var defaultConfig =  opts.defaultConfig     || null
    , serialize     =  sinless(opts.serialize || defaultSerialize)
    , edit          =  opts.edit ? sinless(opts.edit) : null
    , notfound      =  sinless(noConfigFound)
    ;

  var load = sinless(opts.load || defaultLoad);

  var tasks = [
      runnel.seed(configFile)
    , mkconfigDir
    , emit('created-configdir', configDir)
  ];

  fs.exists(configFile, function (exists) {
    if (!exists) {
      if (defaultConfig) {
        // config didn't exist but we were supplied a default config
        tasks = tasks.concat(
          [ copyDefaultConfig.bind(null, defaultConfig)
          , emit('copied-default', defaultConfig)
          , load
          , emit('loaded-config')
          ]
        );
      } else {
        // config didn't exist and we were not given a default config
        tasks = tasks.concat(
          [ notfound
          , emit('notfound-config')
          ]
        );
      }
    } else {
      // config existed
      tasks = tasks.concat(
        [ load
        , emit('loaded-config')
        ]
      );
    }

    if (edit) {
      tasks = tasks.concat(
        [ edit
        , emit('edited-config')
        ]
      )
    }

    tasks = tasks.concat(
      [ serialize
      , emit('serialized-config')
      , writeConfig.bind(null, configFile)
      , emit('wrote-config')
      , cb
      ]
    )

    runnel(tasks);
  });

  return events;
};
<|endoftext|>


<commit_before>define(['jquery', 'd3', 'util/eventemitter', 'util/hud'],
function ($, d3, EventEmitter, HUD) {

    var Dock = function (element) {
        var self = this;

        var docked = {};
        var updateActions = [];
        var dockHudContentCallback = function (nodes) {
            var dock = this;
            var list = $("
");
            dock.hud.append(list);
            nodes.forEach(function (d) {
                list.append("
" + d + "
");
            });
        }

        var w = element.attr("width");
        var h = element.attr("height");
        var dock = element.append("rect")
            .attr("id", "networkDock")
            .attr("width", w / 2)
            .attr("height", 30)
            .attr("rx", 5)
            .attr("ry", 5)
            .attr("x", w / 4)
            .attr("y", h * 3 / 6)
            .style("fill", "black")
            .style("opacity", "0.1");
        var dockDims = {
            x1: parseInt(dock.attr("x")),
            x2: parseInt(dock.attr("x")) + parseInt(dock.attr("width")),
            y1: parseInt(dock.attr("y")),
            y2: parseInt(dock.attr("y")) + parseInt(dock.attr("height")),
        };

        dock
            .on("mouseover", function () { dock.style("opacity", "0.2"); })
            .on("mouseout",  function () { dock.style("opacity", "0.1"); })
            .on("click", dockhud);

        self.changedState = false;

        var hud = self.hud = new HUD({
            width: 300,
            position: { top: 50, right: 20 },
        });

        self.updateHud = function () {
            hud.empty();
            hud.append("
Dock
");
            var nodes = [];
            for (var d in docked) {
                nodes.push(d);
            }
            dockHudContentCallback.call(self, nodes);
            updateActions.forEach(function (callback) {
                callback.call(self, nodes);
            });
        }

        function dockhud() {
            self.updateHud();
            hud.show();
        }

        self.drag = function () {
            return d3.behavior.drag()
                .on("dragstart", nodeDragstart)
                .on("drag",      nodeDragmove)
                .on("dragend",   nodeDragend);
        }

        function nodeDragstart() {
            self.emit("dragstart.dock");
        }

        function nodeDragmove(d) {
            d.px += d3.event.dx;
            d.py += d3.event.dy;
            d.x += d3.event.dx;
            d.y += d3.event.dy;
            self.emit("dragmove.dock", d);
        }

        function nodeDragend(d) {
            var draggedNode = this;
            var selected = d3.select(draggedNode);
            if (intersects(d)) {
                self.dockElement(d, selected);
            } else {
                self.undockElement(d, selected);
            }
            self.emit("dragend.dock", d);
        }

        function intersects(d) {
            return d.px >= dockDims.x1 &&
                   d.px <= dockDims.x2 &&
                   d.py >= dockDims.y1 &&
                   d.py <= dockDims.y2
        }

        self.dockElement = function (d, element) {
            if (d == null) {
                throw Error("Cannot dock a null element");
            }
            d.fixed = true;
            docked[d.name] = d;
            self.updateHud();
            self.emit("dock", [d, element]);
        }

        self.undockElement = function (d, element) {
            if (d == null) {
                throw Error("Cannot undock a null element");
            }
            d.fixed = false;
            delete docked[d.name];
            self.updateHud();
            self.emit("undock", [d, element]);
        }

        self.reset = function () {
            for (var d in docked) self.undockElement(d);
        }

        self.set = function (nodes) {
            self.reset();
            var interval = dock.attr('width') / (nodes.length + 1);
            for (var i = 0; i < nodes.length; i++) {
                var element = d3.select("#" + nodes[i].elementId)
                self.dockElement(nodes[i], element);
                nodes[i].px = dockDims.x1 + (i+1) * interval
                nodes[i].py = (dockDims.y1 + dockDims.y2) / 2;
            }
        }
        self.addUpdateAction = function (callback) {
            updateActions.push(callback);
        }
        self.hudContent = function (callback) {
            dockHudContentCallback = callback;
        }
    };

    $.extend(Dock.prototype, EventEmitter);
    return Dock;
});<commit_msg>Dock can now be dragged.<commit_after>define(['jquery', 'd3', 'util/eventemitter', 'util/hud'],
function ($, d3, EventEmitter, HUD) {

    var DOCK_HEIGHT = 30;
    var Dock = function (element) {
        var self = this;

        var docked = {};
        var updateActions = [];

        var dockHudContentCallback = function (nodes) {
            var dock = this;
            var list = $("
");
            dock.hud.append(list);
            nodes.forEach(function (d) {
                list.append("
" + d + "
");
            });
        }

        function dockDragStart() {
            this._elemOffsets = [];
            this._yoffset = d3.event.sourceEvent.pageY - dockDims.y1;
            for (var n in docked) {
                this._elemOffsets[n] = docked[n][0].py - dockDims.y1;
            }
        }

        function dockDrag() {
            dock.attr("y", dockDims.y1 = d3.event.y - this._yoffset);
            for (var name in docked) {
                var el = docked[name];
                var y = dockDims.y1 + this._elemOffsets[name];
                el[1].attr("cy", y);
                el[0].py = el[0].y = y;
            }
        }

        function dockDragEnd() {
            for (var name in docked) {
                var el = docked[name];
                var y = dockDims.y1 + this._elemOffsets[name];
                el[1].attr("cy", y);
                el[0].py = el[0].y = y;
            }
            dockDims.y2 = dockDims.y1 + dockDims.h;
        }

        var w = element.attr("width");
        var h = element.attr("height");
        var dockDims = { x1: w / 4, y1: h / 2, w: w / 2, h: DOCK_HEIGHT };
        dockDims.x2 = dockDims.x1 + dockDims.w; // For convenience
        dockDims.y2 = dockDims.y1 + dockDims.h; // For convenience
        var dock = element.append("rect")
            .attr("id", "networkDock")
            .attr("width",  dockDims.w)
            .attr("height", dockDims.h)
            .attr("rx", 5)
            .attr("ry", 5)
            .attr("x", dockDims.x1)
            .attr("y", dockDims.y1)
            .style("fill", "black")
            .style("opacity", "0.1")
            .call(d3.behavior.drag()
                .on("dragstart", dockDragStart)
                .on("drag", dockDrag)
                .on("dragend", dockDragEnd)
            );

        dock
            .on("mouseover", function () { dock.style("opacity", 0.2); })
            .on("mouseout",  function () { dock.style("opacity", 0.1); })
            .on("click", dockhud);

        self.changedState = false;

        var hud = self.hud = new HUD({
            width: 300,
            position: { top: 50, right: 20 },
        });

        self.updateHud = function () {
            hud.empty();
            hud.append("
Dock
");
            var nodes = [];
            for (var d in docked) {
                nodes.push(d);
            }
            dockHudContentCallback.call(self, nodes);
            updateActions.forEach(function (callback) {
                callback.call(self, nodes);
            });
        }

        function dockhud() {
            self.updateHud();
            hud.show();
        }

        self.drag = function () {
            return d3.behavior.drag()
                .on("dragstart", nodeDragstart)
                .on("drag",      nodeDragmove)
                .on("dragend",   nodeDragend);
        }

        function nodeDragstart() {
            self.emit("dragstart.dock");
        }

        function nodeDragmove(d) {
            d.px += d3.event.dx;
            d.py += d3.event.dy;
            d.x += d3.event.dx;
            d.y += d3.event.dy;
            self.emit("dragmove.dock", d);
        }

        function nodeDragend(d) {
            var draggedNode = this;
            var selected = d3.select(draggedNode);
            if (intersects(d)) {
                self.dockElement(d, selected);
            } else {
                self.undockElement(d, selected);
            }
            self.emit("dragend.dock", d);
        }

        function intersects(d) {
            return d.px >= dockDims.x1 &&
                   d.px <= dockDims.x2 &&
                   d.py >= dockDims.y1 &&
                   d.py <= dockDims.y2
        }

        self.dockElement = function (d, element) {
            if (d == null) {
                throw Error("Cannot dock a null element");
            }
            d.fixed = true;
            docked[d.name] = [d, element];
            self.updateHud();
            self.emit("dock", [d, element]);
        }

        self.undockElement = function (d, element) {
            if (d == null) {
                throw Error("Cannot undock a null element");
            }
            d.fixed = false;
            delete docked[d.name];
            self.updateHud();
            self.emit("undock", [d, element]);
        }

        self.reset = function () {
            for (var d in docked)
                self.undockElement(docked[d][0], docked[d][1]);
        }

        self.set = function (nodes) {
            self.reset();
            var interval = dock.attr('width') / (nodes.length + 1);
            for (var i = 0; i < nodes.length; i++) {
                var element = d3.select("#" + nodes[i].elementId)
                self.dockElement(nodes[i], element);
                nodes[i].px = dockDims.x1 + (i+1) * interval
                nodes[i].py = (dockDims.y1 + dockDims.y2) / 2;
            }
        }
        self.addUpdateAction = function (callback) {
            updateActions.push(callback);
        }
        self.hudContent = function (callback) {
            dockHudContentCallback = callback;
        }
    };

    $.extend(Dock.prototype, EventEmitter);
    return Dock;
});<|endoftext|>


<commit_before>/*
test ranged fs.createReadStream
re: https://github.com/felixge/node-form-data/issues/71
*/

var common       = require('../common');
var assert       = common.assert;
var http         = require('http');
var fs           = require('fs');

var FormData     = require(common.dir.lib + '/form_data');
var IncomingForm = require('formidable').IncomingForm;

var testSubjects = {
  'a_file': {
    file: 'veggies.txt',
    start: 8,
    end: 18
  }, 'b_file': {
    file: 'veggies.txt',
    start: 6
  }, 'c_file': {
    file: 'veggies.txt',
    end: 16
  }, 'd_file': {
    file: 'veggies.txt',
    start: 0,
    end: 16
  }, 'e_file': {
    file: 'veggies.txt',
    start: 0,
    end: 0
  }
};

var server = http.createServer(function(req, res) {
  var requestBodyLength = 0;

  // calculate actual length of the request body
  req.on('data', function(data) {
      requestBodyLength += data.length;
  });

  var form = new IncomingForm({uploadDir: common.dir.tmp});

  form.parse(req);

  form
    .on('file', function(name, file) {

      // make sure total Content-Length is properly calculated
      assert.equal(req.headers['content-length'], requestBodyLength);
      // make sure chunks are the same size
      assert.equal(file.size, testSubjects[name].readSize);
    })
    .on('end', function() {
      res.writeHead(200);
      res.end('done');
    });
});

server.listen(common.port, function() {
  var form = new FormData();
  var name, options;

  // add test subjects to the form
  for (name in testSubjects) {
    if (!testSubjects.hasOwnProperty(name)) continue;

    options = {encoding: 'utf8'};
    testSubjects[name].start && (options.start = testSubjects[name].start);
    testSubjects[name].end && (options.end = testSubjects[name].end);

    form.append(name, testSubjects[name].fsStream = fs.createReadStream(common.dir.fixture + '/' + testSubjects[name].file, options));

    // calculate data size
    testSubjects[name].readSize = 0;
    testSubjects[name].fsStream.on('data', function(data) {
      this.readSize += data.length;
    }.bind(testSubjects[name]));
  }

  form.submit('http://localhost:' + common.port + '/', function(err, res) {
    if (err) {
      throw err;
    }

    assert.strictEqual(res.statusCode, 200);

    // unstuck new streams
    res.resume();

    server.close();
  });

});
<commit_msg>Fixed ranged test.<commit_after>/*
test ranged fs.createReadStream
re: https://github.com/felixge/node-form-data/issues/71
*/

var common       = require('../common');
var assert       = common.assert;
var http         = require('http');
var fs           = require('fs');

var FormData     = require(common.dir.lib + '/form_data');
var IncomingForm = require('formidable').IncomingForm;

var testSubjects = {
  'a_file': {
    file: 'veggies.txt',
    start: 8,
    end: 18
  }, 'b_file': {
    file: 'veggies.txt',
    start: 6
  }, 'c_file': {
    file: 'veggies.txt',
    end: 16
  }, 'd_file': {
    file: 'veggies.txt',
    start: 0,
    end: 16
  }, 'e_file': {
    file: 'veggies.txt',
    start: 0,
    end: 0
  }
};

var server = http.createServer(function(req, res) {
  var requestBodyLength = 0;

  // calculate actual length of the request body
  req.on('data', function(data) {
      requestBodyLength += data.length;
  });

  req.on('end', function() {
    // make sure total Content-Length is properly calculated
    assert.equal(req.headers['content-length'], requestBodyLength);
    // successfully accepted request and it's good
    res.writeHead(200);
  });

  var form = new IncomingForm({uploadDir: common.dir.tmp});
  form.parse(req);

  form
    .on('file', function(name, file) {
      // make sure chunks are the same size
      assert.equal(file.size, testSubjects[name].readSize);
      // clean up tested subject
      delete testSubjects[name];
    })
    .on('end', function()
    {
      // done here
      res.end();
    });
});

server.listen(common.port, function() {
  var form = new FormData();
  var name, options;

  // add test subjects to the form
  for (name in testSubjects) {
    if (!testSubjects.hasOwnProperty(name)) continue;

    options = {encoding: 'utf8'};
    testSubjects[name].start && (options.start = testSubjects[name].start);
    testSubjects[name].end && (options.end = testSubjects[name].end);

    form.append(name, testSubjects[name].fsStream = fs.createReadStream(common.dir.fixture + '/' + testSubjects[name].file, options));

    // calculate data size
    testSubjects[name].readSize = 0;
    testSubjects[name].fsStream.on('data', function(data) {
      this.readSize += data.length;
    }.bind(testSubjects[name]));
  }

  form.submit('http://localhost:' + common.port + '/', function(err, res) {
    if (err) {
      throw err;
    }

    assert.strictEqual(res.statusCode, 200);

    // wait for server to finish
    res.on('end', function()
    {
      // check that all subjects were tested
      assert.strictEqual(Object.keys(testSubjects).length, 0);
      server.close();
    });

    // unstuck new streams
    res.resume();
  });

});
<|endoftext|>


<commit_before>module.exports = require(__dirname+'/build/Release/compress_buffer_bindings');
<commit_msg>zmiana sciezki dla v0.4 node'a<commit_after>module.exports = require(__dirname+'/build/default/compress-buffer-bindings');
<|endoftext|>


<commit_before>var config    = require('./config/config').config,
    instagram = require('./lib/instagram').
                  createClient(config.clientId, config.accessToken),
    util      = require('./lib/util'),
    database  = require('./lib/database'),
    people    = require('./lib/person').
                  fromUserIds(config.userIds),
    server    = require('./lib/pushserver').
                  createServer(config.port, __dirname + '/public'),
    atom      = require('./lib/atom'),
    blog      = new atom.Feed(config.atom.url),
    cachedInitialUpdates = null;

var E = util.errorHandler(function(err){
  util.printErr(err);
});

var main = function(dbCollection){

  // Find latest update ID for each person
  // on response:
  //   - start polling for person.
  //
  util.objForEach(people, function(_, person){
    var pollInterval = config.pollInterval.normal;
    dbCollection.getLatestUpdateId(person.userId, E(function(n){
      person.setMinId(n);
      var poll = function(){
        console.log('polling '+person.userId);
        person.getLatestUpdates(instagram, function(err, res){
          if (err) {
            pollInterval = config.pollInterval.error;
            printErr(err);
          } else {
            pollInterval = config.pollInterval.normal;
            if (res) { updateReceived(res); }
          }
        });
        // This will be reached before the success/failure is known. That's OK,
        // because:
        // 1) we want to poll again regardless of what happens; and
        // 2) even if the next poll happens soon, over the long run we will
        // back off and avoid hammering the API.
        setTimeout(poll, pollInterval);
      };
      poll();
    }));
  });

  // Find latest blog post time
  // on response:
  //   - start polling for blog posts
  //
  dbCollection.getLatestBlogPostTime(E(function(n){
    blog.setMinTimestamp(n);
    var poll = function(){
      console.log('polling blog feed');
      blog.getLatestPosts(E(function(post){
        updateReceived(post);
      }));
      setTimeout(poll, config.atom.pollInterval);
    };
    poll();
  }));

  // For each update received:
  //   - expire initial update cache
  //   - save to database
  //   - broadcast to all clients
  //
  var updateReceived = function(update){
    switch (update.type) {
      case 'image':
        console.log('received update for ' + update.user.username);
        break;
      case 'blog':
        console.log('found blog post ' + update.title);
        break;
      default:
        console.log('unknown update ' + update.type);
    }
    cachedInitialUpdates = null;
    dbCollection.insert(update, E());
    server.clientPool.broadcast(util.encodeMessage('new', [update]));
  };

  // Send client a batch of the latest N updates before timestamp
  //
  var sendUpdates = function(client, timestamp){
    var criteria = {created_time: {$lt: timestamp}};
    dbCollection.getUpdates(criteria, config.chunkSize, E(function(data){
      client.send(util.encodeMessage('more', data));
    }));
  };

  // Send client a starting batch of the latest N updates
  //
  var sendInitialUpdates = function(client){
    var send = function(data){
      client.send(util.encodeMessage('start', data));
    };
    if (cachedInitialUpdates) {
      send(cachedInitialUpdates);
    } else {
      dbCollection.getUpdates({}, config.chunkSize, E(function(data){
        cachedInitialUpdates = data;
        send(data);
      }));
    }
  };

  // Handle an incoming message
  //
  var receivedMessage = function(client, raw){
    util.decodeMessage(raw, E(function(type, data){
      switch (type) {
        case 'more':
          sendUpdates(client, data);
          break;
      }
    }));
  };

  // On socket connection:
  //   - Add to pool
  //   - Set up disconnection handler
  //   - Set up message handler
  //   - Send an initial set of updates
  //
  server.socket.on('connection', function(client){
    server.clientPool.add(client);
    client.on('disconnect', function(){
      server.clientPool.remove(client);
    });
    client.on('message', function(raw){
      receivedMessage(client, raw);
    });
    sendInitialUpdates(client);
  });
};

database.withCollection(config, E(function(collection){
  main(collection);
}));
<commit_msg>Fix error logging.<commit_after>var config    = require('./config/config').config,
    instagram = require('./lib/instagram').
                  createClient(config.clientId, config.accessToken),
    util      = require('./lib/util'),
    database  = require('./lib/database'),
    people    = require('./lib/person').
                  fromUserIds(config.userIds),
    server    = require('./lib/pushserver').
                  createServer(config.port, __dirname + '/public'),
    atom      = require('./lib/atom'),
    blog      = new atom.Feed(config.atom.url),
    cachedInitialUpdates = null;

var E = util.errorHandler(function(err){
  util.printErr(err);
});

var main = function(dbCollection){

  // Find latest update ID for each person
  // on response:
  //   - start polling for person.
  //
  util.objForEach(people, function(_, person){
    var pollInterval = config.pollInterval.normal;
    dbCollection.getLatestUpdateId(person.userId, E(function(n){
      person.setMinId(n);
      var poll = function(){
        console.log('polling '+person.userId);
        person.getLatestUpdates(instagram, function(err, res){
          if (err) {
            pollInterval = config.pollInterval.error;
            util.printErr(err);
          } else {
            pollInterval = config.pollInterval.normal;
            if (res) { updateReceived(res); }
          }
        });
        // This will be reached before the success/failure is known. That's OK,
        // because:
        // 1) we want to poll again regardless of what happens; and
        // 2) even if the next poll happens soon, over the long run we will
        // back off and avoid hammering the API.
        setTimeout(poll, pollInterval);
      };
      poll();
    }));
  });

  // Find latest blog post time
  // on response:
  //   - start polling for blog posts
  //
  dbCollection.getLatestBlogPostTime(E(function(n){
    blog.setMinTimestamp(n);
    var poll = function(){
      console.log('polling blog feed');
      blog.getLatestPosts(E(function(post){
        updateReceived(post);
      }));
      setTimeout(poll, config.atom.pollInterval);
    };
    poll();
  }));

  // For each update received:
  //   - expire initial update cache
  //   - save to database
  //   - broadcast to all clients
  //
  var updateReceived = function(update){
    switch (update.type) {
      case 'image':
        console.log('received update for ' + update.user.username);
        break;
      case 'blog':
        console.log('found blog post ' + update.title);
        break;
      default:
        console.log('unknown update ' + update.type);
    }
    cachedInitialUpdates = null;
    dbCollection.insert(update, E());
    server.clientPool.broadcast(util.encodeMessage('new', [update]));
  };

  // Send client a batch of the latest N updates before timestamp
  //
  var sendUpdates = function(client, timestamp){
    var criteria = {created_time: {$lt: timestamp}};
    dbCollection.getUpdates(criteria, config.chunkSize, E(function(data){
      client.send(util.encodeMessage('more', data));
    }));
  };

  // Send client a starting batch of the latest N updates
  //
  var sendInitialUpdates = function(client){
    var send = function(data){
      client.send(util.encodeMessage('start', data));
    };
    if (cachedInitialUpdates) {
      send(cachedInitialUpdates);
    } else {
      dbCollection.getUpdates({}, config.chunkSize, E(function(data){
        cachedInitialUpdates = data;
        send(data);
      }));
    }
  };

  // Handle an incoming message
  //
  var receivedMessage = function(client, raw){
    util.decodeMessage(raw, E(function(type, data){
      switch (type) {
        case 'more':
          sendUpdates(client, data);
          break;
      }
    }));
  };

  // On socket connection:
  //   - Add to pool
  //   - Set up disconnection handler
  //   - Set up message handler
  //   - Send an initial set of updates
  //
  server.socket.on('connection', function(client){
    server.clientPool.add(client);
    client.on('disconnect', function(){
      server.clientPool.remove(client);
    });
    client.on('message', function(raw){
      receivedMessage(client, raw);
    });
    sendInitialUpdates(client);
  });
};

database.withCollection(config, E(function(collection){
  main(collection);
}));
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');

var tildify = require('tildify');
var loop = require('serial-loop');
var _ = require('underscore');
var cheerio = require('cheerio');
var concat = require('concat-files');
var UglifyJS = require("uglify-js");
var CleanCSS = require('clean-css');
var chalk = require('chalk');
var copy = require('copy-files');
var glob = require("glob");
var mkdirp = require('mkdirp');
var beautifyHTML = require('js-beautify').html;

const  PACK_JS_DEFAULTS = {
  inline: {concat: false, minify:false},
  local: {concat: true, minify:true},
  remote: false, //NOT SUPPORTED YET
  exclude:[],
  append: 'body',
  name:'bundle.js'
};
const  PACK_CSS_DEFAULTS = {
  inline: {concat: false, minify:true},
  local: {concat: true, minify:true},
  remote: false, //NOT SUPPORTED YET
  exclude:[],
  append: 'head',
  name:'style.css'
};
const  PACK_HTML_DEFAULTS = {
  minify:false,
  name:'index.html',
  //options of htmlparser2 apply
  normalizeWhitespace: true
};

const VERBOSE = true;
var _options = {},
  scriptElements,
  originalCWD = process.cwd();

module.exports = function(options){
  _options = sanitizeOptions(options);

  try {
    log('changing cwd to '+_options.basePath);
    process.chdir(_options.basePath);
  }
  catch (err) {
    console.error('chdir: ' + err);
  }

  //create output folder and sub directories
  mkdirp(_options.output, function(err){
    if (err) throw err;
    log('creating dir '+_options.output+' if not alreay created.');
    var numSubDirectories = 0, numCreatedSubDirectories = 0;
    _.each(_options.output, function(target){
      if (target != _options.output){
        var directory = path.dirname(target);
        if (directory != '.') {
          log('Creating directory '+directory+' in output directory.');
          numSubDirectories++;
          mkdirp(path.join(_options.output, directory), function(){
            numCreatedSubDirectories++;
            //All directories created.
            if(numCreatedSubDirectories == numSubDirectories){
              log('sub directories created.');
            }
          });
        }
      }
    });
    log('Opening Entry File '+path.basename(_options.entry));
    readFile(path.basename(_options.entry), function(htmlString){
      htmlString = remove(htmlString);
      compile(htmlString);
    });
    copyFiles();
  });
};

process.on('exit', function(code) {
  try {
    process.chdir(originalCWD);
    if (code === 0){
      log(chalk.bgGreen.black.bold('\n Finished. You find your files neatly packed together in "'+tildify(path.join(process.cwd(), _options.output))+'".'));
    }
  }
  catch (err) {
    console.error('chdir: ' + err);
  }
});

function copyFiles(){
  logTitle('Copying files...');
  _.each(_options.copy, function(copyEntry){
    log("file pattern: "+copyEntry);
    glob(copyEntry, {ignore:_options.output}, function (err, files) {
      if (err) {
        console.error(err);
      }
      else {
        if (files.length>0) {
          _.each(files, function(file){
            log('trying to copy file '+file);
            var targetFile = path.join(_options.output, file);
            if (fs.lstatSync(file).isFile()) {
              mkdirp(path.dirname(targetFile), function (err) {
                  if (err) console.error(err);
                  else {
                    fs.createReadStream(file).pipe(fs.createWriteStream(targetFile));
                  }
              });
            } else {
              log(chalk.bgYellow.black(targetFile +' is a directory. skipping.'));
            }
          });
        }
      }
    });
  });
}

function remove(htmlString){
  logTitle('removing references');
  var $ = cheerio.load(htmlString);
  _.each(_options.remove, function(element){
    log('Searching for element '+element);
    var $element = findElementBySelectorOrFilename($, element);
    if ($element) {
      log('Element '+element+' found. Removing...');
      $element.remove();
    }
  });

  return $.html();
}

function compile(htmlString) {
  logTitle('processing files');

  processJS(htmlString);
  processCSS(htmlString);

  compileHTML(htmlString);
}

function processJS(htmlString){
  log('processing js..');
  scriptElements = getScripts(htmlString);
  var jsOptions = _options.pack.js;

  var jsString = '';
  var concatAll = jsOptions.local.concat && jsOptions.inline.concat;
  var minifyAll = jsOptions.local.minify && jsOptions.inline.minify;

  if (concatAll && minifyAll){
    jsString = minifyScripts(concatSync(scriptElements.local)+';'+scriptElements.inline.join(';'));
  }
  else if (concatAll && !minifyAll){
    var localJS = concatSync(scriptElements.local);
    var inlineJS = scriptElements.inline.join(';');
    if (jsOptions.local.minify){
      localJS = minifyScripts(localJS);
    }
    if (jsOptions.inline.minify){
      inlineJS = minifyScripts(inlineJS);
    }

    jsString = localJS+';'+inlineJS;
  }
  else if (!concatAll) {
    if (jsOptions.local.concat){
      jsString = concatSync(scriptElements.local);
      if (jsOptions.local.minify){
        jsString = minifyScripts(jsString);
      }
    }
    if (jsOptions.inline.minify){
      //todo
    }
  }

  if (jsString.length>1){
    var bundleFile = path.join(_options.output, _options.pack.js.name);
    writeFile(bundleFile, jsString, function(){
      log('done processing js');
    });
  }
}

//processStyles(, path.join(_options.output, _options.pack.css.name), function(){
function processCSS(htmlString){
  log('processing css..');
  styleElements = getStyles(htmlString);
  var cssOptions = _options.pack.css;

  var cssString = '';
  var concatAll = cssOptions.local.concat && cssOptions.inline.concat;
  var minifyAll = cssOptions.local.minify && cssOptions.inline.minify;
  var localCSS = concatSync(_.pluck(styleElements.local, 'href'));

  if (concatAll) {
    var inlineCSS = styleElements.inline.join();
    if (minifyAll) {
      cssString = minifyStyles(localCSS+inlineCSS);
    }
    else {
      if (cssOptions.local.minify){
        localCSS = minifyStyles(localCSS);
      }
      if (cssOptions.inline.minify){
        inlineCSS = minifyScripts(inlineCSS);
      }
      cssString = localCSS+inlineCSS;
    }
  }
  else if (!concatAll) {
    if (cssOptions.local.concat){
      cssString = localCSS;
      if (cssOptions.local.minify){
        cssString = minifyStyles(cssString);
      }
    }
    if (cssOptions.inline.minify){
      //todo
    }
  }

  if (cssString.length>1){
    var bundleFile = path.join(_options.output, _options.pack.css.name);
    writeFile(bundleFile, cssString, function(){
      log('done processing css');
    });
  }
}

function sanitizeOptions(options) {
  options.pack = options.pack || options.minify;
  options.entry = options.entry || options.entryFile;

  options.pack.js = defaults(options.pack.js, PACK_JS_DEFAULTS);
  options.pack.css = defaults(options.pack.css, PACK_CSS_DEFAULTS);
  options.pack.html = defaults(options.pack.html, PACK_HTML_DEFAULTS);

  normalizePaths(options.pack.js.exclude);
  normalizePaths(options.pack.css.exclude);

  options.basePath = path.dirname(options.entry);
  options.remove = options.remove || [];
  options.copy = options.copy || [];

  return options;
}
function normalizePaths(pathArray){
  _.each(pathArray, function(thePath, i){
    pathArray[i] = path.normalize(thePath);
  })
}

function defaults(object, defaultOptions){
  if (object === true) {
    return defaultOptions;
  }
  else if (!object) {
    return _.each(defaultOptions, function(item, key){defaultOptions[key]=false;});
  }
  else if (_.isObject(object)) {
    return _.defaults(object, defaultOptions);
  }
}

function getScripts(htmlString){
  var jsOptions = _options.pack.js;
  var $ = cheerio.load(htmlString);
  _.each(jsOptions.exclude, function(itemToExclude){
    var $itemToExclude = findElementBySelectorOrFilename($, itemToExclude);
    if ($itemToExclude) {
      $itemToExclude.remove();
    }
  });
  htmlString = $.html();
  var scriptElements = getTags(htmlString, 'script');
  scriptElements =  _.filter(scriptElements, function(element){
    var result = isLocalJS(element.attribs);
    result = result && (jsOptions.local.concat && isLocalJS(element.attribs)) || (jsOptions.inline.concat && isInlineJS(element.attribs));
    return result;
  });

  //return like {local:[], inline:[], remote:[]}
  scriptElements =  _.groupBy(scriptElements, function(element){
    if (isLocalJS(element.attribs)){
      log ('\tfound js '+element.attribs.src);
      return 'local';
    }
    else if (isInlineJS(element.attribs)){
      log ('\tfound inline js '+cheerio(element).text().substr(0, 30));
      return 'inline';
    }
    else return 'other';
  });

  scriptElements.local = _.map(scriptElements.local, function(element){
    return element.attribs.src;
  });

  scriptElements.inline = _.map(scriptElements.inline, function(element){
    return cheerio(element).text();
  });

  return scriptElements;
}

//return local css files
function getStyles(htmlString){
  var result  = {};
  var localCSS = getTags(htmlString, 'link');
  localCSS =  _.filter(localCSS, function(element){
    var result = isLocalCSS(element.attribs);
    if (result) log ('\tfound css file '+element.attribs.href);
    return result;
  });
  localCSS = _.pluck(localCSS, 'attribs');
  result.local = localCSS;

  result.inline = getTags(htmlString, 'style');
  result.inline = _.map(result.inline, function(element){
    return cheerio(element).text();
  });

  return result;
}

function getTags(htmlString, tag){
  return cheerio.load(htmlString)(tag);
}

// CONCAT AND MINIFY
function concatJS(input){
  var result = '';
  if (input.local.length) {
    result = concatSync(input.local)+';';
  }
  if (input.inline.length){
    result += input.inline.join(';');
  }

  if (_options.pack.js.minify) {
    result = UglifyJS.minify(input.local, {
        // outSourceMap: output+".map",
        cwd:_options.basePath,
        compress:true
      });
    result = result.code;
  }

  return result;
}

function concatCSS(input){
  concat(input, output, function() {
    if (_options.pack.css.minify) {
      fs.readFile(output, 'utf8', function(){
        minifyStyles(output, output, onComplete);
      });
    }
    else {
      onComplete && onComplete();
    }
  });
}

//concat css and minify it if specified
function processStyles(input, output, onComplete) {
  concat(input, output, function() {
    if (_options.pack.css.minify) {
      fs.readFile(output, 'utf8', function(){
        minifyStyles(output, output, onComplete);
      });
    }
    else {
      onComplete && onComplete();
    }
  });
}

function compileHTML(data){
  var $ = cheerio.load(data),
      removedJS = false,
      removedCSS = false;
  log('compiling html');

  //remove bundled js script tags
  $('script').each(function(index, element){
    if (_.contains(scriptElements.local, element.attribs.src)||
        _.contains(scriptElements.inline, element.attribs)){
        //_options.pack.js.inline && isInlineJS(element.attribs)) {
      removedJS = true;
      $(this).remove();
    }
  });

  //add bundled js script
  if (removedJS) {
    var $jsParent = $(_options.pack.js.append);
    if ($jsParent.length == 1){
      $jsParent.append('<script type="text/javascript" charset="utf-8" src="'+_options.pack.js.name+'"/>');
    }
    else {
      console.error("Can't append JS to "+_options.pack.js.append+'. No distinct item found.')
    }
  }

  //remove local css links
  $('link').each(function(index, element){
    if (isLocalCSS(element.attribs)) {
      removedCSS = true;
      $(this).remove();
    }
  });

  //add bundled css
  if (removedCSS) {
    var $cssParent = $(_options.pack.css.append);
    if ($cssParent.length == 1){
      $cssParent.append('<link rel="stylesheet" type="text/css" href="'+_options.pack.css.name+'"/>');
    }
    else {
      console.error("Can't append CSS to "+_options.pack.css.append+'. No distinct item found.')
    }
  }

  var html = maybeMinifyHTML(beautifyHTML($.html(), {preserve_newlines:false}));
  writeFile(path.join(_options.output, _options.pack.html.name), html, function(){
    log('done compiling html');
  });
}

function maybeMinifyHTML(html){
  if (_options.pack.html.minify !== false){
    return cheerio.load(html, _options.pack.html).html();
  }

  return html;
}

function minifyScripts(jsString){
  var result = UglifyJS.minify(jsString, {
      // outSourceMap: output+".map",
      fromString:true,
      cwd:_options.basePath,
      compress:true
    });
  return result.code;
}

function minifyStyles(input){
  return new CleanCSS().minify(input).styles;

}

// CONVENIENCE FUNCTIONS
function readFile(filename, onComplete){
  fs.readFile(filename, 'utf8', function(err, data){
    if (err) throw err;
    onComplete(data);
  });
}

function writeFile(filename, data, onComplete){
  fs.writeFile(filename, data, 'utf8', function(err, data){
    if (err) throw err;
    onComplete(data);
  });
}

String.prototype.isLocalFile = function() {
  return this.indexOf('//') === -1;
};

function isLocalJS(file) {
  var filename =  file.src ? file.src.toLowerCase() : file.length ? file.toLowerCase() : null;
  return path.extname(filename) === '.js' && filename.isLocalFile();
}

function isInlineJS(attributes) {
  return attributes.src === undefined && (attributes.type === 'text/javascript' || attributes.type === undefined);
}

function isLocalCSS(file) {
  var filename =  file.href ? file.href.toLowerCase() : file.toLowerCase();
  return path.extname(filename) === '.css' && filename.isLocalFile();
}

function findElementBySelectorOrFilename($, selectorOrFilename){
  var $element;
  try {
    $element = $(selectorOrFilename);
  }
  catch(err) {
      try {
        $element = $('[src="'+selectorOrFilename+'"]');
      }
      catch(err){
        console.error('Couldnt find element '+selectorOrFilename+'.');
      }
  }

  if ($element && $element.length>0){
    return $element;
  }

  return null;
}

function concatSync(files) {
  var str = '';
  for (var i=0; i< files.length; i++){
    var buffer = fs.readFileSync(files[i], 'utf8');
    str += buffer;
  }
  return str;
}

function log(string){
  if (VERBOSE){
    console.log(' '+string);
  }
}

function logTitle(string){
  log(chalk.bgBlue.black.bold('\n '+string.toUpperCase()));
}
<commit_msg>FIXED: parse error when concatenating files<commit_after>var fs = require('fs');
var path = require('path');

var tildify = require('tildify');
var loop = require('serial-loop');
var _ = require('underscore');
var cheerio = require('cheerio');
var concat = require('concat-files');
var UglifyJS = require("uglify-js");
var CleanCSS = require('clean-css');
var chalk = require('chalk');
var copy = require('copy-files');
var glob = require("glob");
var mkdirp = require('mkdirp');
var beautifyHTML = require('js-beautify').html;

const  PACK_JS_DEFAULTS = {
  inline: {concat: false, minify:false},
  local: {concat: true, minify:true},
  remote: false, //NOT SUPPORTED YET
  exclude:[],
  append: 'body',
  name:'bundle.js'
};
const  PACK_CSS_DEFAULTS = {
  inline: {concat: false, minify:true},
  local: {concat: true, minify:true},
  remote: false, //NOT SUPPORTED YET
  exclude:[],
  append: 'head',
  name:'style.css'
};
const  PACK_HTML_DEFAULTS = {
  minify:false,
  name:'index.html',
  //options of htmlparser2 apply
  normalizeWhitespace: true
};

const VERBOSE = true;
var _options = {},
  scriptElements,
  originalCWD = process.cwd();

module.exports = function(options){
  _options = sanitizeOptions(options);

  try {
    log('changing cwd to '+_options.basePath);
    process.chdir(_options.basePath);
  }
  catch (err) {
    console.error('chdir: ' + err);
  }

  //create output folder and sub directories
  mkdirp(_options.output, function(err){
    if (err) throw err;
    log('creating dir '+_options.output+' if not alreay created.');
    var numSubDirectories = 0, numCreatedSubDirectories = 0;
    _.each(_options.output, function(target){
      if (target != _options.output){
        var directory = path.dirname(target);
        if (directory != '.') {
          log('Creating directory '+directory+' in output directory.');
          numSubDirectories++;
          mkdirp(path.join(_options.output, directory), function(){
            numCreatedSubDirectories++;
            //All directories created.
            if(numCreatedSubDirectories == numSubDirectories){
              log('sub directories created.');
            }
          });
        }
      }
    });
    log('Opening Entry File '+path.basename(_options.entry));
    readFile(path.basename(_options.entry), function(htmlString){
      htmlString = remove(htmlString);
      compile(htmlString);
    });
    copyFiles();
  });
};

process.on('exit', function(code) {
  try {
    process.chdir(originalCWD);
    if (code === 0){
      log(chalk.bgGreen.black.bold('\n Finished. You find your files neatly packed together in "'+tildify(path.join(process.cwd(), _options.output))+'".'));
    }
  }
  catch (err) {
    console.error('chdir: ' + err);
  }
});

function copyFiles(){
  logTitle('Copying files...');
  _.each(_options.copy, function(copyEntry){
    log("file pattern: "+copyEntry);
    glob(copyEntry, {ignore:_options.output}, function (err, files) {
      if (err) {
        console.error(err);
      }
      else {
        if (files.length>0) {
          _.each(files, function(file){
            log('trying to copy file '+file);
            var targetFile = path.join(_options.output, file);
            if (fs.lstatSync(file).isFile()) {
              mkdirp(path.dirname(targetFile), function (err) {
                  if (err) console.error(err);
                  else {
                    fs.createReadStream(file).pipe(fs.createWriteStream(targetFile));
                  }
              });
            } else {
              log(chalk.bgYellow.black(targetFile +' is a directory. skipping.'));
            }
          });
        }
      }
    });
  });
}

function remove(htmlString){
  logTitle('removing references');
  var $ = cheerio.load(htmlString);
  _.each(_options.remove, function(element){
    log('Searching for element '+element);
    var $element = findElementBySelectorOrFilename($, element);
    if ($element) {
      log('Element '+element+' found. Removing...');
      $element.remove();
    }
  });

  return $.html();
}

function compile(htmlString) {
  logTitle('processing files');

  processJS(htmlString);
  processCSS(htmlString);

  compileHTML(htmlString);
}

function processJS(htmlString){
  log('processing js..');
  scriptElements = getScripts(htmlString);
  var jsOptions = _options.pack.js;

  var jsString = '';
  var concatAll = jsOptions.local.concat && jsOptions.inline.concat;
  var minifyAll = jsOptions.local.minify && jsOptions.inline.minify;
  if (concatAll && minifyAll){
    jsString = minifyScripts(concatSync(scriptElements.local)+';'+scriptElements.inline.join(';'));
  }
  else if (concatAll && !minifyAll){
    var localJS = concatSync(scriptElements.local);
    var inlineJS = scriptElements.inline.join(';');
    if (jsOptions.local.minify){
      localJS = minifyScripts(localJS);
    }
    if (jsOptions.inline.minify){
      inlineJS = minifyScripts(inlineJS);
    }

    jsString = localJS+';'+inlineJS;
  }
  else if (!concatAll) {
    if (jsOptions.local.concat){
      jsString = concatSync(scriptElements.local);
      if (jsOptions.local.minify){
        jsString = minifyScripts(jsString);
      }
    }
    if (jsOptions.inline.minify){
      //todo
    }
  }

  if (jsString.length>1){
    var bundleFile = path.join(_options.output, _options.pack.js.name);
    writeFile(bundleFile, jsString, function(){
      log('done processing js');
    });
  }
}

//processStyles(, path.join(_options.output, _options.pack.css.name), function(){
function processCSS(htmlString){
  log('processing css..');
  styleElements = getStyles(htmlString);
  var cssOptions = _options.pack.css;

  var cssString = '';
  var concatAll = cssOptions.local.concat && cssOptions.inline.concat;
  var minifyAll = cssOptions.local.minify && cssOptions.inline.minify;
  var localCSS = concatSync(_.pluck(styleElements.local, 'href'));

  if (concatAll) {
    var inlineCSS = styleElements.inline.join(';');
    if (minifyAll) {
      cssString = minifyStyles(localCSS+inlineCSS);
    }
    else {
      if (cssOptions.local.minify){
        localCSS = minifyStyles(localCSS);
      }
      if (cssOptions.inline.minify){
        inlineCSS = minifyScripts(inlineCSS);
      }
      cssString = localCSS+inlineCSS;
    }
  }
  else if (!concatAll) {
    if (cssOptions.local.concat){
      cssString = localCSS;
      if (cssOptions.local.minify){
        cssString = minifyStyles(cssString);
      }
    }
    if (cssOptions.inline.minify){
      //todo
    }
  }

  if (cssString.length>1){
    var bundleFile = path.join(_options.output, _options.pack.css.name);
    writeFile(bundleFile, cssString, function(){
      log('done processing css');
    });
  }
}

function sanitizeOptions(options) {
  options.pack = options.pack || options.minify;
  options.entry = options.entry || options.entryFile;

  options.pack.js = defaults(options.pack.js, PACK_JS_DEFAULTS);
  options.pack.css = defaults(options.pack.css, PACK_CSS_DEFAULTS);
  options.pack.html = defaults(options.pack.html, PACK_HTML_DEFAULTS);

  normalizePaths(options.pack.js.exclude);
  normalizePaths(options.pack.css.exclude);

  options.basePath = path.dirname(options.entry);
  options.remove = options.remove || [];
  options.copy = options.copy || [];

  return options;
}
function normalizePaths(pathArray){
  _.each(pathArray, function(thePath, i){
    pathArray[i] = path.normalize(thePath);
  })
}

function defaults(object, defaultOptions){
  if (object === true) {
    return defaultOptions;
  }
  else if (!object) {
    return _.each(defaultOptions, function(item, key){defaultOptions[key]=false;});
  }
  else if (_.isObject(object)) {
    return _.defaults(object, defaultOptions);
  }
}

function getScripts(htmlString){
  var jsOptions = _options.pack.js;
  var $ = cheerio.load(htmlString);
  _.each(jsOptions.exclude, function(itemToExclude){
    var $itemToExclude = findElementBySelectorOrFilename($, itemToExclude);
    if ($itemToExclude) {
      $itemToExclude.remove();
    }
  });
  htmlString = $.html();
  var scriptElements = getTags(htmlString, 'script');
  scriptElements =  _.filter(scriptElements, function(element){
    var result = isLocalJS(element.attribs);
    result = result && (jsOptions.local.concat && isLocalJS(element.attribs)) || (jsOptions.inline.concat && isInlineJS(element.attribs));
    return result;
  });

  //return like {local:[], inline:[], remote:[]}
  scriptElements =  _.groupBy(scriptElements, function(element){
    if (isLocalJS(element.attribs)){
      log ('\tfound js '+element.attribs.src);
      return 'local';
    }
    else if (isInlineJS(element.attribs)){
      log ('\tfound inline js '+cheerio(element).text().substr(0, 30));
      return 'inline';
    }
    else return 'other';
  });

  scriptElements.local = _.map(scriptElements.local, function(element){
    return element.attribs.src;
  });

  scriptElements.inline = _.map(scriptElements.inline, function(element){
    return cheerio(element).text();
  });

  return scriptElements;
}

//return local css files
function getStyles(htmlString){
  var result  = {};
  var localCSS = getTags(htmlString, 'link');
  localCSS =  _.filter(localCSS, function(element){
    var result = isLocalCSS(element.attribs);
    if (result) log ('\tfound css file '+element.attribs.href);
    return result;
  });
  localCSS = _.pluck(localCSS, 'attribs');
  result.local = localCSS;

  result.inline = getTags(htmlString, 'style');
  result.inline = _.map(result.inline, function(element){
    return cheerio(element).text();
  });

  return result;
}

function getTags(htmlString, tag){
  return cheerio.load(htmlString)(tag);
}

// CONCAT AND MINIFY
function concatJS(input){
  var result = '';
  if (input.local.length) {
    result = concatSync(input.local)+';';
  }
  if (input.inline.length){
    result += input.inline.join(';');
  }

  if (_options.pack.js.minify) {
    result = UglifyJS.minify(input.local, {
        // outSourceMap: output+".map",
        cwd:_options.basePath,
        compress:true
      });
    result = result.code;
  }

  return result;
}

function concatCSS(input){
  concat(input, output, function() {
    if (_options.pack.css.minify) {
      fs.readFile(output, 'utf8', function(){
        minifyStyles(output, output, onComplete);
      });
    }
    else {
      onComplete && onComplete();
    }
  });
}

//concat css and minify it if specified
function processStyles(input, output, onComplete) {
  concat(input, output, function() {
    if (_options.pack.css.minify) {
      fs.readFile(output, 'utf8', function(){
        minifyStyles(output, output, onComplete);
      });
    }
    else {
      onComplete && onComplete();
    }
  });
}

function compileHTML(data){
  var $ = cheerio.load(data),
      removedJS = false,
      removedCSS = false;
  log('compiling html');

  //remove bundled js script tags
  $('script').each(function(index, element){
    if (_.contains(scriptElements.local, element.attribs.src)||
        _.contains(scriptElements.inline, element.attribs)){
        //_options.pack.js.inline && isInlineJS(element.attribs)) {
      removedJS = true;
      $(this).remove();
    }
  });

  //add bundled js script
  if (removedJS) {
    var $jsParent = $(_options.pack.js.append);
    if ($jsParent.length == 1){
      $jsParent.append('<script type="text/javascript" charset="utf-8" src="'+_options.pack.js.name+'"/>');
    }
    else {
      console.error("Can't append JS to "+_options.pack.js.append+'. No distinct item found.')
    }
  }

  //remove local css links
  $('link').each(function(index, element){
    if (isLocalCSS(element.attribs)) {
      removedCSS = true;
      $(this).remove();
    }
  });

  //add bundled css
  if (removedCSS) {
    var $cssParent = $(_options.pack.css.append);
    if ($cssParent.length == 1){
      $cssParent.append('<link rel="stylesheet" type="text/css" href="'+_options.pack.css.name+'"/>');
    }
    else {
      console.error("Can't append CSS to "+_options.pack.css.append+'. No distinct item found.')
    }
  }

  var html = maybeMinifyHTML(beautifyHTML($.html(), {preserve_newlines:false}));
  writeFile(path.join(_options.output, _options.pack.html.name), html, function(){
    log('done compiling html');
  });
}

function maybeMinifyHTML(html){
  if (_options.pack.html.minify !== false){
    return cheerio.load(html, _options.pack.html).html();
  }

  return html;
}

function minifyScripts(jsString){
  var result = UglifyJS.minify(jsString, {
      // outSourceMap: output+".map",
      fromString:true,
      cwd:_options.basePath,
      compress:true
    });
  return result.code;
}

function minifyStyles(input){
  return new CleanCSS().minify(input).styles;

}

// CONVENIENCE FUNCTIONS
function readFile(filename, onComplete){
  fs.readFile(filename, 'utf8', function(err, data){
    if (err) throw err;
    onComplete(data);
  });
}

function writeFile(filename, data, onComplete){
  fs.writeFile(filename, data, 'utf8', function(err, data){
    if (err) throw err;
    onComplete(data);
  });
}

String.prototype.isLocalFile = function() {
  return this.indexOf('//') === -1;
};

function isLocalJS(file) {
  var filename =  file.src ? file.src.toLowerCase() : file.length ? file.toLowerCase() : null;
  return path.extname(filename) === '.js' && filename.isLocalFile();
}

function isInlineJS(attributes) {
  return attributes.src === undefined && (attributes.type === 'text/javascript' || attributes.type === undefined);
}

function isLocalCSS(file) {
  var filename =  file.href ? file.href.toLowerCase() : file.toLowerCase();
  return path.extname(filename) === '.css' && filename.isLocalFile();
}

function findElementBySelectorOrFilename($, selectorOrFilename){
  var $element;
  try {
    $element = $(selectorOrFilename);
  }
  catch(err) {
      try {
        $element = $('[src="'+selectorOrFilename+'"]');
      }
      catch(err){
        console.error('Couldnt find element '+selectorOrFilename+'.');
      }
  }

  if ($element && $element.length>0){
    return $element;
  }

  return null;
}

function concatSync(files) {
  var str = ';';
  for (var i=0; i< files.length; i++){
    var buffer = fs.readFileSync(files[i], 'utf8');
    str += buffer+';';
  }
  return str;
}

function log(string){
  if (VERBOSE){
    console.log(' '+string);
  }
}

function logTitle(string){
  log(chalk.bgBlue.black.bold('\n '+string.toUpperCase()));
}
<|endoftext|>


<commit_before>var utils = require('./utils'),
    scope = require('./scope'),
    _global = require('./core/global'),
    _array = require('./core/array'),
    _date = require('./core/date'),
    _function = require('./core/function'),
    _json = require('./core/json'),
    _string = require('./core/string'),
    _math = require('./core/math'),
    _number = require('./core/number');

module.exports = {

  evaluate: function(node) {
    var handler = undefined;

    if (node.property) {
      var method = node.property.name;
      handler = _array[method] || _date[method] || _function[method] || _json[method] || _string[method] || _math[method] || _number[method];

    } else if (node.callee) {
      handler = _global[node.callee.name];
    }

    if (handler) {
      var node = handler(node);
      node.scope = scope.create(node);
    }

    return node;
  }

}
<commit_msg>better syntax<commit_after>var utils = require('./utils'),
    scope = require('./scope'),
    _global = require('./core/global'),
    _array = require('./core/array'),
    _date = require('./core/date'),
    _function = require('./core/function'),
    _json = require('./core/json'),
    _string = require('./core/string'),
    _math = require('./core/math'),
    _number = require('./core/number');

module.exports = {

  evaluate: function(node) {
    var handler = undefined;

    if (node.property) {
      var method = node.property.name;
      handler = _array[method] || _date[method] || _function[method] || _json[method] || _string[method] || _math[method] || _number[method];

    } else if (node.callee) {
      handler = _global[node.callee.name];
    }

    if (handler) {
      node = handler(node);
      node.scope = scope.create(node);
    }

    return node;
  }

}
<|endoftext|>


<commit_before>var ambi = require('node-ambiclimate');
var Service, Characteristic;

module.exports = function(homebridge) {
    Service        = homebridge.hap.Service;
    Characteristic = homebridge.hap.Characteristic;
    homebridge.registerAccessory("homebridge-ambiclimate", "AmbiClimate", AmbiClimate);
}

function AmbiClimate(log, config) {
    this.log           = log;
    this.name          = config.name;
    this.settings      = {
        room_name: config.roomName,
        location_name: config.locationName
    };

    this.client = new ambi(config.clientId, config.clientSecret, config.username, config.password);

    // Object to maintain the state of the device.  This is done as there is
    // not official API to get this information.  If the Ambi Climate state is
    // changed through an alternative channel, that change will not be reflected
    // within Homekit
    this.state              = {};
    this.state.on           = false;

    this.temperatureService = new Service.TemperatureSensor(this.name);
    this.humidityService    = new Service.HumiditySensor(this.name);
    this.switchService      = new Service.Switch(this.name);
    this.informationService = new Service.AccessoryInformation();
}

AmbiClimate.prototype = {
    getCurrentTemperature: function(callback) {
        var accessory = this;
        console.log("Temperature - settings: "+JSON.stringify(accessory.settings));
        accessory.client.sensor_temperature(accessory.settings, function (err, data) {
            console.log("Temperature - typeof data: "+(typeof data));
            console.log("Temperature - isArray: "+(data.isArray))
            console.log("Temperature - data: " +JSON.stringify(data));
            callback(err, 0);
//            callback(err, data[0].value);
        });
    },
    getCurrentRelativeHumidity: function(callback) {
        var accessory = this;
        console.log("Humidity - settings: "+JSON.stringify(accessory.settings));
        accessory.client.sensor_humidity(accessory.settings, function (err, data) {
            console.log("Humidity - typeof data: "+(typeof data));
            console.log("Humidity - isArray: "+(data.isArray))
            console.log("Humidity - data: " +JSON.stringify(data));
            callback(err, 0);
//            callback(err, data[0].value);
        });
    },
    // Sets the Ambi Climate Mode based on a switch.  If the device is being
    // turned on, change the state of 'Comfort'.  Otherwise turn it off.
    setMode: function(callback) {
        var accessory = this;

        if (accessory.state.on) {
            accessory.client.comfort(accessory.settings, function (err,data) {
                callback(err);
            });
        } else {
            accessory.client.off(accessory.settings, function (err,data) {
                callback(err);
            });
        }
    },

    //
    // Services
    //
    getServices: function () {
        this.temperatureService.getCharacteristic(Characteristic.CurrentTemperature)
            .on('get', function(callback) {
                this.getCurrentTemperature(function(error,data){
                    this.log("Returned temperature: "+ data)
                    callback(error, data);
                }.bind(this));
            }.bind(this));

        this.humidityService.getCharacteristic(Characteristic.CurrentRelativeHumidity)
            .on('get', function(callback) {
                this.getCurrentRelativeHumidity(function(error,data){
                    this.log("Returned humidity: "+ data)
                    callback(error, data);
                }.bind(this));
            }.bind(this));

        this.switchService.getCharacteristic(Characteristic.On)
            // Return value maintained within state machine
            .on('get', function(callback) {
                callback(null, this.state.on);
            }.bind(this))
            .on('set', function(value, callback) {
                this.state.on = value;
                this.setMode(function(error,data) {
                    callback(error);
                }.bind(this));
            }.bind(this));

 		this.informationService
			.setCharacteristic(Characteristic.Manufacturer, "Ambi Labs")
			.setCharacteristic(Characteristic.Model, "Ambi Climate")
			.setCharacteristic(Characteristic.SerialNumber, " ");

        return [this.temperatureService,this.humidityService,this.switchService,this.informationService];
    }
}
<commit_msg>Changed method of setting this.settings<commit_after>var ambi = require('node-ambiclimate');
var Service, Characteristic;

module.exports = function(homebridge) {
    Service        = homebridge.hap.Service;
    Characteristic = homebridge.hap.Characteristic;
    homebridge.registerAccessory("homebridge-ambiclimate", "AmbiClimate", AmbiClimate);
}

function AmbiClimate(log, config) {
    this.log                    = log;
    this.name                   = config.name;
    this.settings               = {};
    this.settings.room_name     = config.roomName,
    this.settings.location_name = config.locationName;

    this.client = new ambi(config.clientId, config.clientSecret, config.username, config.password);

    // Object to maintain the state of the device.  This is done as there is
    // not official API to get this information.  If the Ambi Climate state is
    // changed through an alternative channel, that change will not be reflected
    // within Homekit
    this.state              = {};
    this.state.on           = false;

    this.temperatureService = new Service.TemperatureSensor(this.name);
    this.humidityService    = new Service.HumiditySensor(this.name);
    this.switchService      = new Service.Switch(this.name);
    this.informationService = new Service.AccessoryInformation();
}

AmbiClimate.prototype = {
    getCurrentTemperature: function(callback) {
        var accessory = this;
        console.log("Temperature - settings: "+JSON.stringify(accessory.settings));
        accessory.client.sensor_temperature(accessory.settings, function (err, data) {
            console.log("Temperature - typeof data: "+(typeof data));
            console.log("Temperature - isArray: "+(data.isArray))
            console.log("Temperature - data: " +JSON.stringify(data));
            callback(err, 0);
//            callback(err, data[0].value);
        });
    },
    getCurrentRelativeHumidity: function(callback) {
        var accessory = this;
        console.log("Humidity - settings: "+JSON.stringify(accessory.settings));
        accessory.client.sensor_humidity(accessory.settings, function (err, data) {
            console.log("Humidity - typeof data: "+(typeof data));
            console.log("Humidity - isArray: "+(data.isArray))
            console.log("Humidity - data: " +JSON.stringify(data));
            callback(err, 0);
//            callback(err, data[0].value);
        });
    },
    // Sets the Ambi Climate Mode based on a switch.  If the device is being
    // turned on, change the state of 'Comfort'.  Otherwise turn it off.
    setMode: function(callback) {
        var accessory = this;

        if (accessory.state.on) {
            accessory.client.comfort(accessory.settings, function (err,data) {
                callback(err);
            });
        } else {
            accessory.client.off(accessory.settings, function (err,data) {
                callback(err);
            });
        }
    },

    //
    // Services
    //
    getServices: function () {
        this.temperatureService.getCharacteristic(Characteristic.CurrentTemperature)
            .on('get', function(callback) {
                this.getCurrentTemperature(function(error,data){
                    this.log("Returned temperature: "+ data)
                    callback(error, data);
                }.bind(this));
            }.bind(this));

        this.humidityService.getCharacteristic(Characteristic.CurrentRelativeHumidity)
            .on('get', function(callback) {
                this.getCurrentRelativeHumidity(function(error,data){
                    this.log("Returned humidity: "+ data)
                    callback(error, data);
                }.bind(this));
            }.bind(this));

        this.switchService.getCharacteristic(Characteristic.On)
            // Return value maintained within state machine
            .on('get', function(callback) {
                callback(null, this.state.on);
            }.bind(this))
            .on('set', function(value, callback) {
                this.state.on = value;
                this.setMode(function(error,data) {
                    callback(error);
                }.bind(this));
            }.bind(this));

 		this.informationService
			.setCharacteristic(Characteristic.Manufacturer, "Ambi Labs")
			.setCharacteristic(Characteristic.Model, "Ambi Climate")
			.setCharacteristic(Characteristic.SerialNumber, " ");

        return [this.temperatureService,this.humidityService,this.switchService,this.informationService];
    }
}
<|endoftext|>


<commit_before>var crypto  = require('crypto');
var express = require('express');
var app = express();
var rooms = {};
var counter = 0;

app.use(express.bodyParser());
app.use('/static/lib', express.static(__dirname + '/bower_components'));
app.use('/static', express.static(__dirname + '/public'));

app.get("/", function(req, res) {
  res.sendfile(__dirname + '/public/index.html');
});

app.post("/rooms", function(req, res) {
  var room = req.param('room') || crypto.randomBytes(16).toString('hex');
  rooms[room] = [];
  res.redirect('/rooms/' + room);
});

app.get('/rooms/:room', function(req, res) {
  var room  = req.param('room');

  if (room in rooms)
    res.sendfile(__dirname + '/public/room.html');
  else
    res.status(404).sendfile(__dirname + '/public/404.html');
});

app.get("/rooms/:room/signalling", function(req, res) {
  var room = req.param('room');
  var users = rooms[room];
  var uid = crypto.randomBytes(16).toString('hex');
  var timer;
  console.log('new friend');

  res.writeHead(200, {
    "Content-Type":  "text/event-stream",
    "Cache-Control": "no-cache",
    "Connection":    "keep-alive"
  });

  req.on("close", function() {
    var users = rooms[room];
    rooms[room] = users.filter(function(user) {
      return user.connection !== res;
    });
    clearInterval(timer);
  });

  var event = JSON.stringify({type: 'uid', uid: uid});
  res.write("event: uid\n");
  res.write("data: " + event + "\n\n");

  // we send a ping comment every n seconds to keep the connection
  // alive.
  timer = setInterval(function() {
    res.write(":p\n\n");
  }, 20000);

  users.forEach(function(user) {
    user.stream.write("event: newbuddy\n");
    user.stream.write("data: {}\n\n");
  });
  users.push({uid: uid, stream: res});
});

app.post("/rooms/:room/signalling", function(req, res) {
  var room  = req.param('room');
  var users = rooms[room];
  var type  = req.body.type;
  var event = JSON.stringify(req.body);
  console.log(req.body);

  users.forEach(function(user) {
    if (user.uid === req.body.from)
      return;

    user.stream.write("event: " + type + "\n");
    user.stream.write("data: " + event + "\n\n");
  });

  res.send(200);
});

app.listen(6424);
console.log('Listening on port 6424');

<commit_msg>Upgrade express.js<commit_after>var crypto  = require('crypto');
var express = require('express');
var app = express();
var rooms = {};
var counter = 0;

app.use(express.bodyParser());
app.use('/static/lib', express.static(__dirname + '/bower_components'));
app.use('/static', express.static(__dirname + '/public'));

app.get("/", function(req, res) {
  res.sendfile('/public/index.html', {root: __dirname});
});

app.post("/rooms", function(req, res) {
  var room = req.param('room') || crypto.randomBytes(16).toString('hex');
  rooms[room] = [];
  res.redirect('/rooms/' + room);
});

app.get('/rooms/:room', function(req, res) {
  var room  = req.param('room');

  if (room in rooms)
    res.sendfile('/public/room.html', {root: __dirname});
  else
    res.status(404).sendfile('/public/404.html', {root: __dirname});
});

app.get("/rooms/:room/signalling", function(req, res) {
  var room = req.param('room');
  var users = rooms[room];
  var uid = crypto.randomBytes(16).toString('hex');
  var timer;
  console.log('new friend');

  res.writeHead(200, {
    "Content-Type":  "text/event-stream",
    "Cache-Control": "no-cache",
    "Connection":    "keep-alive"
  });

  req.on("close", function() {
    var users = rooms[room];
    rooms[room] = users.filter(function(user) {
      return user.connection !== res;
    });
    clearInterval(timer);
  });

  var event = JSON.stringify({type: 'uid', uid: uid});
  res.write("event: uid\n");
  res.write("data: " + event + "\n\n");

  // we send a ping comment every n seconds to keep the connection
  // alive.
  timer = setInterval(function() {
    res.write(":p\n\n");
  }, 20000);

  users.forEach(function(user) {
    user.stream.write("event: newbuddy\n");
    user.stream.write("data: {}\n\n");
  });
  users.push({uid: uid, stream: res});
});

app.post("/rooms/:room/signalling", function(req, res) {
  var room  = req.param('room');
  var users = rooms[room];
  var type  = req.body.type;
  var event = JSON.stringify(req.body);
  console.log(req.body);

  users.forEach(function(user) {
    if (user.uid === req.body.from)
      return;

    user.stream.write("event: " + type + "\n");
    user.stream.write("data: " + event + "\n\n");
  });

  res.send(200);
});

app.listen(6424);
console.log('Listening on port 6424');

<|endoftext|>