<commit_before>/*
  Setup user details for exception handling
 */

App.then(function(app) {
    App.CurrentUser.find('current').then(function(user) {
        if (typeof Raven == 'object') {
            Raven.setUser({
                id: user.get('id_for_ember'),
                name: user.get('full_name'),
                email: user.get('email'),
            });
        }
    });

    // Override the BB project / status search list
    // TODO: we should just define the 'list' when initializing
    //       and then BB should use it when setting up the list
    App.ProjectPhase.find().then(function(data){
        var list = [
            {id: 5, name: gettext("Running campaigns")},
            {id: [7,8], name: gettext("Finished campaigns")}
        ];
        App.ProjectPhaseSelectView.reopen({
            content: list
        });
    });

    // Facebook API ID
    if (FACEBOOK_AUTH_ID)
        App.set('appId', FACEBOOK_AUTH_ID);

    app.appLogin = function (fbResponse) {
        var _this = this,
            currentUsercontroller = App.__container__.lookup('controller:currentUser');

        // Clear any existing tokens which might be present but expired. clearJwtToken action is on the App.ApplicationRoute
        // FIXME: should call the clearJwtToken action here but it isn't being called.
        // currentUsercontroller.send('clearJwtToken');
        delete localStorage['jwtToken'];
        App.set('jwtToken', null);

        return Ember.RSVP.Promise(function (resolve, reject) {
            var hash = {
              url: "/api/social-login/facebook/",
              dataType: "json",
              type: 'post',
              data: fbResponse
            };

            hash.success = function (response) {

                App.AuthJwt.processSuccessResponse(response).then(function (user) {

                    // If success
                    currentUsercontroller.set('model', user);
                    currentUsercontroller.send('close');
                    currentUsercontroller.send('setFlash', gettext('Welcome to the 1%Club'));

                    Ember.run(null, resolve, user);
                 }, function (error) {
                    // If failed

                    Ember.run(null, reject, error);
                });
            };

            hash.error = function (response) {

                currentUsercontroller.send('setFlash', gettext('Something went wrong :-('), 'error');
                var error = JSON.parse(response.responseText);
                Ember.run(null, reject, error);
            };

            Ember.$.ajax(hash);
        });
    };
});

/*
  Bluebottle Route Overrides
 */

App.ApplicationRoute.reopen(App.LogoutJwtMixin, {
    init: function () {
        this._super();

        // Set the facebook appId
        // TODO: move this to the server side settings
        this.set('appId', '1438115069790112');
    },

    actions: {
        logout: function (redirect) {
            // call the standard logout code => clear JWT token etc
            this._super(redirect);

            // If the has logged in via FB, eg there is a FBUser then they should
            // be logged out so that the user can log in with user/email
            if (FB && !Em.isEmpty(FB.getUserID()))
                FB.logout()
        },
        addDonation: function (project, fundraiser) {
            var route = this;
            App.CurrentOrder.find('current').then(function(order) {
                var store = route.get('store');

                var projectHasDonation = order.get('donations').anyBy('project', project);
                var fundraiserHasDonation = false;
                if(fundraiser !== undefined){
                    fundraiserHasDonation = order.get('donations').anyBy('fundraiser', fundraiser);
                }

                // TODO: functional test this.
                // *  Donate directly to project: check if no direct donations exist
                // *  Donate through fundraiser: check if donation for that fundraiser exists
                // *  We can have the same project multiple times, but all different fundraisers

                if (fundraiserHasDonation ||
                    (projectHasDonation && !fundraiserHasDonation && fundraiser === undefined)) {
                    // Donation for this already exists in this order.
                } else {
                    var donation = store.createRecord(App.CurrentOrderDonation);
                    donation.set('project', project);
                    if(fundraiser !== undefined){
                        donation.set('fundraiser', fundraiser);
                    }
                    donation.set('order', order);
                    donation.save();
                }
                route.transitionTo('currentOrder.donationList');
            });
        }
    }
});

/*
  Bluebottle Controller Overrides
 */
App.ApplicationController.reopen({
    needs: ['currentOrder', 'myProjectList'],

    missingCurrentUser: function () {
        // FIXME: should call the clearJwtToken action here but it isn't being called.
        delete localStorage['jwtToken'];
        App.set('jwtToken', null);
    },
});

App.EventMixin = Em.Mixin.create({

  bindScrolling: function(opts) {
    var onScroll, self = this;

    onScroll = function() {
      var scrollTop = $(this).scrollTop();
      return self.scrolled(scrollTop);
    };

    $(window).bind('scroll', onScroll);
    $(document).bind('touchmove', onScroll);
  },

  unbindScrolling: function () {
    $(window).unbind('scroll');
    $(document).unbind('touchmove');
  },

  bindMobileClick: function() {
    toggleMenu = function() {
      $('.mobile-nav-holder').toggleClass('is-active');
    };

    closeMenu = function(event) {
      $('.mobile-nav-holder').removeClass('is-active');
    };

    $('.mobile-nav-btn').bind('click', toggleMenu);
    $('#content').bind('hover', closeMenu);
  }
});

/*
  Bluebottle View Overrides
*/

App.ApplicationView.reopen(App.EventMixin, {
    setBindScrolling: function() {
        this.bindScrolling();
    }.on('didInsertElement'),

    setUnbindScrolling: function() {
        this.unbindScrolling();
    }.on('didInsertElement'),

    setBindClick: function() {
        this.bindMobileClick();
    }.on('didInsertElement'),

    scrolled: function(dist) {
        top = $('#content').offset();
        elm = top.screen.availTop;

        if (dist <= 53) {
            $('#header').removeClass('is-scrolled');
            $('.nav-member-dropdown').removeClass('is-scrolled');
            $('.mobile-nav-holder').removeClass('is-scrolled');
            $('#content').append('

');
        } else {
            $('#header').addClass('is-scrolled');
            $('.nav-member-dropdown').addClass('is-scrolled');
            $('.mobile-nav-holder').addClass('is-scrolled');
        }
    }
});
<commit_msg>added check for last login<commit_after>/*
  Setup user details for exception handling
 */

App.then(function(app) {
    App.CurrentUser.find('current').then(function(user) {
        if (typeof Raven == 'object') {
            Raven.setUser({
                id: user.get('id_for_ember'),
                name: user.get('full_name'),
                email: user.get('email'),
            });
        }
    });

    // Override the BB project / status search list
    // TODO: we should just define the 'list' when initializing
    //       and then BB should use it when setting up the list
    App.ProjectPhase.find().then(function(data){
        var list = [
            {id: 5, name: gettext("Running campaigns")},
            {id: [7,8], name: gettext("Finished campaigns")}
        ];
        App.ProjectPhaseSelectView.reopen({
            content: list
        });
    });

    // Facebook API ID
    if (FACEBOOK_AUTH_ID)
        App.set('appId', FACEBOOK_AUTH_ID);

    app.appLogin = function (fbResponse) {
        var _this = this,
            currentUsercontroller = App.__container__.lookup('controller:currentUser');

        // Clear any existing tokens which might be present but expired. clearJwtToken action is on the App.ApplicationRoute
        // FIXME: should call the clearJwtToken action here but it isn't being called.
        // currentUsercontroller.send('clearJwtToken');
        delete localStorage['jwtToken'];
        App.set('jwtToken', null);

        return Ember.RSVP.Promise(function (resolve, reject) {
            var hash = {
              url: "/api/social-login/facebook/",
              dataType: "json",
              type: 'post',
              data: fbResponse
            };

            hash.success = function (response) {

                App.AuthJwt.processSuccessResponse(response).then(function (user) {

                    // If success
                    currentUsercontroller.set('model', user);
                    currentUsercontroller.send('close');
                    if (user.get('last_login') == user.get('date_joined')) {
                        currentUsercontroller.send('setFlash', gettext('Welcome to the 1%Club'));
                    }

                    Ember.run(null, resolve, user);
                 }, function (error) {
                    // If failed

                    Ember.run(null, reject, error);
                });
            };

            hash.error = function (response) {

                currentUsercontroller.send('setFlash', gettext('Something went wrong :-('), 'error');
                var error = JSON.parse(response.responseText);
                Ember.run(null, reject, error);
            };

            Ember.$.ajax(hash);
        });
    };
});

/*
  Bluebottle Route Overrides
 */

App.ApplicationRoute.reopen(App.LogoutJwtMixin, {
    init: function () {
        this._super();

        // Set the facebook appId
        // TODO: move this to the server side settings
        this.set('appId', '1438115069790112');
    },

    actions: {
        logout: function (redirect) {
            // call the standard logout code => clear JWT token etc
            this._super(redirect);

            // If the has logged in via FB, eg there is a FBUser then they should
            // be logged out so that the user can log in with user/email
            if (FB && !Em.isEmpty(FB.getUserID()))
                FB.logout()
        },
        addDonation: function (project, fundraiser) {
            var route = this;
            App.CurrentOrder.find('current').then(function(order) {
                var store = route.get('store');

                var projectHasDonation = order.get('donations').anyBy('project', project);
                var fundraiserHasDonation = false;
                if(fundraiser !== undefined){
                    fundraiserHasDonation = order.get('donations').anyBy('fundraiser', fundraiser);
                }

                // TODO: functional test this.
                // *  Donate directly to project: check if no direct donations exist
                // *  Donate through fundraiser: check if donation for that fundraiser exists
                // *  We can have the same project multiple times, but all different fundraisers

                if (fundraiserHasDonation ||
                    (projectHasDonation && !fundraiserHasDonation && fundraiser === undefined)) {
                    // Donation for this already exists in this order.
                } else {
                    var donation = store.createRecord(App.CurrentOrderDonation);
                    donation.set('project', project);
                    if(fundraiser !== undefined){
                        donation.set('fundraiser', fundraiser);
                    }
                    donation.set('order', order);
                    donation.save();
                }
                route.transitionTo('currentOrder.donationList');
            });
        }
    }
});

/*
  Bluebottle Controller Overrides
 */
App.ApplicationController.reopen({
    needs: ['currentOrder', 'myProjectList'],

    missingCurrentUser: function () {
        // FIXME: should call the clearJwtToken action here but it isn't being called.
        delete localStorage['jwtToken'];
        App.set('jwtToken', null);
    },
});

App.EventMixin = Em.Mixin.create({

  bindScrolling: function(opts) {
    var onScroll, self = this;

    onScroll = function() {
      var scrollTop = $(this).scrollTop();
      return self.scrolled(scrollTop);
    };

    $(window).bind('scroll', onScroll);
    $(document).bind('touchmove', onScroll);
  },

  unbindScrolling: function () {
    $(window).unbind('scroll');
    $(document).unbind('touchmove');
  },

  bindMobileClick: function() {
    toggleMenu = function() {
      $('.mobile-nav-holder').toggleClass('is-active');
    };

    closeMenu = function(event) {
      $('.mobile-nav-holder').removeClass('is-active');
    };

    $('.mobile-nav-btn').bind('click', toggleMenu);
    $('#content').bind('hover', closeMenu);
  }
});

/*
  Bluebottle View Overrides
*/

App.ApplicationView.reopen(App.EventMixin, {
    setBindScrolling: function() {
        this.bindScrolling();
    }.on('didInsertElement'),

    setUnbindScrolling: function() {
        this.unbindScrolling();
    }.on('didInsertElement'),

    setBindClick: function() {
        this.bindMobileClick();
    }.on('didInsertElement'),

    scrolled: function(dist) {
        top = $('#content').offset();
        elm = top.screen.availTop;

        if (dist <= 53) {
            $('#header').removeClass('is-scrolled');
            $('.nav-member-dropdown').removeClass('is-scrolled');
            $('.mobile-nav-holder').removeClass('is-scrolled');
            $('#content').append('

');
        } else {
            $('#header').addClass('is-scrolled');
            $('.nav-member-dropdown').addClass('is-scrolled');
            $('.mobile-nav-holder').addClass('is-scrolled');
        }
    }
});
<|endoftext|>


<commit_before>'use strict';

var babelHelpers = {};

babelHelpers.classCallCheck = function (instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
};

babelHelpers.createClass = function () {
  function defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }

  return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);
    if (staticProps) defineProperties(Constructor, staticProps);
    return Constructor;
  };
}();

