<commit_before>"use strict";

var https = require('https');
var http = require('http');
var Step = require('step');
var SmtpapiHeaders = require('./smtpapi_headers');
var FileHandler = require('./file_handler');
var _ = require('underscore');

/**
 * Class to handle storing the properties relative to an email.
 *
 * @param  {Object}          params
 * @param  {string|array}    params.to       The to address(es) of the email
 * @param  {string}          params.from     The from address of the email
 * @param  {SmtpapiHeaders}  params.smtpapi  The SendGrid x-smtpapi headers object
 * @param  {string}          params.subject  The subject of the email
 * @param  {string}          params.text     The text/plain content of an email
 * @param  {string}          params.html     The text/html content of an email
 * @param  {string|array}    params.bcc      The bcc address(es) of the email
 * @param  {Date}            params.date     The date of the email
 * @param  {object}          params.headers  The custom headers on an email
 */
function Email(params) {

  params = params || {};

  this.to      = params.to      || [];
  this.from    = params.from    || '';
  this.smtpapi = params.smtpapi || new SmtpapiHeaders();
  this.subject = params.subject || '';
  this.text    = params.text    || '';
  this.html    = params.html    || '';
  this.bcc     = params.bcc     || [];
  this.replyto = params.replyto || '';
  this.date    = params.date    || new Date();
  this.headers = params.headers || {};

  // auto handle calling the constructor for the file handler
  this.files = [];
  if (params.files) {
    params.files.forEach(function(file) {
      this.files.push(new FileHandler(file));
    }, this);
  }
}

/**
 * Validates an email. This is used before sending, but
 * can still be invoked programatically
 *
 * @return  {Boolean}  The result of the validation
 */
Email.prototype.validate = function() {
  //TODO: add validation
};

/**
 * This method sets the headers on an email, if the value passed in is an object.
 *
 * @param  {object}  val  An object of custom headers
 */
Email.prototype.setHeaders = function(val) {
  if (_.isObject(val)) {
    this.headers = val;
  }
};

/**
 * This method will add a header, or multiple headers, to an email.
 *
 * @param  {object}  val  An object of custom headers
 */
Email.prototype.addHeaders = function(val) {
  if (_.isObject(val)) {
    _.extend(this.headers, val);
  }
};

/**
 * This method is a proxy for adding a to address to the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addTo
 */
Email.prototype.addTo = function(to) {
  this.smtpapi.addTo(to);
};

/**
 * This method is a proxy for the add sub val on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addSubVal
 */
Email.prototype.addSubVal = function(key, val) {
  this.smtpapi.addSubVal(key, val);
};

/**
 * This method is a proxy for setting unique args on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.setUniqueArgs
 */
Email.prototype.setUniqueArgs = function(val) {
  this.smtpapi.setUniqueArgs(val);
};

/**
 * This method is a proxy for adding unique args on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addUniqueArgs
 */
Email.prototype.addUniqueArgs = function (val) {
  this.smtpapi.addUniqueArgs(val);
};

/**
 * This method is a proxy for setting categories on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.setCategory
 */
Email.prototype.setCategory = function(val) {
  this.smtpapi.setCategory(val);
};

/**
 * This method is a proxy for adding categories on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addCategory
 */
Email.prototype.addCategory = function(val) {
  this.smtpapi.addCategory(val);
};

/**
 * This method is a proxy for setting sections on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.setSection
 */
Email.prototype.setSection = function(val) {
  this.smtpapi.setSection(val);
};

/**
 * This method is a proxy for adding sections on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addSection
 */
Email.prototype.addSection = function(val) {
  this.smtpapi.addSection(val);
};

/**
 * This method is a proxy for adding a filter setting on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addFilterSetting
 */
Email.prototype.addFilterSetting = function(filter, setting, val) {
  this.smtpapi.addFilterSetting(filter, setting, val);
};

/**
 * This method is a proxy for setting a filter setting on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.setFilterSetting
 */
Email.prototype.setFilterSetting = function(filters) {
  this.smtpapi.setFilterSetting(filters);
};

/**
 * This method adds a file to the email object as an attachment
 * It uses the FileHandler object.
 *
 * @param  {object}  file_object  The file object
 *
 * @see FileHandler
 */
Email.prototype.addFile = function(file_object) {
  this.files.push(new FileHandler(file_object));
};

/**
 * This method is used to process files. It uses step.js to asychronously load the contents of each file.
 *
 * @param  {function}  callback  The callback to call when the method returns
 */
Email.prototype.processFiles = function(callback) {
  var self = this;

  function handleFiles() {
    for(var i in self.files) {
      self.files[i].loadContent(this.parallel());
    }
  };

  function finish(err, messages) {
    if (err) {
      callback(false, messages);
    } else {
      callback(true);
    }
  };

  Step(handleFiles, finish);
};

/**
 * This method returns the email object is a format to be consumed by the SendGrid.send
 * using the web api
 *
 * @see SendGrid.send
 */
Email.prototype.toWebFormat = function() {
  var data = {
    to: this.to,
    from: this.from,
    'x-smtpapi': this.smtpapi.toJson(),
    subject: this.subject,
    text: this.text,
    html: this.html,
    bcc: this.bcc,
    replyto: this.replyto,
    headers: JSON.stringify(this.headers)
  };

  if (this.fromname != null) {
    data.fromname = this.fromname;
  }
  if (this.toname != null) {
    data.toname = this.toname;
  }
  this.updateMissingTo(data);

  return data;
};

/**
 * This method returns the email object is a format to be consumed by the SendGrid.smtp
 * using the smtp api
 *
 * @see SendGrid.smtp
 */
Email.prototype.toSmtpFormat = function() {
  var data = {
    to: this.to,
    sender: this.from,
    subject: this.subject,
    body: this.text,
    html: this.html,
    reply_to: this.replyto,
    headers: this.headers
  };
  data.headers['x-smtpapi'] = this.smtpapi.toJson();

  if (_.size(this.files) > 0) {
    var attachments = [];
    _(this.files).each(function(file) {
      attachments.push({filename: file.filename, contents: file.content});
    });
    data.attachments = attachments;
  }

  this.updateMissingTo(data);

  return data;
};

/**
 * There needs to be at least 1 to address, or else the mail won't send.
 * This method modifies the data that will be sent via either Rest or SMTP.
 *
 * @param  {object}  data  The data parameter to send via Rest or SMTP
 */
Email.prototype.updateMissingTo = function(data) {
  if (_.isEmpty(data.to) && this.smtpapi.to && !_.isEmpty(this.smtpapi.to)) {
    data.to = this.from;
  }
};

/**
 * This method is used to show if there are files on this email object
 *
 * @return boolean
 */
Email.prototype.hasFiles = function() {
  return _(this.files).size() > 0;
};

// export the object as the only object in this module
module.exports = Email;
<commit_msg>Added comments for params.<commit_after>"use strict";

var https = require('https');
var http = require('http');
var Step = require('step');
var SmtpapiHeaders = require('./smtpapi_headers');
var FileHandler = require('./file_handler');
var _ = require('underscore');

/**
 * Class to handle storing the properties relative to an email.
 *
 * @param  {Object}          params
 * @param  {string|array}    params.to       The to address(es) of the email
 * @param  {string|array}    params.fromname The display name of the email recipients
 * @param  {string}          params.from     The from address of the email
 * @param  {string}          params.fromname The display name of the email sender
 * @param  {SmtpapiHeaders}  params.smtpapi  The SendGrid x-smtpapi headers object
 * @param  {string}          params.subject  The subject of the email
 * @param  {string}          params.text     The text/plain content of an email
 * @param  {string}          params.html     The text/html content of an email
 * @param  {string|array}    params.bcc      The bcc address(es) of the email
 * @param  {Date}            params.date     The date of the email
 * @param  {object}          params.headers  The custom headers on an email
 */
function Email(params) {

  params = params || {};

  this.to      = params.to      || [];
  this.from    = params.from    || '';
  this.smtpapi = params.smtpapi || new SmtpapiHeaders();
  this.subject = params.subject || '';
  this.text    = params.text    || '';
  this.html    = params.html    || '';
  this.bcc     = params.bcc     || [];
  this.replyto = params.replyto || '';
  this.date    = params.date    || new Date();
  this.headers = params.headers || {};

  // auto handle calling the constructor for the file handler
  this.files = [];
  if (params.files) {
    params.files.forEach(function(file) {
      this.files.push(new FileHandler(file));
    }, this);
  }
}

/**
 * Validates an email. This is used before sending, but
 * can still be invoked programatically
 *
 * @return  {Boolean}  The result of the validation
 */
Email.prototype.validate = function() {
  //TODO: add validation
};

/**
 * This method sets the headers on an email, if the value passed in is an object.
 *
 * @param  {object}  val  An object of custom headers
 */
Email.prototype.setHeaders = function(val) {
  if (_.isObject(val)) {
    this.headers = val;
  }
};

/**
 * This method will add a header, or multiple headers, to an email.
 *
 * @param  {object}  val  An object of custom headers
 */
Email.prototype.addHeaders = function(val) {
  if (_.isObject(val)) {
    _.extend(this.headers, val);
  }
};

/**
 * This method is a proxy for adding a to address to the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addTo
 */
Email.prototype.addTo = function(to) {
  this.smtpapi.addTo(to);
};

/**
 * This method is a proxy for the add sub val on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addSubVal
 */
Email.prototype.addSubVal = function(key, val) {
  this.smtpapi.addSubVal(key, val);
};

/**
 * This method is a proxy for setting unique args on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.setUniqueArgs
 */
Email.prototype.setUniqueArgs = function(val) {
  this.smtpapi.setUniqueArgs(val);
};

/**
 * This method is a proxy for adding unique args on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addUniqueArgs
 */
Email.prototype.addUniqueArgs = function (val) {
  this.smtpapi.addUniqueArgs(val);
};

/**
 * This method is a proxy for setting categories on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.setCategory
 */
Email.prototype.setCategory = function(val) {
  this.smtpapi.setCategory(val);
};

/**
 * This method is a proxy for adding categories on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addCategory
 */
Email.prototype.addCategory = function(val) {
  this.smtpapi.addCategory(val);
};

/**
 * This method is a proxy for setting sections on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.setSection
 */
Email.prototype.setSection = function(val) {
  this.smtpapi.setSection(val);
};

/**
 * This method is a proxy for adding sections on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addSection
 */
Email.prototype.addSection = function(val) {
  this.smtpapi.addSection(val);
};

/**
 * This method is a proxy for adding a filter setting on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.addFilterSetting
 */
Email.prototype.addFilterSetting = function(filter, setting, val) {
  this.smtpapi.addFilterSetting(filter, setting, val);
};

/**
 * This method is a proxy for setting a filter setting on the SmtpapiHeaders
 *
 * @see SmtpapiHeaders.setFilterSetting
 */
Email.prototype.setFilterSetting = function(filters) {
  this.smtpapi.setFilterSetting(filters);
};

/**
 * This method adds a file to the email object as an attachment
 * It uses the FileHandler object.
 *
 * @param  {object}  file_object  The file object
 *
 * @see FileHandler
 */
Email.prototype.addFile = function(file_object) {
  this.files.push(new FileHandler(file_object));
};

/**
 * This method is used to process files. It uses step.js to asychronously load the contents of each file.
 *
 * @param  {function}  callback  The callback to call when the method returns
 */
Email.prototype.processFiles = function(callback) {
  var self = this;

  function handleFiles() {
    for(var i in self.files) {
      self.files[i].loadContent(this.parallel());
    }
  };

  function finish(err, messages) {
    if (err) {
      callback(false, messages);
    } else {
      callback(true);
    }
  };

  Step(handleFiles, finish);
};

/**
 * This method returns the email object is a format to be consumed by the SendGrid.send
 * using the web api
 *
 * @see SendGrid.send
 */
