<commit_before>'use strict';
Array.prototype.last = function () {return this[this.length - 1]};
const fs = require('fs');
const cp = require('child_process');
const entities = new (require('html-entities').AllHtmlEntities)();
let server;
let fails = 0;
runServer();

function runServer() {
  try {
    if (process.argv[2] === 'use-https') {
      const https = require('https');
      let options = {
        key: fs.readFileSync('key.pem'),
        cert: fs.readFileSync('cert.pem')
      };
      server = https.createServer(options, listener);
    } else {
      const http = require('http');
      server = http.createServer(listener);
    }
    server.listen(8192, function () {
      console.log('Server online.');
    });
  } catch (e) {
    console.log(e.message);
    fails++;
    if (fails >= 30) return;
    runServer();
  }
}

function listener(request, response) {
  let url = require('url').parse(request.url);
  switch (request.method) {
    case 'GET':
      processGET(request, response, url);
      break;
    case 'POST':
      processPOST(request, response, url);
      break;
    default: sendError(response, 400, `Bad request: method not supported (${request.method}).`);
  }
}

function processPOST(request, response, url) {
  let body = '';
  request.setEncoding('utf8');
  request.on('data', function (e) {body += e});
  request.on('end', function () {
    body = entities.decode(body.replace(/\t/g, '\n'));
    execute(url.pathname.slice(1), body, function (error, stdout, stderr) {
      if (error) {
        console.error(`Code encountered an error: ${error.message}`);
        sendError(response, 400, `Could not execute code: ${error.message}`);
      } else {
        response.writeHead(200, {
          'Cache-Control': 'max-age=0',
          'Access-Control-Allow-Origin': '109.103.29.52',
          'Content-Type': 'text/plain',
          'Server': 'Slak\'s Server'
        });
        response.write(stdout);
        response.end();
      }
    });
  });
}

function processGET(request, response, url) {
  switch (url.pathname) {
    case '/':
      sendFile(response, 'index/main.html', 'document');
      break;
    case '/highlight/obsidian.css':
    case '/main.css':
      sendFile(response, `index${url.pathname}`, 'text/css');
      break;
    case '/highlight/highlight.pack.js':
    case '/script.js':
      sendFile(response, `index${url.pathname}`, 'text/javascript');
      break;
    default: sendError(response, 404, 'Not found.');
  }
}

function sendFile(response, filePath, mimeType) {
  if (!filePath) throw new Error('Path not specified.');
  if (!mimeType) mimeType = 'text/plain';
  fs.readFile(filePath, {encoding: 'utf-8'}, function (err, data) {
    if (err) sendError(response, 500, `Internal server error: could not find ${filePath}`);
    else {
      response.writeHead(200, {
        'Cache-Control': 'max-age=3600',
        'Access-Control-Allow-Origin': '109.103.29.52',
        'Content-Type': mimeType,
        'Server': 'Slak\'s Server'
      });
      response.write(data);
      response.end();
    }
  });
}

function sendError(response, code, msg) {
  response.writeHead(code, msg, {
    'Access-Control-Allow-Origin': '109.103.29.52',
    'Connection': 'close',
    'Content-Type': 'text/html',
    'Server': 'Slak\'s Server'
  });
  response.write(
    `
      <title>${code}</title>

${code}: ${msg}

    `
  );
  response.end();
}

function execute(lang, code, output) {
  let fileName = `${Math.random()}.${lang.slice(5)}`;
  if (lang === 'lang-java') fileName = `${code.match(/class(.*?){/).last().trim()}.java`; // Because java's a special snowflake and hates misnamed files
  fs.writeFile(fileName, code.trim(), function (err) {
    if (err) throw err;
    cp.exec(`iojs -harmony ./execute/${lang}.js "${fileName}"`, function (err, stdout, stderr) {
      fs.unlink(fileName);
      output(err, stdout, stderr);
    });
  });
}<commit_msg>Implemented output in server<commit_after>'use strict';
Array.prototype.last = function () {return this[this.length - 1]};
const fs = require('fs');
const cp = require('child_process');
const entities = new (require('html-entities').AllHtmlEntities)();
let server;
let fails = 0;
runServer();

function runServer() {
  try {
    if (process.argv[2] === 'use-https') {
      const https = require('https');
      let options = {
        key: fs.readFileSync('key.pem'),
        cert: fs.readFileSync('cert.pem')
      };
      server = https.createServer(options, listener);
    } else {
      const http = require('http');
      server = http.createServer(listener);
    }
    server.listen(8192, function () {
      console.log('Server online.');
    });
  } catch (e) {
    console.log(e.message);
    fails++;
    if (fails >= 30) return;
    runServer();
  }
}

function listener(request, response) {
  let url = require('url').parse(request.url);
  switch (request.method) {
    case 'GET':
      processGET(request, response, url);
      break;
    case 'POST':
      processPOST(request, response, url);
      break;
    default: sendError(response, 400, `Bad request: method not supported (${request.method}).`);
  }
}

function processPOST(request, response, url) {
  let body = '';
  request.setEncoding('utf8');
  request.on('data', function (e) {body += e});
  request.on('end', function () {
    body = entities.decode(body.replace(/\t/g, '\n'));
    execute(url.pathname.slice(1), body, function (error, stdout, stderr) {
      if (error) console.error(`Could not execute code: ${error.message}`);
      response.writeHead((error)? 400 : 200, {
        'Cache-Control': 'max-age=0',
        'Access-Control-Allow-Origin': '109.103.29.52',
        'Content-Type': 'text/plain',
        'Server': 'Slak\'s Server'
      });
      response.write(entities.encode(`Status:\n${(error)? '400 Bad Request' : '200 OK'}\n\nSTDERR:\n${stderr}\nSTDOUT:\n${stdout}`));
      response.end();
    });
  });
}

function processGET(request, response, url) {
  switch (url.pathname) {
    case '/':
      sendFile(response, 'index/main.html', 'document');
      break;
    case '/highlight/obsidian.css':
    case '/main.css':
      sendFile(response, `index${url.pathname}`, 'text/css');
      break;
    case '/highlight/highlight.pack.js':
    case '/script.js':
      sendFile(response, `index${url.pathname}`, 'text/javascript');
      break;
    default: sendError(response, 404, 'Not found.');
  }
}

function sendFile(response, filePath, mimeType) {
  if (!filePath) throw new Error('Path not specified.');
  if (!mimeType) mimeType = 'text/plain';
  fs.readFile(filePath, {encoding: 'utf-8'}, function (err, data) {
    if (err) sendError(response, 500, `Internal server error: could not find ${filePath}`);
    else {
      response.writeHead(200, {
        'Cache-Control': 'max-age=3600',
        'Access-Control-Allow-Origin': '109.103.29.52',
        'Content-Type': mimeType,
        'Server': 'Slak\'s Server'
      });
      response.write(data);
      response.end();
    }
  });
}

function sendError(response, code, msg) {
  response.writeHead(code, msg, {
    'Access-Control-Allow-Origin': '109.103.29.52',
    'Connection': 'close',
    'Content-Type': 'text/html',
    'Server': 'Slak\'s Server'
  });
  response.write(
    `
      <title>${code}</title>

${code}: ${msg}

    `
  );
  response.end();
}

function execute(lang, code, output) {
  let fileName = `${Math.random()}.${lang.slice(5)}`;
  if (lang === 'lang-java') fileName = `${code.match(/class(.*?){/).last().trim()}.java`; // Because java's a special snowflake and hates misnamed files
  fs.writeFile(fileName, code.trim(), function (err) {
    if (err) throw err;
    cp.exec(`iojs -harmony ./execute/${lang}.js "${fileName}"`, function (err, stdout, stderr) {
      fs.unlink(fileName);
      output(err, stdout, stderr);
    });
  });
}<|endoftext|>


<commit_before>// Gulp utils
var gulp = require('gulp-help')(require('gulp'));
var u = require('gulp-util');
var log = u.log;
var c = u.colors;
var spawn = require('child_process').spawn;

// Include Our Plugins
var bs = require('browser-sync');
var reload = bs.reload;
var rename = require('gulp-rename');
var sass = require('gulp-sass');
var prefix = require('gulp-autoprefixer');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var minCSS = require('gulp-minify-css');
var imagemin = require('gulp-imagemin');

//////////////////////////////
// Jekyll
//////////////////////////////
gulp.task('jekyll', 'Compiles Jekyll site in dev mode.', function() {
  bs.notify('Jekyll building...');

  return spawn('bundle', ['exec', 'jekyll', 'build', '--config=_config.yml,_config.dev.yml'], {stdio: 'inherit'})
    .on('close', reload);
});

//////////////////////////////
// BrowserSync
//////////////////////////////
gulp.task('browser-sync', false, function() {
  bs({
    server: './_site/'
  });
});

//////////////////////////////
// Sass
//////////////////////////////
gulp.task('sass', 'Compiles Sass using libsass.', function () {
  bs.notify('Sass compiling...');

  return gulp.src('_sass/**/*.scss')
    .pipe(sass({
      outputStyle: 'nested',
      onSuccess: function(css) {
        var dest = css.stats.entry.split('/');
        log(c.green('sass'), 'compiled to', dest[dest.length - 1]);
      },
      onError: function(err, res) {
        bs.notify('Sass failed');
        log(c.red('Sass failed to compile'));
        log(c.red('> ') + err.file.split('/')[err.file.split('/').length - 1] + ' ' + c.underline('line ' + err.line) + ': ' + err.message);
      }
    }))
    .pipe(gulp.dest('css'))
    .pipe(prefix("last 2 versions", "> 1%"))
    .pipe(minCSS())
    .pipe(rename('main.min.css'))
    .pipe(gulp.dest('css'))
    .pipe(gulp.dest('_site/css'))
    .pipe(gulp.dest('_includes'))
    .pipe(reload({stream: true}));
});