babelHelpers;

var exec = require('child_process').exec;
var defaultOptions = {
  onBuildStart: [],
  onBuildEnd: [],
  onBuildExit: [],
  dev: true,
  verbose: false,
  watch: false
};

function puts(error, stdout, stderr) {
  if (error) {
    console.log('Error: ', error, stderr);
  }
  console.log(stdout);
}

function validateInput(options) {
  if (typeof options.onBuildStart === 'string') {
    options.onBuildStart = options.onBuildStart.split('&&');
  }
  if (typeof options.onBuildEnd === 'string') {
    options.onBuildEnd = options.onBuildEnd.split('&&');
  }
  if (typeof options.onBuildExit === 'string') {
    options.onBuildExit = options.onBuildExit.split('&&');
  }
  return options;
}

function mergeOptions(options, defaults) {
  for (var key in defaults) {
    if (options.hasOwnProperty(key)) {
      defaults[key] = options[key];
    }
  }
  return defaults;
}

var WebpackShellPlugin = function () {
  function WebpackShellPlugin(options) {
    babelHelpers.classCallCheck(this, WebpackShellPlugin);

    this.options = validateInput(mergeOptions(options, defaultOptions));
  }

  babelHelpers.createClass(WebpackShellPlugin, [{
    key: 'apply',
    value: function apply(compiler) {
      var _this = this;

      compiler.plugin('compilation', function (compilation) {
        if (_this.options.verbose) {
          console.log('Report compilation: ' + compilation);
        }
        if (_this.options.onBuildStart.length) {
          console.log('Executing pre-build scripts');
          _this.options.onBuildStart.forEach(function (script) {
            exec(script, puts);
          });
          if (_this.options.dev) {
            _this.options.onBuildStart = [];
          }
        }
      });

      compiler.plugin('emit', function (compilation, callback) {
        for (var key in compilation.options) {
          console.log(key);
        }
        console.log('EMITTING');
        if (_this.options.onBuildEnd.length) {
          console.log('Executing post-build scripts');
          _this.options.onBuildEnd.forEach(function (script) {
            exec(script, puts);
          });
          if (_this.options.dev) {
            _this.options.onBuildEnd = [];
          }
        }
        callback();
      });

      compiler.plugin('done', function () {
        if (_this.options.onBuildExit.length) {
          console.log('Executing additional scripts before exit');
          _this.options.onBuildExit.forEach(function (script) {
            exec(script, puts);
          });
        }
      });
    }
  }]);
  return WebpackShellPlugin;
}();

module.exports = WebpackShellPlugin;<commit_msg>Provide support for emitting watcher<commit_after>'use strict';

var babelHelpers = {};

babelHelpers.classCallCheck = function (instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
};

babelHelpers.createClass = function () {
  function defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }

  return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);
    if (staticProps) defineProperties(Constructor, staticProps);
    return Constructor;
  };
}();

babelHelpers;

var exec = require('child_process').exec;
var defaultOptions = {
  onBuildStart: [],
  onBuildEnd: [],
  onBuildExit: [],
  dev: true,
  verbose: false
};

function puts(error, stdout, stderr) {
  if (error) {
    console.log('Error: ', error, stderr);
  }
}

function spreadStdoutAndStdErr(proc) {
  proc.stdout.pipe(process.stdout);
  proc.stderr.pipe(process.stdout);
}

function validateInput(options) {
  if (typeof options.onBuildStart === 'string') {
    options.onBuildStart = options.onBuildStart.split('&&');
  }
  if (typeof options.onBuildEnd === 'string') {
    options.onBuildEnd = options.onBuildEnd.split('&&');
  }
  if (typeof options.onBuildExit === 'string') {
    options.onBuildExit = options.onBuildExit.split('&&');
  }
  return options;
}

function mergeOptions(options, defaults) {
  for (var key in defaults) {
    if (options.hasOwnProperty(key)) {
      defaults[key] = options[key];
    }
  }
  return defaults;
}

var WebpackShellPlugin = function () {
  function WebpackShellPlugin(options) {
    babelHelpers.classCallCheck(this, WebpackShellPlugin);

    this.options = validateInput(mergeOptions(options, defaultOptions));
  }

  babelHelpers.createClass(WebpackShellPlugin, [{
    key: 'apply',
    value: function apply(compiler) {
      var _this = this;

      compiler.plugin('compilation', function (compilation) {
        if (_this.options.verbose) {
          console.log('Report compilation: ' + compilation);
        }
        if (_this.options.onBuildStart.length) {
          console.log('Executing pre-build scripts');
          _this.options.onBuildStart.forEach(function (script) {
            spreadStdoutAndStdErr(exec(script, puts));
          });
          if (_this.options.dev) {
            _this.options.onBuildStart = [];
          }
        }
      });

      compiler.plugin('emit', function (compilation, callback) {
        if (_this.options.onBuildEnd.length) {
          console.log('Executing post-build scripts');
          _this.options.onBuildEnd.forEach(function (script) {
            spreadStdoutAndStdErr(exec(script, puts));
          });
          if (_this.options.dev) {
            _this.options.onBuildEnd = [];
          }
        }
        callback();
      });

      compiler.plugin('done', function () {
        if (_this.options.onBuildExit.length) {
          console.log('Executing additional scripts before exit');
          _this.options.onBuildExit.forEach(function (script) {
            spreadStdoutAndStdErr(exec(script, puts));
          });
        }
      });
    }
  }]);
  return WebpackShellPlugin;
}();

module.exports = WebpackShellPlugin;<|endoftext|>


<commit_before>liveblogSyndication
    .factory('IngestPanelReducers', function() {
        var locallySyndicatedItems = function(syndicationIn, localSyndTokens) {
            return syndicationIn._items.filter(function(item) {
                return (localSyndTokens.indexOf(item.blog_token) != -1);
            });
        };

        return function(state, action) {
            switch (action.type) {
                case 'ON_GET_SYND':
                    var localSyndTokens = action.syndicationIn._items
                        .filter(function(syndication) {
                            return (syndication.blog_id == state.consumerBlogId);
                        })
                        .map(function(syndication) {
                            return syndication.blog_token;
                        });

                    return angular.extend(state, {
                        syndicationIn: action.syndicationIn, //ACTION
                        localSyndTokens: localSyndTokens,
                        locallySyndicatedItems: locallySyndicatedItems(
                            action.syndicationIn,
                            localSyndTokens
                        ),
                        localProducerBlogIds: [], // Reset list after syndication
                        producerBlogs: [] // Same here
                    });

                case 'ON_UPDATED_SYND':
                    return angular.extend(state, {
                        syndicationIn: angular.extend(state.syndicationIn, {
                            _items: state.syndicationIn._items.map(function(item) {
                                if (item._id == action.syndEntry._id)
                                    return action.syndEntry;
                                else
                                    return item;
                            })
                        })
                    });

                case 'ON_GET_PRODUCERS':
                    return angular.extend(state, {
                        producers: action.producers
                    });

                case 'ON_GET_PRODUCER_BLOGS':
                    var localProducerBlogIds = [];

                    return angular.extend(state, {
                        producerBlogs: angular.extend(action.producerBlogs, {
                            _items: action.producerBlogs._items
                                .filter(function(blog) {
                                    // Only display the producer's blogs with an enabled syndication
                                    return (blog.syndication_enabled);
                                })
                                .map(function(blog) {
                                    blog.checked = false;
                                    blog.start_date = null; // Default start_date as null
                                    blog.auto_publish = false; // Default autopublish as false
                                    blog.auto_retrieve = true; // Default autoretrieve as true

                                    state.locallySyndicatedItems.forEach(function(localBlog) {
                                        if (localBlog.producer_blog_id == blog._id) {
                                            localProducerBlogIds.push(blog._id);
                                            blog.checked = true;
                                        }

                                    });

                                    return blog;
                                })
                        }),
                        localProducerBlogIds: localProducerBlogIds
                    });

                case 'ON_TOGGLE_MODAL':
                    if (action.modalActive)
                        return angular.extend(state, {
                            modalActive: action.modalActive
                        });
                    else
                        return angular.extend(state, {
                            producerBlogs: {},
                            localProducerBlogIds: [],
                            modalActive: action.modalActive
                        });

                case 'ON_ERROR':
                    return angular.extend(state, {
                        error: action.error
                    });
            }
        }
    });