Email.prototype.toWebFormat = function() {
  var data = {
    to: this.to,
    from: this.from,
    'x-smtpapi': this.smtpapi.toJson(),
    subject: this.subject,
    text: this.text,
    html: this.html,
    bcc: this.bcc,
    replyto: this.replyto,
    headers: JSON.stringify(this.headers)
  };

  if (this.fromname != null) {
    data.fromname = this.fromname;
  }
  if (this.toname != null) {
    data.toname = this.toname;
  }
  this.updateMissingTo(data);

  return data;
};

/**
 * This method returns the email object is a format to be consumed by the SendGrid.smtp
 * using the smtp api
 *
 * @see SendGrid.smtp
 */
Email.prototype.toSmtpFormat = function() {
  var data = {
    to: this.to,
    sender: this.from,
    subject: this.subject,
    body: this.text,
    html: this.html,
    reply_to: this.replyto,
    headers: this.headers
  };
  data.headers['x-smtpapi'] = this.smtpapi.toJson();

  if (_.size(this.files) > 0) {
    var attachments = [];
    _(this.files).each(function(file) {
      attachments.push({filename: file.filename, contents: file.content});
    });
    data.attachments = attachments;
  }

  this.updateMissingTo(data);

  return data;
};

/**
 * There needs to be at least 1 to address, or else the mail won't send.
 * This method modifies the data that will be sent via either Rest or SMTP.
 *
 * @param  {object}  data  The data parameter to send via Rest or SMTP
 */
Email.prototype.updateMissingTo = function(data) {
  if (_.isEmpty(data.to) && this.smtpapi.to && !_.isEmpty(this.smtpapi.to)) {
    data.to = this.from;
  }
};

/**
 * This method is used to show if there are files on this email object
 *
 * @return boolean
 */
Email.prototype.hasFiles = function() {
  return _(this.files).size() > 0;
};

// export the object as the only object in this module
module.exports = Email;
<|endoftext|>


<commit_before>var
  config = require('yaml-config')
  .readConfig(__dirname + '/../config/config.yml'),
  defaultMailTransport = require('../config/mail')(config.smtp),
  jade = require('jade'),
  path = require('path'),
  fs = require('fs');

var TEMPLATE_DIR = '../templates/emails';

/*
Get the template file path
 @param {String} file the file template name
 */
 function getTemplate (file) {

  return path.join(__dirname, TEMPLATE_DIR, file);
}

/**
 * Email base class
 *
 * @param {Object} transport mail transport
 */
 exports.Email = function (transport) {

  this.mailTransport = transport || defaultMailTransport;
  this.send = function () {};
};

/**
 * Send a welcoming account registration message
 *
 * @param {String} email recipient
 */
 exports.AccountRegistration = function (email) {

  email.send = function (recipient, subject, templateData, cb) {
    fs.readFile(getTemplate('welcome.jade'), {encoding: 'utf8'},
      function (err, templateContent) {
        var fn = jade.compile(templateContent, {
          filename: getTemplate('welcome.jade'),
          pretty: true
        });

        var mailOptions = {
          from: 'My Web Class <mywebclass@webizly.com>',
          to: recipient,
          subject: subject,
          html: fn(templateData)
        };

        email.mailTransport.sendMail(mailOptions, function (err, response) {
          if (err) {
            cb(err);
          } else {
            cb(null, response);
          }
          email.mailTransport.close();
        });
      });
  };
};

exports.CancelAccount = function (email) {

  email.send =
  function sendCancelConfirmation (recipient, subject, templateData, cb) {
    fs.readFile(getTemplate('cancel.jade'), {encoding: 'utf8'},
      function (err, templateContent) {
        var fn = jade.compile(templateContent, {
          filename: getTemplate('cancel.jade'),
          pretty: true
        });

        var mailOptions = {
          from: 'My Web Class <mywebclass@webizly.com>',
          to: recipient,
          subject: subject,
          html: fn(templateData)
        };

        email.mailTransport.sendMail(mailOptions, function (err, response) {
          if (err) {
            cb(err);
          } else {
            cb(null, response);
          }
          email.mailTransport.close();
        });
      });
  };
};

exports.AccountConfirmation = function () {

};

exports.AccountInvite = function () {

};
<commit_msg>Extract function to send the actual email message to recipient<commit_after>var
  config = require('yaml-config')
  .readConfig(__dirname + '/../config/config.yml'),
  defaultMailTransport = require('../config/mail')(config.smtp),
  jade = require('jade'),
  path = require('path'),
  fs = require('fs');

var TEMPLATE_DIR = '../templates/emails';

/*
Get the template file path
 @param {String} file the file template name
 */
function getTemplate (file) {

  return path.join(__dirname, TEMPLATE_DIR, file);
}

/**
* Send the actual email message to recipient
*/
function emailSender (email, recipient, subject, fn, templateData, cb) {

  var mailOptions = {
    from: 'My Web Class <mywebclass@webizly.com>',
    to: recipient,
    subject: subject,
    html: fn(templateData)
  };

  email.mailTransport.sendMail(mailOptions, function (err, response) {
    if (err) {
      cb(err);
    } else {
      cb(null, response);
    }
    email.mailTransport.close();
  });
}

/**
 * Email base class
 *
 * @param {Object} transport mail transport
 */
 exports.Email = function (transport) {

  this.mailTransport = transport || defaultMailTransport;
  this.send = function () {};
};

/**
 * Send a welcoming account registration message
 *
 * @param {String} email recipient
 */
 exports.AccountRegistration = function (email) {

  email.send = function (recipient, subject, templateData, cb) {
    fs.readFile(getTemplate('welcome.jade'), {encoding: 'utf8'},
      function (err, templateContent) {
        var fn = jade.compile(templateContent, {
          filename: getTemplate('welcome.jade'),
          pretty: true
        });

        emailSender(email, recipient, subject, fn, templateData, cb);
      });
  };
};

exports.CancelAccount = function (email) {

  email.send =
  function sendCancelConfirmation (recipient, subject, templateData, cb) {
    fs.readFile(getTemplate('cancel.jade'), {encoding: 'utf8'},
      function (err, templateContent) {
        var fn = jade.compile(templateContent, {
          filename: getTemplate('cancel.jade'),
          pretty: true
        });

        emailSender(email, recipient, subject, fn, templateData, cb);
      });
  };
};

exports.AccountConfirmation = function () {

};

exports.AccountInvite = function () {

};
<|endoftext|>


<commit_before>/*!
 * ws: a node.js websocket client
 * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
 * MIT Licensed
 */

var util = require('util');

function BufferPool(initialSize, growStrategy, shrinkStrategy) {
  if (typeof initialSize === 'function') {
    shrinkStrategy = growStrategy;
    growStrategy = initialSize;
    initialSize = 0;
  }
  else if (typeof initialSize === 'undefined') {
    initialSize = 0;
  }
  this._growStrategy = (growStrategy || function(db, size) {
    return db.used + size;
  }).bind(null, this);
  this._shrinkStrategy = (shrinkStrategy || function(db) {
    return initialSize;
  }).bind(null, this);
  this._buffer = new Buffer(initialSize);
  this._offset = 0;
  this._used = 0;
  this._changeFactor = 0;
  this.__defineGetter__('size', function(){
    return this._buffer == null ? 0 : this._buffer.length;
  });
  this.__defineGetter__('used', function(){
    return this._used;
  });
}

BufferPool.prototype.get = function(length) {
  if (this._buffer == null || this._offset + length > this._buffer.length) {
    var newBuf = new Buffer(this._growStrategy(length));
    this._buffer = newBuf;
    this._offset = 0;
  }
  this._used += length;
  var buf = this._buffer.slice(this._offset, this._offset + length);
  this._offset += length;
  return buf;
}

BufferPool.prototype.reset = function(forceNewBuffer) {
  // var len = this._shrinkStrategy();
  // this._buffer = len ? new Buffer(len) : null;
  // this._offset = 0;
  // this._used = 0;
  var len = this._shrinkStrategy();
  if (len < this.size) this._changeFactor -= 1;
  if (forceNewBuffer || this._changeFactor < -2) {
    this._changeFactor = 0;
    this._buffer = len ? new Buffer(len) : null;
  }
  this._offset = 0;
  this._used = 0;
}

module.exports = BufferPool;
<commit_msg>remove comments<commit_after>/*!
 * ws: a node.js websocket client
 * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
 * MIT Licensed
 */

var util = require('util');

function BufferPool(initialSize, growStrategy, shrinkStrategy) {
  if (typeof initialSize === 'function') {
    shrinkStrategy = growStrategy;
    growStrategy = initialSize;
    initialSize = 0;
  }
  else if (typeof initialSize === 'undefined') {
    initialSize = 0;
  }
  this._growStrategy = (growStrategy || function(db, size) {
    return db.used + size;
  }).bind(null, this);
  this._shrinkStrategy = (shrinkStrategy || function(db) {
    return initialSize;
  }).bind(null, this);
  this._buffer = new Buffer(initialSize);
  this._offset = 0;
  this._used = 0;
  this._changeFactor = 0;
  this.__defineGetter__('size', function(){
    return this._buffer == null ? 0 : this._buffer.length;
  });
  this.__defineGetter__('used', function(){
    return this._used;
  });
}

BufferPool.prototype.get = function(length) {
  if (this._buffer == null || this._offset + length > this._buffer.length) {
    var newBuf = new Buffer(this._growStrategy(length));
    this._buffer = newBuf;
    this._offset = 0;
  }
  this._used += length;
  var buf = this._buffer.slice(this._offset, this._offset + length);
  this._offset += length;
  return buf;
}

BufferPool.prototype.reset = function(forceNewBuffer) {
  var len = this._shrinkStrategy();
  if (len < this.size) this._changeFactor -= 1;
  if (forceNewBuffer || this._changeFactor < -2) {
    this._changeFactor = 0;
    this._buffer = len ? new Buffer(len) : null;
  }
  this._offset = 0;
  this._used = 0;
}

module.exports = BufferPool;
<|endoftext|>


<commit_before><commit_msg>delete user<commit_after><|endoftext|>


<commit_before>'use strict';

var
    _ = require('lodash'),
    through = require('through2'),
    path = require('path'),
    fs = require('fs'),
    pug = require('pug'),
    ext = require('gulp-util').replaceExtension,
    md5File = require('md5-file');

var isExists = function (filepath) {
    try {
        fs.accessSync(filepath, fs.F_OK);

        return true;
    } catch (e) {
        return false;
    }

};

var loadData = function (filepath) {
    var data = undefined;

    if (isExists(filepath)) {
        delete require.cache[require.resolve(filepath)];
        data = require(filepath);
    } else {
        data = {};
    }

    return data;
};

var calcBlockName = function (filename) {
    var words = _.split(filename, '-');
    var upperWords = _.map(words, function (word) {
        return _.upperFirst(word);
    });

    return _.lowerFirst(_.join(upperWords, ''));
};

var getBlockTemplate = function (blockName, filename) {
    var mixinName = calcBlockName(filename);

    return `
include ./${blockName}/${filename}.pug
include ./layout/layout.pug

+layout(layoutData)
  +${mixinName}(blockData)
    `;
};
var getLayoutTemplate = function () {
    return `
include ./layout/layout.pug

+layout(layoutData)
    `;
};

var pugCompile = function (template, data, tmpFile) {
    var fn = pug.compile(template, {
        pretty: true,
        filename: tmpFile
    });

    return fn(data);
};

var files = {};
var checkFileUpdates = function (filepath) {
    if (!isExists(filepath)) {
        return false;
    }

    var hash = md5File.sync(filepath);

    if (undefined === files[filepath] || files[filepath] !== hash) {
        files[filepath] = hash;

        return true;
    }

    return false;
};

