<commit_before>// Categorical distribution

var limit = require('./lib/limit');
var distSum = require('./lib/distSum');
var assertDist = require('./lib/assertDist');

// Constructor

var Cat = function (d, amount) {
  // Parameters:
  //   d (optional)
  //     a distribution
  //   amount (optional)
  //     mass of the distribution

  this.w = {};
  this.sum = 0;

  if (typeof d === 'object') {
    this.learnDist(d, amount);
  }
};

// Class methods

Cat.createFromDiscrete = function (disc) {
  // Parameters:
  //   disc
  //     discrete distribution
  return new Cat(disc.w, disc.sum);
};

// Public methods

Cat.prototype.addMass = function (dist) {
  // Directly add to distribution weights

  var k;
  for (k in dist) {
    if (dist.hasOwnProperty(k)) {
      if (this.w.hasOwnProperty(k)) {
        this.w[k] += dist[k];
      } else {
        this.w[k] = dist[k];
      }
      this.sum += dist[k];
    }
  }
};

Cat.prototype.divergenceFrom = function (prior) {
  // Kullback-Leibler divergence D_kl(P||Q) in bits, where
  // P is this distribution and
  // Q is the given prior.
  //
  // Returns the information gained when switching from prior to this cat.

  var div = 0;

  prior.forEach(function (ev, pr) {
    var pi = this.prob(ev);
    div += pi * Math.log(pi / pr);
  }, this);

  // From nats to bits
  return div * Math.LOG2E;
};

Cat.prototype.entropy = function () {
  // Entropy in nats.
  var k, p;
  var sum = 0;
  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      p = this.w[k] / this.sum;
      sum += p * Math.log(p);
    }
  }
  return -sum;
};

Cat.prototype.events = function () {
  // Return a list of events with non-zero probability
  return Object.keys(this.w);
};

Cat.prototype.eventsWithMassAbove = function (minMass) {
  var self = this;
  return self.events().filter(function (ev) {
    return self.w[ev] > minMass;
  });
};

Cat.prototype.forEach = function (iteratee, ctx) {
  // Parameters:
  //   iteratee
  //     function (ev, probability)
  //   ctx (optional, default to undefined)
  //     iteratee's this value
  var k, p;
  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      p = this.w[k] / this.sum;
      iteratee.call(ctx, k, p);
    }
  }
};

Cat.prototype.getMassDist = function () {
  // Get distribution
  var d = {};

  var k;
  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      d[k] = this.w[k];
    }
  }

  return d;
};

Cat.prototype.getProbDist = function () {
  // Get distribution
  var d = {};

  var k;
  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      d[k] = this.w[k] / this.sum;
    }
  }

  return d;
};

Cat.prototype.has = function (ev) {
  return this.w.hasOwnProperty(ev);
};

Cat.prototype.learn = function (ev, amount) {
  // Parameters:
  //   ev
  //     string or distribution

  if (typeof ev === 'object') {
    this.learnDist(ev, amount);
    return;
  }

  if (typeof amount !== 'number') {
    amount = 1;
  }

  if (this.w.hasOwnProperty(ev)) {
    this.w[ev] += amount;
  } else {
    this.w[ev] = amount;
  }

  this.sum += amount;
};

Cat.prototype.learnDist = function (evDist, amount) {
  // Learn a distribution of events so that the total mass
  // raises by 'amount'

  assertDist(evDist);

  if (typeof amount !== 'number') {
    amount = 1;
  }

  var k, p;
  var sum = distSum(evDist);
  var psum = 0;  // psum stays 0 if evDist is empty.

  for (k in evDist) {
    if (evDist.hasOwnProperty(k)) {
      p = evDist[k] / sum;
      psum += p;

      if (this.w.hasOwnProperty(k)) {
        this.w[k] += p * amount;
      } else {
        this.w[k] = p * amount;
      }
    }
  }

  this.sum += psum * amount;
};

Cat.prototype.mass = function () {
  return this.sum;
};

Cat.prototype.mode = function () {
  // Return the category with the highest probability.

  var maxW = 0;
  var maxKey = null;
  var k;

  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      if (this.w[k] > maxW) {
        maxKey = k;
        maxW = this.w[k];
      }
    }
  }

  return maxKey;
};

Cat.prototype.prob = function (ev) {
  var raw;

  if (!this.w.hasOwnProperty(ev)) {
    return 0;
  }

  if (this.sum === 0) {
    raw = 0;
  } else {
    raw = this.w[ev] / this.sum;
  }

  // Ensure that rounding errors do not lead to non-probability values
  return limit(raw, 0.0, 1.0);
};

Cat.prototype.sample = function () {

  var r = Math.random();
  var sum = 0;

  var ev, p;
  for (ev in this.w) {
    if (this.w.hasOwnProperty(ev)) {
      p = this.w[ev] / this.sum;
      sum += p;
      if (r < sum) {
        return ev;
      }
    }
  }

  return null;
};

Cat.prototype.substractMass = function (dist) {
  // Directly substract from distribution weights

  var k;
  for (k in dist) {
    if (dist.hasOwnProperty(k)) {
      if (this.w.hasOwnProperty(k)) {
        if (this.w[k] - dist[k] < 0) {
          this.sum -= this.w[k];
          delete this.w[k];
        } else {
          this.w[k] -= dist[k];
          this.sum -= dist[k];
        }
      }
    }
  }
};

Cat.prototype.unlearn = function (ev, amount) {

  if (typeof amount !== 'number') {
    amount = 1;
  }

  if (this.w.hasOwnProperty(ev)) {
    if (this.w[ev] - amount > 0) {
      this.w[ev] -= amount;
      this.sum -= amount;
    } else {
      this.sum -= this.w[ev];
      delete this.w[ev];
    }
  }
};

Cat.prototype.weight = function (ev) {
  if (this.w.hasOwnProperty(ev)) {
    return this.w[ev];
  }
  return 0;
};

Cat.prototype.weightSum = function () {
  return this.sum;
};

module.exports = Cat;
<commit_msg>Categorical#forEach calls iteratee with mass<commit_after>// Categorical distribution

var limit = require('./lib/limit');
var distSum = require('./lib/distSum');
var assertDist = require('./lib/assertDist');

// Constructor

var Cat = function (d, amount) {
  // Parameters:
  //   d (optional)
  //     a distribution
  //   amount (optional)
  //     mass of the distribution

  this.w = {};
  this.sum = 0;

  if (typeof d === 'object') {
    this.learnDist(d, amount);
  }
};

// Class methods

Cat.createFromDiscrete = function (disc) {
  // Parameters:
  //   disc
  //     discrete distribution
  return new Cat(disc.w, disc.sum);
};

// Public methods

Cat.prototype.addMass = function (dist) {
  // Directly add to distribution weights

  var k;
  for (k in dist) {
    if (dist.hasOwnProperty(k)) {
      if (this.w.hasOwnProperty(k)) {
        this.w[k] += dist[k];
      } else {
        this.w[k] = dist[k];
      }
      this.sum += dist[k];
    }
  }
};

Cat.prototype.divergenceFrom = function (prior) {
  // Kullback-Leibler divergence D_kl(P||Q) in bits, where
  // P is this distribution and
  // Q is the given prior.
  //
  // Returns the information gained when switching from prior to this cat.

  var div = 0;

  prior.forEach(function (ev, pr) {
    var pi = this.prob(ev);
    div += pi * Math.log(pi / pr);
  }, this);

  // From nats to bits
  return div * Math.LOG2E;
};

Cat.prototype.entropy = function () {
  // Entropy in nats.
  var k, p;
  var sum = 0;
  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      p = this.w[k] / this.sum;
      sum += p * Math.log(p);
    }
  }
  return -sum;
};

Cat.prototype.events = function () {
  // Return a list of events with non-zero probability
  return Object.keys(this.w);
};

Cat.prototype.eventsWithMassAbove = function (minMass) {
  var self = this;
  return self.events().filter(function (ev) {
    return self.w[ev] > minMass;
  });
};

Cat.prototype.forEach = function (iteratee, ctx) {
  // Parameters:
  //   iteratee
  //     function (ev, probability, mass)
  //   ctx (optional, default to undefined)
  //     iteratee's this value
  var k, p;
  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      p = this.w[k] / this.sum;
      iteratee.call(ctx, k, p, this.w[k]);
    }
  }
};

Cat.prototype.getMassDist = function () {
  // Get distribution
  var d = {};

  var k;
  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      d[k] = this.w[k];
    }
  }

  return d;
};

Cat.prototype.getProbDist = function () {
  // Get distribution
  var d = {};

  var k;
  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      d[k] = this.w[k] / this.sum;
    }
  }

  return d;
};

Cat.prototype.has = function (ev) {
  return this.w.hasOwnProperty(ev);
};

Cat.prototype.learn = function (ev, amount) {
  // Parameters:
  //   ev
  //     string or distribution

  if (typeof ev === 'object') {
    this.learnDist(ev, amount);
    return;
  }

  if (typeof amount !== 'number') {
    amount = 1;
  }

  if (this.w.hasOwnProperty(ev)) {
    this.w[ev] += amount;
  } else {
    this.w[ev] = amount;
  }

  this.sum += amount;
};

Cat.prototype.learnDist = function (evDist, amount) {
  // Learn a distribution of events so that the total mass
  // raises by 'amount'

  assertDist(evDist);

  if (typeof amount !== 'number') {
    amount = 1;
  }

  var k, p;
  var sum = distSum(evDist);
  var psum = 0;  // psum stays 0 if evDist is empty.

  for (k in evDist) {
    if (evDist.hasOwnProperty(k)) {
      p = evDist[k] / sum;
      psum += p;

      if (this.w.hasOwnProperty(k)) {
        this.w[k] += p * amount;
      } else {
        this.w[k] = p * amount;
      }
    }
  }

  this.sum += psum * amount;
};