<commit_msg>Fix etag issue when updating auto publish several times<commit_after>liveblogSyndication
    .factory('IngestPanelReducers', function() {
        var locallySyndicatedItems = function(syndicationIn, localSyndTokens) {
            return syndicationIn._items.filter(function(item) {
                return (localSyndTokens.indexOf(item.blog_token) != -1);
            });
        };

        return function(state, action) {
            switch (action.type) {
                case 'ON_GET_SYND':
                    var localSyndTokens = action.syndicationIn._items
                        .filter(function(syndication) {
                            return (syndication.blog_id == state.consumerBlogId);
                        })
                        .map(function(syndication) {
                            return syndication.blog_token;
                        });

                    return angular.extend(state, {
                        syndicationIn: action.syndicationIn, //ACTION
                        localSyndTokens: localSyndTokens,
                        locallySyndicatedItems: locallySyndicatedItems(
                            action.syndicationIn,
                            localSyndTokens
                        ),
                        localProducerBlogIds: [], // Reset list after syndication
                        producerBlogs: [] // Same here
                    });

                case 'ON_UPDATED_SYND':
                    var syndicationIn = angular.extend(state.syndicationIn, {
                        _items: state.syndicationIn._items.map(function(item) {
                            if (item._id == action.syndEntry._id)
                                return action.syndEntry;
                            else
                                return item;
                        })
                    });

                    return angular.extend(state, {
                        syndicationIn: syndicationIn,
                        locallySyndicatedItems: locallySyndicatedItems(
                            syndicationIn,
                            state.localSyndTokens
                        )
                    });

                case 'ON_GET_PRODUCERS':
                    return angular.extend(state, {
                        producers: action.producers
                    });

                case 'ON_GET_PRODUCER_BLOGS':
                    var localProducerBlogIds = [];

                    return angular.extend(state, {
                        producerBlogs: angular.extend(action.producerBlogs, {
                            _items: action.producerBlogs._items
                                .filter(function(blog) {
                                    // Only display the producer's blogs with an enabled syndication
                                    return (blog.syndication_enabled);
                                })
                                .map(function(blog) {
                                    blog.checked = false;
                                    blog.start_date = null; // Default start_date as null
                                    blog.auto_publish = false; // Default autopublish as false
                                    blog.auto_retrieve = true; // Default autoretrieve as true

                                    state.locallySyndicatedItems.forEach(function(localBlog) {
                                        if (localBlog.producer_blog_id == blog._id) {
                                            localProducerBlogIds.push(blog._id);
                                            blog.checked = true;
                                        }

                                    });

                                    return blog;
                                })
                        }),
                        localProducerBlogIds: localProducerBlogIds
                    });

                case 'ON_TOGGLE_MODAL':
                    if (action.modalActive)
                        return angular.extend(state, {
                            modalActive: action.modalActive
                        });
                    else
                        return angular.extend(state, {
                            producerBlogs: {},
                            localProducerBlogIds: [],
                            modalActive: action.modalActive
                        });

                case 'ON_ERROR':
                    return angular.extend(state, {
                        error: action.error
                    });
            }
        }
    });
<|endoftext|>


<commit_before>import { buildLogger } from '../log-factory';
import Question from '../question';
import CliCommand from './cli-command';
import { resolve, join } from 'path';
import ExampleApp from '../example-app';
import { softWrite } from '../file-helper';
import { removeSync } from 'fs-extra';
import tmpSupport from './tmp-support';
import { run as runManifest } from './manifest';
const logger = buildLogger();

export class PackQuestionOpts {
  constructor(dir, clean, buildExample, exampleFile, keepBuildAssets) {
    this.dir = dir;
    this.clean = clean;
    this.buildExample = buildExample;
    this.exampleFile = exampleFile;
    this.keepBuildAssets = keepBuildAssets;
  }

  static build(args) {

    if (args.keepBuildAssets) {
      logger.error('TODO: plug keepBuildAssets back in');
    }

    return new PackQuestionOpts(
      args.dir || process.cwd(),
      args.clean === 'true' || args.clean === true,
      args.buildExample !== 'false' && args.buildExample !== false,
      args.exampleFile || 'example.html',
      args.keepBuildAssets || false);
  }
}

class PackQuestionCommand extends CliCommand {
  constructor() {
    super('pack-question', 'generate a question package');
  }

  run(args) {
    let packOpts = PackQuestionOpts.build(args);
    let dir = resolve(packOpts.dir);
    let exampleApp = new ExampleApp();
    let questionOpts = Question.buildOpts(args);
    let question = new Question(dir, questionOpts, tmpSupport, exampleApp);

    logger.silly('[run] packOpts? ', packOpts);

    let maybeDeleteBuildAssets = packOpts.keepBuildAssets ? Promise.resolve() : () => {
      return question.clean()
        .then(() => {
          if (!packOpts.buildExample) {
            removeSync(join(dir, packOpts.exampleFile));
          }
        });
    }

    return question.pack(packOpts.clean)
      .then((result) => {
        logger.debug('pack result: ', result);

        if (packOpts.buildExample) {
          let paths = {
            client: result.client,
            controllers: result.controllers.filename
          }

          let ids = {
            controllers: result.controllers.library
          }

          logger.silly('question: ', question)
          let markup = exampleApp.staticMarkup(paths, ids, question.config.markup, question.config.config);

          logger.silly('markup: ', markup);

          let examplePath = join(dir, packOpts.exampleFile);

          if (packOpts.clean) {
            removeSync(examplePath);
          }

          return softWrite(examplePath, markup);
        }
      })
      .then(maybeDeleteBuildAssets)
      .then(() => runManifest({ outfile: args.manifestOutfile }));
  }
}

let cmd = new PackQuestionCommand();
exports.match = cmd.match.bind(cmd);
exports.usage = cmd.usage;
exports.summary = cmd.summary;
exports.run = cmd.run.bind(cmd);<commit_msg>rm todo<commit_after>import { buildLogger } from '../log-factory';
import Question from '../question';
import CliCommand from './cli-command';
import { resolve, join } from 'path';
import ExampleApp from '../example-app';
import { softWrite } from '../file-helper';
import { removeSync } from 'fs-extra';
import tmpSupport from './tmp-support';
import { run as runManifest } from './manifest';
const logger = buildLogger();

export class PackQuestionOpts {
  constructor(dir, clean, buildExample, exampleFile, keepBuildAssets) {
    this.dir = dir;
    this.clean = clean;
    this.buildExample = buildExample;
    this.exampleFile = exampleFile;
    this.keepBuildAssets = keepBuildAssets;
  }

  static build(args) {
    return new PackQuestionOpts(
      args.dir || process.cwd(),
      args.clean === 'true' || args.clean === true,
      args.buildExample !== 'false' && args.buildExample !== false,
      args.exampleFile || 'example.html',
      args.keepBuildAssets || false);
  }
}

class PackQuestionCommand extends CliCommand {
  constructor() {
    super('pack-question', 'generate a question package');
  }

  run(args) {
    let packOpts = PackQuestionOpts.build(args);
    let dir = resolve(packOpts.dir);
    let exampleApp = new ExampleApp();
    let questionOpts = Question.buildOpts(args);
    let question = new Question(dir, questionOpts, tmpSupport, exampleApp);

    logger.silly('[run] packOpts? ', packOpts);

    let maybeDeleteBuildAssets = packOpts.keepBuildAssets ? Promise.resolve() : () => {
      return question.clean()
        .then(() => {
          if (!packOpts.buildExample) {
            removeSync(join(dir, packOpts.exampleFile));
          }
        });
    }

    return question.pack(packOpts.clean)
      .then((result) => {
        logger.debug('pack result: ', result);

        if (packOpts.buildExample) {
          let paths = {
            client: result.client,
            controllers: result.controllers.filename
          }

          let ids = {
            controllers: result.controllers.library
          }

          logger.silly('question: ', question)
          let markup = exampleApp.staticMarkup(paths, ids, question.config.markup, question.config.config);

          logger.silly('markup: ', markup);

          let examplePath = join(dir, packOpts.exampleFile);

          if (packOpts.clean) {
            removeSync(examplePath);
          }

          return softWrite(examplePath, markup);
        }
      })
      .then(maybeDeleteBuildAssets)
      .then(() => runManifest({ outfile: args.manifestOutfile }));
  }
}

let cmd = new PackQuestionCommand();
exports.match = cmd.match.bind(cmd);
exports.usage = cmd.usage;
exports.summary = cmd.summary;
exports.run = cmd.run.bind(cmd);<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import {Link, Element} from 'react-scroll';
import classes from './Calendar.css'
import YearButtons from "./YearButtons";
import SqueezeNumberButtons from "./SqueezeNumberButtons";
import ScrollStickyMenu from "./ScrollStickyMenu";

const Calendar = (props) => (

{`År ${props.year}`}

Regner {props.squeezeNumber} dager mellom fri som
                inneklemt

        <ScrollStickyMenu>
            <YearButtons
                style={{margin: '2px'}}
                switchYear={props.switchYear}
                year={props.year}
            />
            <SqueezeNumberButtons
                style={{margin: '2px'}}
                switchSqueezeNumber={props.switchSqueezeNumber}
                currentSqueezeNumber={props.squeezeNumber}
            />
        </ScrollStickyMenu>

        <SqueezedDays calendar={props.calendar}/>

            {_.map(props.calendar, (day) => {
                return (
                    <CalendarDay type={day.type} day={day} includeExtraText/>
                )
            })}

);

Calendar.propTypes = {
    calendar: PropTypes.object,
    year: PropTypes.number,
    squeezeNumber: PropTypes.number,
    switchYear: PropTypes.func,
    switchSqueezeNumber: PropTypes.func
};

const Day = (props) => {

    console.log(props.day.formattedDate);

    let backgroundColor;
    let color;
    let text;

    // Add appropriate styling and text to days
    switch (props.type) {
        case 'inneklemt':
            backgroundColor = '#71a74b';
            color = 'black';
            text = props.day.formattedDate + ' - INNEKLEMT!';
            break;
        case 'weekend':
            backgroundColor = 'rgb(197, 150, 237)';
            color = 'inherit';
            break;
        case 'holiday':
            backgroundColor = 'lightcoral';
            color = 'inherit';
            text = props.day.formattedDate + ' - ' + props.day.name;
            break;
        default:
            backgroundColor = 'lightblue';
            color = 'inherit';
    }

    const style = {
        backgroundColor: backgroundColor,
        color: color,
        marginTop: props.firstSqueezedDay ? '5px' : 0,
        padding: '5px 0',
        fontSize: '1.1em',
        listStyle: 'none'
    };
    return (

            {
                props.includeExtraText && text ? text : props.day.formattedDate
            }

    )
};

Day.propTypes = {
    day: PropTypes.object.isRequired,
    type: PropTypes.string,
    includeExtraText: PropTypes.bool,
    firstSqueezedDay: PropTypes.bool
};

const ButtonSqueezedDay = (props) => {
    return (
        <Link to={props.day.formattedDate} offset={-document.documentElement.clientHeight / 2} smooth={true}
              duration={200}>
            <Day day={props.day} firstSqueezedDay={props.firstSqueezedDay} includeExtraText={false}
                 type={'inneklemt'}/>
        </Link>
    )
};

ButtonSqueezedDay.propTypes = {
    day: PropTypes.object.isRequired,
    firstSqueezedDay: PropTypes.bool
};

const CalendarDay = (props) => {
    return (
        <Element name={props.day.formattedDate}>
            <Day day={props.day} firstSqueezedDay={false} includeExtraText={true} type={props.type}/>
        </Element>
    )
};

CalendarDay.propTypes = {
    day: PropTypes.object.isRequired,
    type: PropTypes.string,
};

const SqueezedDays = (props) => (

{`Inneklemte dager (${_.filter(props.calendar, day => day.type === 'inneklemt').length})`}

            {
                /**
                 * Getting all squeezed days and adding a small space if there is some other type of days between two
                 * continuous chunks of squeezed days.
                 */
                _
                    .filter(props.calendar, day => day.type === 'inneklemt')
                    .map((day) => {
                        if (day.daysFromLast === 0) {
                            return <ButtonSqueezedDay key={day.formattedDate} day={day} firstSqueezedDay/>
                        } else {
                            return <ButtonSqueezedDay key={day.formattedDate} day={day}/>
                        }
                    })
            }

);