var compile = function (file, enc, cb) {
    var
        dirname = path.dirname(file.path),
        blocksPath = dirname + '/..',
        layoutDataFilepath = blocksPath + '/layout/layout.data.js',
        templateFilename = path.basename(file.path, '.pug'),
        blockDataFilepath = dirname + '/' + templateFilename + '.data.js';

    var isTemplateUpdated = checkFileUpdates(file.path),
        isLayoutDataFileUpdated = checkFileUpdates(layoutDataFilepath),
        isTemplateDataFileUpdated = checkFileUpdates(blockDataFilepath);

    if (!isTemplateUpdated && !isLayoutDataFileUpdated && !isTemplateDataFileUpdated) {
        cb();
        return;
    }

    var blockName = _.last(_.split(dirname, '/'));

    file.path = file.cwd + '/' + path.basename(file.path);

    var template = (templateFilename == 'layout') ? getLayoutTemplate() : getBlockTemplate(blockName, templateFilename);

    var html = pugCompile(template, {
        layoutData: loadData(layoutDataFilepath),
        blockData: loadData(blockDataFilepath)
    }, dirname + '/../tmp.pug');

    file.path = ext(file.path, '.html');

    if (file.isBuffer()) {
        file.contents = new Buffer(html);
    }

    cb(null, file);
};

module.exports = function () {
    return through.obj(compile);
};
<commit_msg>Incremental block compiling with dependencies<commit_after>'use strict';

var
    _ = require('lodash'),
    through2 = require('through2').obj,
    path = require('path'),
    fs = require('fs'),
    pug = require('pug'),
    ext = require('gulp-util').replaceExtension;

var index = {};

var getBlockIndex = function(relativePath) {
    if (undefined === index[relativePath]) {
        index[relativePath] = {
            template: {},
            data: {}
        };
    }

    return index[relativePath];
};

var compareTimes = function (time1, time2) {
    if (!time1 || !time2) {
        return false;
    }

    return time1.getTime() == time2.getTime();
};

var updateFileInfo = function (filepath, oldData) {
    if (!isExists(filepath)) {
        return undefined;
    }

    var stats = fs.statSync(filepath);
    var blockData = {};

    blockData.filepath = filepath;
    blockData.oldTimestamp = oldData.newTimestamp;
    blockData.newTimestamp = stats.mtime;
    blockData.isChanged = !compareTimes(blockData.oldTimestamp, blockData.newTimestamp);

    return blockData;
};

var getIncludesBlocks = function (file) {
    var matches = file.contents.toString().match(/include .+\.pug/ig);
    var blockDir = path.normalize(file.dirname + '/../');

    if (!matches) {
        return [];
    }

    return _.map(matches, function (str) {
        str = _.replace(str, 'include .', file.dirname);
        str = path.normalize(str);
        str = _.replace(str, blockDir, '');

        return str;
    });
};

var isNeedUpdate = function (relativePath) {
    var blockIndex = index[relativePath];

    if (blockIndex.template.isChanged) {
        return true;
    } else if (!blockIndex.dependecies.length) {
        return false;
    } else {
        var isNeedDependenciesUpdate = _.map(blockIndex.dependecies, function (dependencyRelativePath) {
            return isNeedUpdate(dependencyRelativePath);
        });

        return -1 != _.indexOf(isNeedDependenciesUpdate, true);
    }
};

var isExists = function (filepath) {
    try {
        fs.accessSync(filepath, fs.F_OK);

        return true;
    } catch (e) {
        return false;
    }

};

var loadData = function (filepath) {
    delete require.cache[require.resolve(filepath)];
    return require(filepath);
};

var calcBlockName = function (filename) {
    var words = _.split(filename, '-');
    var upperWords = _.map(words, function (word) {
        return _.upperFirst(word);
    });

    return _.lowerFirst(_.join(upperWords, ''));
};

var getBlockTemplate = function (blockName, filename) {
    var mixinName = calcBlockName(filename);

    return `
include ./${blockName}/${filename}.pug
include ./layout/layout.pug

+layout(layoutData)
  +${mixinName}(blockData)
    `;
};
var getLayoutTemplate = function () {
    return `
include ./layout/layout.pug

+layout(layoutData)
    `;
};

var pugCompile = function (template, data, tmpFile) {
    var fn = pug.compile(template, {
        pretty: true,
        filename: tmpFile
    });

    return fn(data);
};

var isChanged = function (blockIndex) {
    if (blockIndex.template.isChanged) {
        return true;
    }

    if (!blockIndex.data) {
        return false;
    }

    return blockIndex.data.isChanged;
};

var compileFile = function (file, enc, cb) {
    var
        dirname = path.dirname(file.path),
        blocksPath = dirname + '/..',
        layoutDataFilepath = blocksPath + '/layout/layout.data.js',
        templateFilename = path.basename(file.path, '.pug');

    var blockIndex = index[file.relative];
    blockIndex.template.isChanged = isNeedUpdate(file.relative);

    if (!isChanged(blockIndex)) {
        cb();
        return;
    }
    var blockName = _.last(_.split(dirname, '/'));

    file.path = file.cwd + '/' + path.basename(file.path);

    var template = (templateFilename == 'layout') ? getLayoutTemplate() : getBlockTemplate(blockName, templateFilename);

    var html = pugCompile(template, {
        layoutData: isExists(layoutDataFilepath) ? loadData(layoutDataFilepath) : {},
        blockData: blockIndex.data ? loadData(blockIndex.data.filepath) : {}
    }, dirname + '/../tmp.pug');

    file.path = ext(file.path, '.html');

    if (file.isBuffer()) {
        file.contents = new Buffer(html);
    }

    cb(null, file);
};

var indexFile = function (file, enc, callback) {
    var templateFilename = path.basename(file.relative, '.pug');
    var blockDataFilepath = file.dirname + '/' + templateFilename + '.data.js';

    var blockIndex = getBlockIndex(file.relative);

    blockIndex.template = updateFileInfo(file.path, blockIndex.template);
    blockIndex.data = updateFileInfo(blockDataFilepath, blockIndex.data);
    blockIndex.dependecies = getIncludesBlocks(file);

    callback(null, file);
};

module.exports = function () {
    return through2(compileFile);
};

module.exports.index = function () {
    return through2(indexFile);
};
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 * Wicket Date parse function for the Calendar/ Date picker component.
 */

// Wicket Namespace

if (typeof(Wicket) == "undefined")
	Wicket = { };

Wicket.DateTime = { }

/**
 * Parses date from simple date pattern. Only parses dates with yy, MM and dd like patterns, though
 * it is safe to have time as long as it comes after the pattern (which should be the case
 * anyway 99.9% of the time).
 */
Wicket.DateTime.parseDate = function(pattern, value) {
	numbers = value.match(/(\d+)/g);
	if (numbers == null) return Number.NaN;
	var day, month, year;
	arrayPos = 0;
	for (i = 0; i < pattern.length; i++) {
		c = pattern.charAt(i);
		while ((pattern.charAt(i) == c) && (i < pattern.length)) {
			i++;
		}
		if (c == 'y') {
			year = numbers[arrayPos++];
		} else if (c == 'M') {
			month = numbers[arrayPos++];
		} else if (c == 'd') {
			day = numbers[arrayPos++];
		}
		if (arrayPos > 2) break;
	}
	// TODO this is a bit crude. Make nicer some time.
	if (year < 100) {
		if (year < 70) {
			year = year * 1 + 2000;
		} else {
			year = year * 1 + 1900;
		}
	}
	var date = new Date();
	date.setFullYear(year, (month - 1), day);
	return date;
}

/**
 * Returns a string containing the value, with a leading zero if the value is < 10.
 */
Wicket.DateTime.padDateFragment = function(value) {
	return (value < 10 ? "0" : "") + value;
}

/**
 * Gets the height of the displayed area of the window, as YAHOO.util.Dom.getViewportHeight()
 * has issues with Firefox.
 * See http://tech.groups.yahoo.com/group/ydn-javascript/message/5850
 * Implementation taken from: http://www.quirksmode.org/viewport/compatibility.html#link2
 */
Wicket.DateTime.getViewportHeight = function() {
	if (window.innerHeight) // all browsers except IE
		viewPortHeight = window.innerHeight;
	else if (document.documentElement && document.documentElement.clientHeight) // IE 6 strict mode
		viewPortHeight = document.documentElement.height;
	else if (document.body) // other IEs
		viewPortHeight = document.body.clientHeight;
	return viewPortHeight;
}

/**
 * Position subject relative to target top-left by default.
 * If there is too little space on the right side/bottom,
 * the datepicker's position is corrected so that the right side/bottom
 * is aligned with the display area's right side/bottom.
 * @param subject the dom element to has to be positioned
 * @param target id of the dom element to position relative to
 */
Wicket.DateTime.positionRelativeTo = function(subject, target) {

	targetPos = YAHOO.util.Dom.getXY(target);
	targetHeight = YAHOO.util.Dom.get(target).offsetHeight;
	subjectHeight = YAHOO.util.Dom.get(subject).offsetHeight;
	subjectWidth = YAHOO.util.Dom.get(subject).offsetWidth;

	viewPortHeight = Wicket.DateTime.getViewportHeight();
	viewPortWidth = YAHOO.util.Dom.getViewportWidth();

	// also take scroll position into account
	scrollPos = [YAHOO.util.Dom.getDocumentScrollLeft(), YAHOO.util.Dom.getDocumentScrollTop()];

	// correct datepicker's position so that it isn't rendered off screen on the right side or bottom
	if (targetPos[0] + subjectWidth > scrollPos[0] + viewPortWidth) {
		// correct horizontal position
		YAHOO.util.Dom.setX(subject, Math.max(targetPos[0], viewPortWidth) - subjectWidth);
	} else {
		YAHOO.util.Dom.setX(subject, targetPos[0]);
	}
	if (targetPos[1] + targetHeight + 1 + subjectHeight > scrollPos[1] + viewPortHeight) {
		// correct vertical position
		YAHOO.util.Dom.setY(subject, Math.max(targetPos[1], viewPortHeight) - subjectHeight);
	} else {
		YAHOO.util.Dom.setY(subject, targetPos[1] + targetHeight + 1);
	}
}

/**
 * Return the result of interpolating the value (date) argument with the date pattern.
 * The dateValue has to be an array, where year is in the first, month in the second
 * and date (day of month) in the third slot.
 */
Wicket.DateTime.substituteDate = function(datePattern, date) {
	day = date[2];
	month = date[1];
	year = date[0];
	// optionally do some padding to match the pattern
	if(datePattern.match(/dd+/)) day = Wicket.DateTime.padDateFragment(day);
	if(datePattern.match(/MM+/)) month = Wicket.DateTime.padDateFragment(month);
  if(datePattern.match(/yyy+/)) {
    year = Wicket.DateTime.padDateFragment(year);
  } else if(datePattern.match(/yy+/)) {
    year = Wicket.DateTime.padDateFragment(year % 100);
  }
	// replace pattern with real values
	return datePattern.replace(/d+/, day).replace(/M+/, month).replace(/y+/, year);
}

/**
 * Display the YUI calendar widget. If the date is not null (should be a string) then it is parsed
 * using the provided date pattern, and set as the current date on the widget.
 */
Wicket.DateTime.showCalendar = function(widget, date, datePattern) {
	if (date) {
		date = Wicket.DateTime.parseDate(datePattern, date);
		if (!isNaN(date)) {
			widget.select(date);
			firstDate = widget.getSelectedDates()[0];
			if (firstDate) {
				widget.cfg.setProperty("pagedate", (firstDate.getMonth() + 1) + "/" + firstDate.getFullYear());
				widget.render();
			}
		}
	}
	widget.show();
}