Cat.prototype.mass = function () {
  return this.sum;
};

Cat.prototype.mode = function () {
  // Return the category with the highest probability.

  var maxW = 0;
  var maxKey = null;
  var k;

  for (k in this.w) {
    if (this.w.hasOwnProperty(k)) {
      if (this.w[k] > maxW) {
        maxKey = k;
        maxW = this.w[k];
      }
    }
  }

  return maxKey;
};

Cat.prototype.prob = function (ev) {
  var raw;

  if (!this.w.hasOwnProperty(ev)) {
    return 0;
  }

  if (this.sum === 0) {
    raw = 0;
  } else {
    raw = this.w[ev] / this.sum;
  }

  // Ensure that rounding errors do not lead to non-probability values
  return limit(raw, 0.0, 1.0);
};

Cat.prototype.sample = function () {

  var r = Math.random();
  var sum = 0;

  var ev, p;
  for (ev in this.w) {
    if (this.w.hasOwnProperty(ev)) {
      p = this.w[ev] / this.sum;
      sum += p;
      if (r < sum) {
        return ev;
      }
    }
  }

  return null;
};

Cat.prototype.substractMass = function (dist) {
  // Directly substract from distribution weights

  var k;
  for (k in dist) {
    if (dist.hasOwnProperty(k)) {
      if (this.w.hasOwnProperty(k)) {
        if (this.w[k] - dist[k] < 0) {
          this.sum -= this.w[k];
          delete this.w[k];
        } else {
          this.w[k] -= dist[k];
          this.sum -= dist[k];
        }
      }
    }
  }
};

Cat.prototype.unlearn = function (ev, amount) {

  if (typeof amount !== 'number') {
    amount = 1;
  }

  if (this.w.hasOwnProperty(ev)) {
    if (this.w[ev] - amount > 0) {
      this.w[ev] -= amount;
      this.sum -= amount;
    } else {
      this.sum -= this.w[ev];
      delete this.w[ev];
    }
  }
};

Cat.prototype.weight = function (ev) {
  if (this.w.hasOwnProperty(ev)) {
    return this.w[ev];
  }
  return 0;
};

Cat.prototype.weightSum = function () {
  return this.sum;
};

module.exports = Cat;
<|endoftext|>


<commit_before>var SplitApp = React.createClass({displayName: "SplitApp",
  renderBoxes(num) {
    var boxes = [];
    for (var i = 0; i < num; i++) {
      boxes.push(React.createElement(Box, {key: i}));
    }
    return boxes;
  },
  render() {
    return (
      React.createElement("div", {className: "app"},
        React.createElement("div", {className: "demo"},
          this.renderBoxes(12),
          React.createElement("div", {className: "footer"},
            React.createElement("a", {href: "https://github.com/chrisbolin/glitch"}, "???")
          )
        )
      )
    );
  },
});

var Box = React.createClass({displayName: "Box",
  propTypes: {
    split: React.PropTypes.bool,
    dim: React.PropTypes.number,
  },
  getDefaultProps() {
    return {
      split: false,
      dim: 128,
    };
  },
  getInitialState() {
    return {
      split: false,
    };
  },
  split(e) {
    e.preventDefault();
    this.setState({split: true});
  },
  unsplit(e) {
    e.preventDefault();
    this.setState({split: false});
  },
  render() {
    // http://www.paulirish.com/2009/random-hex-color-code-snippets/
    var color = Math.floor(Math.random() * 16777215).toString(16);
    var style = {
      width: this.props.dim,
      height: this.props.dim,
      backgroundColor: color,
    };
    return (
      this.state.split ? (
        React.createElement("div", {className: "container", onContextMenu: this.unsplit},
          React.createElement(Box, {dim: this.props.dim / 2}),
          React.createElement(Box, {dim: this.props.dim / 2}),
          React.createElement("br", null),
          React.createElement(Box, {dim: this.props.dim / 2}),
          React.createElement(Box, {dim: this.props.dim / 2})
        )
      ) : (
        React.createElement("div", {className: "container box", style: style, onMouseEnter: this.split}
        )
      )
    );
  },
});

React.render(React.createElement(SplitApp, null),
  document.body
);
<commit_msg>build with babel<commit_after>'use strict';

var SplitApp = React.createClass({
  displayName: 'SplitApp',

  renderBoxes: function renderBoxes(num) {
    var boxes = [];
    for (var i = 0; i < num; i++) {
      boxes.push(React.createElement(Box, { key: i }));
    }
    return boxes;
  },
  render: function render() {
    return React.createElement(
      'div',
      { className: 'app' },
      React.createElement(
        'div',
        { className: 'demo' },
        this.renderBoxes(12),
        React.createElement(
          'div',
          { className: 'footer' },
          React.createElement(
            'a',
            { href: 'https://github.com/chrisbolin/glitch' },
            '???'
          )
        )
      )
    );
  }
});

var Box = React.createClass({
  displayName: 'Box',

  propTypes: {
    split: React.PropTypes.bool,
    dim: React.PropTypes.number
  },
  getDefaultProps: function getDefaultProps() {
    return {
      split: false,
      dim: 128
    };
  },
  getInitialState: function getInitialState() {
    return {
      split: false
    };
  },
  split: function split(e) {
    e.preventDefault();
    this.setState({ split: true });
  },
  unsplit: function unsplit(e) {
    e.preventDefault();
    this.setState({ split: false });
  },
  render: function render() {
    // http://www.paulirish.com/2009/random-hex-color-code-snippets/
    var color = Math.floor(Math.random() * 16777215).toString(16);
    var style = {
      width: this.props.dim,
      height: this.props.dim,
      backgroundColor: color
    };
    return this.state.split ? React.createElement(
      'div',
      { className: 'container', onContextMenu: this.unsplit },
      React.createElement(Box, { dim: this.props.dim / 2 }),
      React.createElement(Box, { dim: this.props.dim / 2 }),
      React.createElement('br', null),
      React.createElement(Box, { dim: this.props.dim / 2 }),
      React.createElement(Box, { dim: this.props.dim / 2 })
    ) : React.createElement('div', { className: 'container box', style: style, onMouseEnter: this.split });
  }
});

React.render(React.createElement(SplitApp, null), document.body);<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')
const express = require('express')
const logger = require('morgan')
const cors = require('cors')
const compression = require('compression')
const errorhandler = require('errorhandler')
const objectAssign = require('object-assign')
const bodyParser = require('./body-parser')