export default Calendar;
<commit_msg>Remove logging.<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import {Link, Element} from 'react-scroll';
import classes from './Calendar.css'
import YearButtons from "./YearButtons";
import SqueezeNumberButtons from "./SqueezeNumberButtons";
import ScrollStickyMenu from "./ScrollStickyMenu";

const Calendar = (props) => (

{`År ${props.year}`}

Regner {props.squeezeNumber} dager mellom fri som
                inneklemt

        <ScrollStickyMenu>
            <YearButtons
                style={{margin: '2px'}}
                switchYear={props.switchYear}
                year={props.year}
            />
            <SqueezeNumberButtons
                style={{margin: '2px'}}
                switchSqueezeNumber={props.switchSqueezeNumber}
                currentSqueezeNumber={props.squeezeNumber}
            />
        </ScrollStickyMenu>

        <SqueezedDays calendar={props.calendar}/>

            {_.map(props.calendar, (day) => {
                return (
                    <CalendarDay type={day.type} day={day} includeExtraText/>
                )
            })}

);

Calendar.propTypes = {
    calendar: PropTypes.object,
    year: PropTypes.number,
    squeezeNumber: PropTypes.number,
    switchYear: PropTypes.func,
    switchSqueezeNumber: PropTypes.func
};

const Day = (props) => {

    let backgroundColor;
    let color;
    let text;

    // Add appropriate styling and text to days
    switch (props.type) {
        case 'inneklemt':
            backgroundColor = '#71a74b';
            color = 'black';
            text = props.day.formattedDate + ' - INNEKLEMT!';
            break;
        case 'weekend':
            backgroundColor = 'rgb(197, 150, 237)';
            color = 'inherit';
            break;
        case 'holiday':
            backgroundColor = 'lightcoral';
            color = 'inherit';
            text = props.day.formattedDate + ' - ' + props.day.name;
            break;
        default:
            backgroundColor = 'lightblue';
            color = 'inherit';
    }

    const style = {
        backgroundColor: backgroundColor,
        color: color,
        marginTop: props.firstSqueezedDay ? '5px' : 0,
        padding: '5px 0',
        fontSize: '1.1em',
        listStyle: 'none'
    };
    return (

            {
                props.includeExtraText && text ? text : props.day.formattedDate
            }

    )
};

Day.propTypes = {
    day: PropTypes.object.isRequired,
    type: PropTypes.string,
    includeExtraText: PropTypes.bool,
    firstSqueezedDay: PropTypes.bool
};

const ButtonSqueezedDay = (props) => {
    return (
        <Link to={props.day.formattedDate} offset={-document.documentElement.clientHeight / 2} smooth={true}
              duration={200}>
            <Day day={props.day} firstSqueezedDay={props.firstSqueezedDay} includeExtraText={false}
                 type={'inneklemt'}/>
        </Link>
    )
};

ButtonSqueezedDay.propTypes = {
    day: PropTypes.object.isRequired,
    firstSqueezedDay: PropTypes.bool
};

const CalendarDay = (props) => {
    return (
        <Element name={props.day.formattedDate}>
            <Day day={props.day} firstSqueezedDay={false} includeExtraText={true} type={props.type}/>
        </Element>
    )
};

CalendarDay.propTypes = {
    day: PropTypes.object.isRequired,
    type: PropTypes.string,
};

const SqueezedDays = (props) => (

{`Inneklemte dager (${_.filter(props.calendar, day => day.type === 'inneklemt').length})`}

            {
                /**
                 * Getting all squeezed days and adding a small space if there is some other type of days between two
                 * continuous chunks of squeezed days.
                 */
                _
                    .filter(props.calendar, day => day.type === 'inneklemt')
                    .map((day) => {
                        if (day.daysFromLast === 0) {
                            return <ButtonSqueezedDay key={day.formattedDate} day={day} firstSqueezedDay/>
                        } else {
                            return <ButtonSqueezedDay key={day.formattedDate} day={day}/>
                        }
                    })
            }

);

export default Calendar;
<|endoftext|>


<commit_before>var typ = require("./representation.js");
var tool = require("./tools.js");

// Tokenization

var left_paren = /^\(/;
var right_paren = /^\)/;

var left_brace = /^\{/;
var right_brace = /^\}/;

var def = /^def/;

var left_square = /^\[/;
var right_square = /^\]/;
var comma = /^,/;

var truelit = /^true/;
var falselit = /^false/;

var stringlit = /^\"[^\"]*\"/;

var number = /^(\+|-)?\d+(\.\d+)?/;

var ifexp = /^if/;
var thenexp = /^then/;
var elsexp = /^else/;

var identifier = /^[^\s\.\(\)\{\}\[\]\""]+/;

var lambda = /^lambda/;

var arrow = /^->/;

function tokmatch(t) {
	var ttype;
	var m;
	if (m = t.match(left_paren))
		ttype = "left_paren";
	else if (m = t.match(right_paren))
		ttype = "right_paren";
	else if (m = t.match(left_brace))
		ttype = "left_brace";
	else if (m = t.match(right_brace))
		ttype = "right_brace";
	else if (m = t.match(left_square))
		ttype = "left_square";
	else if (m = t.match(right_square))
		ttype = "right_square";
	else if (m = t.match(def))
		ttype = "def";
	else if (m = t.match(lambda))
		ttype = "lambda";
	else if (m = t.match(arrow))
		ttype = "arrow";
	else if (m = t.match(comma))
		ttype = "comma";
	else if (m = t.match(truelit))
		ttype = "truelit";
	else if (m = t.match(falselit))
		ttype = "falselit";
	else if (m = t.match(stringlit))
		ttype = "stringlit";
	else if (m = t.match(number))
		if (m[0].indexOf(".") !== -1) {
			ttype = "float";
			return [[ttype, m[0]], m.input.slice(m[0].length)];
		}
		else {
			ttype = "integer";
			return [[ttype, m[0]], m.input.slice(m[0].length)];
		}
	else if (m = t.match(ifexp))
		ttype = "ifexp";
	else if (m = t.match(thenexp))
		ttype = "thenexp";
	else if (m = t.match(elsexp))
		ttype = "elsexp";
	else if (m = t.match(identifier))
		ttype = "identifier";
	else {
		console.log("Error: unmatched string: " + t);
		return;
	}
	return [[ttype, m[0]], m.input.slice(m[0].length)];
}

function tokenize(exp) {
	var current, next;
	var tokens = [];
	while (exp != '') {
		if (exp[0].match(/\s/)) {
			exp = exp.slice(1);
			// skip whitespace
		}
		else {
			current = tokmatch(exp);
			if (!current)
				break;
			exp = current[1];
			tokens.push(current[0]);
		}
	}
	return tokens;
}

function fst(ts) {
	return ts[ts.length-1];
}

function snd(ts) {
	return ts[ts.length-2];
}

//Checks if the next token is not followed by any of ``checks''
function notFollowedBy(tokens, checks) {
	var nextT = fst(tokens)[0];
	if (!snd(tokens))
		console.log("Error: "+ fst(tokens)[0] +" must be followed by something");
	else if (checks.some(function (x) {return x === nextT;}))
		return false;
	else
		return true;
}

//returns a function that takes a parameter and
//checks if it is in the array ``props''
function makeChecker(props) {
	return function(x) {
		return x && props.some(function (y) {return y === x;});
	};
}

/*Tries to parse until the prediction ``valid'' fails or the wrong type is parsed
  Collects the results into an array and returns it*/
function parseMany(exprType, valid, tokens) {
	var current = fst(tokens)[0];
	var results = [];
	var parsed;

	if (valid(fst(tokens)[0])) {
		parsed = parse(tokens);
		//console.log(parsed.exprType);
	}
	else {
		console.log("Error: unexpected token "+fst(tokens));
		return;
	}
	results.push(parsed);

	//make sure there are at least 2 tokens to parse
	if (tokens.length > 1 && valid(fst(tokens)[0])) {
		while (valid(snd(tokens)[0])) {
			results.push(parse(tokens));
			//console.log(results);
			if (!exprType(fst(results).exprType))
				break;
			//console.log(results);
			current = fst(tokens)[0]
			if (tokens.length <= 1)
				break;
		}
	}
	//do the same validity check as before and in the loop
	if (valid(fst(tokens)[0]))
		results.push(parse(tokens));
	return results;
}

function parseDef(tokens) {
	if (notFollowedBy(tokens, ["identifier"])) {
		console.log("Error: def must be followed by identifier, not "+fst(tokens)[0]);
		return undefined;
	}
	else {
		return new typ.Def(parse(tokens), parse(tokens));
	}
 }

function parseIf(tokens) {
	if (!notFollowedBy(tokens, ["def","comma","lambda"])) {
		console.log("Error: ``if'' cannot be followed by "+fst(tokens)[0])
		return;
	}
	else {
		var ifC = parse(tokens);
		if (!fst(tokens) || fst(tokens)[0] !== "thenexp")
			console.log("Error: if <exp> must be folowed by <then> exp, not "+snd(tokens)[0]);
		else {
			tokens.pop();
			var thenC = parse(tokens);

			if (fst(tokens) && fst(tokens)[0] === "elsexp") {
				tokens.pop();
				var elseC = parse(tokens);
				return new typ.If(ifC, thenC, elseC);

			}
			else {
				return new typ.If(ifC, thenC);
			}
		}
	}
}

var validFormPar = makeChecker(["identifier"]);
var validName = makeChecker(["Name"]);

function parseLambda(tokens) {
	var parameters = parseMany(validName,validFormPar, tokens);

	if (fst(tokens)[0] !== "arrow") {
		console.log("Error: arrow must follow parameters in lambda, not "+fst(tokens)[0])
		return;
	}
	tokens.pop()
	var body = parse(tokens);
	return new typ.FuncT(parameters, body);
}

var invalidArguments = ["def", "comma", "right_paren", "right_square", "right_brace", "left_brace", "right_brace"];
var validArgument = tool.compose(tool.not, makeChecker(invalidArguments));
var validArgTypes = tool.compose(tool.not, makeChecker(["Definition"]));
var validOperator = makeChecker(["identifier"]);

function parse(tokens) {
	if (fst(tokens))
		var toktype = fst(tokens)[0];
	else {
		console.log("Unexpected end of source")
		process.exit(code=1);
	}
	var token = fst(tokens)[1];
	tokens.pop();
	if (toktype === "stringlit")
		return new typ.StrT(token);
	else if (toktype === "lambda")
		return checkParse(parseLambda(tokens));
	else if (toktype === "integer")
		return new typ.IntT(token);
	else if (toktype === "float")
		return new typ.FloatT(token);
	else if (toktype === "identifier")
		return new typ.Name(token);
	else if (toktype === "truelit" || toktype === "falselit")
		return new typ.BoolT(token);
	else if (toktype === "def")
		return checkParse(parseDef(tokens));
	else if (toktype === "ifexp")
		return checkParse(parseIf(tokens));
	else if (toktype === "left_paren")
		return computeApp(tokens);
}