// configures a datepicker using the cfg object
Wicket.DateTime.init = function(cfg) {
	cfg.dpJs = cfg.widgetId + "DpJs";
	cfg.dp = cfg.widgetId + "Dp";
	cfg.icon = cfg.widgetId +"Icon";
	YAHOO.namespace("wicket");

	if (cfg.calendarInit.pages && cfg.calendarInit.pages > 1) {
		YAHOO.wicket[cfg.dpJs] = new YAHOO.widget.CalendarGroup(cfg.dpJs,cfg.dp, cfg.calendarInit);
	} else {
		YAHOO.wicket[cfg.dpJs] = new YAHOO.widget.Calendar(cfg.dpJs,cfg.dp, cfg.calendarInit);
	}
	YAHOO.wicket[cfg.dpJs].isVisible = function() { return YAHOO.wicket[cfg.dpJs].oDomContainer.style.display == 'block'; }

	function showCalendar() {
		Wicket.DateTime.showCalendar(YAHOO.wicket[cfg.dpJs], YAHOO.util.Dom.get(cfg.componentId).value, cfg.datePattern);
		if (cfg.alignWithIcon) Wicket.DateTime.positionRelativeTo(YAHOO.wicket[cfg.dpJs].oDomContainer, cfg.icon);
	}

	YAHOO.util.Event.addListener(cfg.icon, "click", showCalendar, YAHOO.wicket[cfg.dpJs], true);

	if (cfg.showOnFieldClick) {
		YAHOO.util.Event.addListener(cfg.widgetId, "click", showCalendar, YAHOO.wicket[cfg.dpJs], true);
	}

	function selectHandler(type, args, cal) {
		YAHOO.util.Dom.get(cfg.componentId).value = Wicket.DateTime.substituteDate(cfg.datePattern, args[0][0]);
		if (cal.isVisible()) {
			if (cfg.hideOnSelect) cal.hide();
			if (cfg.fireChangeEvent) {
				var field = YAHOO.util.Dom.get(cfg.componentId);
				if (field.onchangeoriginal != null && typeof(field.onchangeoriginal) != 'undefined') field.onchangeoriginal();
				if (field.onchange != null && typeof(field.onchange) != 'undefined') field.onchange();
			}
		}
	}

	YAHOO.wicket[cfg.dpJs].selectEvent.subscribe(selectHandler,YAHOO.wicket[cfg.dpJs]);
	YAHOO.wicket[cfg.dpJs].render();
}

// init method variant that needs less character to invoke
Wicket.DateTime.init2 = function(widgetId, componentId, calendarInit, datePattern,
		alignWithIcon, fireChangeEvent, hideOnSelect, showOnFieldClick, i18n) {
	calendarInit.MONTHS_SHORT = i18n.MONTHS_SHORT;
	calendarInit.MONTHS_LONG = i18n.MONTHS_LONG;
	calendarInit.WEEKDAYS_MEDIUM = i18n.WEEKDAYS_MEDIUM;
	calendarInit.WEEKDAYS_LONG = i18n.WEEKDAYS_LONG;
	calendarInit.START_WEEKDAY = i18n.START_WEEKDAY;
	calendarInit.WEEKDAYS_1CHAR = i18n.WEEKDAYS_1CHAR;
	calendarInit.WEEKDAYS_SHORT = i18n.WEEKDAYS_SHORT;

	Wicket.DateTime.init({
		widgetId: widgetId,
		componentId: componentId,
		calendarInit: calendarInit,
		datePattern: datePattern,
		alignWithIcon: alignWithIcon,
		fireChangeEvent: fireChangeEvent,
		hideOnSelect: hideOnSelect,
		showOnFieldClick: showOnFieldClick
	});
}

YAHOO.register("wicket-date", Wicket.DateTime, {version: "1.3.0", build: "rc1"});
<commit_msg>WICKET-3598 DatePicker issues with locale medium date format<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 * Wicket Date parse function for the Calendar/ Date picker component.
 */

// Wicket Namespace

if (typeof(Wicket) == "undefined")
	Wicket = { };

Wicket.DateTime = { }

/**
 * Parses date from simple date pattern.
 *
 * Supports patterns built up from the following elements:
 * yy OR yyyy for year
 * M OR MM OR MMM OR MMMM for month
 * d OR dd for day
 * EEEE for weekday (optional)
 */
Wicket.DateTime.parseDate = function(cfg, value) {
	var numbers = value.match(/(\d+)/g);
	var pattern = cfg.datePattern;
	if (numbers == null) return Number.NaN;
	var day, month, year;
	var arrayPos = 0;
	for (var i = 0; i < pattern.length; i++) {
		var c = pattern.charAt(i);
		var len = 0;
		while ((pattern.charAt(i) == c) && (i < pattern.length)) {
			i++;
			len++;
		}
		if (c == 'y') {
			year = numbers[arrayPos++];
		} else if (c == 'M') {
			var nameArray;
			switch (len) {
			case 3:
				nameArray = cfg.calendarInit.MONTHS_SHORT;
				break;
			case 4:
				nameArray = cfg.calendarInit.MONTHS_LONG;
				break;
			default:
				nameArray = null;
			}
			if (nameArray != null) {
				for (var j = 0; j < nameArray.length; j++) {
					if (value.indexOf(nameArray[j]) >= 0) {
						month = j + 1;
						break;
					}
				}
			} else {
				month = numbers[arrayPos++];
			}
		} else if (c == 'd') {
			day = numbers[arrayPos++];
		}
		if (arrayPos > 2) break;
	}
	// TODO this is a bit crude. Make nicer some time.
	if (year < 100) {
		if (year < 70) {
			year = year * 1 + 2000;
		} else {
			year = year * 1 + 1900;
		}
	}
	var date = new Date();
	date.setHours(0);
	date.setMinutes(0);
	date.setSeconds(0);
	date.setMilliseconds(0);
	date.setFullYear(year, (month - 1), day);

	return date;
}

/**
 * Returns a string containing the value, with a leading zero if the value is < 10.
 */
Wicket.DateTime.padDateFragment = function(value) {
	return (value < 10 ? "0" : "") + value;
}

/**
 * Gets the height of the displayed area of the window, as YAHOO.util.Dom.getViewportHeight()
 * has issues with Firefox.
 * See http://tech.groups.yahoo.com/group/ydn-javascript/message/5850
 * Implementation taken from: http://www.quirksmode.org/viewport/compatibility.html#link2
 */
Wicket.DateTime.getViewportHeight = function() {
	if (window.innerHeight) // all browsers except IE
		viewPortHeight = window.innerHeight;
	else if (document.documentElement && document.documentElement.clientHeight) // IE 6 strict mode
		viewPortHeight = document.documentElement.height;
	else if (document.body) // other IEs
		viewPortHeight = document.body.clientHeight;
	return viewPortHeight;
}

/**
 * Position subject relative to target top-left by default.
 * If there is too little space on the right side/bottom,
 * the datepicker's position is corrected so that the right side/bottom
 * is aligned with the display area's right side/bottom.
 * @param subject the dom element to has to be positioned
 * @param target id of the dom element to position relative to
 */
Wicket.DateTime.positionRelativeTo = function(subject, target) {

	targetPos = YAHOO.util.Dom.getXY(target);
	targetHeight = YAHOO.util.Dom.get(target).offsetHeight;
	subjectHeight = YAHOO.util.Dom.get(subject).offsetHeight;
	subjectWidth = YAHOO.util.Dom.get(subject).offsetWidth;

	viewPortHeight = Wicket.DateTime.getViewportHeight();
	viewPortWidth = YAHOO.util.Dom.getViewportWidth();

	// also take scroll position into account
	scrollPos = [YAHOO.util.Dom.getDocumentScrollLeft(), YAHOO.util.Dom.getDocumentScrollTop()];

	// correct datepicker's position so that it isn't rendered off screen on the right side or bottom
	if (targetPos[0] + subjectWidth > scrollPos[0] + viewPortWidth) {
		// correct horizontal position
		YAHOO.util.Dom.setX(subject, Math.max(targetPos[0], viewPortWidth) - subjectWidth);
	} else {
		YAHOO.util.Dom.setX(subject, targetPos[0]);
	}
	if (targetPos[1] + targetHeight + 1 + subjectHeight > scrollPos[1] + viewPortHeight) {
		// correct vertical position
		YAHOO.util.Dom.setY(subject, Math.max(targetPos[1], viewPortHeight) - subjectHeight);
	} else {
		YAHOO.util.Dom.setY(subject, targetPos[1] + targetHeight + 1);
	}
}

/**
 * Return the result of interpolating the value (date) argument with the date pattern.
 * The date has to be an array, where year is in the first, month in the second
 * and date (day of month) in the third slot.
 */
Wicket.DateTime.substituteDate = function(cfg, date) {
	var day = date[2];
	var month = date[1];
	var year = date[0];

	var date = new Date();
	date.setHours(0);
	date.setMinutes(0);
	date.setSeconds(0);
	date.setMilliseconds(0);
	date.setFullYear(year, (month - 1), day);

	var dayName = null;
	var datePattern = cfg.datePattern;

	// optionally do some padding to match the pattern
	if(datePattern.match(/dd+/)) day = Wicket.DateTime.padDateFragment(day);
	if (datePattern.match(/MMMM/)) month = cfg.calendarInit.MONTHS_LONG[month - 1];
	else if (datePattern.match(/MMM/)) month = cfg.calendarInit.MONTHS_SHORT[month - 1];
	else if(datePattern.match(/MM+/)) month = Wicket.DateTime.padDateFragment(month);
	if(datePattern.match(/yyy+/)) {
		year = Wicket.DateTime.padDateFragment(year);
	} else if(datePattern.match(/yy+/)) {
		year = Wicket.DateTime.padDateFragment(year % 100);
	}
	if (datePattern.match(/EEEE/)) {
		// figure out which weekday it is...
		var engDayName = date.toString().match(/(\S*)/)[0];
		var engDayNames = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
		for (var i = 0; i < engDayNames.length; i++) {
			if (engDayName === engDayNames[i]) {
				dayName = cfg.calendarInit.WEEKDAYS_LONG[i];
				break;
			}
		}
	}
	// replace pattern with real values
	var result = datePattern.replace(/d+/, day).replace(/y+/, year).replace(/M+/, month);

	if (dayName != null) {
		result = result.replace(/EEEE/, dayName);
	}

	return result;
}

/**
 * Display the YUI calendar widget. If the date is not null (should be a string) then it is parsed
 * using the provided date pattern, and set as the current date on the widget.
 */
Wicket.DateTime.showCalendar = function(widget, date, cfg) {
	if (date) {
		date = Wicket.DateTime.parseDate(cfg, date);
		if (!isNaN(date)) {
			widget.select(date);
			firstDate = widget.getSelectedDates()[0];
			if (firstDate) {
				widget.cfg.setProperty("pagedate", (firstDate.getMonth() + 1) + "/" + firstDate.getFullYear());
				widget.render();
			}
		}
	}
	widget.show();
}