module.exports = function(opts) {
  const userDir = path.join(process.cwd(), 'public')
  const defaultDir = path.join(__dirname, 'public')
  const staticDir = fs.existsSync(userDir) ? userDir : defaultDir

  opts = objectAssign({ logger: true, static: staticDir }, opts)

  const arr = []

  // Compress all requests
  if (!opts.noGzip) {
    arr.push(compression())
  }

  // Logger
  if (opts.logger) {
    arr.push(
      logger('dev', {
        skip: req =>
          process.env.NODE_ENV === 'test' || req.path === '/favicon.ico'
      })
    )
  }

  // Enable CORS for all the requests, including static files
  if (!opts.noCors) {
    arr.push(cors({ origin: true, credentials: true }))
  }

  if (process.env.NODE_ENV === 'development') {
    // only use in development
    arr.push(errorhandler())
  }

  // Serve static files
  arr.push(express.static(opts.static))

  // No cache for IE
  // https://support.microsoft.com/en-us/kb/234067
  arr.push((req, res, next) => {
    res.header('Cache-Control', 'no-cache')
    res.header('Pragma', 'no-cache')
    res.header('Expires', '-1')
    next()
  })

  // Read-only
  if (opts.readOnly) {
    arr.push((req, res, next) => {
      if (req.method === 'GET') {
        next() // Continue
      } else {
        res.sendStatus(403) // Forbidden
      }
    })
  }

  // Add middlewares
  if (opts.bodyParser) {
    arr.push(bodyParser)
  }

  return arr
}
<commit_msg>moving logger after express.static to prevent unnecessary logging of static files with express (#587)<commit_after>const fs = require('fs')
const path = require('path')
const express = require('express')
const logger = require('morgan')
const cors = require('cors')
const compression = require('compression')
const errorhandler = require('errorhandler')
const objectAssign = require('object-assign')
const bodyParser = require('./body-parser')

module.exports = function(opts) {
  const userDir = path.join(process.cwd(), 'public')
  const defaultDir = path.join(__dirname, 'public')
  const staticDir = fs.existsSync(userDir) ? userDir : defaultDir

  opts = objectAssign({ logger: true, static: staticDir }, opts)

  const arr = []

  // Compress all requests
  if (!opts.noGzip) {
    arr.push(compression())
  }

  // Enable CORS for all the requests, including static files
  if (!opts.noCors) {
    arr.push(cors({ origin: true, credentials: true }))
  }

  if (process.env.NODE_ENV === 'development') {
    // only use in development
    arr.push(errorhandler())
  }

  // Serve static files
  arr.push(express.static(opts.static))

  // Logger
  if (opts.logger) {
    arr.push(
      logger('dev', {
        skip: req =>
          process.env.NODE_ENV === 'test' || req.path === '/favicon.ico'
      })
    )
  }

  // No cache for IE
  // https://support.microsoft.com/en-us/kb/234067
  arr.push((req, res, next) => {
    res.header('Cache-Control', 'no-cache')
    res.header('Pragma', 'no-cache')
    res.header('Expires', '-1')
    next()
  })

  // Read-only
  if (opts.readOnly) {
    arr.push((req, res, next) => {
      if (req.method === 'GET') {
        next() // Continue
      } else {
        res.sendStatus(403) // Forbidden
      }
    })
  }

  // Add middlewares
  if (opts.bodyParser) {
    arr.push(bodyParser)
  }

  return arr
}
<|endoftext|>


<commit_before>console.log( "=== simpread storage load ===" )

import "babel-polyfill";
import * as st   from 'site';
import {browser} from 'browser';

/**
 * Read and Write Chrome storage
 *
 * @class
 */

const name = "simpread",
    remote = "http://ojec5ddd5.bkt.clouddn.com/website_list.json",
    local  = browser.extension.getURL( "website_list.json" ),
    mode   = {
        focus     : "focus",
        read      : "read",
        option    : "option",
    },
    site   = {
        name      : "",   // only read mode
        title     : "",   // only read mode
        desc      : "",   // only read mode
        exclude   : [],
        include   : "",
    },
    focus  = {
        version   : "2016-12-29",
        bgcolor   : "rgba( 235, 235, 235, 0.9 )",
        opacity   : 90,
        shortcuts : "A S",
        sites     : [],    // e.g. [ "<url>", site ]
    },
    read   = {
        version   : "2017-03-16",
        shortcuts : "A A",
        theme     : "github",
        fontfamily: "default",
        fontsize  : "",  // default 62.5%
        layout    : "",  // default 20%
        sites     : []   // e.g. [ "<url>", site ]
    },
    option = {
        version   : "2017-03-04",
        update    : "",
    };

let current  = {},
    curori   = {},
    origin   = {},
    sync     = {},
    simpread = {
        option,
        focus,
        read,
        sites  : [],
    },
    rdstcode = -1;

class Storage {

    /**
     * Get simpread.focus data structure
     *
     * @return {object} simpread["focus"]
     */
    get focus() {
        return simpread[ mode.focus ];
    }

    /**
     * Get simpread.read data structure
     *
     * @return {object} simpread["read"]
     */
    get read() {
        return simpread[ mode.read ];
    }

    /**
     * Get current data structure
     *
     * @return {object} current
     */
    get current() {
        return current;
    }

    /**
     * Get read site code
     *
     * @return {int} @see setCode
     */
    get rdstcode() {
        return rdstcode;
    }

    /**
     * Restore simpread[key]
     *
     * @param {string} @see mode
     */
    Restore( key ) {
        simpread[key] = clone( origin[key] );
        this.Setcur( key );
    }

    /**
     * Set current object, current object structure include:
     *
     * focus mode: { url, mode, site, shortcuts, bgcolor, opacity }
     * read  mode: { url, mode, site, shortcuts, theme, fontsize, fontfamily, layout }
     *
     * @param {string} @see mode
     */
    Setcur( key ) {
        const [ url, sites ] = [ st.GetURI(), new Map( simpread[key].sites )];
        current      = swap( simpread[key], {} );
        current.url  = url;
        current.mode = key;
        let arr = st.Getsite( new Map( simpread[key].sites ), url );
        arr  ? setCode( key, 0 ) : setCode( key, 1 );
        !arr && ( arr = st.Getsite( new Map( simpread.sites ), url ));
        if ( arr ) {
            current.site = arr[0];
            current.url  = arr[1];
        } else {
            sites.set( url, clone( site ));
            current.site = sites.get( url );
            setCode( key, -1 );
        }
        curori      = { ...current };
        curori.site = { ...current.site };
        console.log( "current site object is ", current )
    }

    /**
     * Save simpread to chrome storage
     *
     * @param {string} @see mode
     */
    Set( key ) {
        const { code } = compare();
        if ( code != 0 ) {
            ( code == 2 || code == 3 ) && simpread[key].sites.push([ current.url, current.site ]);
            swap( current, simpread[key] );
            save();
        }
        return code;
    }

    /**
     * Sync simpread data structure
     *
     * @param {function} callback
     */
    Sync( callback ) {
        sync = { ...simpread };
        delete sync.sites;
        browser.storage.sync.set( { [name] : sync }, () => {
            console.log( "chrome storage sync success!" )
            sync.option.update     = now();
            simpread.option.update = sync.option.update;
            callback();
        });
    }

    /**
     * Get simpread object from chrome storage
     *
     * @param {function} callback
     */
    Get ( callback ) {
        browser.storage.local.get( [name], function( result ) {
            if ( result && !$.isEmptyObject( result )) {
                simpread = result[name];
            }
            origin   = clone( simpread );
            callback();
            console.log( "chrome storage read success!", simpread, origin, result );
        });
    }

    /**
     * Set simpread object to chrome storage
     *
     * @param {function} callback
     */
    Write( callback ) {
        save( callback );
    }

    /**
     * Get local/remote JSON usage async
     *
     * @param {string} url, e.g. chrome-extension://xxxx/website_list.json or http://xxxx.xx/website_list.json
     */
    async GetNewsites( type ) {
        try {
            const url    = type === "remote" ? remote : local,
                response = await fetch( url + "?_=" + Math.round(+new Date()) ),
                sites    = await response.json(),
                len      = simpread.sites.length;
            if ( len == 0 ) {
                simpread.sites = formatSites( sites );
            }
            if ( len == 0 || addsites( formatSites( sites )) ) {
                save();
            }
        } catch ( error ) {
            console.error( error );
        }
    }

    /**
     * Verity current changed
     *
     * @param {string} @see mode
     */
    VerifyCur( type ) {
        return ( current.mode && current.mode != type ) ||
               ( current.url  && current.url != st.GetURI() ) ||
               $.isEmptyObject( current );
    }

}

/**
 * Swap source and target property
 *
 * @param {object} source origin
 * @param {object} target origin
 */
function swap( source, target ) {
    for ( const key of Object.keys( source ) ) {
        if ( ![ "site", "sites", "version", "url", "mode" ].includes( key ) ) {
            target[key] = source[key];
        }
    }
    return target;
}

/**
 * Deep clone object
 *
 * @param  {object} target object
 * @return {object} new target object
 */
function clone( target ) {
    return $.extend( true, {}, target );
}

/**
 * Format sites object from loacal or remote json file
 *
 * @param  {object} sites.[array]
 * @return {array} foramat e.g. [[ <url>, object ],[ <url>, object ]]
 */
function formatSites( result ) {
    const format = new Map();
    for ( let site of result.sites ) {
        const url = site.url;
        delete site.url;
        format.set( url, site );
    }
    return [ ...format ];
}

/**
 * Add new sites to old sites
 *
 * @param  {array} new sites from local or remote
 * @return {boolean} true: update; false:not update
 */
function addsites( sites ) {
    const update   = new Map( simpread.sites ),
          urls     = [ ...update.keys() ];
    let   isupdate = false;
    sites.map( ( site ) => {
        if ( !urls.includes( site[0] ) ) {
            simpread.sites.push([ site[0], site[1] ]);
            isupdate = true;
        } else if ( urls.includes( site[0] ) && site[1].override ) {
            update.set( site[0], site[1] );
            simpread.sites = [ ...update ];
            isupdate = true;
        }
    });
    return isupdate;
}

/**
 * Call chrome storage set
 */
function save( callback ) {
    browser.storage.local.set( { [name] : simpread }, function() {
        console.log( "chrome storage save success!", simpread );
        origin      = clone( simpread );
        curori      = { ...current };
        curori.site = { ...current.site };
        callback && callback();
    });
}

/**
 * Set read site code
 *
 * @param {string} mode type
 * @param {int}    -1: not found; 0: simpread.read.sites; 1: simpread.sites
 */
function setCode( type, value ) {
    if ( type == mode.read ) rdstcode = value;
}

/**
 * Compare current and curori( origin_current )
 *
 * return {object}
 *      code    {number} include 0: equal； 1: option changed; 2: site changed; 3: all changed
 *      changed {array}  changed key, e.g. [ "theme", "title", "exclude" ]
 */
function compare() {
    let key, code = 0, changed = [], site_changed = false;
    for ( key of Object.keys( curori ) ) {
        if ( typeof curori[key] == "string" && curori[key] != current[key] ) {
            changed.push( key );
            code = 1;
        }
    }
    for ( key of Object.keys( curori.site ) ) {
        if ( ( typeof curori.site[key] == "object" && curori.site[key].join( "" ) != current.site[key].join( "" ) ) || curori.site[key] != current.site[key] ) {
            changed.push( key );
            site_changed = true;
        }
    }
    site_changed && ( code = code + 2 );
    console.log( "current changed state is ", code, changed );
    return { code, changed };
}

/**
 * Get now time
 *
 * @return {string} return now, e.g. 2017-04-03-11-43-53
 */
function now() {
    const date   = new Date(),
          format = value => value = value < 10 ? "0" + value : value;
    return date.getFullYear() + "-" + format( date.getUTCMonth() + 1 ) + "-" + format( date.getUTCDate() ) + "-" + format( date.getHours() ) + "-" + format( date.getMinutes() ) + "-" + format( date.getSeconds() );
}

const storage = new Storage();

export {
    storage,
    mode  as STORAGE_MODE,
    clone as Clone
};<commit_msg>Modify now() logic.<commit_after>console.log( "=== simpread storage load ===" )

import "babel-polyfill";
import * as st   from 'site';
import {browser} from 'browser';

/**
 * Read and Write Chrome storage
 *
 * @class
 */

const name = "simpread",
    remote = "http://ojec5ddd5.bkt.clouddn.com/website_list.json",
    local  = browser.extension.getURL( "website_list.json" ),
    mode   = {
        focus     : "focus",
        read      : "read",
        option    : "option",
    },
    site   = {
        name      : "",   // only read mode
        title     : "",   // only read mode
        desc      : "",   // only read mode
        exclude   : [],
        include   : "",
    },
    focus  = {
        version   : "2016-12-29",
        bgcolor   : "rgba( 235, 235, 235, 0.9 )",
        opacity   : 90,
        shortcuts : "A S",
        sites     : [],    // e.g. [ "<url>", site ]
    },
    read   = {
        version   : "2017-03-16",
        shortcuts : "A A",
        theme     : "github",
        fontfamily: "default",
        fontsize  : "",  // default 62.5%
        layout    : "",  // default 20%
        sites     : []   // e.g. [ "<url>", site ]
    },
    option = {
        version   : "2017-03-04",
        update    : "",
    };

let current  = {},
    curori   = {},
    origin   = {},
    sync     = {},
    simpread = {
        option,
        focus,
        read,
        sites  : [],
    },
    rdstcode = -1;

class Storage {

    /**
     * Get simpread.focus data structure
     *
     * @return {object} simpread["focus"]
     */
    get focus() {
        return simpread[ mode.focus ];
    }

    /**
     * Get simpread.read data structure
     *
     * @return {object} simpread["read"]
     */
    get read() {
        return simpread[ mode.read ];
    }

    /**
     * Get current data structure
     *
     * @return {object} current
     */
    get current() {
        return current;
    }

    /**
     * Get read site code
     *
     * @return {int} @see setCode
     */
    get rdstcode() {
        return rdstcode;
    }

    /**
     * Restore simpread[key]
     *
     * @param {string} @see mode
     */
    Restore( key ) {
        simpread[key] = clone( origin[key] );
        this.Setcur( key );
    }

    /**
     * Set current object, current object structure include:
     *
     * focus mode: { url, mode, site, shortcuts, bgcolor, opacity }
     * read  mode: { url, mode, site, shortcuts, theme, fontsize, fontfamily, layout }
     *
     * @param {string} @see mode
     */
    Setcur( key ) {
        const [ url, sites ] = [ st.GetURI(), new Map( simpread[key].sites )];
        current      = swap( simpread[key], {} );
        current.url  = url;
        current.mode = key;
        let arr = st.Getsite( new Map( simpread[key].sites ), url );
        arr  ? setCode( key, 0 ) : setCode( key, 1 );
        !arr && ( arr = st.Getsite( new Map( simpread.sites ), url ));
        if ( arr ) {
            current.site = arr[0];
            current.url  = arr[1];
        } else {
            sites.set( url, clone( site ));
            current.site = sites.get( url );
            setCode( key, -1 );
        }
        curori      = { ...current };
        curori.site = { ...current.site };
        console.log( "current site object is ", current )
    }

    /**
     * Save simpread to chrome storage
     *
     * @param {string} @see mode
     */
    Set( key ) {
        const { code } = compare();
        if ( code != 0 ) {
            ( code == 2 || code == 3 ) && simpread[key].sites.push([ current.url, current.site ]);
            swap( current, simpread[key] );
            save();
        }
        return code;
    }

    /**
     * Sync simpread data structure
     *
     * @param {function} callback
     */
    Sync( callback ) {
        sync = { ...simpread };
        delete sync.sites;
        browser.storage.sync.set( { [name] : sync }, () => {
            console.log( "chrome storage sync success!" )
            sync.option.update     = now();
            simpread.option.update = sync.option.update;
            callback( sync.option.update );
        });
    }

    /**
     * Get simpread object from chrome storage
     *
     * @param {function} callback
     */
    Get ( callback ) {
        browser.storage.local.get( [name], function( result ) {
            if ( result && !$.isEmptyObject( result )) {
                simpread = result[name];
            }
            origin   = clone( simpread );
            callback();
            console.log( "chrome storage read success!", simpread, origin, result );
        });
    }

    /**
     * Set simpread object to chrome storage
     *
     * @param {function} callback
     */
    Write( callback ) {
        save( callback );
    }

    /**
     * Get local/remote JSON usage async
     *
     * @param {string} url, e.g. chrome-extension://xxxx/website_list.json or http://xxxx.xx/website_list.json
     */
    async GetNewsites( type ) {
        try {
            const url    = type === "remote" ? remote : local,
                response = await fetch( url + "?_=" + Math.round(+new Date()) ),
                sites    = await response.json(),
                len      = simpread.sites.length;
            if ( len == 0 ) {
                simpread.sites = formatSites( sites );
            }
            if ( len == 0 || addsites( formatSites( sites )) ) {
                save();
            }
        } catch ( error ) {
            console.error( error );
        }
    }

    /**
     * Verity current changed
     *
     * @param {string} @see mode
     */
    VerifyCur( type ) {
        return ( current.mode && current.mode != type ) ||
               ( current.url  && current.url != st.GetURI() ) ||
               $.isEmptyObject( current );
    }

}

/**
 * Swap source and target property
 *
 * @param {object} source origin
 * @param {object} target origin
 */
function swap( source, target ) {
    for ( const key of Object.keys( source ) ) {
        if ( ![ "site", "sites", "version", "url", "mode" ].includes( key ) ) {
            target[key] = source[key];
        }
    }
    return target;
}

/**
 * Deep clone object
 *
 * @param  {object} target object
 * @return {object} new target object
 */
function clone( target ) {
    return $.extend( true, {}, target );
}

/**
 * Format sites object from loacal or remote json file
 *
 * @param  {object} sites.[array]
 * @return {array} foramat e.g. [[ <url>, object ],[ <url>, object ]]
 */
function formatSites( result ) {
    const format = new Map();
    for ( let site of result.sites ) {
        const url = site.url;
        delete site.url;
        format.set( url, site );
    }
    return [ ...format ];
}

/**
 * Add new sites to old sites
 *
 * @param  {array} new sites from local or remote
 * @return {boolean} true: update; false:not update
 */
function addsites( sites ) {
    const update   = new Map( simpread.sites ),
          urls     = [ ...update.keys() ];
    let   isupdate = false;
    sites.map( ( site ) => {
        if ( !urls.includes( site[0] ) ) {
            simpread.sites.push([ site[0], site[1] ]);
            isupdate = true;
        } else if ( urls.includes( site[0] ) && site[1].override ) {
            update.set( site[0], site[1] );
            simpread.sites = [ ...update ];
            isupdate = true;
        }
    });
    return isupdate;
}

/**
 * Call chrome storage set
 */
function save( callback ) {
    browser.storage.local.set( { [name] : simpread }, function() {
        console.log( "chrome storage save success!", simpread );
        origin      = clone( simpread );
        curori      = { ...current };
        curori.site = { ...current.site };
        callback && callback();
    });
}

/**
 * Set read site code
 *
 * @param {string} mode type
 * @param {int}    -1: not found; 0: simpread.read.sites; 1: simpread.sites
 */
function setCode( type, value ) {
    if ( type == mode.read ) rdstcode = value;
}

/**
 * Compare current and curori( origin_current )
 *
 * return {object}
 *      code    {number} include 0: equal； 1: option changed; 2: site changed; 3: all changed
 *      changed {array}  changed key, e.g. [ "theme", "title", "exclude" ]
 */
function compare() {
    let key, code = 0, changed = [], site_changed = false;
    for ( key of Object.keys( curori ) ) {
        if ( typeof curori[key] == "string" && curori[key] != current[key] ) {
            changed.push( key );
            code = 1;
        }
    }
    for ( key of Object.keys( curori.site ) ) {
        if ( ( typeof curori.site[key] == "object" && curori.site[key].join( "" ) != current.site[key].join( "" ) ) || curori.site[key] != current.site[key] ) {
            changed.push( key );
            site_changed = true;
        }
    }
    site_changed && ( code = code + 2 );
    console.log( "current changed state is ", code, changed );
    return { code, changed };
}

/**
 * Get now time
 *
 * @return {string} return now, e.g. 2017年04月03日 11:43:53
 */
function now() {
    const date   = new Date(),
          format = value => value = value < 10 ? "0" + value : value;
    return date.getFullYear() + "年" + format( date.getUTCMonth() + 1 ) + "月" + format( date.getUTCDate() ) + "日 " + format( date.getHours() ) + ":" + format( date.getMinutes() ) + ":" + format( date.getSeconds() );
}

const storage = new Storage();

export {
    storage,
    mode  as STORAGE_MODE,
    clone as Clone
};<|endoftext|>


<commit_before>define([
    'jquery', 'underscore', '../service', '../utils'
], function ($, _, Service, utils) {
    "use strict";

    var Canvas = Service.extend({
        // selector on wich to append the main canvas.
        selector: 'body',

        useDeep: false,

        initialize: function (options) {
            utils.copyOption(['selector'], this, options);
        },

        // Listen to `do:view:attach` event and attach given view to selector.
        //
        // It is possible to override selector on a module basis
        // by providing a selector option.
        //
        // ``` javascript
        // var canvas = new SelectorCanvas({selector: "body"});
        //
        // // default behavior
        // var module = new Module();
        // module
        //   .use('canvas', canvas); // append view to "body"
        //
        // // override on module basis
        // var module = new Module({selector: ".l-content"});
        // module
        //   .use('canvas', canvas); // append view to ".l-content"
        // ```
        use: function (module, parent) {
            // copy selector option if any.
            utils.copyOption(['selector'], module, module.options);
            // Listen to view attach event.
            module.on('do:view:attach', this.attachView, this);
        },

        dispose: function (module, parent) {
            module.off('do:view:attach', this.attachView, this);
        },

        attachView: function (module, view) {
            if (this.currentView) {
                this.currentView.remove();
            }

            this.currentView = view;

            $(this.selector).append(view.$el);

            if (view._attachPlugin) {
                view._attachPlugin();
            } else if(view.attachPlugin()) {
                view.attachPlugin();
            }
        }

    });

    return Canvas;
});
<commit_msg>Add canvas selector override on module basis.<commit_after>define([
    'jquery', 'underscore', '../service', '../utils'
], function ($, _, Service, utils) {
    "use strict";

    var Canvas = Service.extend({
        // selector on wich to append the main canvas.
        selector: 'body',

        useDeep: false,

        initialize: function (options) {
            utils.copyOption(['selector'], this, options);
            this.currentView = {};
        },

        // Listen to `do:view:attach` event and attach given view to selector.
        //
        // It is possible to override selector on a module basis
        // by providing a selector option.
        //
        // ``` javascript
        // var canvas = new SelectorCanvas({selector: "body"});
        //
        // // default behavior
        // var module = new Module();
        // module
        //   .use('canvas', canvas); // append view to "body"
        //
        // // override on module basis
        // var module = new Module({selector: ".l-content"});
        // module
        //   .use('canvas', canvas); // append view to ".l-content"
        // ```
        use: function (module, parent) {
            // copy selector option if any.
            utils.copyOption(['selector'], module, module.options);
            // Listen to view attach event.
            module.on('do:view:attach', this.attachView, this);
        },

        dispose: function (module, parent) {
            module.off('do:view:attach', this.attachView, this);
        },

        attachView: function (module, view) {
            var selector = module.selector || this.selector;
            if (this.currentView[selector]) {
                this.currentView[selector].remove();
            }

            this.currentView[selector] = view;

            $(selector).append(view.$el);

            if (view._attachPlugin) {
                view._attachPlugin();
            } else if(view.attachPlugin()) {
                view.attachPlugin();
            }
        }

    });

    return Canvas;
});
<|endoftext|>


<commit_before>var utils = require('../utils');

/**
 * @doc method
 * @id DSCache.methods:put
 * @name put
 * @description
 * Insert a value into the cache under the given key.
 *
 * ## Signature:
 * ```js
 * DSCache#put(key, value)
 * ```
 *
 * ## Example:
 * ```js
 * var cache = DSCacheFactory('cache');
 *
 * cache.put('1', 'apple');
 * cache.put('2', 3);
 * cache.put('3', { stuff: 'more stuff' });
 *
 * cache.get('1'); // "apple"
 * cache.get('2'); // 3
 * cache.get('3'); // { stuff: 'more stuff' }
 * cache.get('4'); // undefined
 * ```
 *
 * ## Throws:
 * - `Error` - `key` must be a string.
 *
 * @param {string} key The key under which to store the given value.
 * @param {*} value The value to store.
 * @returns {*} The newly stored item.
 */
module.exports = function put(key, value) {
  var _this = this;
  if (this.$$disabled || value === null || value === undefined) {
    return;
  }
  if (value && value.then) {
    value.then(function (v) {
      if (angular.isObject(v) && 'status' in v && 'data' in v) {
        _this.put(key, [v.status, v.data, v.headers(), v.statusText]);
      } else {
        _this.put(key, v);
      }
    });
    return;
  }
  key = utils.stringifyNumber(key);

  if (!angular.isString(key)) {
    throw angular.$$minErr('ng')('areq', 'Expected key to be a string! Found: {0}.', typeof key);
  }

  var now = new Date().getTime(),
    item = {
      key: key,
      value: value,
      created: now,
      accessed: now
    };

  item.expires = item.created + this.$$maxAge;

  if (this.$$storage) {
    var keysJson = this.$$storage.getItem(this.$$prefix + '.keys'),
      keys = keysJson ? angular.fromJson(keysJson) : [],
      itemJson = this.$$storage.getItem(this.$$prefix + '.data.' + key);

    // Remove existing
    if (itemJson) {
      this.remove(key);
    }
    // Add to expires heap
    this.$$expiresHeap.push({
      key: key,
      expires: item.expires
    });
    // Add to lru heap
    this.$$lruHeap.push({
      key: key,
      accessed: item.accessed
    });

    // Set item
    try {
      this.$$storage.setItem(this.$$prefix + '.data.' + key, angular.toJson(item));
    } catch(e){

      var targetItemSize = angular.toJson(item).length;
      var releasedMemorySize = 0, keyToRemove, itemToRemove;

      while(releasedMemorySize < (targetItemSize * 2)){
        // we release 2 * memory more than the size of the target item to avoid generating too much exceptions
        if(this.$$storage){
          keyToRemove = angular.fromJson(this.$$storage.getItem(this.$$prefix + '.keys'))[0];
          itemToRemove = this.$$storage.getItem(this.$$prefix + '.data.' + keyToRemove);

          if(itemToRemove) {
            releasedMemorySize += itemToRemove.length;
            this.remove(keyToRemove);
          } else { // No more items to remove
            return;
          }
        }
      }

      this.$$storage.setItem(this.$$prefix + '.data.' + key, angular.toJson(item));
      }

    var exists = false;
    for (var i = 0; i < keys.length; i++) {
      if (keys[i] === key) {
        exists = true;
        break;
      }
    }
    if (!exists) {
      keys.push(key);
    }
    this.$$storage.setItem(this.$$prefix + '.keys', angular.toJson(keys));
  } else {
    // Remove existing
    if (this.$$data[key]) {
      this.remove(key);
    }
    // Add to expires heap
    this.$$expiresHeap.push(item);
    // Add to lru heap
    this.$$lruHeap.push(item);
    // Set item
    this.$$data[key] = item;
  }

  // Handle exceeded capacity
  if (this.$$lruHeap.size() > this.$$capacity) {
    this.remove(this.$$lruHeap.peek().key);
  }

  return value;
};
<commit_msg>Changed the flushing strategy + catch of chrome and FF exceeded quota specific events<commit_after>var utils = require('../utils');

/**
 * @doc method
 * @id DSCache.methods:put
 * @name put
 * @description
 * Insert a value into the cache under the given key.
 *
 * ## Signature:
 * ```js
 * DSCache#put(key, value)
 * ```
 *
 * ## Example:
 * ```js
 * var cache = DSCacheFactory('cache');
 *
 * cache.put('1', 'apple');
 * cache.put('2', 3);
 * cache.put('3', { stuff: 'more stuff' });
 *
 * cache.get('1'); // "apple"
 * cache.get('2'); // 3
 * cache.get('3'); // { stuff: 'more stuff' }
 * cache.get('4'); // undefined
 * ```
 *
 * ## Throws:
 * - `Error` - `key` must be a string.
 *
 * @param {string} key The key under which to store the given value.
 * @param {*} value The value to store.
 * @returns {*} The newly stored item.
 */
module.exports = function put(key, value) {
  var _this = this;
  if (this.$$disabled || value === null || value === undefined) {
    return;
  }
  if (value && value.then) {
    value.then(function (v) {
      if (angular.isObject(v) && 'status' in v && 'data' in v) {
        _this.put(key, [v.status, v.data, v.headers(), v.statusText]);
      } else {
        _this.put(key, v);
      }
    });
    return;
  }
  key = utils.stringifyNumber(key);

  if (!angular.isString(key)) {
    throw angular.$$minErr('ng')('areq', 'Expected key to be a string! Found: {0}.', typeof key);
  }

  var now = new Date().getTime(),
    item = {
      key: key,
      value: value,
      created: now,
      accessed: now
    };

  item.expires = item.created + this.$$maxAge;

  if (this.$$storage) {
    var keysJson = this.$$storage.getItem(this.$$prefix + '.keys'),
      keys = keysJson ? angular.fromJson(keysJson) : [],
      itemJson = this.$$storage.getItem(this.$$prefix + '.data.' + key);

    // Remove existing
    if (itemJson) {
      this.remove(key);
    }
    // Add to expires heap
    this.$$expiresHeap.push({
      key: key,
      expires: item.expires
    });
    // Add to lru heap
    this.$$lruHeap.push({
      key: key,
      accessed: item.accessed
    });

    // Set item
    try {
      this.$$storage.setItem(this.$$prefix + '.data.' + key, angular.toJson(item));
    } catch(e){
        if(e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED'){

          // release 30% of the used memory (could be a parameter) + size of the rejected item
          var requiredMemory = JSON.stringify(this.$$storage).length * 0.3 + JSON.stringify(item).length;
          var releasedMemorySize = 0, keyToRemove, itemToRemove;

          while(releasedMemorySize < requiredMemory){
            if(this.$$storage){
              keyToRemove = angular.fromJson(this.$$storage.getItem(this.$$prefix + '.keys'))[0];
              itemToRemove = this.$$storage.getItem(this.$$prefix + '.data.' + keyToRemove);

              if(itemToRemove) {
                releasedMemorySize += itemToRemove.length;
                this.remove(keyToRemove);
              } else { // No more items to remove
                break;
              }
            }
          }

          this.$$storage.setItem(this.$$prefix + '.data.' + key, angular.toJson(item));
        }
      }

    var exists = false;
    for (var i = 0; i < keys.length; i++) {
      if (keys[i] === key) {
        exists = true;
        break;
      }
    }
    if (!exists) {
      keys.push(key);
    }
    this.$$storage.setItem(this.$$prefix + '.keys', angular.toJson(keys));
  } else {
    // Remove existing
    if (this.$$data[key]) {
      this.remove(key);
    }
    // Add to expires heap
    this.$$expiresHeap.push(item);
    // Add to lru heap
    this.$$lruHeap.push(item);
    // Set item
    this.$$data[key] = item;
  }

  // Handle exceeded capacity
  if (this.$$lruHeap.size() > this.$$capacity) {
    this.remove(this.$$lruHeap.peek().key);
  }

  return value;
};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 airbug inc. http://airbug.com
 *
 * bugflow may be freely distributed under the MIT license.
 */

//-------------------------------------------------------------------------------
// Requires
//-------------------------------------------------------------------------------

var buildbug            = require('buildbug');

//-------------------------------------------------------------------------------
// Simplify References
//-------------------------------------------------------------------------------

var buildProject        = buildbug.buildProject;
var buildProperties     = buildbug.buildProperties;
var buildScript         = buildbug.buildScript;
var buildTarget         = buildbug.buildTarget;
var enableModule        = buildbug.enableModule;
var parallel            = buildbug.parallel;
var series              = buildbug.series;
var targetTask          = buildbug.targetTask;

//-------------------------------------------------------------------------------
// Enable Modules
//-------------------------------------------------------------------------------

var aws                 = enableModule("aws");
var bugpack             = enableModule('bugpack');
var bugunit             = enableModule('bugunit');
var core                = enableModule('core');
var lintbug             = enableModule("lintbug");
var nodejs              = enableModule('nodejs');
var uglifyjs            = enableModule("uglifyjs");

//-------------------------------------------------------------------------------
// Values
//-------------------------------------------------------------------------------

var name                = "bugflow";
var version             = "0.1.6";
var dependencies        = {
    bugpack: "0.1.14"
};

//-------------------------------------------------------------------------------
// BuildProperties
//-------------------------------------------------------------------------------

buildProperties({
    node: {
        packageJson: {
            name: name,
            version: version,
            description: "Declarative async flow control for object oriented JavaScript provided by the bugcore library",
            main: "./scripts/bugflow-node-module.js",
            dependencies: dependencies,
            author: "Brian Neisler <brian@airbug.com>",
            repository: {
                type: "git",
                url: "https://github.com/airbug/bugflow.git"
            },
            bugs: {
                url: "https://github.com/airbug/bugflow/issues"
            },
            licenses: [
                {
                    type : "MIT",
                    url : "https://raw.githubusercontent.com/airbug/bugflow/master/LICENSE"
                }
            ]
        },
        sourcePaths: [
            "../bugcore/libraries/bugcore/js/src",
            "./projects/bugflow/js/src"
        ],
        scriptPaths: [
            "./projects/bugflow-node/js/scripts"
        ],
        readmePath: "./README.md",
        unitTest: {
            packageJson: {
                name: name + "-test",
                version: version,
                main: "./scripts/bugflow-node-module.js",
                dependencies: dependencies,
                scripts: {
                    test: "./scripts/bugunit-run.js"
                }
            },
            sourcePaths: [
                "../buganno/projects/buganno/js/src",
                "../bugfs/projects/bugfs/js/src",
                "../bugmeta/projects/bugmeta/js/src",
                "../bugunit/projects/bugdouble/js/src",
                "../bugunit/projects/bugunit/js/src",
                "../bugyarn/libraries/bugyarn/js/src"
            ],
            scriptPaths: [
                "../buganno/projects/buganno/js/scripts",
                "../bugunit/projects/bugunit/js/scripts"
            ],
            testPaths: [
                "../bugcore/libraries/bugcore/js/test",
                "./projects/bugflow/js/test"
            ]
        }
    },
    web: {
        buildPath: buildProject.getProperty("buildPath") + "/web",
        name: name,
        version: version,
        sourcePaths: [
            "../bugcore/libraries/bugcore/js/src",
            "./projects/bugflow/js/src"
        ],
        outputFile: "{{distPath}}/{{web.name}}-{{web.version}}.js",
        outputMinFile: "{{distPath}}/{{web.name}}-{{web.version}}.min.js"
    },
    lint: {
        targetPaths: [
            "."
        ],
        ignorePatterns: [
            ".*\\.buildbug$",
            ".*\\.bugunit$",
            ".*\\.git$",
            ".*node_modules$"
        ]
    }
});

//-------------------------------------------------------------------------------
// BuildTargets
//-------------------------------------------------------------------------------

// Clean BuildTarget
//-------------------------------------------------------------------------------

buildTarget('clean').buildFlow(
    targetTask('clean')
);

// Local BuildTarget
//-------------------------------------------------------------------------------

buildTarget('local').buildFlow(
    series([
        targetTask('clean'),
        targetTask('lint', {
            properties: {
                targetPaths: buildProject.getProperty("lint.targetPaths"),
                ignores: buildProject.getProperty("lint.ignorePatterns"),
                lintTasks: [
                    "cleanupExtraSpacingAtEndOfLines",
                    "ensureNewLineEnding",
                    "indentEqualSignsForPreClassVars",
                    "orderBugpackRequires",
                    "orderRequireAnnotations",
                    "updateCopyright"
                ]
            }
        }),
        parallel([
            series([
                targetTask('createNodePackage', {
                    properties: {
                        packageJson: buildProject.getProperty("node.packageJson"),
                        packagePaths: {
                            ".": [buildProject.getProperty("node.readmePath")],
                            "./lib": buildProject.getProperty("node.sourcePaths").concat(
                                buildProject.getProperty("node.unitTest.sourcePaths")
                            ),
                            "./scripts": buildProject.getProperty("node.scriptPaths").concat(
                                buildProject.getProperty("node.unitTest.scriptPaths")
                            ),
                            "./test": buildProject.getProperty("node.unitTest.testPaths")
                        }
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    init: function(task, buildProject, properties) {
                        var nodePackage = nodejs.findNodePackage(
                            buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version")
                        );
                        task.updateProperties({
                            sourceRoot: nodePackage.getBuildPath()
                        });
                    }
                }),
                targetTask('packNodePackage', {
                    properties: {
                        packageName: "{{node.packageJson.name}}",
                        packageVersion: "{{node.packageJson.version}}"
                    }
                }),
                targetTask('startNodeModuleTests', {
                    init: function(task, buildProject, properties) {
                        var packedNodePackage = nodejs.findPackedNodePackage(
                            buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version")
                        );
                        task.updateProperties({
                            modulePath: packedNodePackage.getFilePath()
                            //checkCoverage: true
                        });
                    }
                }),
                targetTask("s3PutFile", {
                    init: function(task, buildProject, properties) {
                        var packedNodePackage = nodejs.findPackedNodePackage(buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version"));
                        task.updateProperties({
                            file: packedNodePackage.getFilePath(),
                            options: {
                                acl: 'public-read',
                                encrypt: true
                            }
                        });
                    },
                    properties: {
                        bucket: "{{local-bucket}}"
                    }
                })
            ]),
            series([
                targetTask('copyContents', {
                    properties: {
                        fromPaths: buildProject.getProperty("web.sourcePaths"),
                        intoPath: "{{web.buildPath}}"
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    properties: {
                        name: "{{web.name}}",
                        sourceRoot: "{{web.buildPath}}"
                    }
                }),
                targetTask("concat", {
                    init: function(task, buildProject, properties) {
                        var bugpackRegistry = bugpack.findBugPackRegistry(buildProject.getProperty("web.name"));
                        var sources         = [];
                        var registryEntries = bugpackRegistry.getRegistryEntriesInDependentOrder();

                        registryEntries.forEach(function(bugPackRegistryEntry) {
                            sources.push(bugPackRegistryEntry.getResolvedPath().getAbsolutePath());
                        });
                        task.updateProperties({
                            sources: sources.concat("./projects/bugflow-web/js/scripts/bugflow-web.js")
                        });
                    },
                    properties: {
                        outputFile: "{{web.outputFile}}"
                    }
                }),
                parallel([
                    targetTask("s3PutFile", {
                        properties: {
                            file:  "{{web.outputFile}}",
                            options: {
                                acl: 'public-read',
                                gzip: true
                            },
                            bucket: "{{local-bucket}}"
                        }
                    }),
                    series([
                        targetTask("uglifyjsMinify", {
                            properties: {
                                sources: ["{{web.outputFile}}"],
                                outputFile: "{{web.outputMinFile}}"
                            }
                        }),
                        targetTask("s3PutFile", {
                            properties: {
                                file:  "{{web.outputMinFile}}",
                                options: {
                                    acl: 'public-read',
                                    gzip: true
                                },
                                bucket: "{{local-bucket}}"
                            }
                        })
                    ])
                ])
            ])
        ])
    ])
).makeDefault();

// Prod BuildTarget
//-------------------------------------------------------------------------------

buildTarget('prod').buildFlow(
    series([
        targetTask('clean'),
        targetTask('lint', {
            properties: {
                targetPaths: buildProject.getProperty("lint.targetPaths"),
                ignores: buildProject.getProperty("lint.ignorePatterns"),
                lintTasks: [
                    "cleanupExtraSpacingAtEndOfLines",
                    "ensureNewLineEnding",
                    "indentEqualSignsForPreClassVars",
                    "orderBugpackRequires",
                    "orderRequireAnnotations",
                    "updateCopyright"
                ]
            }
        }),
        parallel([

            //Create test node bugflow package

            series([
                targetTask('createNodePackage', {
                    properties: {
                        packageJson: buildProject.getProperty("node.unitTest.packageJson"),
                        packagePaths: {
                            "./lib": buildProject.getProperty("node.sourcePaths").concat(
                                buildProject.getProperty("node.unitTest.sourcePaths")
                            ),
                            "./scripts": buildProject.getProperty("node.scriptPaths").concat(
                                buildProject.getProperty("node.unitTest.scriptPaths")
                            ),
                            "./test": buildProject.getProperty("node.unitTest.testPaths")
                        }
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    init: function(task, buildProject, properties) {
                        var nodePackage = nodejs.findNodePackage(
                            buildProject.getProperty("node.unitTest.packageJson.name"),
                            buildProject.getProperty("node.unitTest.packageJson.version")
                        );
                        task.updateProperties({
                            sourceRoot: nodePackage.getBuildPath()
                        });
                    }
                }),
                targetTask('packNodePackage', {
                    properties: {
                        packageName: "{{node.unitTest.packageJson.name}}",
                        packageVersion: "{{node.unitTest.packageJson.version}}"
                    }
                }),
                targetTask('startNodeModuleTests', {
                    init: function(task, buildProject, properties) {
                        var packedNodePackage = nodejs.findPackedNodePackage(
                            buildProject.getProperty("node.unitTest.packageJson.name"),
                            buildProject.getProperty("node.unitTest.packageJson.version")
                        );
                        task.updateProperties({
                            modulePath: packedNodePackage.getFilePath(),
                            checkCoverage: true
                        });
                    }
                })
            ]),

            // Create production node bugflow package

            series([
                targetTask('createNodePackage', {
                    properties: {
                        packageJson: buildProject.getProperty("node.packageJson"),
                        packagePaths: {
                            ".": [buildProject.getProperty("node.readmePath")],
                            "./lib": buildProject.getProperty("node.sourcePaths"),
                            "./scripts": buildProject.getProperty("node.scriptPaths")
                        }
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    init: function(task, buildProject, properties) {
                        var nodePackage = nodejs.findNodePackage(
                            buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version")
                        );
                        task.updateProperties({
                            sourceRoot: nodePackage.getBuildPath()
                        });
                    }
                }),
                targetTask('packNodePackage', {
                    properties: {
                        packageName: "{{node.packageJson.name}}",
                        packageVersion: "{{node.packageJson.version}}"
                    }
                }),
                targetTask("s3PutFile", {
                    init: function(task, buildProject, properties) {
                        var packedNodePackage = nodejs.findPackedNodePackage(buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version"));
                        task.updateProperties({
                            file: packedNodePackage.getFilePath(),
                            options: {
                                acl: 'public-read',
                                encrypt: true
                            }
                        });
                    },
                    properties: {
                        bucket: "{{public-bucket}}"
                    }
                }),
                targetTask('npmConfigSet', {
                    properties: {
                        config: buildProject.getProperty("npmConfig")
                    }
                }),
                targetTask('npmAddUser'),
                targetTask('publishNodePackage', {
                    properties: {
                        packageName: "{{node.packageJson.name}}",
                        packageVersion: "{{node.packageJson.version}}"
                    }
                })
            ]),

            series([
                targetTask('copyContents', {
                    properties: {
                        fromPaths: buildProject.getProperty("web.sourcePaths"),
                        intoPath: "{{web.buildPath}}"
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    properties: {
                        name: "{{web.name}}",
                        sourceRoot: "{{web.buildPath}}"
                    }
                }),
                targetTask("concat", {
                    init: function(task, buildProject, properties) {
                        var bugpackRegistry = bugpack.findBugPackRegistry(buildProject.getProperty("web.name"));
                        var sources         = [];
                        var registryEntries = bugpackRegistry.getRegistryEntriesInDependentOrder();

                        registryEntries.forEach(function(bugPackRegistryEntry) {
                            sources.push(bugPackRegistryEntry.getResolvedPath().getAbsolutePath());
                        });
                        task.updateProperties({
                            sources: sources.concat("./projects/bugflow-web/js/scripts/bugflow-web.js")
                        });
                    },
                    properties: {
                        outputFile: "{{web.outputFile}}"
                    }
                }),
                parallel([
                    targetTask("s3PutFile", {
                        properties: {
                            file:  "{{web.outputFile}}",
                            options: {
                                acl: 'public-read',
                                gzip: true,
                                cacheControl: "max-age=31536000, public"
                            },
                            bucket: "{{public-bucket}}"
                        }
                    }),
                    series([
                        targetTask("uglifyjsMinify", {
                            properties: {
                                sources: ["{{web.outputFile}}"],
                                outputFile: "{{web.outputMinFile}}"
                            }
                        }),
                        targetTask("s3PutFile", {
                            properties: {
                                file:  "{{web.outputMinFile}}",
                                options: {
                                    acl: 'public-read',
                                    gzip: true,
                                    cacheControl: "max-age=31536000, public"
                                },
                                bucket: "{{public-bucket}}"
                            }
                        })
                    ])
                ])
            ])
        ])
    ])
);

//-------------------------------------------------------------------------------
// Build Scripts
//-------------------------------------------------------------------------------

buildScript({
    dependencies: [
        "bugcore",
        "bugflow",
        "bugfs"
    ],
    script: "./lintbug.js"
});
<commit_msg>Move BugFlow api class to a library folder. Modify buildbug script to match changes in projects<commit_after>/*
 * Copyright (c) 2014 airbug inc. http://airbug.com
 *
 * bugflow may be freely distributed under the MIT license.
 */

//-------------------------------------------------------------------------------
// Requires
//-------------------------------------------------------------------------------

var buildbug            = require('buildbug');

//-------------------------------------------------------------------------------
// Simplify References
//-------------------------------------------------------------------------------

var buildProject        = buildbug.buildProject;
var buildProperties     = buildbug.buildProperties;
var buildScript         = buildbug.buildScript;
var buildTarget         = buildbug.buildTarget;
var enableModule        = buildbug.enableModule;
var parallel            = buildbug.parallel;
var series              = buildbug.series;
var targetTask          = buildbug.targetTask;

//-------------------------------------------------------------------------------
// Enable Modules
//-------------------------------------------------------------------------------

var aws                 = enableModule("aws");
var bugpack             = enableModule('bugpack');
var bugunit             = enableModule('bugunit');
var core                = enableModule('core');
var lintbug             = enableModule("lintbug");
var nodejs              = enableModule('nodejs');
var uglifyjs            = enableModule("uglifyjs");

//-------------------------------------------------------------------------------
// Values
//-------------------------------------------------------------------------------

var name                = "bugflow";
var version             = "0.1.6";
var dependencies        = {
    bugpack: "0.1.14"
};

//-------------------------------------------------------------------------------
// BuildProperties
//-------------------------------------------------------------------------------

buildProperties({
    name: name,
    version: version
});

buildProperties({
    node: {
        packageJson: {
            name: "{{name}}",
            version: "{{version}}",
            description: "Declarative async flow control for object oriented JavaScript provided by the bugcore library",
            main: "./scripts/bugflow-node.js",
            dependencies: dependencies,
            author: "Brian Neisler <brian@airbug.com>",
            repository: {
                type: "git",
                url: "https://github.com/airbug/bugflow.git"
            },
            bugs: {
                url: "https://github.com/airbug/bugflow/issues"
            },
            licenses: [
                {
                    type : "MIT",
                    url : "https://raw.githubusercontent.com/airbug/bugflow/master/LICENSE"
                }
            ]
        },
        sourcePaths: [
            "../bugcore/libraries/bugcore/js/src",
            "./libraries/bugflow/js/src"
        ],
        scriptPaths: [
            "./projects/bugflow-node/js/scripts"
        ],
        readmePath: "./README.md",
        unitTest: {
            packageJson: {
                name: "{{name}}-test",
                version: "{{version}}",
                main: "./scripts/bugflow-node.js",
                dependencies: dependencies,
                private: true,
                scripts: {
                    test: "node ./test/scripts/bugunit-run.js"
                }
            },
            sourcePaths: [
                "../buganno/libraries/buganno/js/src",
                "../bugdouble/libraries/bugdouble/js/src",
                "../bugfs/libraries/bugfs/js/src",
                "../bugmeta/libraries/bugmeta/js/src",
                "../bugunit/libraries/bugunit/js/src",
                "../bugyarn/libraries/bugyarn/js/src"
            ],
            scriptPaths: [
                "../buganno/libraries/buganno/js/scripts",
                "../bugunit/libraries/bugunit/js/scripts"
            ],
            testPaths: [
                "../bugcore/libraries/bugcore/js/test",
                "./libraries/bugflow/js/test"
            ]
        }
    },
    web: {
        buildPath: buildProject.getProperty("buildPath") + "/web",
        name: name,
        version: version,
        sourcePaths: [
            "../bugcore/libraries/bugcore/js/src",
            "./libraries/bugflow/js/src"
        ],
        outputFile: "{{distPath}}/{{web.name}}-{{web.version}}.js",
        outputMinFile: "{{distPath}}/{{web.name}}-{{web.version}}.min.js"
    },
    lint: {
        targetPaths: [
            "."
        ],
        ignorePatterns: [
            ".*\\.buildbug$",
            ".*\\.bugunit$",
            ".*\\.git$",
            ".*node_modules$"
        ]
    }
});

//-------------------------------------------------------------------------------
// BuildTargets
//-------------------------------------------------------------------------------

// Clean BuildTarget
//-------------------------------------------------------------------------------

buildTarget('clean').buildFlow(
    targetTask('clean')
);

// Local BuildTarget
//-------------------------------------------------------------------------------

buildTarget('local').buildFlow(
    series([
        targetTask('clean'),
        targetTask('lint', {
            properties: {
                targetPaths: buildProject.getProperty("lint.targetPaths"),
                ignores: buildProject.getProperty("lint.ignorePatterns"),
                lintTasks: [
                    "cleanupExtraSpacingAtEndOfLines",
                    "ensureNewLineEnding",
                    "indentEqualSignsForPreClassVars",
                    "orderBugpackRequires",
                    "orderRequireAnnotations",
                    "updateCopyright"
                ]
            }
        }),
        parallel([
            series([
                targetTask('createNodePackage', {
                    properties: {
                        packageJson: buildProject.getProperty("node.packageJson"),
                        packagePaths: {
                            ".": [buildProject.getProperty("node.readmePath")],
                            "./lib": buildProject.getProperty("node.sourcePaths"),
                            "./scripts": buildProject.getProperty("node.scriptPaths"),
                            "./test": buildProject.getProperty("node.unitTest.testPaths"),
                            "./test/lib": buildProject.getProperty("node.unitTest.sourcePaths"),
                            "./test/scripts": buildProject.getProperty("node.unitTest.scriptPaths")
                        }
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    init: function(task, buildProject, properties) {
                        var nodePackage = nodejs.findNodePackage(
                            buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version")
                        );
                        task.updateProperties({
                            sourceRoot: nodePackage.getBuildPath()
                        });
                    }
                }),
                targetTask('packNodePackage', {
                    properties: {
                        packageName: "{{node.packageJson.name}}",
                        packageVersion: "{{node.packageJson.version}}"
                    }
                }),
                targetTask('startNodeModuleTests', {
                    init: function(task, buildProject, properties) {
                        var packedNodePackage = nodejs.findPackedNodePackage(
                            buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version")
                        );
                        task.updateProperties({
                            modulePath: packedNodePackage.getFilePath()
                            //checkCoverage: true
                        });
                    }
                }),
                targetTask("s3PutFile", {
                    init: function(task, buildProject, properties) {
                        var packedNodePackage = nodejs.findPackedNodePackage(buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version"));
                        task.updateProperties({
                            file: packedNodePackage.getFilePath(),
                            options: {
                                acl: 'public-read',
                                encrypt: true
                            }
                        });
                    },
                    properties: {
                        bucket: "{{local-bucket}}"
                    }
                })
            ]),
            series([
                targetTask('copyContents', {
                    properties: {
                        fromPaths: buildProject.getProperty("web.sourcePaths"),
                        intoPath: "{{web.buildPath}}"
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    properties: {
                        name: "{{web.name}}",
                        sourceRoot: "{{web.buildPath}}"
                    }
                }),
                targetTask("concat", {
                    init: function(task, buildProject, properties) {
                        var bugpackRegistry = bugpack.findBugPackRegistry(buildProject.getProperty("web.name"));
                        var sources         = [];
                        var registryEntries = bugpackRegistry.getRegistryEntriesInDependentOrder();

                        registryEntries.forEach(function(bugPackRegistryEntry) {
                            sources.push(bugPackRegistryEntry.getResolvedPath().getAbsolutePath());
                        });
                        task.updateProperties({
                            sources: sources.concat("./projects/bugflow-web/js/scripts/bugflow-web.js")
                        });
                    },
                    properties: {
                        outputFile: "{{web.outputFile}}"
                    }
                }),
                parallel([
                    targetTask("s3PutFile", {
                        properties: {
                            file:  "{{web.outputFile}}",
                            options: {
                                acl: 'public-read',
                                gzip: true
                            },
                            bucket: "{{local-bucket}}"
                        }
                    }),
                    series([
                        targetTask("uglifyjsMinify", {
                            properties: {
                                sources: ["{{web.outputFile}}"],
                                outputFile: "{{web.outputMinFile}}"
                            }
                        }),
                        targetTask("s3PutFile", {
                            properties: {
                                file:  "{{web.outputMinFile}}",
                                options: {
                                    acl: 'public-read',
                                    gzip: true
                                },
                                bucket: "{{local-bucket}}"
                            }
                        })
                    ])
                ])
            ])
        ])
    ])
).makeDefault();

// Prod BuildTarget
//-------------------------------------------------------------------------------

buildTarget('prod').buildFlow(
    series([
        targetTask('clean'),
        targetTask('lint', {
            properties: {
                targetPaths: buildProject.getProperty("lint.targetPaths"),
                ignores: buildProject.getProperty("lint.ignorePatterns"),
                lintTasks: [
                    "cleanupExtraSpacingAtEndOfLines",
                    "ensureNewLineEnding",
                    "indentEqualSignsForPreClassVars",
                    "orderBugpackRequires",
                    "orderRequireAnnotations",
                    "updateCopyright"
                ]
            }
        }),
        parallel([

            //Create test node bugflow package

            series([
                targetTask('createNodePackage', {
                    properties: {
                        packageJson: buildProject.getProperty("node.unitTest.packageJson"),
                        packagePaths: {
                            "./lib": buildProject.getProperty("node.sourcePaths"),
                            "./scripts": buildProject.getProperty("node.scriptPaths"),
                            "./test": buildProject.getProperty("node.unitTest.testPaths"),
                            "./test/lib": buildProject.getProperty("node.unitTest.sourcePaths"),
                            "./test/scripts": buildProject.getProperty("node.unitTest.scriptPaths")
                        }
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    init: function(task, buildProject, properties) {
                        var nodePackage = nodejs.findNodePackage(
                            buildProject.getProperty("node.unitTest.packageJson.name"),
                            buildProject.getProperty("node.unitTest.packageJson.version")
                        );
                        task.updateProperties({
                            sourceRoot: nodePackage.getBuildPath()
                        });
                    }
                }),
                targetTask('packNodePackage', {
                    properties: {
                        packageName: "{{node.unitTest.packageJson.name}}",
                        packageVersion: "{{node.unitTest.packageJson.version}}"
                    }
                }),
                targetTask('startNodeModuleTests', {
                    init: function(task, buildProject, properties) {
                        var packedNodePackage = nodejs.findPackedNodePackage(
                            buildProject.getProperty("node.unitTest.packageJson.name"),
                            buildProject.getProperty("node.unitTest.packageJson.version")
                        );
                        task.updateProperties({
                            modulePath: packedNodePackage.getFilePath(),
                            checkCoverage: true
                        });
                    }
                })
            ]),

            // Create production node bugflow package

            series([
                targetTask('createNodePackage', {
                    properties: {
                        packageJson: buildProject.getProperty("node.packageJson"),
                        packagePaths: {
                            ".": [buildProject.getProperty("node.readmePath")],
                            "./lib": buildProject.getProperty("node.sourcePaths"),
                            "./scripts": buildProject.getProperty("node.scriptPaths")
                        }
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    init: function(task, buildProject, properties) {
                        var nodePackage = nodejs.findNodePackage(
                            buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version")
                        );
                        task.updateProperties({
                            sourceRoot: nodePackage.getBuildPath()
                        });
                    }
                }),
                targetTask('packNodePackage', {
                    properties: {
                        packageName: "{{node.packageJson.name}}",
                        packageVersion: "{{node.packageJson.version}}"
                    }
                }),
                targetTask("s3PutFile", {
                    init: function(task, buildProject, properties) {
                        var packedNodePackage = nodejs.findPackedNodePackage(buildProject.getProperty("node.packageJson.name"),
                            buildProject.getProperty("node.packageJson.version"));
                        task.updateProperties({
                            file: packedNodePackage.getFilePath(),
                            options: {
                                acl: 'public-read',
                                encrypt: true
                            }
                        });
                    },
                    properties: {
                        bucket: "{{public-bucket}}"
                    }
                }),
                targetTask('npmConfigSet', {
                    properties: {
                        config: buildProject.getProperty("npmConfig")
                    }
                }),
                targetTask('npmAddUser'),
                targetTask('publishNodePackage', {
                    properties: {
                        packageName: "{{node.packageJson.name}}",
                        packageVersion: "{{node.packageJson.version}}"
                    }
                })
            ]),

            series([
                targetTask('copyContents', {
                    properties: {
                        fromPaths: buildProject.getProperty("web.sourcePaths"),
                        intoPath: "{{web.buildPath}}"
                    }
                }),
                targetTask('generateBugPackRegistry', {
                    properties: {
                        name: "{{web.name}}",
                        sourceRoot: "{{web.buildPath}}"
                    }
                }),
                targetTask("concat", {
                    init: function(task, buildProject, properties) {
                        var bugpackRegistry = bugpack.findBugPackRegistry(buildProject.getProperty("web.name"));
                        var sources         = [];
                        var registryEntries = bugpackRegistry.getRegistryEntriesInDependentOrder();

                        registryEntries.forEach(function(bugPackRegistryEntry) {
                            sources.push(bugPackRegistryEntry.getResolvedPath().getAbsolutePath());
                        });
                        task.updateProperties({
                            sources: sources.concat("./projects/bugflow-web/js/scripts/bugflow-web.js")
                        });
                    },
                    properties: {
                        outputFile: "{{web.outputFile}}"
                    }
                }),
                parallel([
                    targetTask("s3PutFile", {
                        properties: {
                            file:  "{{web.outputFile}}",
                            options: {
                                acl: 'public-read',
                                gzip: true,
                                cacheControl: "max-age=31536000, public"
                            },
                            bucket: "{{public-bucket}}"
                        }
                    }),
                    series([
                        targetTask("uglifyjsMinify", {
                            properties: {
                                sources: ["{{web.outputFile}}"],
                                outputFile: "{{web.outputMinFile}}"
                            }
                        }),
                        targetTask("s3PutFile", {
                            properties: {
                                file:  "{{web.outputMinFile}}",
                                options: {
                                    acl: 'public-read',
                                    gzip: true,
                                    cacheControl: "max-age=31536000, public"
                                },
                                bucket: "{{public-bucket}}"
                            }
                        })
                    ])
                ])
            ])
        ])
    ])
);

//-------------------------------------------------------------------------------
// Build Scripts
//-------------------------------------------------------------------------------

buildScript({
    dependencies: [
        "bugcore",
        "bugflow",
        "bugfs"
    ],
    script: "./lintbug.js"
});
<|endoftext|>