function checkParse(p) {
	if (p === undefined) {
		console.log("Quitting, could not finish parsing!");
		process.exit(code=1);
	}
	else
		return p;
}

//Parses function application (either infix or prefix)
function computeApp(tokens) {
	var lhs = parse(tokens);
	if (fst(tokens))
		var next = fst(tokens);
	else {
		console.log("Unexpected end of source");
		process.exit(code=1);
	}
	if (typ.OPInfo[next[1]]) {
		//it's an infix expression
		var result = parseInfix(tokens, 1, lhs);
		if (fst(tokens)[0] !== "right_paren") {
			console.log("Error: mismatched parentheses");
			process.exit(code=1);
		}
		else {
			//return the result
			return result;
		}
	}
	else {
		//it's a prefix application
		var parameters = parseMany(validArgTypes, validArgument, tokens);
		if (fst(tokens)[0] !== "right_paren") {
			console.log("Error: mismatched parentheses");
			process.exit(code=1);
		}
		else {
			//return the result
			return typ.makeApp(lhs, parameters);
		}
	}
}

/*Parses infix expressions by precedence climbing
  See this for more info and an implementation in python
  http://eli.thegreenplace.net/2012/08/02/parsing-expressions-by-precedence-climbing/
*/
function parseInfix(tokens, minPrec, lhs) {
	if (!lhs) {
		var lhs = parse(tokens);
	}
	while (true) {
		var cur = fst(tokens);
		if (!cur) {
			console.log("Unexpected end of source")
			process.exit(code=1);
		}
		var opinfo = typ.OPInfo[cur[1]];

		if (!opinfo || opinfo[0] < minPrec)
			break;

		var op = cur[1];
		var prec = opinfo[0];
		var assoc = opinfo[1];
		var nextMinPrec = assoc === "Left" ? prec + 1 : prec;
		tokens.pop();
		//remove the operator token
		var rhs = parseInfix(tokens, nextMinPrec);
		lhs = typ.makeApp(op, [lhs, rhs]);

	}
	return lhs;
}

var input = process.argv.slice(2).reduce(function(acc, x) {return acc + " " + x}, "");
var wat = tokenize(input).reverse();
//console.log(tool.pprint(parse(wat)));
console.log(parse(wat));
//console.log(wat);
//parse(wat);
<commit_msg>fixed bug where right parens were not getting popped after parsing applications, added a partial pprint function<commit_after>var typ = require("./representation.js");
var tool = require("./tools.js");

// Tokenization

var left_paren = /^\(/;
var right_paren = /^\)/;

var left_brace = /^\{/;
var right_brace = /^\}/;

var def = /^def/;

var left_square = /^\[/;
var right_square = /^\]/;
var comma = /^,/;

var truelit = /^true/;
var falselit = /^false/;

var stringlit = /^\"[^\"]*\"/;

var number = /^(\+|-)?\d+(\.\d+)?/;

var ifexp = /^if/;
var thenexp = /^then/;
var elsexp = /^else/;

var identifier = /^[^\s\.\(\)\{\}\[\]\""]+/;

var lambda = /^lambda/;

var arrow = /^->/;

function tokmatch(t) {
	var ttype;
	var m;
	if (m = t.match(left_paren))
		ttype = "left_paren";
	else if (m = t.match(right_paren))
		ttype = "right_paren";
	else if (m = t.match(left_brace))
		ttype = "left_brace";
	else if (m = t.match(right_brace))
		ttype = "right_brace";
	else if (m = t.match(left_square))
		ttype = "left_square";
	else if (m = t.match(right_square))
		ttype = "right_square";
	else if (m = t.match(def))
		ttype = "def";
	else if (m = t.match(lambda))
		ttype = "lambda";
	else if (m = t.match(arrow))
		ttype = "arrow";
	else if (m = t.match(comma))
		ttype = "comma";
	else if (m = t.match(truelit))
		ttype = "truelit";
	else if (m = t.match(falselit))
		ttype = "falselit";
	else if (m = t.match(stringlit))
		ttype = "stringlit";
	else if (m = t.match(number))
		if (m[0].indexOf(".") !== -1) {
			ttype = "float";
			return [[ttype, m[0]], m.input.slice(m[0].length)];
		}
		else {
			ttype = "integer";
			return [[ttype, m[0]], m.input.slice(m[0].length)];
		}
	else if (m = t.match(ifexp))
		ttype = "ifexp";
	else if (m = t.match(thenexp))
		ttype = "thenexp";
	else if (m = t.match(elsexp))
		ttype = "elsexp";
	else if (m = t.match(identifier))
		ttype = "identifier";
	else {
		console.log("Error: unmatched string: " + t);
		return;
	}
	return [[ttype, m[0]], m.input.slice(m[0].length)];
}

function tokenize(exp) {
	var current, next;
	var tokens = [];
	while (exp != '') {
		if (exp[0].match(/\s/)) {
			exp = exp.slice(1);
			// skip whitespace
		}
		else {
			current = tokmatch(exp);
			if (!current)
				break;
			exp = current[1];
			tokens.push(current[0]);
		}
	}
	return tokens;
}

function fst(ts) {
	return ts[ts.length-1];
}

function snd(ts) {
	return ts[ts.length-2];
}

//Checks if the next token is not followed by any of ``checks''
function notFollowedBy(tokens, checks) {
	var nextT = fst(tokens)[0];
	if (!snd(tokens))
		console.log("Error: "+ fst(tokens)[0] +" must be followed by something");
	else if (checks.some(function (x) {return x === nextT;}))
		return false;
	else
		return true;
}

//returns a function that takes a parameter and
//checks if it is in the array ``props''
function makeChecker(props) {
	return function(x) {
		return x && props.some(function (y) {return y === x;});
	};
}

/*Tries to parse until the prediction ``valid'' fails or the wrong type is parsed
  Collects the results into an array and returns it*/
function parseMany(exprType, valid, tokens) {
	var current = fst(tokens)[0];
	var results = [];
	var parsed;

	if (valid(fst(tokens)[0])) {
		parsed = parse(tokens);
		//console.log(parsed.exprType);
	}
	else {
		console.log("Error: unexpected token "+fst(tokens));
		return;
	}
	results.push(parsed);

	//make sure there are at least 2 tokens to parse
	if (tokens.length > 1 && valid(fst(tokens)[0])) {
		while (valid(snd(tokens)[0])) {
			results.push(parse(tokens));
			//console.log(results);
			if (!exprType(fst(results).exprType))
				break;
			//console.log(results);
			current = fst(tokens)[0]
			if (tokens.length <= 1)
				break;
		}
	}
	//do the same validity check as before and in the loop
	if (valid(fst(tokens)[0]))
		results.push(parse(tokens));
  //console.log(tokens);
	return results;
}

function parseDef(tokens) {
	if (notFollowedBy(tokens, ["identifier"])) {
		console.log("Error: def must be followed by identifier, not "+fst(tokens)[0]);
		return undefined;
	}
	else {
		return new typ.Def(parse(tokens), parse(tokens));
	}
 }

function parseIf(tokens) {
	if (!notFollowedBy(tokens, ["def","comma","lambda"])) {
		console.log("Error: ``if'' cannot be followed by "+fst(tokens)[0])
		return;
	}
	else {
		var ifC = parse(tokens);
		if (!fst(tokens) || fst(tokens)[0] !== "thenexp")
			console.log("Error: if <exp> must be folowed by <then> exp, not "+snd(tokens)[0]);
		else {
			tokens.pop();
			var thenC = parse(tokens);

			if (fst(tokens) && fst(tokens)[0] === "elsexp") {
				tokens.pop();
				var elseC = parse(tokens);
				return new typ.If(ifC, thenC, elseC);

			}
			else {
				return new typ.If(ifC, thenC);
			}
		}
	}
}

var validFormPar = makeChecker(["identifier"]);
var validName = makeChecker(["Name"]);

function parseLambda(tokens) {
	var parameters = parseMany(validName,validFormPar, tokens);

	if (fst(tokens)[0] !== "arrow") {
		console.log("Error: arrow must follow parameters in lambda, not "+fst(tokens)[0])
		return;
	}
	tokens.pop()
	var body = parse(tokens);
	return new typ.FuncT(parameters, body);
}

var invalidArguments = ["def", "comma", "right_paren", "right_square", "right_brace", "left_brace", "right_brace"];
var validArgument = tool.compose(tool.not, makeChecker(invalidArguments));
var validArgTypes = tool.compose(tool.not, makeChecker(["Definition"]));
var validOperator = makeChecker(["identifier"]);

function parse(tokens) {
	if (fst(tokens))
		var toktype = fst(tokens)[0];
	else {
		console.log("Unexpected end of source")
		process.exit(code=1);
	}
	var token = fst(tokens)[1];
	tokens.pop();
	if (toktype === "stringlit")
		return new typ.StrT(token);
	else if (toktype === "lambda")
		return checkParse(parseLambda(tokens));
	else if (toktype === "integer")
		return new typ.IntT(token);
	else if (toktype === "float")
		return new typ.FloatT(token);
	else if (toktype === "identifier")
		return new typ.Name(token);
	else if (toktype === "truelit" || toktype === "falselit")
		return new typ.BoolT(token);
	else if (toktype === "def")
		return checkParse(parseDef(tokens));
	else if (toktype === "ifexp")
		return checkParse(parseIf(tokens));
	else if (toktype === "left_paren")
		return computeApp(tokens);
  else {
    console.log("Unexpected token: " + toktype);
    process.exit(code=1);
  }
}

function checkParse(p) {
	if (p === undefined) {
		console.log("Quitting, could not finish parsing!");
		process.exit(code=1);
	}
	else
		return p;
}

//Parses function application (either infix or prefix)
function computeApp(tokens) {
  var lhs = parse(tokens);
  //console.log(lhs);
	if (fst(tokens))
		var next = fst(tokens);
	else {
		console.log("Unexpected end of source");
		process.exit(code=1);
	}
	if (typ.OPInfo[next[1]]) {
		//it's an infix expression
		var result = parseInfix(tokens, 1, lhs);
		if (fst(tokens)[0] !== "right_paren") {
			console.log("Error: mismatched parentheses");
			process.exit(code=1);
		}
		else {
			//return the result
      tokens.pop();
			return result;
		}
	}
	else {
		//it's a prefix application
		var parameters = parseMany(validArgTypes, validArgument, tokens);
    //console.log(parameters);
		if (fst(tokens)[0] !== "right_paren") {
			console.log("Error: mismatched parentheses");
			process.exit(code=1);
		}
		else {
			//return the result
      tokens.pop();
			return typ.makeApp(lhs, parameters);
		}
	}
}