// configures a datepicker using the cfg object
Wicket.DateTime.init = function(cfg) {
	cfg.dpJs = cfg.widgetId + "DpJs";
	cfg.dp = cfg.widgetId + "Dp";
	cfg.icon = cfg.widgetId +"Icon";
	YAHOO.namespace("wicket");

	if (cfg.calendarInit.pages && cfg.calendarInit.pages > 1) {
		YAHOO.wicket[cfg.dpJs] = new YAHOO.widget.CalendarGroup(cfg.dpJs,cfg.dp, cfg.calendarInit);
	} else {
		YAHOO.wicket[cfg.dpJs] = new YAHOO.widget.Calendar(cfg.dpJs,cfg.dp, cfg.calendarInit);
	}
	YAHOO.wicket[cfg.dpJs].isVisible = function() { return YAHOO.wicket[cfg.dpJs].oDomContainer.style.display == 'block'; }

	function showCalendar() {
		Wicket.DateTime.showCalendar(YAHOO.wicket[cfg.dpJs], YAHOO.util.Dom.get(cfg.componentId).value, cfg);
		if (cfg.alignWithIcon) Wicket.DateTime.positionRelativeTo(YAHOO.wicket[cfg.dpJs].oDomContainer, cfg.icon);
	}

	YAHOO.util.Event.addListener(cfg.icon, "click", showCalendar, YAHOO.wicket[cfg.dpJs], true);

	if (cfg.showOnFieldClick) {
		YAHOO.util.Event.addListener(cfg.widgetId, "click", showCalendar, YAHOO.wicket[cfg.dpJs], true);
	}

	function selectHandler(type, args, cal) {
		YAHOO.util.Dom.get(cfg.componentId).value = Wicket.DateTime.substituteDate(cfg, args[0][0]);
		if (cal.isVisible()) {
			if (cfg.hideOnSelect) cal.hide();
			if (cfg.fireChangeEvent) {
				var field = YAHOO.util.Dom.get(cfg.componentId);
				if (field.onchangeoriginal != null && typeof(field.onchangeoriginal) != 'undefined') field.onchangeoriginal();
				if (field.onchange != null && typeof(field.onchange) != 'undefined') field.onchange();
			}
		}
	}

	YAHOO.wicket[cfg.dpJs].selectEvent.subscribe(selectHandler,YAHOO.wicket[cfg.dpJs]);
	YAHOO.wicket[cfg.dpJs].render();
}

// init method variant that needs less character to invoke
Wicket.DateTime.init2 = function(widgetId, componentId, calendarInit, datePattern,
		alignWithIcon, fireChangeEvent, hideOnSelect, showOnFieldClick, i18n) {
	calendarInit.MONTHS_SHORT = i18n.MONTHS_SHORT;
	calendarInit.MONTHS_LONG = i18n.MONTHS_LONG;
	calendarInit.WEEKDAYS_MEDIUM = i18n.WEEKDAYS_MEDIUM;
	calendarInit.WEEKDAYS_LONG = i18n.WEEKDAYS_LONG;
	calendarInit.START_WEEKDAY = i18n.START_WEEKDAY;
	calendarInit.WEEKDAYS_1CHAR = i18n.WEEKDAYS_1CHAR;
	calendarInit.WEEKDAYS_SHORT = i18n.WEEKDAYS_SHORT;

	Wicket.DateTime.init({
		widgetId: widgetId,
		componentId: componentId,
		calendarInit: calendarInit,
		datePattern: datePattern,
		alignWithIcon: alignWithIcon,
		fireChangeEvent: fireChangeEvent,
		hideOnSelect: hideOnSelect,
		showOnFieldClick: showOnFieldClick
	});
}

YAHOO.register("wicket-date", Wicket.DateTime, {version: "1.5", build: "rc3"});
<|endoftext|>


<commit_before>/*jshint regexp:false */