//////////////////////////////
// Minify images
//////////////////////////////
gulp.task('js', 'Lint, bundle, minify JS', function() {
  return gulp.src('_js/**/*.js')
    .pipe(concat('main.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('js'))
    .pipe(gulp.dest('_site/js'));
});

//////////////////////////////
// Minify images
//////////////////////////////
gulp.task('imagemin', 'Compress images.', function() {
  return gulp.src('_img/**/*')
    .pipe(imagemin({
      progressive: true,
      svgoPlugins: [{removeViewBox: false}]
    }))
    .pipe(gulp.dest('img'));
});

//////////////////////////////
// BrowserSync + Gulp watch
//////////////////////////////
gulp.task('bs', 'Run dev tasks:', ['sass', 'js', 'imagemin', 'jekyll', 'browser-sync', 'watch']);

// Watch Files For Changes
gulp.task('watch', 'Watch various files for changes and re-compile them.', function() {
  gulp.watch('_sass/**/*.scss', ['sass']);
  gulp.watch('_img/**/*', ['imagemin']);
  gulp.watch('_js/**/*', ['js']);
  gulp.watch(['_config*', '**/*.{md,html}', '!_site/**/*.*'], ['jekyll']);
});

// Add a default task to render the available commands.
gulp.task('default', false, ['help']);
<commit_msg>:construction: reload page when JS is saved<commit_after>// Gulp utils
var gulp = require('gulp-help')(require('gulp'));
var u = require('gulp-util');
var log = u.log;
var c = u.colors;
var spawn = require('child_process').spawn;

// Include Our Plugins
var bs = require('browser-sync');
var reload = bs.reload;
var rename = require('gulp-rename');
var sass = require('gulp-sass');
var prefix = require('gulp-autoprefixer');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var minCSS = require('gulp-minify-css');
var imagemin = require('gulp-imagemin');

//////////////////////////////
// Jekyll
//////////////////////////////
gulp.task('jekyll', 'Compiles Jekyll site in dev mode.', function() {
  bs.notify('Jekyll building...');

  return spawn('bundle', ['exec', 'jekyll', 'build', '--config=_config.yml,_config.dev.yml'], {stdio: 'inherit'})
    .on('close', reload);
});

//////////////////////////////
// BrowserSync
//////////////////////////////
gulp.task('browser-sync', false, function() {
  bs({
    server: './_site/'
  });
});

//////////////////////////////
// Sass
//////////////////////////////
gulp.task('sass', 'Compiles Sass using libsass.', function () {
  bs.notify('Sass compiling...');

  return gulp.src('_sass/**/*.scss')
    .pipe(sass({
      outputStyle: 'nested',
      onSuccess: function(css) {
        var dest = css.stats.entry.split('/');
        log(c.green('sass'), 'compiled to', dest[dest.length - 1]);
      },
      onError: function(err, res) {
        bs.notify('Sass failed');
        log(c.red('Sass failed to compile'));
        log(c.red('> ') + err.file.split('/')[err.file.split('/').length - 1] + ' ' + c.underline('line ' + err.line) + ': ' + err.message);
      }
    }))
    .pipe(gulp.dest('css'))
    .pipe(prefix("last 2 versions", "> 1%"))
    .pipe(minCSS())
    .pipe(rename('main.min.css'))
    .pipe(gulp.dest('css'))
    .pipe(gulp.dest('_site/css'))
    .pipe(gulp.dest('_includes'))
    .pipe(reload({stream: true}));
});

//////////////////////////////
// Minify images
//////////////////////////////
gulp.task('js', 'Lint, bundle, minify JS', function() {
  bs.notify('Building JS...');

  return gulp.src('_js/**/*.js')
    .pipe(concat('main.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('js'))
    .pipe(gulp.dest('_site/js'))
    .pipe(reload({stream: true}));
});

//////////////////////////////
// Minify images
//////////////////////////////
gulp.task('imagemin', 'Compress images.', function() {
  return gulp.src('_img/**/*')
    .pipe(imagemin({
      progressive: true,
      svgoPlugins: [{removeViewBox: false}]
    }))
    .pipe(gulp.dest('img'));
});

//////////////////////////////
// BrowserSync + Gulp watch
//////////////////////////////
gulp.task('bs', 'Run dev tasks:', ['sass', 'js', 'imagemin', 'jekyll', 'browser-sync', 'watch']);

// Watch Files For Changes
gulp.task('watch', 'Watch various files for changes and re-compile them.', function() {
  gulp.watch('_sass/**/*.scss', ['sass']);
  gulp.watch('_img/**/*', ['imagemin']);
  gulp.watch('_js/**/*', ['js']);
  gulp.watch(['_config*', '**/*.{md,html}', '!_site/**/*.*'], ['jekyll']);
});

// Add a default task to render the available commands.
gulp.task('default', false, ['help']);
<|endoftext|>


<commit_before>'use strict';

const lint = require('mocha-eslint');

let paths = [
  'lib/**/*.js',
  'tests/**/*.js',
  '!tests/fixtures/**',
];

let options = {
  strict: true,  // Defaults to `false`, only notify the warnings
};

// Run the tests
lint(paths, options);
<commit_msg>Allow Node v0.12.x support<commit_after>'use strict';

var lint = require('mocha-eslint');

var paths = [
  'lib/**/*.js',
  'tests/**/*.js',
  '!tests/fixtures/**',
];

var options = {
  strict: true,  // Defaults to `false`, only notify the warnings
};

// Run the tests
lint(paths, options);
<|endoftext|>


<commit_before>var gulp = require('gulp');
var through = require('through2');
var gutil = require('gulp-util');
var mlqcow = require('./lib/index');
var PluginError = gutil.PluginError;

var OUT_DIR = './QC/';
var IN_DIR = './QC/';
var CONF, EXPORT_NAME;
// todo: review config format. convert to tab array

gulp.task('default', showHelp);
gulp.task('generate', generate);

//-----
function generate () {
    mlqcow.setup({
        outDir : OUT_DIR,
        inDir : IN_DIR
    });
    mlqcow.generate()
}
function showHelp (cb) {
    console.log([
	'',
	'gulp TASK',
	'USAGE:',
	'  generate    : creates something.xml for import',
	''
    ].join('\n'));
    cb();
}
<commit_msg>Gulp dependency extraneous since changing to global package<commit_after><|endoftext|>


<commit_before>/* eslint-env browser, node */

'use strict';

// Imports
var conversions = require('./conversions');
var isNumeric = require('isNumeric/isNumeric');

var units = {};

//  Public interface
//------------------------------------------------------------------------------

units.convert = function(to, value, element, property) {
  var parts = units.parse(value, property);
  var values;
  var len;
  var i;

  if (Array.isArray(parts)) {
    values = [];

    if (!Array.isArray(to)) {
      to = [to];
    }

    for (i = 0, len = parts.length; i < len; i++) {
      if (typeof to[i] === 'undefined') {
        to[i] = units.getDefaultUnit(property);
      }

      values.push(units.convert(to[i], parts[i].value + parts[i].unit, element, property));
    }

    return values;
  }

  return {
    'value': to === parts.unit
      ? parts.value
      : units.processConversion(parts.unit, to, parts.value, element, property),
    'unit': to
  };
};

units.parse = function(value, property) {
  var stringValue = value.toString().trim();
  var parts;
  var matches;
  var values;
  var len;
  var i;

  if (/\s/g.test(value)) {
    values = stringValue.split(/\s/);
    parts = [];

    for (i = 0, len = values.length; i < len; i++) {
      parts.push(units.parse(values[i], property));
    }

    return parts;
  }

  parts = {
    'value': units.getDefaultValue(property),
    'unit': units.getDefaultUnit(property)
  };

  matches = stringValue.toString().match(/^(-?[\d+\.\-]+)([a-z]+|%)$/i);

  if (typeof units.properties[property] !== 'undefined' && units.properties[property].defaultUnit !== parts.unit) {
    parts.unit = units.properties[property].defaultUnit;
  }

  if (matches === null) {
    isNumeric(value)
      ? parts.value = value
      : parts.unit = value;
  } else {
    parts.value = matches[1];
    parts.unit = matches[2];
  }

  parts.value = parseFloat(parts.value);

  return parts;
};

units.getDefault = function(property) {
  return units.getDefaultValue(property) + units.getDefaultUnit(property);
};

units.getDefaultValue = function(property) {
  return typeof units.properties[property] !== 'undefined' && typeof units.properties[property].defaultValue !== 'undefined'
    ? units.properties[property].defaultValue
    : 0;
};

units.getDefaultUnit = function(property) {
  return typeof units.properties[property] !== 'undefined' && typeof units.properties[property].defaultUnit !== 'undefined'
    ? units.properties[property].defaultUnit
    : 'px';
};

//  Protected methods
//------------------------------------------------------------------------------

units.processConversion = function(fromUnits, toUnits, value, element, property) {
  var type = units.getConversionType(fromUnits);
  var method;

  if (typeof type[fromUnits][toUnits] === 'function') {
    method = type[fromUnits][toUnits];
  } else {
    method = type[type._default][toUnits];
    value = type[fromUnits][type._default](value, element, property); // Use px conversion as an interstitial step
  }

  return method(value, element, property);
};

units.getConversionType = function(fromUnits) {
  var property;
  var type = null;

  for (property in units.conversions) {
    if (!units.conversions.hasOwnProperty(property)) continue;

    if (typeof units.conversions[property][fromUnits] !== 'undefined') {
      type = units.conversions[property];
      break;
    }
  }

  return type;
};

//  Expose conversion functions
//------------------------------------------------------------------------------

units.conversions = conversions;

//  Properties with non default unit/value
//------------------------------------------------------------------------------

units.properties = {
  'opacity': {
    'defaultUnit': '',
    'defaultValue': 1
  },
  'rotateX': {
    'defaultUnit': 'deg'
  },
  'rotateY': {
    'defaultUnit': 'deg'
  },
  'rotateZ': {
    'defaultUnit': 'deg'
  },
  'skewX': {
    'defaultUnit': 'deg'
  },
  'skewY': {
    'defaultUnit': 'deg'
  },
  'scaleX': {
    'defaultUnit': '',
    'defaultValue': 1
  },
  'scaleY': {
    'defaultUnit': '',
    'defaultValue': 1
  },
  'scaleZ': {
    'defaultUnit': '',
    'defaultValue': 1
  },
  'line-height': {
    'defaultUnit': '',
    'defaultValue': 1
  }
};

// Exports
module.exports = units;
<commit_msg>Fix isnumeric package name case<commit_after>/* eslint-env browser, node */

'use strict';

// Imports
var conversions = require('./conversions');
var isNumeric = require('isnumeric/isNumeric');

var units = {};

//  Public interface
//------------------------------------------------------------------------------

units.convert = function(to, value, element, property) {
  var parts = units.parse(value, property);
  var values;
  var len;
  var i;

  if (Array.isArray(parts)) {
    values = [];

    if (!Array.isArray(to)) {
      to = [to];
    }

    for (i = 0, len = parts.length; i < len; i++) {
      if (typeof to[i] === 'undefined') {
        to[i] = units.getDefaultUnit(property);
      }

      values.push(units.convert(to[i], parts[i].value + parts[i].unit, element, property));
    }

    return values;
  }

  return {
    'value': to === parts.unit
      ? parts.value
      : units.processConversion(parts.unit, to, parts.value, element, property),
    'unit': to
  };
};

units.parse = function(value, property) {
  var stringValue = value.toString().trim();
  var parts;
  var matches;
  var values;
  var len;
  var i;

  if (/\s/g.test(value)) {
    values = stringValue.split(/\s/);
    parts = [];

    for (i = 0, len = values.length; i < len; i++) {
      parts.push(units.parse(values[i], property));
    }

    return parts;
  }

  parts = {
    'value': units.getDefaultValue(property),
    'unit': units.getDefaultUnit(property)
  };

  matches = stringValue.toString().match(/^(-?[\d+\.\-]+)([a-z]+|%)$/i);

  if (typeof units.properties[property] !== 'undefined' && units.properties[property].defaultUnit !== parts.unit) {
    parts.unit = units.properties[property].defaultUnit;
  }

  if (matches === null) {
    isNumeric(value)
      ? parts.value = value
      : parts.unit = value;
  } else {
    parts.value = matches[1];
    parts.unit = matches[2];
  }

  parts.value = parseFloat(parts.value);

  return parts;
};

units.getDefault = function(property) {
  return units.getDefaultValue(property) + units.getDefaultUnit(property);
};

units.getDefaultValue = function(property) {
  return typeof units.properties[property] !== 'undefined' && typeof units.properties[property].defaultValue !== 'undefined'
    ? units.properties[property].defaultValue
    : 0;
};

units.getDefaultUnit = function(property) {
  return typeof units.properties[property] !== 'undefined' && typeof units.properties[property].defaultUnit !== 'undefined'
    ? units.properties[property].defaultUnit
    : 'px';
};

//  Protected methods
//------------------------------------------------------------------------------

units.processConversion = function(fromUnits, toUnits, value, element, property) {
  var type = units.getConversionType(fromUnits);
  var method;

  if (typeof type[fromUnits][toUnits] === 'function') {
    method = type[fromUnits][toUnits];
  } else {
    method = type[type._default][toUnits];
    value = type[fromUnits][type._default](value, element, property); // Use px conversion as an interstitial step
  }

  return method(value, element, property);
};

units.getConversionType = function(fromUnits) {
  var property;
  var type = null;

  for (property in units.conversions) {
    if (!units.conversions.hasOwnProperty(property)) continue;

    if (typeof units.conversions[property][fromUnits] !== 'undefined') {
      type = units.conversions[property];
      break;
    }
  }

  return type;
};

//  Expose conversion functions
//------------------------------------------------------------------------------

units.conversions = conversions;

//  Properties with non default unit/value
//------------------------------------------------------------------------------

units.properties = {
  'opacity': {
    'defaultUnit': '',
    'defaultValue': 1
  },
  'rotateX': {
    'defaultUnit': 'deg'
  },
  'rotateY': {
    'defaultUnit': 'deg'
  },
  'rotateZ': {
    'defaultUnit': 'deg'
  },
  'skewX': {
    'defaultUnit': 'deg'
  },
  'skewY': {
    'defaultUnit': 'deg'
  },
  'scaleX': {
    'defaultUnit': '',
    'defaultValue': 1
  },
  'scaleY': {
    'defaultUnit': '',
    'defaultValue': 1
  },
  'scaleZ': {
    'defaultUnit': '',
    'defaultValue': 1
  },
  'line-height': {
    'defaultUnit': '',
    'defaultValue': 1
  }
};

// Exports
module.exports = units;
<|endoftext|>


<commit_before>import { Command } from 'substance'
import { getRange } from './sheetHelpers'

class RowsCommand extends Command {

  getCommandState(params) {
    const sel = params.selection
    if (sel && sel.isCustomSelection() && sel.customType === 'sheet') {
      let data = sel.data
      if (data.type === 'rows') {
        let startRow = Math.min(data.anchorRow, data.focusRow)
        let endRow = Math.max(data.anchorRow, data.focusRow)
        let nrows = endRow-startRow+1
        return {
          disabled: false,
          startRow, endRow, nrows
        }
      }
    }
    // otherwise
    return {
      disabled: true
    }
  }
}

class ColsCommand extends Command {

  getCommandState(params) {
    const sel = params.selection
    if (sel && sel.isCustomSelection() && sel.customType === 'sheet') {
      let data = sel.data
      if (data.type === 'columns') {
        let startCol = Math.min(data.anchorCol, data.focusCol)
        let endCol = Math.max(data.anchorCol, data.focusCol)
        let ncolumns = endCol-startCol+1
        return {
          disabled: false,
          startCol, endCol, ncolumns
        }
      }
    }
    // otherwise
    return {
      disabled: true
    }
  }

}

class ColumnMetaCommand extends Command {

  getCommandState(params) {
    const sel = params.selection
    if (sel && sel.isCustomSelection() && sel.customType === 'sheet') {
      let data = sel.data
      if (data.type === 'columns') {
        let startCol = Math.min(data.anchorCol, data.focusCol)
        let endCol = Math.max(data.anchorCol, data.focusCol)
        let ncolumns = endCol-startCol+1
        if (ncolumns === 1) {
          let colIdx = startCol
          let node = params.surface.getSheet().getColumnMeta(colIdx)
          return {
            disabled: false,
            colIdx, node
          }
        }
      }
    }
    // otherwise
    return {
      disabled: true
    }
  }

}

function insertRows({editorSession, selection, commandState}, mode) {
  //const sel = selection.data
  const refRow = mode === 'above' ?
    commandState.startRow :
    commandState.endRow + 1
  const nrows = commandState.nrows
  editorSession.transaction((tx) => {
    tx.getDocument().createRowsAt(refRow, nrows)
  })
}

function insertCols({editorSession, selection, commandState}, mode) {
  //const sel = selection.data
  const refCol = mode === 'left' ?
    commandState.startCol :
    commandState.endCol + 1
  const ncols = commandState.ncolumns
  editorSession.transaction((tx) => {
    tx.getDocument().createColumnsAt(refCol, ncols)
  })
}

function deleteRows({editorSession, commandState}) {
  editorSession.transaction((tx) => {
    tx.getDocument().deleteRows(commandState.startRow, commandState.endRow)
  })
}

function deleteColumns({editorSession, commandState}) {
  editorSession.transaction((tx) => {
    tx.getDocument().deleteColumns(commandState.startCol, commandState.endCol)
  })
}

export class InsertRowsAbove extends RowsCommand {
  execute(params) {
    insertRows(params, 'above')
  }
}

export class InsertRowsBelow extends RowsCommand {
  execute(params) {
    insertRows(params, 'below')
  }
}

export class DeleteRows extends RowsCommand {
  execute(params) {
    deleteRows(params)
  }
}

export class InsertColumnsLeft extends ColsCommand {
  execute(params) {
    insertCols(params, 'left')
  }
}

export class InsertColumnsRight extends ColsCommand {
  execute(params) {
    insertCols(params, 'right')
  }
}

export class DeleteColumns extends ColsCommand {
  execute(params) {
    deleteColumns(params)
  }
}

export class OpenColumnSettings extends ColumnMetaCommand {
  execute(params) {
    // NOTE: when the OpenColumnSettings command is active
    // params.surface is the corresponding SheetComponent
    params.surface.openColumnSettings(params)
  }
}

export class SetLanguageCommand extends Command {

  getCommandState({ selection, editorSession }) {
    if (selection.isNull() || !(selection.isCustomSelection() && selection.customType === 'sheet')) {
      return { disabled: true }
    }
    let doc = editorSession.getDocument()
    const { anchorRow, anchorCol } = selection.data
    if(anchorRow === -1 || anchorCol === -1) {
      return { disabled: true }
    }
    let anchorCell = doc.getCell(anchorRow, anchorCol)
    let language = anchorCell.attr('language')
    let state = {
      cellId: anchorCell.id,
      newLanguage: this.config.language,
      disabled: false,
      active: this.config.language === language
    }
    return state
  }

  execute({ editorSession, commandState }) {
    let { cellId, newLanguage, disabled } = commandState
    if (!disabled) {
      editorSession.transaction((tx) => {
        let cell = tx.get(cellId)
        cell.attr({ language: newLanguage })
      })
    }
  }
}

export class SetTypeCommand extends Command {

  getCommandState({ selection, editorSession }) {
    if (selection.isNull() || !(selection.isCustomSelection() && selection.customType === 'sheet')) {
      return { disabled: true }
    }
    let labelProvider = editorSession.getConfigurator().getLabelProvider()
    let doc = editorSession.getDocument()
    let state = {
      disabled: true
    }
    const { anchorRow, anchorCol } = selection.data
    if(anchorRow === -1 || anchorCol === -1) {
      const selectionType = selection.data.type
      if(selectionType === 'columns') {
        let columnMeta = doc.getColumnMeta(anchorCol)
        let columnType = columnMeta.attr('type')
        state = {
          cellId: columnMeta.id,
          newType: this.config.type,
          columnType: labelProvider.getLabel(columnType),
          disabled: false,
          active: this.config.type === columnType
        }
      } else if (selectionType === 'rows') {
        let anchorCell = doc.getCell(anchorRow, 0)
        let columnMeta = doc.getColumnForCell(anchorCell.id)
        let columnType = columnMeta.attr('type')
        let cellType = anchorCell.attr('type')
        state = {
          cellId: anchorCell.id,
          newType: this.config.type,
          columnType: labelProvider.getLabel(columnType),
          disabled: false,
          active: this.config.type === cellType
        }
      }
    } else {
      let anchorCell = doc.getCell(anchorRow, anchorCol)
      let columnMeta = doc.getColumnForCell(anchorCell.id)
      let columnType = columnMeta.attr('type')
      let cellType = anchorCell.attr('type')

      state = {
        cellId: anchorCell.id,
        newType: this.config.type,
        columnType: labelProvider.getLabel(columnType),
        disabled: false,
        active: this.config.type === cellType
      }
    }
    return state
  }

  execute({ editorSession, commandState, selection }) {
    let { newType, disabled } = commandState
    const selectionType = selection.data.type
    if (!disabled) {
      if(selectionType === 'range' || selectionType === 'rows') {
        const range = getRange(editorSession)
        editorSession.transaction((tx) => {
          tx.getDocument().setTypeForRange(range.startRow, range.startCol, range.endRow, range.endCol, newType)
        })
      } else if (selectionType === 'columns') {
        const range = getRange(editorSession)
        editorSession.transaction((tx) => {
          for (let colIdx = range.startCol; colIdx <= range.endCol; colIdx++) {
            let cell = tx.getDocument().getColumnMeta(colIdx)
            cell.attr({type: newType})
          }
        })
      }
    }
  }
}

export class EditCellExpressionCommand extends Command {

  getCommandState({ selection, editorSession }) {
    if (selection.isNull() || !(selection.isCustomSelection() && selection.customType === 'sheet')) {
      return { disabled: true }
    }
    let doc = editorSession.getDocument()
    const { anchorRow, anchorCol } = selection.data
    if(anchorRow === -1 || anchorCol === -1) {
      return { disabled: true }
    }
    let anchorCell = doc.getCell(anchorRow, anchorCol)
    let state = {
      cellId: anchorCell.id,
      disabled: false
    }
    return state
  }

  execute() {
    // no execute
  }

}

export class ChangeModeCommand extends Command {
  getCommandState(params) {
    const editor = params.editorSession.getEditor()
    if(editor) {
      const surface = editor.refs.sheet
      if(surface) {
        const mode = surface.state.mode
        return {
          newMode: this.config.mode,
          disabled: false,
          active: this.config.mode === mode
        }
      }
    }

    return {
      // TODO: we should get default value from outside
      active: this.config.mode === 'normal',
      disabled: false
    }
  }

  execute(params) {
    const editor = params.editorSession.getEditor()
    let surface = editor.refs.sheet
    surface.extendState({mode: this.config.mode})
    params.editorSession._setDirty('commandStates')
    params.editorSession.performFlow()
  }
}
<commit_msg>Cleanup.<commit_after>import { Command } from 'substance'
import { getRange } from './sheetHelpers'

class RowsCommand extends Command {

  getCommandState(params) {
    const sel = params.selection
    if (sel && sel.isCustomSelection() && sel.customType === 'sheet') {
      let data = sel.data
      if (data.type === 'rows') {
        let startRow = Math.min(data.anchorRow, data.focusRow)
        let endRow = Math.max(data.anchorRow, data.focusRow)
        let nrows = endRow-startRow+1
        return {
          disabled: false,
          startRow, endRow, nrows
        }
      }
    }
    // otherwise
    return {
      disabled: true
    }
  }
}

class ColsCommand extends Command {

  getCommandState(params) {
    const sel = params.selection
    if (sel && sel.isCustomSelection() && sel.customType === 'sheet') {
      let data = sel.data
      if (data.type === 'columns') {
        let startCol = Math.min(data.anchorCol, data.focusCol)
        let endCol = Math.max(data.anchorCol, data.focusCol)
        let ncolumns = endCol-startCol+1
        return {
          disabled: false,
          startCol, endCol, ncolumns
        }
      }
    }
    // otherwise
    return {
      disabled: true
    }
  }

}

class ColumnMetaCommand extends Command {

  getCommandState(params) {
    const sel = params.selection
    if (sel && sel.isCustomSelection() && sel.customType === 'sheet') {
      let data = sel.data
      if (data.type === 'columns') {
        let startCol = Math.min(data.anchorCol, data.focusCol)
        let endCol = Math.max(data.anchorCol, data.focusCol)
        let ncolumns = endCol-startCol+1
        if (ncolumns === 1) {
          let colIdx = startCol
          let node = params.surface.getSheet().getColumnMeta(colIdx)
          return {
            disabled: false,
            colIdx, node
          }
        }
      }
    }
    // otherwise
    return {
      disabled: true
    }
  }

}

function insertRows({editorSession, selection, commandState}, mode) {
  //const sel = selection.data
  const refRow = mode === 'above' ?
    commandState.startRow :
    commandState.endRow + 1
  const nrows = commandState.nrows
  editorSession.transaction((tx) => {
    tx.getDocument().createRowsAt(refRow, nrows)
  })
}

function insertCols({editorSession, selection, commandState}, mode) {
  //const sel = selection.data
  const refCol = mode === 'left' ?
    commandState.startCol :
    commandState.endCol + 1
  const ncols = commandState.ncolumns
  editorSession.transaction((tx) => {
    tx.getDocument().createColumnsAt(refCol, ncols)
  })
}

function deleteRows({editorSession, commandState}) {
  editorSession.transaction((tx) => {
    tx.getDocument().deleteRows(commandState.startRow, commandState.endRow)
  })
}

function deleteColumns({editorSession, commandState}) {
  editorSession.transaction((tx) => {
    tx.getDocument().deleteColumns(commandState.startCol, commandState.endCol)
  })
}

export class InsertRowsAbove extends RowsCommand {
  execute(params) {
    insertRows(params, 'above')
  }
}

export class InsertRowsBelow extends RowsCommand {
  execute(params) {
    insertRows(params, 'below')
  }
}

export class DeleteRows extends RowsCommand {
  execute(params) {
    deleteRows(params)
  }
}

export class InsertColumnsLeft extends ColsCommand {
  execute(params) {
    insertCols(params, 'left')
  }
}

export class InsertColumnsRight extends ColsCommand {
  execute(params) {
    insertCols(params, 'right')
  }
}

export class DeleteColumns extends ColsCommand {
  execute(params) {
    deleteColumns(params)
  }
}

export class OpenColumnSettings extends ColumnMetaCommand {
  execute(params) {
    // NOTE: when the OpenColumnSettings command is active
    // params.surface is the corresponding SheetComponent
    params.surface.openColumnSettings(params)
  }
}

export class SetLanguageCommand extends Command {

  getCommandState({ selection, editorSession }) {
    if (selection.isNull() || !(selection.isCustomSelection() && selection.customType === 'sheet')) {
      return { disabled: true }
    }
    let doc = editorSession.getDocument()
    const { anchorRow, anchorCol } = selection.data
    if(anchorRow === -1 || anchorCol === -1) {
      return { disabled: true }
    }
    let anchorCell = doc.getCell(anchorRow, anchorCol)
    let language = anchorCell.attr('language')
    let state = {
      cellId: anchorCell.id,
      newLanguage: this.config.language,
      disabled: false,
      active: this.config.language === language
    }
    return state
  }

  execute({ editorSession, commandState }) {
    let { cellId, newLanguage, disabled } = commandState
    if (!disabled) {
      editorSession.transaction((tx) => {
        let cell = tx.get(cellId)
        cell.attr({ language: newLanguage })
      })
    }
  }
}

export class SetTypeCommand extends Command {

  getCommandState({ selection, editorSession }) {
    if (selection.isNull() || !(selection.isCustomSelection() && selection.customType === 'sheet')) {
      return { disabled: true }
    }
    let labelProvider = editorSession.getConfigurator().getLabelProvider()
    let doc = editorSession.getDocument()
    let state = {
      disabled: true
    }
    let { anchorRow, anchorCol } = selection.data
    const selectionType = selection.data.type
    if(selectionType === 'columns') {
      let columnMeta = doc.getColumnMeta(anchorCol)
      let columnType = columnMeta.attr('type')
      state = {
        cellId: columnMeta.id,
        newType: this.config.type,
        columnType: labelProvider.getLabel(columnType),
        disabled: false,
        active: this.config.type === columnType
      }
    } else {
      if (selectionType === 'rows') anchorCol = 0
      let anchorCell = doc.getCell(anchorRow, anchorCol)
      let columnMeta = doc.getColumnForCell(anchorCell.id)
      let columnType = columnMeta.attr('type')
      let cellType = anchorCell.attr('type')

      state = {
        cellId: anchorCell.id,
        newType: this.config.type,
        columnType: labelProvider.getLabel(columnType),
        disabled: false,
        active: this.config.type === cellType
      }
    }
    return state
  }

  execute({ editorSession, commandState, selection }) {
    let { newType, disabled } = commandState
    const selectionType = selection.data.type
    if (!disabled) {
      if(selectionType === 'range' || selectionType === 'rows') {
        const range = getRange(editorSession)
        editorSession.transaction((tx) => {
          tx.getDocument().setTypeForRange(range.startRow, range.startCol, range.endRow, range.endCol, newType)
        })
      } else if (selectionType === 'columns') {
        const range = getRange(editorSession)
        editorSession.transaction((tx) => {
          for (let colIdx = range.startCol; colIdx <= range.endCol; colIdx++) {
            let cell = tx.getDocument().getColumnMeta(colIdx)
            cell.attr({type: newType})
          }
        })
      }
    }
  }
}

export class EditCellExpressionCommand extends Command {

  getCommandState({ selection, editorSession }) {
    if (selection.isNull() || !(selection.isCustomSelection() && selection.customType === 'sheet')) {
      return { disabled: true }
    }
    let doc = editorSession.getDocument()
    const { anchorRow, anchorCol } = selection.data
    if(anchorRow === -1 || anchorCol === -1) {
      return { disabled: true }
    }
    let anchorCell = doc.getCell(anchorRow, anchorCol)
    let state = {
      cellId: anchorCell.id,
      disabled: false
    }
    return state
  }

  execute() {
    // no execute
  }

}

export class ChangeModeCommand extends Command {
  getCommandState(params) {
    const editor = params.editorSession.getEditor()
    if(editor) {
      const surface = editor.refs.sheet
      if(surface) {
        const mode = surface.state.mode
        return {
          newMode: this.config.mode,
          disabled: false,
          active: this.config.mode === mode
        }
      }
    }

    return {
      // TODO: we should get default value from outside
      active: this.config.mode === 'normal',
      disabled: false
    }
  }

  execute(params) {
    const editor = params.editorSession.getEditor()
    let surface = editor.refs.sheet
    surface.extendState({mode: this.config.mode})
    params.editorSession._setDirty('commandStates')
    params.editorSession.performFlow()
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
  Portfolio RESTful API
*************************************************************************/
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var Profile = require('./app/models/profile');
var Exp = require('./app/models/exp');
var Work = require('./app/models/work');

//app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser());

var port = process.env.PORT || 8080;
app.set('port', port);

var mongoose = require('mongoose');
var dbUser = 'aaronchuo';
var dbPwd = 'yesyes1008';
mongoose.connect('mongodb://' + dbUser + ':' + dbPwd + '@ds053160.mongolab.com:53160/heroku_app31461352');

var router = express.Router();
// var dbQuery = {

//   //getter: get all / specific data
//   get: function(dbInstance, id) {
//     var callback = function(err, data) {
//       var returnValue = {};
//       if(err) {
//         returnValue.status = 'error';
//         returnValue.message = err;
//       } else {
//         returnValue.status = 'success';
//         returnValue.message = data;
//       }
//       return returnValue;
//     };

//     if(id) {
//       dbName.findById(id, function(err, data) {
//         res.jcallback(err, data);
//       });
//     } else {
//       dbName.find(function(err, data) {
//         if(err) res.send(err);
//         res.json(data);
//       });
//     }
//   },

//   //setter: create / update / delete
//   set: function(id) {

//   }
// };

/*************************************************************************
  API Authentication
*************************************************************************/
router.use(function(req, res, next) {
  //TODO: HTTP BA
  console.log('Test breakpoint.')
  next();
});

/*************************************************************************
  Profile API
*************************************************************************/
router.route('/profile')

  // Create an profile field
  // POST http://portfolio-aaronchuo.rhcloud.com/api/profile
  .post(function(req, res) {
    var profile = new Profile();
    profile.field = req.body.field;
    profile.value = req.body.value;
    profile.save(function(err) {
      if(err) res.send(err);
      res.json({
        message: 'Profile field created.'
      });
    });
  })

  // Get all profile fields
  // GET http://portfolio-aaronchuo.rhcloud.com/api/profile
  .get(function(req, res) {
    res.json({
      message: 'here is profile'
    });
    // Profile.find(function(err, profiles) {
    //   if(err) res.send(err);
    //   res.json(profiles);
    // });
  });

router.route('/profile/:profile_id')

  // Get a specific profile field
  // GET http://portfolio-aaronchuo.rhcloud.com/api/profile/:profile_id
  .get(function(req, res) {
    Profile.findById(req.params.profile_id, function(err, profile) {
      if(err) res.send(err);
      res.json(profile);
    });
  })

  // Update a specific profile
  // PUT http://portfolio-aaronchuo.rhcloud.com/api/profile/:profile_id
  .put(function(req, res) {
    Profile.findById(req.params.profile_id, function(err, profile) {
      if(err) res.send(err);
      profile.field = req.body.field;
      profile.value = req.body.value;
      profile.save(function(err) {
        if(err) res.send(err);
        res.json({
          message: 'Profile updated.'
        });
      });
    });
  })

  // Delete a specific profile
  // DELETE http://portfolio-aaronchuo.rhcloud.com/api/profile/:profile_id
  .delete(function(req, res) {
    Profile.remove({
      _id: req.params.profile_id
    }, function(err, profile) {
      if(err) res.send(err);
      res.json({
        message: 'Profile deleted.'
      })
    });
  });

/*************************************************************************
  Exp API
*************************************************************************/
router.route('/exp')

  // Create an experience
  // POST http://portfolio-aaronchuo.rhcloud.com/api/exp
  .post(function(req, res) {
    var exp = new Exp();
    exp.title = req.body.title;
    exp.desc = req.body.desc;
    exp.date = req.body.date;
    for(var i=0; i<req.body.photo.length; i++) {
      exp.photo.push(req.body.photo[i]);
    }
    exp.save(function(err) {
      if(err) res.send(err);
      res.json({
        message: 'Experience created.'
      });
    });
  })

  // Get all experiences
  // GET http://portfolio-aaronchuo.rhcloud.com/api/exp
  .get(function(req, res) {
    Exp.find(function(err, exps) {
      if(err) res.send(err);
      res.json(exps);
    });
  });

router.route('/exp/:exp_id')

  // Get a specific experience
  // GET http://portfolio-aaronchuo.rhcloud.com/api/exp/:exp_id
  .get(function(req, res) {
    Exp.findById(req.params.exp_id, function(err, exp) {
      if(err) res.send(err);
      res.json(exp);
    });
  })

  // Update a specific experience
  // PUT http://portfolio-aaronchuo.rhcloud.com/api/exp/:exp_id
  .put(function(req, res) {
    Exp.findById(req.params.exp_id, function(err, exp) {
      if(err) res.send(err);
      exp.title = req.body.title;
      exp.desc = req.body.desc;
      exp.date = req.body.date;
      for(var i=0; i<req.body.photo.length; i++) {
        exp.photo.push(req.body.photo[i]);
      }
      exp.save(function(err) {
        if(err) res.send(err);
        res.json({
          message: 'Experience updated.'
        });
      });
    });
  })

  // Delete a specific experience
  // DELETE http://portfolio-aaronchuo.rhcloud.com/api/exp/:exp_id
  .delete(function(req, res) {
    Exp.remove({
      _id: req.params.exp_id
    }, function(err, exp) {
      if(err) res.send(err);
      res.json({
        message: 'Experience deleted.'
      })
    });
  });

/*************************************************************************
  Work API
*************************************************************************/
router.route('/work')

  // Create a work
  // POST http://portfolio-aaronchuo.rhcloud.com/api/work
  .post(function(req, res) {
    var work = new Work();
    work.name = req.body.name;
    work.desc = req.body.desc;
    work.tag = req.body.tag;
    work.save(function(err) {
      if(err) res.send(err);
      res.json({
        message: 'Work created.'
      });
    });
  })

  // Get all works
  // GET http://portfolio-aaronchuo.rhcloud.com/api/work
  .get(function(req, res) {
    Work.find(function(err, works) {
      if(err) res.send(err);
      res.json(works);
    });
  });

router.route('/work/:work_id')

  // Get a specific work
  // GET http://portfolio-aaronchuo.rhcloud.com/api/work/:work_id
  .get(function(req, res) {
    Work.findById(req.params.work_id, function(err, work) {
      if(err) res.send(err);
      res.json(work);
    });
  })

  // Update a specific work
  // PUT http://portfolio-aaronchuo.rhcloud.com/api/work/:work_id
  .put(function(req, res) {
    Work.findById(req.params.work_id, function(err, work) {
      if(err) res.send(err);
      work.name = req.body.name;
      work.desc = req.body.desc;
      work.tag = req.body.tag;
      work.save(function(err) {
        if(err) res.send(err);
        res.json({
          message: 'Work updated.'
        });
      });
    });
  })

  // Delete a specific work
  // DELETE http://portfolio-aaronchuo.rhcloud.com/api/work/:work_id
  .delete(function(req, res) {
    Work.remove({
      _id: req.params.work_id
    }, function(err, work) {
      if(err) res.send(err);
      res.json({
        message: 'Work deleted.'
      })
    });
  });

/*************************************************************************
  API Index
*************************************************************************/
router.get('/', function(req, res) {
  res.json({
    message: 'Hello !'
  });
});

app.use('/', router);

// app.get('/', function(req, res) {
//   res.send('hello world!');
// });

app.listen(app.get('port'), function() {
  console.log(port + ' port is running!');
});
<commit_msg>Testing url encoded http actions<commit_after>/*************************************************************************
  Portfolio RESTful API
*************************************************************************/
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var Profile = require('./app/models/profile');
var Exp = require('./app/models/exp');
var Work = require('./app/models/work');

app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser());

var port = process.env.PORT || 8080;
app.set('port', port);

var mongoose = require('mongoose');
var dbUser = 'aaronchuo';
var dbPwd = 'yesyes1008';
mongoose.connect('mongodb://' + dbUser + ':' + dbPwd + '@ds053160.mongolab.com:53160/heroku_app31461352');

var router = express.Router();
// var dbQuery = {

//   //getter: get all / specific data
//   get: function(dbInstance, id) {
//     var callback = function(err, data) {
//       var returnValue = {};
//       if(err) {
//         returnValue.status = 'error';
//         returnValue.message = err;
//       } else {
//         returnValue.status = 'success';
//         returnValue.message = data;
//       }
//       return returnValue;
//     };

//     if(id) {
//       dbName.findById(id, function(err, data) {
//         res.jcallback(err, data);
//       });
//     } else {
//       dbName.find(function(err, data) {
//         if(err) res.send(err);
//         res.json(data);
//       });
//     }
//   },

//   //setter: create / update / delete
//   set: function(id) {

//   }
// };

/*************************************************************************
  API Authentication
*************************************************************************/
router.use(function(req, res, next) {
  //TODO: HTTP BA
  console.log('Test breakpoint.')
  next();
});

/*************************************************************************
  Profile API
*************************************************************************/
router.route('/profile')

  // Create an profile field
  // POST http://portfolio-aaronchuo.rhcloud.com/api/profile
  .post(function(req, res) {
    var profile = new Profile();
    profile.field = req.body.field;
    profile.value = req.body.value;
    profile.save(function(err) {
      if(err) res.send(err);
      res.json({
        message: 'Profile field created.'
      });
    });
  })

  // Get all profile fields
  // GET http://portfolio-aaronchuo.rhcloud.com/api/profile
  .get(function(req, res) {
    Profile.find(function(err, profiles) {
      if(err) res.send(err);
      res.json(profiles);
    });
  });

router.route('/profile/:profile_id')

  // Get a specific profile field
  // GET http://portfolio-aaronchuo.rhcloud.com/api/profile/:profile_id
  .get(function(req, res) {
    Profile.findById(req.params.profile_id, function(err, profile) {
      if(err) res.send(err);
      res.json(profile);
    });
  })

  // Update a specific profile
  // PUT http://portfolio-aaronchuo.rhcloud.com/api/profile/:profile_id
  .put(function(req, res) {
    Profile.findById(req.params.profile_id, function(err, profile) {
      if(err) res.send(err);
      profile.field = req.body.field;
      profile.value = req.body.value;
      profile.save(function(err) {
        if(err) res.send(err);
        res.json({
          message: 'Profile updated.'
        });
      });
    });
  })

  // Delete a specific profile
  // DELETE http://portfolio-aaronchuo.rhcloud.com/api/profile/:profile_id
  .delete(function(req, res) {
    Profile.remove({
      _id: req.params.profile_id
    }, function(err, profile) {
      if(err) res.send(err);
      res.json({
        message: 'Profile deleted.'
      })
    });
  });

/*************************************************************************
  Exp API
*************************************************************************/
router.route('/exp')

  // Create an experience
  // POST http://portfolio-aaronchuo.rhcloud.com/api/exp
  .post(function(req, res) {
    var exp = new Exp();
    exp.title = req.body.title;
    exp.desc = req.body.desc;
    exp.date = req.body.date;
    for(var i=0; i<req.body.photo.length; i++) {
      exp.photo.push(req.body.photo[i]);
    }
    exp.save(function(err) {
      if(err) res.send(err);
      res.json({
        message: 'Experience created.'
      });
    });
  })

  // Get all experiences
  // GET http://portfolio-aaronchuo.rhcloud.com/api/exp
  .get(function(req, res) {
    Exp.find(function(err, exps) {
      if(err) res.send(err);
      res.json(exps);
    });
  });

router.route('/exp/:exp_id')

  // Get a specific experience
  // GET http://portfolio-aaronchuo.rhcloud.com/api/exp/:exp_id
  .get(function(req, res) {
    Exp.findById(req.params.exp_id, function(err, exp) {
      if(err) res.send(err);
      res.json(exp);
    });
  })

  // Update a specific experience
  // PUT http://portfolio-aaronchuo.rhcloud.com/api/exp/:exp_id
  .put(function(req, res) {
    Exp.findById(req.params.exp_id, function(err, exp) {
      if(err) res.send(err);
      exp.title = req.body.title;
      exp.desc = req.body.desc;
      exp.date = req.body.date;
      for(var i=0; i<req.body.photo.length; i++) {
        exp.photo.push(req.body.photo[i]);
      }
      exp.save(function(err) {
        if(err) res.send(err);
        res.json({
          message: 'Experience updated.'
        });
      });
    });
  })

  // Delete a specific experience
  // DELETE http://portfolio-aaronchuo.rhcloud.com/api/exp/:exp_id
  .delete(function(req, res) {
    Exp.remove({
      _id: req.params.exp_id
    }, function(err, exp) {
      if(err) res.send(err);
      res.json({
        message: 'Experience deleted.'
      })
    });
  });

/*************************************************************************
  Work API
*************************************************************************/
router.route('/work')

  // Create a work
  // POST http://portfolio-aaronchuo.rhcloud.com/api/work
  .post(function(req, res) {
    var work = new Work();
    work.name = req.body.name;
    work.desc = req.body.desc;
    work.tag = req.body.tag;
    work.save(function(err) {
      if(err) res.send(err);
      res.json({
        message: 'Work created.'
      });
    });
  })

  // Get all works
  // GET http://portfolio-aaronchuo.rhcloud.com/api/work
  .get(function(req, res) {
    Work.find(function(err, works) {
      if(err) res.send(err);
      res.json(works);
    });
  });

router.route('/work/:work_id')

  // Get a specific work
  // GET http://portfolio-aaronchuo.rhcloud.com/api/work/:work_id
  .get(function(req, res) {
    Work.findById(req.params.work_id, function(err, work) {
      if(err) res.send(err);
      res.json(work);
    });
  })

  // Update a specific work
  // PUT http://portfolio-aaronchuo.rhcloud.com/api/work/:work_id
  .put(function(req, res) {
    Work.findById(req.params.work_id, function(err, work) {
      if(err) res.send(err);
      work.name = req.body.name;
      work.desc = req.body.desc;
      work.tag = req.body.tag;
      work.save(function(err) {
        if(err) res.send(err);
        res.json({
          message: 'Work updated.'
        });
      });
    });
  })

  // Delete a specific work
  // DELETE http://portfolio-aaronchuo.rhcloud.com/api/work/:work_id
  .delete(function(req, res) {
    Work.remove({
      _id: req.params.work_id
    }, function(err, work) {
      if(err) res.send(err);
      res.json({
        message: 'Work deleted.'
      })
    });
  });

/*************************************************************************
  API Index
*************************************************************************/
router.get('/', function(req, res) {
  res.json({
    message: 'Hello !'
  });
});

app.use('/', router);

// app.get('/', function(req, res) {
//   res.send('hello world!');
// });

app.listen(app.get('port'), function() {
  console.log(port + ' port is running!');
});
<|endoftext|>


<commit_before>/**
 * Created by Awesome on 1/30/2016.
 */

    // use strict
'use strict';

// require dependencies
var fs         = require ('fs');
var os         = require ('os');
var glob       = require ('glob');
var path       = require ('path');
var through    = require ('through2');
var browserify = require ('browserify');
var babelify   = require ('babelify');
var source     = require ('vinyl-source-stream');

// require gulp dependencies
var riot       = require ('gulp-riot');
var sass       = require ('gulp-sass');
var chmod      = require ('gulp-chmod');
var watch      = require ('gulp-watch');
var concat     = require ('gulp-concat');
var header     = require ('gulp-header');
var rename     = require ('gulp-rename');
var uglify     = require ('gulp-uglify');
var nodemon    = require ('gulp-nodemon');
var streamify  = require ('gulp-streamify');
var sourcemaps = require ('gulp-sourcemaps');

// import local dependencies
var config     = require ('./config');
var configPipe = require ('./bin/util/gulp.config.pipe');

/**
 * build gulp builder class
 */
class gulpBuilder {
    /**
     * construct gulp builder class
     */
    constructor () {
        // wait time
        this.wait = (config.gulpDelay ? parseInt (config.gulpDelay) : 500);

        // check cache exists
        if (!fs.existsSync ('./cache')) {
            fs.mkdirSync ('./cache');
        }

        // bind private methods
        this._watch = this._watch.bind (this);

        // bind variables
        this.gulp = require ('gulp');

        // bind methods
        this._tasks = {
            'tmp'    : {
                'skip' : true
            },
            'sass'   : {
                'files' : [
                    './bin/bundles/*/resources/scss/**/*.scss',
                    './app/bundles/*/resources/scss/**/*.scss'
                ],
                'dependencies' : [
                    'tmp'
                ]
            },
            'daemon' : {
                'files' : [
                    './bin/bundles/*/daemon/**/*Daemon.js',
                    './app/bundles/*/daemon/**/*Daemon.js'
                ],
            },
            'config' : {
                'files' : [
                    './bin/bundles/*/controller/**/*Controller.js',
                    './app/bundles/*/controller/**/*Controller.js'
                ],
            },
            'view'   : {
                'files' : [
                    './bin/bundles/*/view/**/*.hbs',
                    './app/bundles/*/view/**/*.hbs'
                ],
            },
            'tag'    : {
                'files' : [
                    './bin/bundles/*/view/tag/**/*.tag',
                    './app/bundles/*/view/tag/**/*.tag'
                ],
                'skip' : true
            },
            'js'     : {
                'files' : [
                    './bin/bundles/*/resources/js/**/*.js',
                    './app/bundles/*/resources/js/**/*.js'
                ],
                'dependencies' : [
                    'tag'
                ]
            },
            'image'  : {
                'files' : [
                    './bin/bundles/*/resources/image/**/*',
                    './app/bundles/*/resources/image/**/*'
                ]
            }
        };

        // set keys array
        var keys     = Object.keys (this._tasks);
        var install  = [];
        var watchers = [];

        // bind and add gulp task methods
        for (var i = 0; i < keys.length; i++) {
            // set task
            let task = keys[i];
            // bind method
            this[task] = this[task].bind (this);
            // setup task
            if (this._tasks[task].dependencies) {
                this.gulp.task (task, this._tasks[task].dependencies, this[task]);
            } else {
                this.gulp.task (task, this[task]);
            }
            // check for skip
            if (this._tasks[task].skip) {
                continue;
            }
            // setup watch task
            var files = this._tasks[task].files;
            if (this._tasks[task].dependencies) {
                for (var a = 0; a < this._tasks[task].dependencies.length; a++) {
                    files = files.concat (this._tasks[this._tasks[task].dependencies[a]].files || []);
                }
            }
            // create watch task
            this._watch (task, files);
            // push to install
            install.push (task);
            // add watch task to array
            watchers.push (task + ':watch');
        }

        // add install task
        this.gulp.task ('install', install);
        // add watch task
        this.gulp.task ('watch', watchers);
        // add dev server task
        this.gulp.task ('dev', ['install'], () => {
            // run nodemon task
            nodemon ({
                'script' : './app.js',
                'ext'    : 'js json',
                'ignore' : [
                    'tags.min.js'
                ],
                'delay'  : this.wait,
                'watch'  : [
                    'cache/'
                ],
                'env'    : {
                    'NODE_ENV' : 'development'
                }
            });

            // start watch task
            this.gulp.start ('watch');
        });
        // add default task
        this.gulp.task ('default', ['dev']);
    }

    /**
     * creates temporary sass file
     *
     * @return {gulp}
     */
    tmp () {
        // set variables
        var that = this;
        var all  = '';

        // set running
        if (this._tmpRunning || this._sassRunning) {
            return;
        }
        this._tmpRunning = true;

        // grab gulp source for sass
        // create local variables array for sass files
        var sassFiles = [
            './bin/bundles/*/resources/scss/variables.scss',
            './app/bundles/*/resources/scss/variables.scss'
        ];

        // loop config sass files
        if (config.sass && config.sass.length) {
            for (var i = 0; i < config.sass.length; i ++) {
                sassFiles.push(config.sass[i]);
            }
        }

        // push local bootstrap files
        sassFiles.push('./bin/bundles/*/resources/scss/bootstrap.scss');
        sassFiles.push('./app/bundles/*/resources/scss/bootstrap.scss');

        // run gulp
        return this.gulp.src (sassFiles)
            .pipe (through.obj (function (chunk, enc, cb) {
                // run through callback
                var type = chunk.path.split('.');
                    type = type[type.length - 1];
                if (type == 'css') {
                    var prepend = fs.readFileSync(chunk.path, 'utf8');
                    this.push ({
                        'all' : prepend + os.EOL
                    });
                } else {
                    this.push ({
                        'all' : '@import "..' + chunk.path.replace (__dirname, '').split (path.delimiter).join ('/') + '";' + os.EOL
                    });
                }

                // run callback
                cb (null, chunk);
            }))
            .on ('data', (data) => {
                if (data.all) {
                    all += data.all;
                }
            })
            .on ('end', function () {
                // write temp sass file
                fs.writeFileSync ('./cache/tmp.scss', all);

                // reset running
                that._tmpRunning = false;
            });
    }

    /**
     * sass task
     */
    sass () {
        // set that
        var that = this;

        // check running
        if (this._tmpRunning || this._sassRunning) {
            return;
        }
        this._sassRunning = true;

        // run gulp task
        return this.gulp.src ('./cache/tmp.scss')
            .pipe (sourcemaps.init ())
            .pipe (sass ({
                outputStyle : 'compressed'
            }))
            .pipe (rename ('app.min.css'))
            .pipe (sourcemaps.write ('./www/assets/css'))
            .pipe (that.gulp.dest ('./www/assets/css'))
            .on ('end', () => {
                // reset running
                that._sassRunning = false;
            });
    }

    /**
     * daemon task
     */
    daemon () {
        // grab daemon controllers
        var daemons = [];
        for (var i = 0; i < this._tasks.daemon.files.length; i++) {
            daemons = daemons.concat (glob.sync (this._tasks.daemon.files[i]));
        }

        // loop daemons
        for (var key in daemons) {
            daemons[key] = daemons[key].replace ('./', '/');
        }

        // write daemons cache file
        this._write ('daemons', daemons);
    }

    /**
     * route task
     */
    config () {
        // set variables
        var that = this;
        var all  = {};

        // set running
        if (this._configRunning) {
            return;
        }
        this._configRunning = true;

        // get all routes
        // do within setTimeout to remove empty files
        return this.gulp.src (this._tasks.config.files)
            .pipe (through.obj (function (chunk, enc, cb) {
                var pip = this;
                configPipe.pipe (chunk).then (result => {
                    pip.push ({
                        'result' : result
                    });
                    cb (null, chunk);
                });
            }))
            .on ('data', (data) => {
                // merge config object
                that._merge (all, data.result);
            })
            .on ('end', function () {
                // write config file
                that._write ('config', all);

                // reset running tag
                that._configRunning = false;
            });
    }

    /**
     * view task
     */
    view () {
        // set that
        var that = this;

        // ensure running only once
        if (this._viewRunning) {
            return;
        }
        this._viewRunning = true;

        // move views into single folder
        // do within setTimeout to remove empty files
        // @todo bundle priority
        return this.gulp.src (this._tasks.view.files)
            .pipe (rename ((filePath) => {
                var amended = filePath.dirname.split (path.sep);
                amended.shift ();
                amended.shift ();
                filePath.dirname = amended.join (path.sep);
            }))
            .pipe (chmod (755))
            .pipe (this.gulp.dest ('cache/view'))
            .on('end', () => {
                // reset view running
                that._viewRunning = false;
            });
    }

    /**
     * tag task
     */
    tag () {
        // set that
        var that = this;

        // ensure running only once
        if (this._tagRunning) {
            return;
        }
        this._tagRunning = true;

        // move tags into javascript compiled file (riotjs)
        return this.gulp.src (this._tasks.tag.files)
            .pipe (riot ({
                compact : true
            }))
            .pipe (concat ('tags.min.js'))
            .pipe (header ('var riot = require(\'riot\');'))
            .pipe (this.gulp.dest ('./cache/tag'))
            .on ('end', () => {
                // reset running flag
                that._tagRunning = false;
            });
    }

    /**
     * javascript task
     */
    js () {
        // set that
        var that = this;

        // ensure running only once
        if (this._jsRunning) {
            return;
        }
        this._jsRunning = true;

        // create javascript array
        var js = [];
        js     = js.concat (glob.sync ('./bin/bundles/*/resources/js/bootstrap.js'));
        js     = js.concat (glob.sync ('./app/bundles/*/resources/js/bootstrap.js'));

        // build vendor prepend
        var vendor = '';
        if (config.js && config.js.length) {
            for (var i = 0; i < config.js.length; i++) {
                vendor += fs.readFileSync (config.js[i], 'utf8') + os.EOL;
            }
        }

        // browserfiy javascript
        // do within setTimeout to remove empty files
        return browserify ({
            entries : js
        })
            .transform (babelify)
            .bundle ()
            .pipe (source ('app.min.js'))
            .pipe (streamify (uglify ()))
            .pipe (streamify (header (vendor)))
            .pipe (this.gulp.dest ('./www/assets/js'))
            .on ('end', () => {
                // reset running flag
                that._jsRunning = false;
            });
    }

    /**
     * image task
     */
    image () {
        // move images into single folder
        // do within setTimeout to remove empty files
        // @todo bundle priority
        setTimeout (() => {
            this.gulp.src (this._tasks.image.files)
                .pipe (rename ((filePath) => {
                    var amended = filePath.dirname.split (path.sep);
                    amended.shift ();
                    amended.shift ();
                    amended.shift ();
                    filePath.dirname = amended.join (path.sep);
                }))
                .pipe (chmod (755))
                .pipe (this.gulp.dest ('www/image'));
        }, this.wait);
    }

    /**
     * creates watch task
     *
     * @param  {String} task
     * @param  {array} files
     */
    _watch (task, files) {
        // set that
        var that = this;

        // create watch task
        this.gulp.task (task + ':watch', () => {
            return watch (files, () => {
                // check running and dependencies
                if (!that['_' + task + 'Running']) {
                    that.gulp.start (task);
                }
            });
        });
    }

    /**
     * writes config file
     *
     * @param name
     * @param obj
     */
    _write (name, obj) {
        fs.writeFile ('./cache/' + name + '.json', JSON.stringify (obj), function (err) {
            if (err) {
                return console.log (err);
            }
        });
    }

    /**
     * merges two objects
     *
     * @param obj1
     * @param obj2
     * @returns {*}
     * @private
     */
    _merge (obj1, obj2) {
        for (var p in obj2) {
            try {
                // Property in destination object set; update its value.
                if (obj2[p].constructor == Object) {
                    obj1[p] = this._merge (obj1[p], obj2[p]);
                } else {
                    obj1[p] = obj2[p];
                }
            } catch (e) {
                // Property in destination object not set; create it and set its value.
                obj1[p] = obj2[p];
            }
        }

        return obj1;
    }
}

/**
 * export gulp builder class
 *
 * @type {gulpBuilder}
 */
module.exports = new gulpBuilder ();
<commit_msg>update config on helper change in<commit_after>/**
 * Created by Awesome on 1/30/2016.
 */

    // use strict
'use strict';

// require dependencies
var fs         = require ('fs');
var os         = require ('os');
var glob       = require ('glob');
var path       = require ('path');
var through    = require ('through2');
var browserify = require ('browserify');
var babelify   = require ('babelify');
var source     = require ('vinyl-source-stream');

// require gulp dependencies
var riot       = require ('gulp-riot');
var sass       = require ('gulp-sass');
var chmod      = require ('gulp-chmod');
var watch      = require ('gulp-watch');
var concat     = require ('gulp-concat');
var header     = require ('gulp-header');
var rename     = require ('gulp-rename');
var uglify     = require ('gulp-uglify');
var nodemon    = require ('gulp-nodemon');
var streamify  = require ('gulp-streamify');
var sourcemaps = require ('gulp-sourcemaps');

// import local dependencies
var config     = require ('./config');
var configPipe = require ('./bin/util/gulp.config.pipe');

/**
 * build gulp builder class
 */
class gulpBuilder {
    /**
     * construct gulp builder class
     */
    constructor () {
        // wait time
        this.wait = (config.gulpDelay ? parseInt (config.gulpDelay) : 500);

        // check cache exists
        if (!fs.existsSync ('./cache')) {
            fs.mkdirSync ('./cache');
        }

        // bind private methods
        this._watch = this._watch.bind (this);

        // bind variables
        this.gulp = require ('gulp');

        // bind methods
        this._tasks = {
            'tmp'    : {
                'skip' : true
            },
            'sass'   : {
                'files' : [
                    './bin/bundles/*/resources/scss/**/*.scss',
                    './app/bundles/*/resources/scss/**/*.scss'
                ],
                'dependencies' : [
                    'tmp'
                ]
            },
            'daemon' : {
                'files' : [
                    './bin/bundles/*/daemon/**/*Daemon.js',
                    './app/bundles/*/daemon/**/*Daemon.js'
                ],
            },
            'config' : {
                'files' : [
                    './bin/bundles/*/controller/**/*Controller.js',
                    './app/bundles/*/controller/**/*Controller.js',
                    './bin/bundles/*/helper/**/*Helper.js',
                    './app/bundles/*/helper/**/*Helper.js'
                ],
            },
            'view'   : {
                'files' : [
                    './bin/bundles/*/view/**/*.hbs',
                    './app/bundles/*/view/**/*.hbs'
                ],
            },
            'tag'    : {
                'files' : [
                    './bin/bundles/*/view/tag/**/*.tag',
                    './app/bundles/*/view/tag/**/*.tag'
                ],
                'skip' : true
            },
            'js'     : {
                'files' : [
                    './bin/bundles/*/resources/js/**/*.js',
                    './app/bundles/*/resources/js/**/*.js'
                ],
                'dependencies' : [
                    'tag'
                ]
            },
            'image'  : {
                'files' : [
                    './bin/bundles/*/resources/image/**/*',
                    './app/bundles/*/resources/image/**/*'
                ]
            }
        };

        // set keys array
        var keys     = Object.keys (this._tasks);
        var install  = [];
        var watchers = [];

        // bind and add gulp task methods
        for (var i = 0; i < keys.length; i++) {
            // set task
            let task = keys[i];
            // bind method
            this[task] = this[task].bind (this);
            // setup task
            if (this._tasks[task].dependencies) {
                this.gulp.task (task, this._tasks[task].dependencies, this[task]);
            } else {
                this.gulp.task (task, this[task]);
            }
            // check for skip
            if (this._tasks[task].skip) {
                continue;
            }
            // setup watch task
            var files = this._tasks[task].files;
            if (this._tasks[task].dependencies) {
                for (var a = 0; a < this._tasks[task].dependencies.length; a++) {
                    files = files.concat (this._tasks[this._tasks[task].dependencies[a]].files || []);
                }
            }
            // create watch task
            this._watch (task, files);
            // push to install
            install.push (task);
            // add watch task to array
            watchers.push (task + ':watch');
        }

        // add install task
        this.gulp.task ('install', install);
        // add watch task
        this.gulp.task ('watch', watchers);
        // add dev server task
        this.gulp.task ('dev', ['install'], () => {
            // run nodemon task
            nodemon ({
                'script' : './app.js',
                'ext'    : 'js json',
                'ignore' : [
                    'tags.min.js'
                ],
                'delay'  : this.wait,
                'watch'  : [
                    'cache/'
                ],
                'env'    : {
                    'NODE_ENV' : 'development'
                }
            });

            // start watch task
            this.gulp.start ('watch');
        });
        // add default task
        this.gulp.task ('default', ['dev']);
    }

    /**
     * creates temporary sass file
     *
     * @return {gulp}
     */
    tmp () {
        // set variables
        var that = this;
        var all  = '';

        // set running
        if (this._tmpRunning || this._sassRunning) {
            return;
        }
        this._tmpRunning = true;

        // grab gulp source for sass
        // create local variables array for sass files
        var sassFiles = [
            './bin/bundles/*/resources/scss/variables.scss',
            './app/bundles/*/resources/scss/variables.scss'
        ];

        // loop config sass files
        if (config.sass && config.sass.length) {
            for (var i = 0; i < config.sass.length; i ++) {
                sassFiles.push(config.sass[i]);
            }
        }

        // push local bootstrap files
        sassFiles.push('./bin/bundles/*/resources/scss/bootstrap.scss');
        sassFiles.push('./app/bundles/*/resources/scss/bootstrap.scss');

        // run gulp
        return this.gulp.src (sassFiles)
            .pipe (through.obj (function (chunk, enc, cb) {
                // run through callback
                var type = chunk.path.split('.');
                    type = type[type.length - 1];
                if (type == 'css') {
                    var prepend = fs.readFileSync(chunk.path, 'utf8');
                    this.push ({
                        'all' : prepend + os.EOL
                    });
                } else {
                    this.push ({
                        'all' : '@import "..' + chunk.path.replace (__dirname, '').split (path.delimiter).join ('/') + '";' + os.EOL
                    });
                }

                // run callback
                cb (null, chunk);
            }))
            .on ('data', (data) => {
                if (data.all) {
                    all += data.all;
                }
            })
            .on ('end', function () {
                // write temp sass file
                fs.writeFileSync ('./cache/tmp.scss', all);

                // reset running
                that._tmpRunning = false;
            });
    }

    /**
     * sass task
     */
    sass () {
        // set that
        var that = this;

        // check running
        if (this._tmpRunning || this._sassRunning) {
            return;
        }
        this._sassRunning = true;

        // run gulp task
        return this.gulp.src ('./cache/tmp.scss')
            .pipe (sourcemaps.init ())
            .pipe (sass ({
                outputStyle : 'compressed'
            }))
            .pipe (rename ('app.min.css'))
            .pipe (sourcemaps.write ('./www/assets/css'))
            .pipe (that.gulp.dest ('./www/assets/css'))
            .on ('end', () => {
                // reset running
                that._sassRunning = false;
            });
    }

    /**
     * daemon task
     */
    daemon () {
        // grab daemon controllers
        var daemons = [];
        for (var i = 0; i < this._tasks.daemon.files.length; i++) {
            daemons = daemons.concat (glob.sync (this._tasks.daemon.files[i]));
        }

        // loop daemons
        for (var key in daemons) {
            daemons[key] = daemons[key].replace ('./', '/');
        }

        // write daemons cache file
        this._write ('daemons', daemons);
    }

    /**
     * route task
     */
    config () {
        // set variables
        var that = this;
        var all  = {};

        // set running
        if (this._configRunning) {
            return;
        }
        this._configRunning = true;

        // get all routes
        // do within setTimeout to remove empty files
        return this.gulp.src (this._tasks.config.files)
            .pipe (through.obj (function (chunk, enc, cb) {
                var pipe = this;
                configPipe.pipe (chunk).then (result => {
                    // push to pipe
                    pipe.push ({
                        'result' : result
                    });

                    // run callback
                    cb (null, chunk);
                });
            }))
            .on ('data', (data) => {
                // merge config object
                that._merge (all, data.result);
            })
            .on ('end', function () {
                // write config file
                that._write ('config', all);

                // reset running tag
                that._configRunning = false;
            });
    }

    /**
     * view task
     */
    view () {
        // set that
        var that = this;

        // ensure running only once
        if (this._viewRunning) {
            return;
        }
        this._viewRunning = true;

        // move views into single folder
        // do within setTimeout to remove empty files
        // @todo bundle priority
        return this.gulp.src (this._tasks.view.files)
            .pipe (rename ((filePath) => {
                var amended = filePath.dirname.split (path.sep);
                amended.shift ();
                amended.shift ();
                filePath.dirname = amended.join (path.sep);
            }))
            .pipe (chmod (755))
            .pipe (this.gulp.dest ('cache/view'))
            .on('end', () => {
                // reset view running
                that._viewRunning = false;
            });
    }

    /**
     * tag task
     */
    tag () {
        // set that
        var that = this;

        // ensure running only once
        if (this._tagRunning) {
            return;
        }
        this._tagRunning = true;

        // move tags into javascript compiled file (riotjs)
        return this.gulp.src (this._tasks.tag.files)
            .pipe (riot ({
                compact : true
            }))
            .pipe (concat ('tags.min.js'))
            .pipe (header ('var riot = require(\'riot\');'))
            .pipe (this.gulp.dest ('./cache/tag'))
            .on ('end', () => {
                // reset running flag
                that._tagRunning = false;
            });
    }

    /**
     * javascript task
     */
    js () {
        // set that
        var that = this;

        // ensure running only once
        if (this._jsRunning) {
            return;
        }
        this._jsRunning = true;

        // create javascript array
        var js = [];
        js     = js.concat (glob.sync ('./bin/bundles/*/resources/js/bootstrap.js'));
        js     = js.concat (glob.sync ('./app/bundles/*/resources/js/bootstrap.js'));

        // build vendor prepend
        var vendor = '';
        if (config.js && config.js.length) {
            for (var i = 0; i < config.js.length; i++) {
                vendor += fs.readFileSync (config.js[i], 'utf8') + os.EOL;
            }
        }

        // browserfiy javascript
        // do within setTimeout to remove empty files
        return browserify ({
            entries : js
        })
            .transform (babelify)
            .bundle ()
            .pipe (source ('app.min.js'))
            .pipe (streamify (uglify ()))
            .pipe (streamify (header (vendor)))
            .pipe (this.gulp.dest ('./www/assets/js'))
            .on ('end', () => {
                // reset running flag
                that._jsRunning = false;
            });
    }

    /**
     * image task
     */
    image () {
        // move images into single folder
        // do within setTimeout to remove empty files
        // @todo bundle priority
        setTimeout (() => {
            this.gulp.src (this._tasks.image.files)
                .pipe (rename ((filePath) => {
                    var amended = filePath.dirname.split (path.sep);
                    amended.shift ();
                    amended.shift ();
                    amended.shift ();
                    filePath.dirname = amended.join (path.sep);
                }))
                .pipe (chmod (755))
                .pipe (this.gulp.dest ('www/image'));
        }, this.wait);
    }

    /**
     * creates watch task
     *
     * @param  {String} task
     * @param  {array} files
     */
    _watch (task, files) {
        // set that
        var that = this;

        // create watch task
        this.gulp.task (task + ':watch', () => {
            return watch (files, () => {
                // check running and dependencies
                if (!that['_' + task + 'Running']) {
                    that.gulp.start (task);
                }
            });
        });
    }

    /**
     * writes config file
     *
     * @param name
     * @param obj
     */
    _write (name, obj) {
        fs.writeFile ('./cache/' + name + '.json', JSON.stringify (obj), function (err) {
            if (err) {
                return console.log (err);
            }
        });
    }

    /**
     * merges two objects
     *
     * @param obj1
     * @param obj2
     * @returns {*}
     * @private
     */
    _merge (obj1, obj2) {
        for (var p in obj2) {
            try {
                // Property in destination object set; update its value.
                if (obj2[p].constructor == Object) {
                    obj1[p] = this._merge (obj1[p], obj2[p]);
                } else {
                    obj1[p] = obj2[p];
                }
            } catch (e) {
                // Property in destination object not set; create it and set its value.
                obj1[p] = obj2[p];
            }
        }

        return obj1;
    }
}

/**
 * export gulp builder class
 *
 * @type {gulpBuilder}
 */
module.exports = new gulpBuilder ();
<|endoftext|>