/*Parses infix expressions by precedence climbing
  See this for more info and an implementation in python
  http://eli.thegreenplace.net/2012/08/02/parsing-expressions-by-precedence-climbing/
*/
function parseInfix(tokens, minPrec, lhs) {
	if (!lhs) {
		var lhs = parse(tokens);
	}
	while (true) {
		var cur = fst(tokens);
		if (!cur) {
			console.log("Unexpected end of source")
			process.exit(code=1);
		}
		var opinfo = typ.OPInfo[cur[1]];

		if (!opinfo || opinfo[0] < minPrec)
			break;

		var op = new typ.Name(cur[1]);
		var prec = opinfo[0];
		var assoc = opinfo[1];
		var nextMinPrec = assoc === "Left" ? prec + 1 : prec;
		tokens.pop();
		//remove the operator token
		var rhs = parseInfix(tokens, nextMinPrec);
		lhs = typ.makeApp(op, [lhs, rhs]);

	}
	return lhs;
}

function pprintName(ident) {
  return pprint(ident.val);
}

function pprintFunc(func) {
  return "lambda " + pprint(func.p) + " -> " + pprint(func.body);
}

function pprintApp(app) {
  if (!app.p || app.p === undefined)
    return "((" + pprint(app.func) + "))";
  return "((" + pprint(app.func) + ") " + pprint(app.p) + ")";
}

function pprint(expr) {
  if (expr.exprType === "Name")
    return expr.val;
  else if (expr.exprType === "Bool")
    return expr.val;
  else if (expr.exprType === "Integer")
    return expr.val;
  else if (expr.exprType === "Float")
    return expr.val;
  else if (expr.exprType === "String")
    return expr.val;
  else if (expr.exprType === "Name")
    return expr.val;
  else if (expr.exprType === "Application")
    return pprintApp(expr);
}

var input = process.argv.slice(2).reduce(function(acc, x) {return acc + " " + x}, "");
var tokenized = tokenize(input).reverse();

console.log(pprint(parse(tokenized)));
//console.log(tokenized);
<|endoftext|>


<commit_before>#!/usr/local/bin/node --es_staging
"use strict";

const fs    = require("fs");
const path  = require("path");

class VimSyntax{

	/**
	 * Begin a new keyword update.
	 *
	 * @param {Object} opts - Object holding filesystem paths
	 * @param {String} opts.atomSyntax - Local path to grammar file
	 * @param {String} opts.vimSyntax - Absolute path to Vim syntax
	 * @constructor
	 */
	constructor(opts = {}){
		const cwd     = process.cwd();
		let vimPath   = path.resolve(__dirname, opts.vimSyntax);
		let atomPath  = path.resolve(__dirname, opts.atomSyntax);

		let vimSyn    = fs.readFileSync(vimPath).toString();
		let atomSyn   = fs.readFileSync(atomPath).toString();
		let vimGroups = this.compile(vimSyn);
		atomSyn       = this.addMissingGroups(atomSyn, vimGroups);
		atomSyn       = this.updateLists(atomSyn, vimGroups);
		fs.writeFileSync(atomPath, atomSyn);
	}

	/**
	 * Assemble a dictionary of keyword-groups from Vim's source.
	 *
	 * @param {String} input - Contents of loaded syntax file
	 * @return {Object}
	 */
	compile(input){
		let match;
		let groups = {};
		const pattern = /^\s*syn\s+keyword\s+(\w+)\s+contained\s+([^\n]+)$/gm;
		const synOpts = /(?<=\s)(conceal|cchar|contained|containedin|nextgroup|transparent|skipwhite|skipnl|skipempty)(?:[\x20\t]*=(?:[^\s|\\]|\\.)*)?(?=\s|$|:|\\|)/g;
		while(match = pattern.exec(input)){
			let [, name, keywords] = match;
			if(undefined === groups[name])
				groups[name] = [];

			/** Strip :syntax options from each keyword line */
			keywords = keywords.replace(synOpts, "");
			groups[name].push(keywords);
		}

		/** Sanitise, filter, and parse each keyword list */
		for(let name in groups){
			groups[name] = Array.from(

				/* Filter duplicates */
				new Set(
					groups[name]
						.join(" ")
						.split(/\s+/g)
					).keys()

				/* Then sort and join with pipes */
				).sort(new Intl.Collator().compare)
				.join("\n")
				.trim()
				.replace(/\n(.+)\n\1\n/g, "\n$1\n")
				.replace(/\[(\w)\]/g, "$1?")
				.replace(/^(\w+)\[(\w+)\]$/gm, "$1\n$1$2")
				.replace(/\n+/g, "|");
		}
		return groups;
	}