module.exports = function(opts, cb) {
  'use strict';

  var format = require('util').format
    , fs = require('fs')
    , path = require('path')
    , request = require('request')
    , async = require('async')
    , mkdirp = require('mkdirp')
    , _after = require('lodash.after');

  var apiKey = opts.trelloApiKey
    , authToken = opts.trelloToken
    , boardId = opts.trelloBoardUrl
      .replace(/.*\/b\//, '')
      .replace(/\/.*$/, '')
    , pagesListName = opts.trelloBoardPagesList
    , blogListName = opts.trelloBoardBlogList;

  var tmpDir = '.stello/trello'
    , bkTmpDir = '.stello/trello-bk'; // Eventually, stash existing tmp dir so we can back out of changes if things go wrong

  var done = _after(2, cb || function() {});

  var getBoardLists = function(boardId) {
    return function(cb) {
      var uri = format('https://api.trello.com/1/boards/%s/lists?key=%s&token=%s', boardId, apiKey, authToken);
      request(uri, function(error, resp, body) {
        if(error) { return cb(error); }
        var lists;
        try {
          lists = JSON.parse(body);
        } catch(error) {
          return cb(error);
        }
        return cb(null, lists);
      });
    };
  };

  var createListFolders = function(lists, cb) {
    var _cb = _after(lists.length, function() {
      cb(null, lists);
    });

    lists.each(function(list) {
      var dir = path.join(tmpDir, list.id);
      mkdirp(dir, function(err) {
        if(err) { return cb(err); }
        _cb();
      });
    });
  };

  var getListCards = function(lists, cb) {
    var allCards = [];
    async.each(
      lists,
      function(list, cb) {
        var listId = list.id
          , uri = format('https://api.trello.com/1/lists/%s/cards?key=%s&token=%s', listId, apiKey, authToken);
        request(uri, function(error, resp, body) {
          if(error) { return cb(error); }
          var cards;
          try {
            cards = JSON.parse(body);
          } catch(error) {
            Array.prototype.push.apply(allCards, cards);
            return cb(error);
          }
          return cb(null, cards);
          }, function(err) {
            if(err) { return cb(err); }
            cb(null, lists);
          }
        );
      },
      function(err) {
        if(err) { return cb(err); }
        return(null, allCards);
      }
    );
  };

  var saveCards = function(cards, cb) {
    async.each(
      cards,
      function(card, cb) {
        // Create frontmatter from card json
        // Save to tmpdir under list directory
      },
      function(err) {
        if(err) { return cb(err); }
        cb(null, cards);
      }
    );
  };

  mkdirp(tmpDir, function(error) {
    if(error) { return cb(error); }

    async.waterfall([
      getBoardLists(boardId),
      createListFolders,
      getListCards,
      saveCards
    ], done);

  });
};

<commit_msg>fix: Create list directories<commit_after>/*jshint regexp:false */

module.exports = function(opts, cb) {
  'use strict';

  var format = require('util').format
    , fs = require('fs')
    , path = require('path')
    , request = require('request')
    , async = require('async')
    , mkdirp = require('mkdirp')
    , _after = require('lodash.after');

  var apiKey = opts.trelloApiKey
    , authToken = opts.trelloToken
    , boardId = opts.trelloBoardUrl
      .replace(/.*\/b\//, '')
      .replace(/\/.*$/, '');

  var outDir = 'data';

  var done = _after(2, cb || function() {});

  var listDirName = function(list) {
    return [
      list.name,
      list.id,
    ].join('_');
  };

  var getBoardLists = function(boardId) {
    return function(cb) {
      var uri = format('https://api.trello.com/1/boards/%s/lists?key=%s&token=%s', boardId, apiKey, authToken);
      request(uri, function(error, resp, body) {
        if(error) { return cb(error); }
        var lists;
        try {
          lists = JSON.parse(body);
        } catch(error) {
          return cb(error);
        }
        return cb(null, lists);
      });
    };
  };

  var createListFolders = function(lists, cb) {
    var _cb = _after(lists.length + 1, function() {
      cb(null, lists);
    });

    lists.forEach(function(list) {
      var dir = path.join(outDir, listDirName(list));
      mkdirp(dir, function(err) {
        if(err) { return cb(err); }
        _cb();
      });
    });

    fs.writeFile(path.join(outDir, 'lists.json'), JSON.stringify(lists, null, '  '), function(err) {
      if(err) { return cb(err); }
      _cb();
    });
  };

  var getListCards = function(lists, cb) {
    var allCards = [];
    async.each(
      lists,
      function(list, cb) {
        var listId = list.id
          , uri = format('https://api.trello.com/1/lists/%s/cards?key=%s&token=%s', listId, apiKey, authToken);
        request(uri, function(error, resp, body) {
          if(error) { return cb(error); }
          var cards;
          try {
            cards = JSON.parse(body);
          } catch(error) {
            Array.prototype.push.apply(allCards, cards);
            return cb(error);
          }
          return cb(null, cards);
          }, function(err) {
            if(err) { return cb(err); }
            cb(null, lists);
          }
        );
      },
      function(err) {
        if(err) { return cb(err); }
        return(null, allCards);
      }
    );
  };

  var saveCards = function(cards, cb) {
    async.each(
      cards,
      function(card, cb) {
        // Create frontmatter from card json
        // Save to tmpdir under list directory
      },
      function(err) {
        if(err) { return cb(err); }
        cb(null, cards);
      }
    );
  };

  /**
   * @todo save existing data dir in a safe spot if it exists, restore it of
   * something goes wrong
   */
  if(fs.existsSync(outDir)) {
    require('shelljs').rm('-rf', outDir);
  }

  mkdirp(outDir, function(error) {
    if(error) { return cb(error); }

    async.waterfall([
      getBoardLists(boardId),
      createListFolders,
      getListCards,
      saveCards
    ], done);

  });
};

<|endoftext|>


<commit_before><commit_msg>shortened twitter text<commit_after><|endoftext|>


<commit_before>'use strict';

var path = require('path');
var fs = require('fs');
var mkdirp = require('mkdirp');
var _ = require('lodash');
var through = require('through2');
var extend = require('extend-shallow');
var htmlParser = require('l10n-tools/html-parser');
var smartling = require('l10n-tools/smartling');
var objParser = require('l10n-tools/object-extractor');
var fs = require('fs');
var q = require('q');
var glob = require('glob');
var crypto = require('crypto');
var smartlingConfig;

try{
  smartlingConfig = fs.readFileSync(path.join(process.cwd(), 'configs/smartlingConfig.json'), {encoding: 'utf8'});
} catch(err){
  console.error('Cannot read Smartling config: ', err);
}
if(smartlingConfig){
  smartlingConfig = JSON.parse(smartlingConfig);
}

var jsParser = require('l10n-tools/js-parser');
var hbsParser = require('l10n-tools/hbs-parser');
var smartling = require('l10n-tools/smartling');
var Q = require('q');
var fs = require('fs');

try{
  var smartlingConfig = fs.readFileSync('./configs/smartlingConfig.json', {encoding: 'utf-8'});
} catch(err){
  console.error('Cannot read Smartling config: ', err);
}
if(smartlingConfig){
  smartlingConfig = JSON.parse(smartlingConfig);
}

module.exports = function (assemble) {
  //var parseFilePath = require('../utils/plugin-parse-file-path')(assemble);
  //var extendFileData = require('../utils/plugin-extend-file-data')(assemble);
  var lang = assemble.get('lang') || {};
  var pageData = assemble.get('pageData');
  var environment = assemble.option('environment');
  var websiteRoot = assemble.get('data.websiteRoot');
  var websiteGuts = assemble.get('data.websiteGuts');
  var locales = assemble.get('data.locales');
  var localeCodes = Object.keys(locales).map(function(subfolder) {
    return locales[subfolder];
  });
  var createTranslationDict = require('../utils/create-dictionary')(assemble);
  var parseFilePath = require('../utils/parse-file-path')(assemble);
  var generateKey = require('../utils/generate-key');
  var env = assemble.get('env');
  var runTranslations =  env === 'test' || env === 'smartling-staging-deploy';
  var phrases = [];

  var checksumChanged = function checksumChanged(content, fname){
    if(env === 'test' && glob.sync('tmp/download/*.pot').length) {
      return true;
    } else {
      var hash = crypto.createHash('md5');
      hash.setEncoding('hex');
      hash.write(content);
      hash.end();
      var newSum = hash.read();

      var latestSum = null;
      if(fs.existsSync(fname))
      {
        // now compare with latest uploaded catalogue checksum
        hash = crypto.createHash('md5');
        hash.setEncoding('hex');
        hash.write(fs.readFileSync(fname, {encoding: 'UTF8'}));
        hash.end();
        latestSum = hash.read();
      }
      return newSum === latestSum;
    }
  };

  return through.obj(function (file, enc, cb) {
    var ppcRe = new RegExp(path.join(websiteRoot, 'om'));
    var filePathData = parseFilePath(file.path);
    var locale = filePathData.locale;
    var dataKey = filePathData.dataKey;
    //create lang dictionary from TR prefixes
    var parsedTranslations = createTranslationDict(file, locale);
    var pagePhrases;

    //parse file contents for tr helper phrases
    if(!file.HTML_page_content && file.contents) {
      pagePhrases = hbsParser.extract(file.contents.toString());
      if(pagePhrases.length) {
        phrases.push({
          fname: dataKey,
          phrases: pagePhrases
        });
      }
    }

    if(Object.keys(parsedTranslations).length > 0) {
      lang[locale] = lang[locale] || {};
      lang[locale][dataKey] = extend({}, lang[locale][dataKey], parsedTranslations);
    }

    this.push(file);
    cb();
  }, function (cb) {
    var globalData = assemble.get('data');
    var globalYml = Object.keys(globalData).reduce(function(o, key) {
      if(/global\_/.test(key)) {
        o[key] = globalData[key];
      }
      return o;
    }, {});
    lang.global = createTranslationDict(globalYml, 'global');
    assemble.set('lang', lang);

    if(runTranslations) {
      var DICT_FNAME = 'marketing_website_yaml.pot';
      var JS_DICT_FNAME = 'marketing_website_js.pot';

      _.forEach(lang, function(pages){
        _.forEach(pages, function(fileInfo, fname){
          var list = objParser.extract(fileInfo);
          phrases.push({fname: fname, phrases: list});
        });
      });

      var extractFrom = function extractFrom(srcs, parser){
        return glob.sync(srcs).map(function (fname) {
          var phrases = parser.extract(fs.readFileSync(fname));
          return {
            fname: generateKey(fname),
            phrases: phrases
          };
        });
      };

      var createDirs = [
        'tmp/upload',
        'tmp/download',
        'dist/assets/js'
      ];

      createDirs.forEach(function(dir) {
        if(!fs.existsSync(dir)) {
          mkdirp.sync(dir);
        }
      });

      var clientHbsPhrases = extractFrom(path.join(websiteGuts, 'templates/client/**/*.hbs'), hbsParser);
      phrases = phrases.concat(clientHbsPhrases);
      var content = smartling.generatePO(phrases);
      var yamlDefer = Q.defer();
      if(checksumChanged(content, 'tmp/upload/' + DICT_FNAME)){
        console.log('Master catalog didn\'t update since last upload - using cached dictionaries.');
        var translations = {};
        localeCodes.map(function(code){
          var body = fs.readFileSync('tmp/download/' + code + '-' + DICT_FNAME, {encoding: 'UTF8'});
          translations[code] = smartling.parsePOWithContext(body);
        });
        assemble.set('dicts', translations);
        yamlDefer.resolve();
      } else {
        fs.writeFile('tmp/upload/' + DICT_FNAME, content);
        smartling.send(content, smartlingConfig.API_KEY, smartlingConfig.PROJECT_ID, DICT_FNAME).then(function(){
          var translations = {};
          var defers = localeCodes.map(function(code){
            return smartling.fetch(smartlingConfig.URL, code, DICT_FNAME, smartlingConfig.API_KEY, smartlingConfig.PROJECT_ID).then(function(body){
              fs.writeFile('tmp/download/' + code + '-' + DICT_FNAME, body);
              translations[code] = smartling.parsePOWithContext(body);
            });
          });

          // when all translations are fetched - call callback
          q.all(defers).then(function(){
            assemble.set('dicts', translations);
            yamlDefer.resolve();
          });
        });
      }

      var jsPhrases = extractFrom('website-guts/assets/js/**/*.js', jsParser);
      content = smartling.generatePO(jsPhrases);
      var jsDefer = Q.defer();

      var deployJSDict = function deployJSDict(locale, body) {
        var dict = smartling.parsePO2dict(body);
        content = 'window.optlyDict = ' + JSON.stringify(dict);
        var outputFname = './dist/assets/js/dict.' + locale + '.js';
        fs.writeFileSync(outputFname, content);
      };

      if(checksumChanged(content, 'tmp/upload/' + JS_DICT_FNAME)){
        console.log('Master catalog didn\'t since last upload - using cached dictionaries for JS.');
        localeCodes.map(function(code){
          var body = fs.readFileSync('tmp/download/' + code + '-' + JS_DICT_FNAME, {encoding: 'UTF8'});
          deployJSDict(code, body);
        });
        jsDefer.resolve();
      } else {
        fs.writeFile('tmp/upload/' + JS_DICT_FNAME, content);
        smartling.send(content, smartlingConfig.API_KEY, smartlingConfig.PROJECT_ID, JS_DICT_FNAME).then(function(){
          var defers = localeCodes.map(function(code){
            return smartling.fetch(smartlingConfig.URL, code, JS_DICT_FNAME, smartlingConfig.API_KEY, smartlingConfig.PROJECT_ID).then(function(body){
              fs.writeFile('tmp/download/' + code + '-' + JS_DICT_FNAME, body);
              deployJSDict(code, body);
            });
          });

          // when all translations are fetched - call callback
          Q.all(defers).then(function(){
            jsDefer.resolve();
          });
        });
      }

      Q.all([yamlDefer.promise, jsDefer.promise]).then(function(){
        //lang has `global` object
        var translated = {};
        Object.keys(locales).forEach(function(localeKey) {
          var dictKey = locales[localeKey];

          translated[dictKey] = Object.keys(lang).reduce(function(o, key){
            //lang object global|layout|partial|modals|website
            var langO = lang[key];
            //get the dict key de_DE|fr_FR|es_ES|jp_JP
            _.forEach(langO, function(val, key){
              //console.log(dictKey)
              o[key] = objParser.translate(langO[key], translations[dictKey][key]);
            });

            return o;
          }, {});
        });

        _.forEach(translated.de_DE, function(val, key) {
          if(/modals/.test(key)) {
            console.log(val);
          }
        });

        cb();
      });
    } else {
      assemble.set('dicts', {});
      cb();
    }
  });

};
<commit_msg>start translating inside plugin<commit_after>'use strict';

var path = require('path');
var fs = require('fs');
var mkdirp = require('mkdirp');
var _ = require('lodash');
var through = require('through2');
var extend = require('extend-shallow');
var htmlParser = require('l10n-tools/html-parser');
var smartling = require('l10n-tools/smartling');
var objParser = require('l10n-tools/object-extractor');
var fs = require('fs');
var q = require('q');
var glob = require('glob');
var crypto = require('crypto');
var smartlingConfig;

try{
  smartlingConfig = fs.readFileSync(path.join(process.cwd(), 'configs/smartlingConfig.json'), {encoding: 'utf8'});
} catch(err){
  console.error('Cannot read Smartling config: ', err);
}
if(smartlingConfig){
  smartlingConfig = JSON.parse(smartlingConfig);
}

var jsParser = require('l10n-tools/js-parser');
var hbsParser = require('l10n-tools/hbs-parser');
var smartling = require('l10n-tools/smartling');
var Q = require('q');
var fs = require('fs');

try{
  var smartlingConfig = fs.readFileSync('./configs/smartlingConfig.json', {encoding: 'utf-8'});
} catch(err){
  console.error('Cannot read Smartling config: ', err);
}
if(smartlingConfig){
  smartlingConfig = JSON.parse(smartlingConfig);
}

module.exports = function (assemble) {
  //var parseFilePath = require('../utils/plugin-parse-file-path')(assemble);
  //var extendFileData = require('../utils/plugin-extend-file-data')(assemble);
  var lang = assemble.get('lang') || {};
  var pageData = assemble.get('pageData');
  var environment = assemble.option('environment');
  var websiteRoot = assemble.get('data.websiteRoot');
  var websiteGuts = assemble.get('data.websiteGuts');
  var locales = assemble.get('data.locales');
  var localeCodes = Object.keys(locales).map(function(subfolder) {
    return locales[subfolder];
  });
  var createTranslationDict = require('../utils/create-dictionary')(assemble);
  var parseFilePath = require('../utils/parse-file-path')(assemble);
  var generateKey = require('../utils/generate-key');
  var env = assemble.get('env');
  var runTranslations =  env === 'test' || env === 'smartling-staging-deploy';
  var phrases = [];

  var checksumChanged = function checksumChanged(content, fname){
    if(env === 'test' && glob.sync('tmp/download/*.pot').length) {
      return true;
    } else {
      var hash = crypto.createHash('md5');
      hash.setEncoding('hex');
      hash.write(content);
      hash.end();
      var newSum = hash.read();

      var latestSum = null;
      if(fs.existsSync(fname))
      {
        // now compare with latest uploaded catalogue checksum
        hash = crypto.createHash('md5');
        hash.setEncoding('hex');
        hash.write(fs.readFileSync(fname, {encoding: 'UTF8'}));
        hash.end();
        latestSum = hash.read();
      }
      return newSum === latestSum;
    }
  };

  return through.obj(function (file, enc, cb) {
    var ppcRe = new RegExp(path.join(websiteRoot, 'om'));
    var filePathData = parseFilePath(file.path);
    var locale = filePathData.locale;
    var dataKey = filePathData.dataKey;
    //create lang dictionary from TR prefixes
    var parsedTranslations = createTranslationDict(file, locale);
    var pagePhrases;

    //parse file contents for tr helper phrases
    if(!file.HTML_page_content && file.contents) {
      pagePhrases = hbsParser.extract(file.contents.toString());
      if(pagePhrases.length) {
        phrases.push({
          fname: dataKey,
          phrases: pagePhrases
        });
      }
    }

    if(Object.keys(parsedTranslations).length > 0) {
      lang[locale] = lang[locale] || {};
      lang[locale][dataKey] = extend({}, lang[locale][dataKey], parsedTranslations);
    }

    this.push(file);
    cb();
  }, function (cb) {
    var globalData = assemble.get('data');
    var globalYml = Object.keys(globalData).reduce(function(o, key) {
      if(/global\_/.test(key)) {
        o[key] = globalData[key];
      }
      return o;
    }, {});
    lang.global = createTranslationDict(globalYml, 'global');
    assemble.set('lang', lang);

    if(runTranslations) {
      var DICT_FNAME = 'marketing_website_yaml.pot';
      var JS_DICT_FNAME = 'marketing_website_js.pot';

      _.forEach(lang, function(pages){
        _.forEach(pages, function(fileInfo, fname){
          var list = objParser.extract(fileInfo);
          phrases.push({fname: fname, phrases: list});
        });
      });

      var extractFrom = function extractFrom(srcs, parser){
        return glob.sync(srcs).map(function (fname) {
          var phrases = parser.extract(fs.readFileSync(fname));
          return {
            fname: generateKey(fname),
            phrases: phrases
          };
        });
      };

      var createDirs = [
        'tmp/upload',
        'tmp/download',
        'dist/assets/js'
      ];

      createDirs.forEach(function(dir) {
        if(!fs.existsSync(dir)) {
          mkdirp.sync(dir);
        }
      });

      var clientHbsPhrases = extractFrom(path.join(websiteGuts, 'templates/client/**/*.hbs'), hbsParser);
      phrases = phrases.concat(clientHbsPhrases);
      var content = smartling.generatePO(phrases);
      var yamlDefer = Q.defer();
      if(checksumChanged(content, 'tmp/upload/' + DICT_FNAME)){
        console.log('Master catalog didn\'t update since last upload - using cached dictionaries.');
        var translations = {};
        localeCodes.map(function(code){
          var body = fs.readFileSync('tmp/download/' + code + '-' + DICT_FNAME, {encoding: 'UTF8'});
          translations[code] = smartling.parsePOWithContext(body);
        });
        assemble.set('dicts', translations);
        yamlDefer.resolve();
      } else {
        fs.writeFile('tmp/upload/' + DICT_FNAME, content);
        smartling.send(content, smartlingConfig.API_KEY, smartlingConfig.PROJECT_ID, DICT_FNAME).then(function(){
          var translations = {};
          var defers = localeCodes.map(function(code){
            return smartling.fetch(smartlingConfig.URL, code, DICT_FNAME, smartlingConfig.API_KEY, smartlingConfig.PROJECT_ID).then(function(body){
              fs.writeFile('tmp/download/' + code + '-' + DICT_FNAME, body);
              translations[code] = smartling.parsePOWithContext(body);
            });
          });

          // when all translations are fetched - call callback
          q.all(defers).then(function(){
            assemble.set('dicts', translations);
            yamlDefer.resolve();
          });
        });
      }

      var jsPhrases = extractFrom('website-guts/assets/js/**/*.js', jsParser);
      content = smartling.generatePO(jsPhrases);
      var jsDefer = Q.defer();

      var deployJSDict = function deployJSDict(locale, body) {
        var dict = smartling.parsePO2dict(body);
        content = 'window.optlyDict = ' + JSON.stringify(dict);
        var outputFname = './dist/assets/js/dict.' + locale + '.js';
        fs.writeFileSync(outputFname, content);
      };

      if(checksumChanged(content, 'tmp/upload/' + JS_DICT_FNAME)){
        console.log('Master catalog didn\'t since last upload - using cached dictionaries for JS.');
        localeCodes.map(function(code){
          var body = fs.readFileSync('tmp/download/' + code + '-' + JS_DICT_FNAME, {encoding: 'UTF8'});
          deployJSDict(code, body);
        });
        jsDefer.resolve();
      } else {
        fs.writeFile('tmp/upload/' + JS_DICT_FNAME, content);
        smartling.send(content, smartlingConfig.API_KEY, smartlingConfig.PROJECT_ID, JS_DICT_FNAME).then(function(){
          var defers = localeCodes.map(function(code){
            return smartling.fetch(smartlingConfig.URL, code, JS_DICT_FNAME, smartlingConfig.API_KEY, smartlingConfig.PROJECT_ID).then(function(body){
              fs.writeFile('tmp/download/' + code + '-' + JS_DICT_FNAME, body);
              deployJSDict(code, body);
            });
          });

          // when all translations are fetched - call callback
          Q.all(defers).then(function(){
            jsDefer.resolve();
          });
        });
      }

      Q.all([yamlDefer.promise, jsDefer.promise]).then(function(){
        //lang has `global` object
        var translated = {};
        Object.keys(locales).forEach(function(localeKey) {
          var dictKey = locales[localeKey];

          translated[dictKey] = Object.keys(lang).reduce(function(o, key){
            //lang object global|layout|partial|modals|website
            var langO = lang[key];
            //get the dict key de_DE|fr_FR|es_ES|jp_JP
            _.forEach(langO, function(val, key){
              //console.log(dictKey)
              o[key] = objParser.translate(langO[key], translations[dictKey][key]);
            });

            return o;
          }, {});
        });

        _.forEach(translated.de_DE, function(val, key) {
          if(/\/website\//.test(key)) {
            console.log(val);
          }
        });

        cb();
      });
    } else {
      assemble.set('dicts', {});
      cb();
    }
  });

};
<|endoftext|>


<commit_before>
/**
 * type alias Key      = String
 * type alias Request  = Dict String a
 * type alias Current  = Dict String a
 * type alias Data     = Dict String a
 *
 * type alias MessageDictionary = Dict String Maybe String
 *
 * type alias Context =
 *   { request        = Request
 *   , current        = Current
 *   , data           = Data
 *   }
 *
 * type alias ValidatedContext =
 *   { request    = Request
 *   , current    = Current
 *   , data       = Data
 *   , validation = MessageDictionary
 *   }
 *
 * type alias AwesomizedContext =
 *   { request    = Request
 *   , current    = Current
 *   , data       = Data
 *   , validation = MessageDictionary
 *   }
 *
 * type alias Validator  = (a, Context -> Either String Nothing)
 * type alias Sanitizer  = (a, Context -> a)
 * type alias Normalizer = (a, Context -> a)
 *
 * type alias FieldConfig =
 *   { read       = (Request -> Response)
 *   , sanitizer  = Array Sanitizer
 *   , validation = Array Validator
 *   , normalizer = Array Normalizer
 *   }
 *
 * type alias Field =
 *   { key    = String
 *   , action = FieldAction
 *   }
 *
 * type alias FieldAction =
 *   [ (Request -> Response)
 *   , (Response -> SanitizedResponse)
 *   , (Response -> ValidatedResponse)
 *   , (Response -> NormalizedResponse)
 *   ]
 *
 * type alias FieldDictionary = Array FieldConfig
 */

const _        = require('ramda');

const CONFIG_KEY_READ      = 'read';
const CONFIG_KEY_SANITIZE  = 'sanitize';
const CONFIG_KEY_VALIDATE  = 'validate';
const CONFIG_KEY_NORMALIZE = 'normalize'

const Validator = require('./validator');

// createValidator : FieldConfig, Key -> (Context -> ValidatedContext)
const createValidator = (config, key) => {
  const validations = _.prop(CONFIG_KEY_VALIDATE, config);

  return validations ?
    Validator.createMapper(key, validations) :
    Validator.nilValidator(key);
};

const Field = (config, key) => {
  return {
    key: key
  , action: [
      _.defaultTo(_.prop(key), _.prop(CONFIG_KEY_READ, config))
    , _.defaultTo(_.identity, _.prop(CONFIG_KEY_SANITIZE, config))
    ,  createValidator(config, key)
    , _.defaultTo(_.identity, _.prop(CONFIG_KEY_NORMALIZE, config))
    ]
  }
};

// configToActionList : FieldDictionary -> List FieldAction
const configToActionList = _.compose(
  _.values
, _.mapObjIndexed(Field)
);

module.exports = { configToActionList };
<commit_msg>Create the structure for actions<commit_after>
/**
 * type alias Key      = String
 * type alias Request  = Dict String a
 * type alias Current  = Dict String a
 * type alias Data     = Dict String a
 *
 * type alias MessageDictionary = Dict String Maybe String
 *
 * type alias Context =
 *   { request        = Request
 *   , current        = Current
 *   , data           = Data
 *   }
 *
 * type alias ValidatedContext =
 *   { request    = Request
 *   , current    = Current
 *   , data       = Data
 *   , validation = MessageDictionary
 *   }
 *
 * type alias AwesomizedContext =
 *   { request    = Request
 *   , current    = Current
 *   , data       = Data
 *   , validation = MessageDictionary
 *   }
 *
 * type alias Validator  = (a, Context -> Either String Nothing)
 * type alias Sanitizer  = (a, Context -> a)
 * type alias Normalizer = (a, Context -> a)
 *
 * type alias FieldConfig =
 *   { read       = (Request -> Response)
 *   , sanitizer  = Array Sanitizer
 *   , validation = Array Validator
 *   , normalizer = Array Normalizer
 *   }
 *
 * type alias Field =
 *   { key    = String
 *   , action = FieldAction
 *   }
 *
 * type alias FieldAction =
 *   [ (Request -> Response)
 *   , (Response -> SanitizedResponse)
 *   , (Response -> ValidatedResponse)
 *   , (Response -> NormalizedResponse)
 *   ]
 *
 * type alias FieldDictionary = Array FieldConfig
 */

const _        = require('ramda');

const CONFIG_KEY_READ      = 'read';
const CONFIG_KEY_SANITIZE  = 'sanitize';
const CONFIG_KEY_VALIDATE  = 'validate';
const CONFIG_KEY_NORMALIZE = 'normalize'

const Validator = require('./validator');

const nilSanitizer  = _.identity;
const nilNormalizer = _.identity;

// createReader : FieldConfig, Key -> Context -> Context
const createReader = (config, key) => {
  return _.defaultTo(_.prop(key), _.prop(CONFIG_KEY_READ, config));
}

// createSanitizer : FieldConfig, Key -> (Context -> SanitizedContext)
const createSanitizer = (config) => {
  const sanitizers = _.prop(CONFIG_KEY_SANITIZE, config);

  return sanitizers ? nilSanitizer : nilSanitizer;
};

// createNormalizer : FieldConfig, Key -> (Context -> NormalizedContext)
const createNormalizer = (config) => {
  const normalizers = _.prop(CONFIG_KEY_NORMALIZE, config);

  return normalizers ? nilNormalizer : nilNormalizer;
};

// createValidator : FieldConfig, Key -> (Context -> ValidatedContext)
const createValidator = (config, key) => {
  const validations = _.prop(CONFIG_KEY_VALIDATE, config);

  return validations ?
    Validator.createMapper(key, validations) :
    Validator.nilValidator(key);
};

const Field = (config, key) => {
  return {
    key: key
  , action: [
      createReader(config, key)
    , createSanitizer(config, key)
    , createValidator(config, key)
    , createNormalizer(config, key)
    ]
  }
};

// configToActionList : FieldDictionary -> List FieldAction
const configToActionList = _.compose(
  _.values
, _.mapObjIndexed(Field)
);

module.exports = { configToActionList };
<|endoftext|>


<commit_before><commit_msg>vanilla javascript doesn't have default values for function arguments<commit_after><|endoftext|>


<commit_before>'use strict';

describe('OIDE Ace Editor', function() {
  browser.get('/');

  it('should load an ace instance with the page', function() {
    expect(element(by.css('#aceplace > textarea')).isPresent()).toBe(true);
  });

  it('contents should be empty', function() {
    element.all(by.css('.ace_line')).then(function(arr) {
      expect(arr.length).toEqual(1);
    });
  });
});

describe('OIDE Editor Tabs', function() {
  browser.get('/');

  it('should initialize with one document', function() {
    element.all(by.css('#editor-nav-tabs li.ng-isolate-scope')).then(function(arr) {
      expect(arr.length).toBe(2);
      expect(arr[1].getAttribute('tooltip')).toBe('Create New Document');
    });
  });

  it('initial document should be -/Untitled0', function() {
    var el = element(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading > span'));
    expect(el.getText()).toBe('UNTITLED0');
    expect(el.getAttribute('tooltip')).toBe('-/untitled0');
  });

  it('should have a functioning dropdown menu', function() {
    element.all(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading > span')).then(function(arr) {
      arr[1].click();
      element.all(by.css('#editor-nav-tabs span.fa-caret-down > ul.dropdown-menu > li')).then(function(arr) {
        expect(arr.length).toBe(11);
      });
    });
  });

  it('should not be marked as unsaved', function() {
    element.all(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading > span')).then(function(arr) {
      expect(arr[2].getAttribute('class')).toContain('fa-times');
    });
  });

  describe('Editor Functions', function() {
    beforeEach(function() {
      browser.get('/');
      var editor = element(by.css('textarea.ace_text-input'));
      browser.actions().doubleClick($('#aceplace')).perform();
      editor.sendKeys('test.');
      browser.sleep(3000);
    });

    // it('should be marked unsaved after edit', function() {
    //   element.all(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading > span')).then(function(arr) {
    //     // Force a digest cycle.
    //     browser.actions().mouseMove(element(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading'))).perform();
    //     expect(arr[2].getAttribute('class')).toContain('fa-circle-o');
    //   });
    // });

    it('should have the entered text', function() {
      element(by.css('div.ace_content')).getText().then(function(text) {
        expect(text.slice(0,-1)).toBe('test.');
      });
    });
  });
});
<commit_msg>add spec for save, close, create tab, switch between apps<commit_after>'use strict';

describe('OIDE Ace Editor', function() {
  browser.get('/');

  it('should load an ace instance with the page', function() {
    expect(element(by.css('#aceplace > textarea')).isPresent()).toBe(true);
  });

  it('contents should be empty', function() {
    element.all(by.css('.ace_line')).then(function(arr) {
      expect(arr.length).toEqual(1);
    });
  });
});

describe('OIDE Editor Tabs', function() {
  browser.get('/');

  it('should initialize with one document', function() {
    element.all(by.css('#editor-nav-tabs li.ng-isolate-scope')).then(function(arr) {
      expect(arr.length).toBe(2);
      expect(arr[1].getAttribute('tooltip')).toBe('Create New Document');
    });
  });

  it('initial document should be -/Untitled0', function() {
    var el = element(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading > span'));
    expect(el.getText()).toBe('UNTITLED0');
    expect(el.getAttribute('tooltip')).toBe('-/untitled0');
  });

  it('should have a functioning dropdown menu', function() {
    element.all(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading > span')).then(function(arr) {
      arr[1].click();
      element.all(by.css('#editor-nav-tabs span.fa-caret-down > ul.dropdown-menu > li')).then(function(arr) {
        expect(arr.length).toBe(11);
      });
    });
  });

  it('should not be marked as unsaved', function() {
    element.all(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading > span')).then(function(arr) {
      expect(arr[2].getAttribute('class')).toContain('fa-times');
    });
  });

  describe('Editor Functions', function() {
    beforeEach(function() {
      browser.get('/');
      var editor = element(by.css('textarea.ace_text-input'));
      browser.actions().doubleClick($('#aceplace')).perform();
      editor.sendKeys('test.');
      browser.sleep(3000);
    });

    // it('should be marked unsaved after edit', function() {
    //   element.all(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading > span')).then(function(arr) {
    //     // Force a digest cycle.
    //     browser.actions().mouseMove(element(by.css('#editor-nav-tabs li.ng-isolate-scope tab-heading'))).perform();
    //     expect(arr[2].getAttribute('class')).toContain('fa-circle-o');
    //   });
    // });

    it('should have the entered text', function() {
      element(by.css('div.ace_content')).getText().then(function(text) {
        expect(text.slice(0,-1)).toBe('test.');
      });
    });

    it("should be able to save a file", function(){
      // Click on Save As
      var driver = browser.driver;
      driver.findElements(by.css('span > .dropdown-menu > li > a')).then(function(elements){
        driver.executeScript("arguments[0].click()", elements[8]).then(function(){
          // Expect a modal to show up with title as Save File As
          expect($('.modal-title').getText()).toBe('Save File As');
        });
      });
    });

    it("should prompt to save unsaved file", function(){
      // Click on Close File
      var driver = browser.driver;
      driver.findElements(by.css('span > .dropdown-menu > li > a')).then(function(elements){
        driver.executeScript("arguments[0].click()", elements[9]).then(function(){
          // Expect a modal to show up with title as File Not Saved
          expect($('.modal-title').getText()).toBe('File Not Saved');
        });
      });
    });

    it("should go to terminal and on returning, it should have the same text", function(){
      // Save Text
      var initialText = '';
      $('div.ace_content').getText().then(function(text){
        initialText = text;
        // Go to terminal
        var driver = browser.driver;
        driver.findElements(by.css('ul.navbar-nav > li > a')).then(function(elements){
          driver.executeScript("arguments[0].click()", elements[1]).then(function(){
            // Go to editor
            driver.executeScript("arguments[0].click()", elements[0]).then(function(){
              //Get Text
              $('div.ace_content').getText().then(function(text){
                // Expect the text to be the same
                expect(text).toBe(initialText);
              });
            });
          });
        });
      });
    });

    it("should be able to create a new tab and be able to switch between them", function(){
      // Create a new tab
      var initialTabCount = 0;
      var finalTabCount = 0;
      var driver = browser.driver;
      driver.findElements(by.css('ul.nav-tabs > li > a')).then(function(elements){
        initialTabCount = elements.length - 1;
        driver.executeScript("arguments[0].click()", elements[1]).then(function(){
          // Get new tab count
          $$('ul.nav-tabs > li > a').then(function(elements){
            // Final Tab Count should be element length - 1 to leave out the 'plus' element
            finalTabCount = elements.length - 1;
            // expect finalTabCount to be 1 more than initial tab count
            expect(finalTabCount).toBe(initialTabCount + 1);
          });
        });
      });
    });

  });
});
<|endoftext|>


<commit_before>/**
 * Created by King Lee on 2014/10/17.
 */
var utils = module.exports;

//  current is the x week
utils.getWeek = function (date) {
    var onejan = new Date(date.getFullYear(), 0, 1);
    //	delay_day ,such as 3,that means wednesday is the first day of new week
    var delay_day = 3;
    return Math.ceil((((date - onejan) / 86400000) + onejan.getDay() + 1 + delay_day) / 7);
};

utils.genNormalDistributionValue1 = function( e, v )
{
    var u1	= Math.random();
    var u2	= Math.random();
    var variable_e = 2.718281828;
    var variable_pi = 3.141592654;
    var r	= e + v * Math.sqrt( -2.0 * ( Math.log( u1 ) / Math.log( variable_e ) ) ) * Math.cos( 2.0 * variable_pi * u2 );
    return r;
};

utils.genNormalDistributionValue2 = function(min_value, max_value, e, v )
{
    var random_value = 0.0;
    do
    {
        random_value = utils.genNormalDistributionValue1( e, v );
    } while ( random_value < min_value || random_value > max_value );

    return random_value;
};

utils.genRandom = function(  e,  min_value,  offset )
{
    return utils.genNormalDistributionValue2( min_value, e + offset, e, ( e - min_value ) / 2.5 );
};<commit_msg>update util.js<commit_after>/**
 * Created by King Lee on 2014/10/17.
 */