	/**
	 * Append any missing groups to a block of grammar source.
	 *
	 * @param {String}  input - Loaded grammar source
	 * @param {Object} groups - Vim keyword-groups
	 * @return {String}
	 */
	addMissingGroups(input, groups){
		const table = /^((\t+)keywordLists\s*:\s*(?:#.*)?(?:\n\2\t+\S.*$|\n\s*$)*$\n\2\t+patterns\s*:\s*\[(?:\s*{)?\s*)((?:\n\2\t{2,}{[^}]+})+)(\n\2\t])/m;
		const tableMatch = input.match(table);

		if(tableMatch){
			let [match, start, tab, rows, end] = tableMatch;
			let {index} = tableMatch;
			let before  = input.substring(0, tableMatch.index);
			let after   = input.substring(tableMatch.index + match.length, input.length);

			let missing = Object.assign({}, groups);
			const row = /[{\s:,[]include\s*:\s*(?:(["'])#((?:(?!\1\\).|\\.)+)\1)\s*/g;
			while(match = row.exec(rows))
				delete missing[match[2]];

			for(let key of Object.keys(missing).sort()){
				rows += `\n${tab}\t\t{include: "#${key}"}`;

				/** Quote this key if we need to */
				let keySafe = !/^[$\w]+$/.test(key)
					? '"' + key.replace(/"/g, "\\\"") + '"'
					: key;

				if(new RegExp(`^${tab}${keySafe}\\s*:`, "gm").test(before + "\n\n" + after))
					console.warn(`Warning: Group "${key}" defined but not listed in #keywordLists`);

				else after += "\n\t" + keySafe + ":\n"
					+ tab + `\tname: "support.function.${key}.viml"\n`
					+ tab + `\tmatch: "\\\\b(_)\\\\b"\n`
			}

			input = before + start + rows + end + after;
		}

		else console.warn("Warning: `#keywordLists` not found in grammar! Returning input unmodified.");
		return input;
	}

	/**
	 * Update the actual capturing groups in the VimL grammar's expressions.
	 *
	 * @private
	 * @param {String}   atomSyn - Atom grammar source
	 * @param {Object} vimGroups - Sanitised dictionary of Vim keyword-groups
	 * @return {String}
	 */
	updateLists(atomSyn, vimGroups){
		for(const name in vimGroups){
			let list = "(^\\t(?:" + name + ")\\s*:\\s*(?:#.*$)?(?:\\n\\t{2}\\s*\\S+.*$|\\n\\s*$)*?\\n\\t{2}\\s*match\\s*:\\s*(['\"])(?:(?!\\2|[(\\\\]).|\\\\.)*)\\([^)]*\\)((?:(?!\\2|[(\\\\]).|\\\\.)*\\2)";
			atomSyn  = atomSyn.replace(
				new RegExp(list, "m"),
				(match, before, quote, after) => before + "(" + vimGroups[name] + ")" + after
			);
		}
		return atomSyn;
	}
}

/** Abort if the user hasn't specified a file */
const vimSyntax = process.argv[2];
if(!vimSyntax){
	const exe = path.join(path.basename(__dirname), path.basename(__filename));
	console.error(`Usage: ${exe} /path/to/vim.syntax`);
	process.exit(2);
}

new VimSyntax({atomSyntax: "../grammars/viml.cson", vimSyntax});
<commit_msg>Delete class definition in update script<commit_after>#!/usr/local/bin/node --es_staging
"use strict";

const fs    = require("fs");
const path  = require("path");

/**
 * Begin a new keyword update.
 *
 * @param {String} source - Path to downloaded VimScript file
 * @param {String} target - Path to Atom's grammar file
 */
function update(source, target){
	const cwd     = process.cwd();
	source        = path.resolve(__dirname, source);
	target        = path.resolve(__dirname, target);

	let vimSyn    = fs.readFileSync(source).toString();
	let atomSyn   = fs.readFileSync(target).toString();
	const prevSyn = atomSyn;

	let vimGroups = compile(vimSyn);
	atomSyn       = addMissingGroups(atomSyn, vimGroups);
	atomSyn       = updateLists(atomSyn, vimGroups);

	/** Nothing's changed */
	if(atomSyn === prevSyn){
		process.stderr.write("Already up-to-date.\n");
		return;
	}

	fs.writeFileSync(target, atomSyn);
}

/**
 * Assemble a dictionary of keyword-groups from Vim's source.
 *
 * @param {String} input - Contents of loaded syntax file
 * @return {Object}
 */
function compile(input){
	let match;
	let groups = {};
	const pattern = /^\s*syn\s+keyword\s+(\w+)\s+contained\s+([^\n]+)$/gm;
	const synOpts = /(?<=\s)(conceal|cchar|contained|containedin|nextgroup|transparent|skipwhite|skipnl|skipempty)(?:[\x20\t]*=(?:[^\s|\\]|\\.)*)?(?=\s|$|:|\\|)/g;
	while(match = pattern.exec(input)){
		let [, name, keywords] = match;
		if(undefined === groups[name])
			groups[name] = [];

		/** Strip :syntax options from each keyword line */
		keywords = keywords.replace(synOpts, "");
		groups[name].push(keywords);
	}

	/** Sanitise, filter, and parse each keyword list */
	for(let name in groups){
		groups[name] = Array.from(

			/* Filter duplicates */
			new Set(
				groups[name]
					.join(" ")
					.split(/\s+/g)
				).keys()

			/* Then sort and join with pipes */
			).sort(new Intl.Collator().compare)
			.join("\n")
			.trim()
			.replace(/\n(.+)\n\1\n/g, "\n$1\n")
			.replace(/\[(\w)\]/g, "$1?")
			.replace(/^(\w+)\[(\w+)\]$/gm, "$1\n$1$2")
			.replace(/\n+/g, "|");
	}
	return groups;
}

/**
 * Append any missing groups to a block of grammar source.
 *
 * @param {String}  input - Loaded grammar source
 * @param {Object} groups - Vim keyword-groups
 * @return {String}
 */
function addMissingGroups(input, groups){
	const table = /^((\t+)keywordLists\s*:\s*(?:#.*)?(?:\n\2\t+\S.*$|\n\s*$)*$\n\2\t+patterns\s*:\s*\[(?:\s*{)?\s*)((?:\n\2\t{2,}{[^}]+})+)(\n\2\t])/m;
	const tableMatch = input.match(table);

	if(tableMatch){
		let [match, start, tab, rows, end] = tableMatch;
		let {index} = tableMatch;
		let before  = input.substring(0, tableMatch.index);
		let after   = input.substring(tableMatch.index + match.length, input.length);

		let missing = Object.assign({}, groups);
		const row = /[{\s:,[]include\s*:\s*(?:(["'])#((?:(?!\1\\).|\\.)+)\1)\s*/g;
		while(match = row.exec(rows))
			delete missing[match[2]];

		for(let key of Object.keys(missing).sort()){
			rows += `\n${tab}\t\t{include: "#${key}"}`;

			/** Quote this key if we need to */
			let keySafe = !/^[$\w]+$/.test(key)
				? '"' + key.replace(/"/g, "\\\"") + '"'
				: key;

			if(new RegExp(`^${tab}${keySafe}\\s*:`, "gm").test(before + "\n\n" + after))
				console.warn(`Warning: Group "${key}" defined but not listed in #keywordLists`);

			else after += "\n\t" + keySafe + ":\n"
				+ tab + `\tname: "support.function.${key}.viml"\n`
				+ tab + `\tmatch: "\\\\b(_)\\\\b"\n`
		}

		input = before + start + rows + end + after;
	}

	else console.warn("Warning: `#keywordLists` not found in grammar! Returning input unmodified.");
	return input;
}

/**
 * Update the actual capturing groups in the VimL grammar's expressions.
 *
 * @private
 * @param {String}   atomSyn - Atom grammar source
 * @param {Object} vimGroups - Sanitised dictionary of Vim keyword-groups
 * @return {String}
 */
function updateLists(atomSyn, vimGroups){
	for(const name in vimGroups){
		let list = "(^\\t(?:" + name + ")\\s*:\\s*(?:#.*$)?(?:\\n\\t{2}\\s*\\S+.*$|\\n\\s*$)*?\\n\\t{2}\\s*match\\s*:\\s*(['\"])(?:(?!\\2|[(\\\\]).|\\\\.)*)\\([^)]*\\)((?:(?!\\2|[(\\\\]).|\\\\.)*\\2)";
		atomSyn  = atomSyn.replace(
			new RegExp(list, "m"),
			(match, before, quote, after) => before + "(" + vimGroups[name] + ")" + after
		);
	}
	return atomSyn;
}

/** Abort if the user hasn't specified a file */
const vimSyntax = process.argv[2];
if(!vimSyntax){
	const exe = path.join(path.basename(__dirname), path.basename(__filename));
	console.error(`Usage: ${exe} /path/to/vim.syntax`);
	process.exit(2);
}

update(vimSyntax, "../grammars/viml.cson");
<|endoftext|>


<commit_before>'use strict';

const request = require('request');
const cheerio = require('cheerio');
const moment = require('moment-timezone');

const menuUrl = "http://marketcreationscafe.com/lunch/cleveland-oh/"

module.exports.menu = (event, context, callback) => {

  request(menuUrl, function (error, response, html) {
    if (!error && response.statusCode == 200) {
      var data = getData(html);

      var message;
      var date = data.shift();
      if (isToday(date)) {
        message = data.join("\n");
      } else {
        message = "Hang tight, it looks like today's menu hasn't been posted yet.";
      }

      callback(null, createResponse(message, event, 200));
    } else {
      callback(null, createResponse("Whoops. I couldn't retrieve the menu.", event, 500));
    }
  });

  function getData(html) {
    var data = [];

    var $ = cheerio.load(html);
    $('article div p').each(function(i, element) {
      var item = $(this).text();
      if (item.trim()) {
        data.push(item);
      }
    });

    return data;
  }

  function isToday(date) {
    var today = moment().tz("America/New_York").format('MM/DD/YY');

    return (date === today);
  }

  function createResponse(message, event, code) {
    const response = {
          statusCode: code,
          body: JSON.stringify({
            message: message,
            input: event,
          }),
        };

    return response;
  }
};
<commit_msg>cleanup menu formatting<commit_after>'use strict';

const request = require('request');
const cheerio = require('cheerio');
const moment = require('moment-timezone');

const menuUrl = "http://marketcreationscafe.com/lunch/cleveland-oh/"

module.exports.menu = (event, context, callback) => {

  request(menuUrl, function (error, response, html) {
    if (!error && response.statusCode == 200) {
      var data = getData(html);

      var message;
      var date = data.shift();
      if (isToday(date)) {
        message = data.join("\n\n");
      } else {
        message = "Hang tight, it looks like today's menu hasn't been posted yet.";
      }

      callback(null, createResponse(message, event, 200));
    } else {
      callback(null, createResponse("Whoops. I couldn't retrieve the menu.", event, 500));
    }
  });

  function getData(html) {
    var data = [];

    var $ = cheerio.load(html, { normalizeWhitespace: true });
    $("div[id='content'] article div").children().each(function(i, element) {
      var item = $(this).text();
      if (item.trim()) {
        data.push(item);
      }
    });

    return data;
  }

  function isToday(date) {
    var today = moment().tz("America/New_York").format('MM/DD/YY');

    return (date === today);
  }

  function createResponse(message, event, code) {
    const response = {
          statusCode: code,
          body: JSON.stringify({
            message: message,
            input: event,
          }),
        };

    return response;
  }
};
<|endoftext|>


<commit_before>(function(root, factory) {
  'use strict';
  var gta;
  gta = factory();
  if (typeof module === 'object' && typeof module.exports === 'object') {
    return module.exports = gta;
  } else if (typeof define === 'function' && define.amd) {
    return define(['jquery'], function() {
      return gta;
    });
  } else {
    return root.Gta = gta;
  }
})((typeof window === 'object' ? window : this), function() {
  'use strict';
  var $body, Provider, Providers, account, checkScript, element, getScript, gta, name, provider, providers, removeElement, scriptUrl, slice, trackUrl;
  slice = Array.prototype.slice;
  $body = null;
  removeElement = function(el) {
    return el.parentNode.removeChild(el);
  };
  checkScript = function(script, key) {
    script.onerror = function() {
      window[key] = null;
      return removeElement(script);
    };
    return script.onload = function() {
      return removeElement(script);
    };
  };
  getScript = function(src) {
    var script, scripts;
    script = document.createElement('script');
    scripts = document.getElementsByTagName('script')[0];
    script.async = 1;
    script.src = src;
    scripts.parentNode.insertBefore(script, scripts);
    return script;
  };
  gta = {
    setUser: function(id, user) {
      var e, provider, _i, _len, _ref;
      try {
        for (_i = 0, _len = providers.length; _i < _len; _i++) {
          provider = providers[_i];
          if ((_ref = provider.setUser) != null) {
            _ref.call(provider, id, user);
          }
        }
      } catch (_error) {
        e = _error;
      }
      return this;
    },
    pageview: function() {
      var e, provider, _i, _len;
      try {
        for (_i = 0, _len = providers.length; _i < _len; _i++) {
          provider = providers[_i];
          provider.pageview.apply(provider, arguments);
        }
      } catch (_error) {
        e = _error;
      }
      return this;
    },
    event: function() {
      var e, provider, _i, _len;
      try {
        arguments[0] || (arguments[0] = ($body != null ? $body.data('category') : void 0) || 'gta');
        for (_i = 0, _len = providers.length; _i < _len; _i++) {
          provider = providers[_i];
          provider.event.apply(provider, arguments);
        }
      } catch (_error) {
        e = _error;
      }
      return this;
    },
    delegateEvents: function() {
      if (!window.$) {
        return;
      }
      $body = $('body');
      return $(document).off('.gta').on('click.gta', '[data-gta="event"]', (function(_this) {
        return function(e) {
          var $target, action, category, label, value;
          $target = $(e.currentTarget);
          category = $target.data('category');
          if (!category) {
            category = $target.closest('[data-category]').data('category');
          }
          action = $target.data('action') || e.type;
          label = $target.data('label');
          value = parseInt($target.data('value'));
          return _this.event(category, action, label, value);
        };
      })(this));
    }
  };
  Providers = {
    google: function(account) {
      var script;
      if (!account) {
        return;
      }
      window.GoogleAnalyticsObject = '_ga';
      window._ga = function() {
        return _ga.q.push(arguments);
      };
      _ga.q = [];
      _ga.l = 1 * new Date();
      _ga('create', account, 'auto');
      _ga('require', 'displayfeatures');
      _ga('require', 'linkid', 'linkid.js');
      _ga('send', 'pageview');
      script = getScript('//www.google-analytics.com/analytics.js');
      checkScript(script, '_ga');
      return {
        name: 'google',
        pageview: function() {
          var args, data;
          if (!window._ga) {
            return;
          }
          args = slice.call(arguments);
          data = typeof args[0] === 'object' ? args[0] : args.join('_');
          return window._ga('send', 'pageview', data);
        },
        event: function(category, action, label, value) {
          var args;
          if (!window._ga) {
            return;
          }
          args = ['send', 'event', category, action, label];
          if (value > 0) {
            args.push(+value);
          }
          return window._ga.apply(null, args);
        }
      };
    },
    baidu: function(account) {
      var script;
      if (!account) {
        return;
      }
      window._hmt = [];
      script = getScript("//hm.baidu.com/hm.js?" + account);
      checkScript(script, '_hmt');
      return {
        name: 'baidu',
        pageview: function() {
          var args, data, key, val, _ref;
          if (!window._hmt) {
            return;
          }
          args = slice.call(arguments);
          if (typeof args[0] === 'object') {
            data = args[0].page;
            if (!data) {
              data = [];
              _ref = args[0];
              for (key in _ref) {
                val = _ref[key];
                data.push(val);
              }
              data = data.join('_');
            }
          } else {
            data = args.join('_');
          }
          return window._hmt.push(['_trackPageview', data]);
        },
        event: function(category, action, label, value) {
          var args;
          if (!window._hmt) {
            return;
          }
          args = ['_trackEvent', category, action, label];
          if (value > 0) {
            args.push(+value);
          }
          return window._hmt.push(args);
        }
      };
    },
    piwik: function(account, scriptUrl, trackUrl) {
      var script;
      if (!(account && scriptUrl && trackUrl)) {
        return;
      }
      window._paq = [['trackPageView'], ['enableLinkTracking'], ['setTrackerUrl', trackUrl], ['setSiteId', account]];
      script = getScript(scriptUrl);
      checkScript(script, '_paq');
      return {
        name: 'piwik',
        setUser: function(id) {
          if (!window._paq) {
            return;
          }
          return window._paq.push(['setUserId', id]);
        },
        pageview: function() {
          var args, data, key, val, _ref;
          if (!window._paq) {
            return;
          }
          args = slice.call(arguments);
          if (typeof args[0] === 'object') {
            data = args[0].page;
            if (!data) {
              data = [];
              _ref = args[0];
              for (key in _ref) {
                val = _ref[key];
                data.push(val);
              }
              data = data.join('_');
            }
          } else {
            data = args.join('_');
          }
          return window._paq.push(['trackPageView', data]);
        },
        event: function(category, action, label, value) {
          var args;
          if (!window._paq) {
            return;
          }
          args = ['trackEvent', category, action, label];
          if (value > 0) {
            args.push(+value);
          }
          return window._paq.push(args);
        }
      };
    },
    segment: function(account) {
      var analytics, method, script, _i, _len, _ref;
      if (!account) {
        return;
      }
      analytics = window.analytics = window.analytics || [];
      analytics.invoked = true;
      analytics.methods = ['trackSubmit', 'trackClick', 'trackLink', 'trackForm', 'pageview', 'identify', 'reset', 'group', 'track', 'ready', 'alias', 'page', 'once', 'off', 'on'];
      analytics.factory = function(method) {
        return function() {
          var args;
          args = slice.call(arguments);
          args.unshift(method);
          analytics.push(args);
          return analytics;
        };
      };
      _ref = analytics.methods;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        method = _ref[_i];
        analytics[method] = analytics.factory(method);
      }
      analytics.SNIPPET_VERSION = '3.1.0';
      script = getScript("//cdn.segment.com/analytics.js/v1/" + account + "/analytics.min.js");
      checkScript(script, 'analytics');
      analytics.page();
      return {
        name: 'segment',
        setUser: function(id, user) {
          var _ref1;
          return (_ref1 = window.analytics) != null ? _ref1.identify(id, user) : void 0;
        },
        pageview: function(data) {
          var _ref1;
          return (_ref1 = window.analytics) != null ? _ref1.page(data.page, data.title) : void 0;
        },
        event: function(category, action, label, value) {
          var data, _ref1;
          data = {
            platform: 'web',
            category: category,
            action: action,
            label: label
          };
          if (value > 0) {
            data.value = value;
          }
          return (_ref1 = window.analytics) != null ? _ref1.track(label, data) : void 0;
        }
      };
    }
  };
  element = document.getElementById('gta-main');
  providers = gta.providers = [];
  if (!element) {
    return gta;
  }
  for (name in Providers) {
    Provider = Providers[name];
    account = element.getAttribute("data-" + name);
    scriptUrl = element.getAttribute("data-" + name + "-script");
    trackUrl = element.getAttribute("data-" + name + "-track");
    if (account && (provider = Provider(account, scriptUrl, trackUrl))) {
      providers.push(provider);
    }
  }
  gta.delegateEvents();
  removeElement(element);
  return gta;
});
<commit_msg>Update index.js<commit_after>;(function(root, factory) {
  'use strict';
  var gta;
  gta = factory();
  if (typeof module === 'object' && typeof module.exports === 'object') {
    return module.exports = gta;
  } else if (typeof define === 'function' && define.amd) {
    return define(['jquery'], function() {
      return gta;
    });
  } else {
    return root.Gta = gta;
  }
})((typeof window === 'object' ? window : this), function() {
  'use strict';
  var $body, Provider, Providers, account, checkScript, element, getScript, gta, name, provider, providers, removeElement, scriptUrl, slice, trackUrl;
  slice = Array.prototype.slice;
  $body = null;
  removeElement = function(el) {
    return el.parentNode.removeChild(el);
  };
  checkScript = function(script, key) {
    script.onerror = function() {
      window[key] = null;
      return removeElement(script);
    };
    return script.onload = function() {
      return removeElement(script);
    };
  };
  getScript = function(src) {
    var script, scripts;
    script = document.createElement('script');
    scripts = document.getElementsByTagName('script')[0];
    script.async = 1;
    script.src = src;
    scripts.parentNode.insertBefore(script, scripts);
    return script;
  };
  gta = {
    setUser: function(id, user) {
      var e, provider, _i, _len, _ref;
      try {
        for (_i = 0, _len = providers.length; _i < _len; _i++) {
          provider = providers[_i];
          if ((_ref = provider.setUser) != null) {
            _ref.call(provider, id, user);
          }
        }
      } catch (_error) {
        e = _error;
      }
      return this;
    },
    pageview: function() {
      var e, provider, _i, _len;
      try {
        for (_i = 0, _len = providers.length; _i < _len; _i++) {
          provider = providers[_i];
          provider.pageview.apply(provider, arguments);
        }
      } catch (_error) {
        e = _error;
      }
      return this;
    },
    event: function() {
      var e, provider, _i, _len;
      try {
        arguments[0] || (arguments[0] = ($body != null ? $body.data('category') : void 0) || 'gta');
        for (_i = 0, _len = providers.length; _i < _len; _i++) {
          provider = providers[_i];
          provider.event.apply(provider, arguments);
        }
      } catch (_error) {
        e = _error;
      }
      return this;
    },
    delegateEvents: function() {
      if (!window.$) {
        return;
      }
      $body = $('body');
      return $(document).off('.gta').on('click.gta', '[data-gta="event"]', (function(_this) {
        return function(e) {
          var $target, action, category, label, value;
          $target = $(e.currentTarget);
          category = $target.data('category');
          if (!category) {
            category = $target.closest('[data-category]').data('category');
          }
          action = $target.data('action') || e.type;
          label = $target.data('label');
          value = parseInt($target.data('value'));
          return _this.event(category, action, label, value);
        };
      })(this));
    }
  };
  Providers = {
    google: function(account) {
      var script;
      if (!account) {
        return;
      }
      window.GoogleAnalyticsObject = '_ga';
      window._ga = function() {
        return _ga.q.push(arguments);
      };
      _ga.q = [];
      _ga.l = 1 * new Date();
      _ga('create', account, 'auto');
      _ga('require', 'displayfeatures');
      _ga('require', 'linkid', 'linkid.js');
      _ga('send', 'pageview');
      script = getScript('//www.google-analytics.com/analytics.js');
      checkScript(script, '_ga');
      return {
        name: 'google',
        pageview: function() {
          var args, data;
          if (!window._ga) {
            return;
          }
          args = slice.call(arguments);
          data = typeof args[0] === 'object' ? args[0] : args.join('_');
          return window._ga('send', 'pageview', data);
        },
        event: function(category, action, label, value) {
          var args;
          if (!window._ga) {
            return;
          }
          args = ['send', 'event', category, action, label];
          if (value > 0) {
            args.push(+value);
          }
          return window._ga.apply(null, args);
        }
      };
    },
    baidu: function(account) {
      var script;
      if (!account) {
        return;
      }
      window._hmt = [];
      script = getScript("//hm.baidu.com/hm.js?" + account);
      checkScript(script, '_hmt');
      return {
        name: 'baidu',
        pageview: function() {
          var args, data, key, val, _ref;
          if (!window._hmt) {
            return;
          }
          args = slice.call(arguments);
          if (typeof args[0] === 'object') {
            data = args[0].page;
            if (!data) {
              data = [];
              _ref = args[0];
              for (key in _ref) {
                val = _ref[key];
                data.push(val);
              }
              data = data.join('_');
            }
          } else {
            data = args.join('_');
          }
          return window._hmt.push(['_trackPageview', data]);
        },
        event: function(category, action, label, value) {
          var args;
          if (!window._hmt) {
            return;
          }
          args = ['_trackEvent', category, action, label];
          if (value > 0) {
            args.push(+value);
          }
          return window._hmt.push(args);
        }
      };
    },
    piwik: function(account, scriptUrl, trackUrl) {
      var script;
      if (!(account && scriptUrl && trackUrl)) {
        return;
      }
      window._paq = [['trackPageView'], ['enableLinkTracking'], ['setTrackerUrl', trackUrl], ['setSiteId', account]];
      script = getScript(scriptUrl);
      checkScript(script, '_paq');
      return {
        name: 'piwik',
        setUser: function(id) {
          if (!window._paq) {
            return;
          }
          return window._paq.push(['setUserId', id]);
        },
        pageview: function() {
          var args, data, key, val, _ref;
          if (!window._paq) {
            return;
          }
          args = slice.call(arguments);
          if (typeof args[0] === 'object') {
            data = args[0].page;
            if (!data) {
              data = [];
              _ref = args[0];
              for (key in _ref) {
                val = _ref[key];
                data.push(val);
              }
              data = data.join('_');
            }
          } else {
            data = args.join('_');
          }
          return window._paq.push(['trackPageView', data]);
        },
        event: function(category, action, label, value) {
          var args;
          if (!window._paq) {
            return;
          }
          args = ['trackEvent', category, action, label];
          if (value > 0) {
            args.push(+value);
          }
          return window._paq.push(args);
        }
      };
    },
    segment: function(account) {
      var analytics, method, script, _i, _len, _ref;
      if (!account) {
        return;
      }
      analytics = window.analytics = window.analytics || [];
      analytics.invoked = true;
      analytics.methods = ['trackSubmit', 'trackClick', 'trackLink', 'trackForm', 'pageview', 'identify', 'reset', 'group', 'track', 'ready', 'alias', 'page', 'once', 'off', 'on'];
      analytics.factory = function(method) {
        return function() {
          var args;
          args = slice.call(arguments);
          args.unshift(method);
          analytics.push(args);
          return analytics;
        };
      };
      _ref = analytics.methods;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        method = _ref[_i];
        analytics[method] = analytics.factory(method);
      }
      analytics.SNIPPET_VERSION = '3.1.0';
      script = getScript("//cdn.segment.com/analytics.js/v1/" + account + "/analytics.min.js");
      checkScript(script, 'analytics');
      analytics.page();
      return {
        name: 'segment',
        setUser: function(id, user) {
          var _ref1;
          return (_ref1 = window.analytics) != null ? _ref1.identify(id, user) : void 0;
        },
        pageview: function(data) {
          var _ref1;
          return (_ref1 = window.analytics) != null ? _ref1.page(data.page, data.title) : void 0;
        },
        event: function(category, action, label, value) {
          var data, _ref1;
          data = {
            platform: 'web',
            category: category,
            action: action,
            label: label
          };
          if (value > 0) {
            data.value = value;
          }
          return (_ref1 = window.analytics) != null ? _ref1.track(label, data) : void 0;
        }
      };
    }
  };
  element = document.getElementById('gta-main');
  providers = gta.providers = [];
  if (!element) {
    return gta;
  }
  for (name in Providers) {
    Provider = Providers[name];
    account = element.getAttribute("data-" + name);
    scriptUrl = element.getAttribute("data-" + name + "-script");
    trackUrl = element.getAttribute("data-" + name + "-track");
    if (account && (provider = Provider(account, scriptUrl, trackUrl))) {
      providers.push(provider);
    }
  }
  gta.delegateEvents();
  removeElement(element);
  return gta;
});
<|endoftext|>