var utils = module.exports;

//  current is the x week
utils.getWeek = function (date) {
    var onejan = new Date(date.getFullYear(), 0, 1);
    //	delay_day ,such as 3,that means wednesday is the first day of new week
    var delay_day = 3;
    return Math.ceil((((date - onejan) / 86400000) + onejan.getDay() + 1 + delay_day) / 7);
};

utils.genNormalDistributionValue1 = function( e, v )
{
    var variable_e = 2.718281828;
    var variable_pi = 3.141592654;
    if(0){
        var u1	= Math.random();
        var u2	= Math.random();
        return e + v * Math.sqrt( -2.0 * ( Math.log( u1 ) / Math.log( variable_e ) ) ) * Math.cos( 2.0 * variable_pi * u2 );
    }else{
        var rand1 = Math.random();
        rand1 = -2.0 * Math.log( rand1 ) / Math.log( variable_e );
        var rand2 = Math.random() * 2 * variable_pi;
        return e + v * Math.sqrt( rand1 ) * Math.cos( rand2 );
    }
};

utils.genNormalDistributionValue2 = function(min_value, max_value, e, v )
{
    var random_value = 0.0;
    do
    {
        random_value = utils.genNormalDistributionValue1( e, v );
    } while ( random_value < min_value || random_value > max_value );

    return random_value;
};

utils.genRandom = function(  e,  min_value,  offset )
{
    return utils.genNormalDistributionValue2( min_value, e + offset, e, ( e - min_value ) / 2.5 );
};<|endoftext|>


<commit_before>var fs=require("fs");

/*
  check if exists
  check if is directory
    if is directory
      check if default filename exists
        if exists respond
        else next
    else is file
      respond
*/

/* Static route */
module.exports=function(statpath,def){
  def=def||"/index.html";
  return function(req,res,next){
    var path=statpath+decodeURIComponent(req.url);
//    console.log(JSON.stringify({      url:req.url      ,path:path    }));
    var bin;

    var response=function(path){
      var ext;
      path.replace(/\.[^.]*$/,function(e){
        ext=e;
      });
      var type;
      console.log("extension: "+ext)
      switch (ext){
        case '.ttf':
          type='application/x-font-ttf';
          bin=true;
          break;
        case '.woff':
          type='application/x-font-woff';
          bin=true;
          break;
        case '.svg':
          type='image/svg+xml';
          break;
        case '.css':
          type='text/css';
          break;
        case '.json':
          type='application/json';
          break;
        case '.js':
          type='text/javascript';
          break;
        case '.ico':
          bin=true;
          type='image/x-icon';
          break;
        case '.gif':
          bin=true;
          type='image/gif';
          break;
        case '.png':
          bin=true;
          type='image/png'
          break;
        case '.jpeg':
        case '.jpg':
          bin=true;
          type='image/jpeg';
          break;
        case '.pdf':
          bin=true;
          type='application/pdf';
          break;
        case '.htm':
        case '.html':
          type='text/html';
          break;
        default:
          type='text/plain;charset=utf8';
          break;
      }
      fs.readFile(path,(!bin)?"utf8":null,function(err,data){
 //       console.log(path);
        if(err)
          console.log(err)||
          next(req,res);
        else{
          res.statusCode=200;
          res.setHeader("Content-Type",type);
          res.end(data);
        }
      });
    };

    // check if there is something there
    fs.exists(path,function(e){
      if(e){ // there is! what is it?
        fs.stat(path,function(err,stats){
          if(err) // problem?
            console.log(err)||next(req,res);

          // is it a directory?
          if(stats.isDirectory()){
            fs.exists(path+def,function(e){
              if(e){ // it exists!
                response(path+def);
              }else{ // it does not
                next(req,res);
              }
            });
          }else if (stats.isFile()){
            response(path);
          }else{
            next(req,res)
          }
        });
      }else
        next(req,res);
    });
  };
};
<commit_msg>add exe mime-type<commit_after>var fs=require("fs");

/*
  check if exists
  check if is directory
    if is directory
      check if default filename exists
        if exists respond
        else next
    else is file
      respond
*/

/* Static route */
module.exports=function(statpath,def){
  def=def||"/index.html";
  return function(req,res,next){
    var path=statpath+decodeURIComponent(req.url);
//    console.log(JSON.stringify({      url:req.url      ,path:path    }));
    var bin;

    var response=function(path){
      var ext;
      path.replace(/\.[^.]*$/,function(e){
        ext=e;
      });
      var type;
      console.log("extension: "+ext)
      switch (ext){
        case '.ttf':
          type='application/x-font-ttf';
          bin=true;
          break;
        case '.woff':
          type='application/x-font-woff';
          bin=true;
          break;
        case '.svg':
          type='image/svg+xml';
          break;
        case '.css':
          type='text/css';
          break;
        case '.json':
          type='application/json';
          break;
        case '.js':
          type='text/javascript';
          break;
        case '.ico':
          bin=true;
          type='image/x-icon';
          break;
        case '.gif':
          bin=true;
          type='image/gif';
          break;
        case '.png':
          bin=true;
          type='image/png'
          break;
        case '.jpeg':
        case '.jpg':
          bin=true;
          type='image/jpeg';
          break;
        case '.pdf':
          bin=true;
          type='application/pdf';
          break;
        case '.exe':
          bin=true;
          type='application/x-msdownload';
          break;
        case '.htm':
        case '.html':
          type='text/html';
          break;
        default:
          type='text/plain;charset=utf8';
          break;
      }
      fs.readFile(path,(!bin)?"utf8":null,function(err,data){
 //       console.log(path);
        if(err)
          console.log(err)||
          next(req,res);
        else{
          res.statusCode=200;
          res.setHeader("Content-Type",type);
          res.end(data);
        }
      });
    };

    // check if there is something there
    fs.exists(path,function(e){
      if(e){ // there is! what is it?
        fs.stat(path,function(err,stats){
          if(err) // problem?
            console.log(err)||next(req,res);

          // is it a directory?
          if(stats.isDirectory()){
            fs.exists(path+def,function(e){
              if(e){ // it exists!
                response(path+def);
              }else{ // it does not
                next(req,res);
              }
            });
          }else if (stats.isFile()){
            response(path);
          }else{
            next(req,res)
          }
        });
      }else
        next(req,res);
    });
  };
};
<|endoftext|>


<commit_before><commit_msg>short geolocation format over the wire<commit_after><|endoftext|>