<commit_before>var ss = require('simple-statistics');

/**
* Takes a {@link FeatureCollection}, a property name, and a set of percentiles and returns a quantile array.
* @module turf/quantile
* @param {FeatureCollection} input a FeatureCollection of any type
* @param {String} field the property on which to retrieve quantile values
* @param {Array<number>} percentiles an Array of percentiles on which to calculate quantile values
* @return {Array<number>} an array of the break values
* @example
* var points = turf.featurecollection([
*   turf.point(5,5, {population: 5}),
*   turf.point(1,3, {population: 40}),
*   turf.point(14,2, {population: 80}),
*   turf.point(13,1, {population: 90}),
*   turf.point(19,7, {population: 100})
* ]);
*
* var breaks = turf.quantile(
*   points, 'population', [25, 50, 75, 99]);
*
* //=breaks
*/
module.exports = function(fc, field, percentiles){
  var vals = [];
  var quantiles = [];

  fc.features.forEach(function(feature){
    vals.push(feature.properties[field]);
  });
  percentiles.forEach(function(percentile){
    quantiles.push(ss.quantile(vals, percentile * 0.01));
  });
  return quantiles;
};
<commit_msg>Fix point form<commit_after>var ss = require('simple-statistics');

/**
* Takes a {@link FeatureCollection}, a property name, and a set of percentiles and returns a quantile array.
* @module turf/quantile
* @param {FeatureCollection} input a FeatureCollection of any type
* @param {String} field the property on which to retrieve quantile values
* @param {Array<number>} percentiles an Array of percentiles on which to calculate quantile values
* @return {Array<number>} an array of the break values
* @example
* var points = turf.featurecollection([
*   turf.point([5,5], {population: 5}),
*   turf.point([1,3], {population: 40}),
*   turf.point([14,2], {population: 80}),
*   turf.point([13,1], {population: 90}),
*   turf.point([19,7], {population: 100})
* ]);
*
* var breaks = turf.quantile(
*   points, 'population', [25, 50, 75, 99]);
*
* //=breaks
*/
module.exports = function(fc, field, percentiles){
  var vals = [];
  var quantiles = [];

  fc.features.forEach(function(feature){
    vals.push(feature.properties[field]);
  });
  percentiles.forEach(function(percentile){
    quantiles.push(ss.quantile(vals, percentile * 0.01));
  });
  return quantiles;
};
<|endoftext|>


<commit_before>angular.module('SmoothScrollbar', [])
    .constant('SCROLLBAR_VERSION', Scrollbar.version)
    .service('ScrollbarService', class ScrollbarService{
        static $inject = ['$q'];

        constructor($q) {
            this.scrollbarInstances = {};
            this.deferreds = {};
            this.$q = $q;
            this.id = 0;
        }

        /**
         * @method
         * Generate a scrollbar name with timestamp + id
         *
         * @return {String}
         */
        generateName() {
            this.id++;
            return Date.now().toString(32) + '$' + this.id;
        }

        /**
         * @method
         * Get scrollbar instance
         * If instance isn't existed,
         * callback wiil be invoked after instance is created
         *
         * @param {String} name: scrollbar name
         *
         * @return {Promise} resolved with scrollbar<Scrollbar>
         */
        getInstance(name) {
            const { scrollbarInstances, deferreds, $q } = this;

            if (scrollbarInstances.hasOwnProperty(name)) {
                return ($q.resolve || $q.when)(scrollbarInstances[name]);
            }

            let deferred = deferreds[name] = deferreds[name] || $q.defer();

            return deferred.promise;
        }

        /**
         * @method
         * Create scrollbar instance
         *
         * @param {String} name: scrollbar name
         * @param {Element} elem: container element
         * @param {Object} options: as is explained in scrollbar constructor
         *
         * @return {Scrollbar} scrollbar instance
         */
        createInstance(name, elem, options) {
            const { scrollbarInstances, deferreds } = this;

            if (scrollbarInstances.hasOwnProperty(name)) {
                return scrollbarInstances[name];
            }

            let instance = scrollbarInstances[name] = Scrollbar.init(elem, options);

            if (deferreds.hasOwnProperty(name)) {
                deferreds[name].resolve(instance);
            }

            return instance;
        }

        /**
         * @method
         * Destroy scrollbar instance
         *
         * @param {String} name: scrollbar name
         */
        destroyInstance(name) {
            let { scrollbarInstances, deferreds } = this;
            let instance = scrollbarInstances[name];

            if (instance) {
                instance.destroy();
                delete scrollbarInstances[name];
                delete deferreds[name];
            }
        }
    })
    .directive('scrollbar', ['ScrollbarService', (ScrollbarService) => {
        return {
            restrict: 'AE',
            transclude: true,
            scope: {
                speed: '@',
                fricton: '@'
            },
            link(scope, elem, attrs, ctrl, transclude) {
                const { speed, fricton } = scope;
                const name = attrs.scrollbar || attrs.name || ScrollbarService.generateName();

                const scrollbar = ScrollbarService.createInstance(name, elem[0], {
                    speed, fricton
                });

                let original = {
                    scrollTo: ::scrollbar.scrollTo,
                    addListener: ::scrollbar.addListener,
                    infiniteScroll: ::scrollbar.infiniteScroll
                };

                let applyChange = (cb) => {
                    if (typeof cb !== 'function') return;

                    return (...args) => {
                        cb(...args);
                        scope.$apply();
                    };
                };

                scrollbar.scrollTo = (x, y, duration, cb) => {
                    original.scrollTo(x, y, duration, applyChange(cb));
                };

                scrollbar.addListener = (cb) => {
                    if (typeof cb !== 'function') return;

                    original.addListener(applyChange(cb));
                };

                scrollbar.infiniteScroll = (cb, threshold) => {
                    if (typeof cb !== 'function') return;

                    original.infiniteScroll(applyChange(cb), threshold);
                };

                scope.$on('$destroy', () => {
                    ScrollbarService.destroyInstance(name);
                });

                const $scrollContent = angular.element(scrollbar.targets.content);

                transclude((clones) => {
                    $scrollContent.append(clones);
                }, $scrollContent);
            }
        };
    }]);<commit_msg>feat: add `ScrollbarServiceProvider`<commit_after>angular.module('SmoothScrollbar', [])
    .constant('SCROLLBAR_VERSION', Scrollbar.version)
    .provider('ScrollbarService', function ScrollbarServiceProvider() {
        const DEFAULT_OPTIONS = {
            speed: 1,
            fricton: 10
        };

        const scrollbarInstances = {};
        const deferreds = {};

        this.setDefaultOptions = (opt = {}) => {
            return Object.assign(DEFAULT_OPTIONS, opt);
        };

        let id = 0;

        this.$get = ['$q', function ($q) {
            class ScrollbarService{
                constructor() {
                    this.id = 0;
                }

                /**
                 * @method
                 * Generate a scrollbar name with timestamp + id
                 *
                 * @return {String}
                 */
                generateName() {
                    this.id++;
                    return Date.now().toString(32) + '$' + this.id;
                }

                /**
                 * @method
                 * Get scrollbar instance
                 * If instance isn't existed,
                 * callback wiil be invoked after instance is created
                 *
                 * @param {String} name: scrollbar name
                 *
                 * @return {Promise} resolved with scrollbar<Scrollbar>
                 */
                getInstance(name) {
                    let deferred = deferreds[name] = deferreds[name] || $q.defer();

                    if (scrollbarInstances.hasOwnProperty(name)) {
                        deferred.resolve(scrollbarInstances[name]);
                    }

                    return deferred.promise;
                }

                /**
                 * @method
                 * Create scrollbar instance
                 *
                 * @param {String} name: scrollbar name
                 * @param {Element} elem: container element
                 * @param {Object} options: as is explained in scrollbar constructor
                 *
                 * @return {Scrollbar} scrollbar instance
                 */
                createInstance(name, elem, options) {
                    if (scrollbarInstances.hasOwnProperty(name)) {
                        return scrollbarInstances[name];
                    }

                    Object.keys(DEFAULT_OPTIONS).forEach((prop) => {
                        if (options[prop] === undefined) {
                            options[prop] = DEFAULT_OPTIONS[prop];
                        }
                    });

                    let instance = scrollbarInstances[name] = Scrollbar.init(elem, options);

                    if (deferreds.hasOwnProperty(name)) {
                        deferreds[name].resolve(instance);
                    }

                    return instance;
                }

                /**
                 * @method
                 * Destroy scrollbar instance
                 *
                 * @param {String} name: scrollbar name
                 */
                destroyInstance(name) {
                    let instance = scrollbarInstances[name];

                    if (instance) {
                        instance.destroy();
                        delete scrollbarInstances[name];
                        delete deferreds[name];
                    }
                }
            }

            return new ScrollbarService();
        }]
    })
    .directive('scrollbar', ['ScrollbarService', (ScrollbarService) => {
        return {
            restrict: 'AE',
            transclude: true,
            scope: {
                speed: '@',
                fricton: '@'
            },
            link(scope, elem, attrs, ctrl, transclude) {
                const { speed, fricton } = scope;
                const name = attrs.scrollbar || attrs.name || ScrollbarService.generateName();

                const scrollbar = ScrollbarService.createInstance(name, elem[0], {
                    speed, fricton
                });

                let original = {
                    scrollTo: ::scrollbar.scrollTo,
                    addListener: ::scrollbar.addListener,
                    infiniteScroll: ::scrollbar.infiniteScroll
                };

                let applyChange = (cb) => {
                    if (typeof cb !== 'function') return;

                    return (...args) => {
                        cb(...args);
                        scope.$apply();
                    };
                };

                scrollbar.scrollTo = (x, y, duration, cb) => {
                    original.scrollTo(x, y, duration, applyChange(cb));
                };

                scrollbar.addListener = (cb) => {
                    if (typeof cb !== 'function') return;

                    original.addListener(applyChange(cb));
                };

                scrollbar.infiniteScroll = (cb, threshold) => {
                    if (typeof cb !== 'function') return;

                    original.infiniteScroll(applyChange(cb), threshold);
                };

                scope.$on('$destroy', () => {
                    ScrollbarService.destroyInstance(name);
                });

                const $scrollContent = angular.element(scrollbar.targets.content);

                transclude((clones) => {
                    $scrollContent.append(clones);
                }, $scrollContent);
            }
        };
    }]);<|endoftext|>


<commit_before>/**
 * @author Titus Wormer
 * @copyright 2016 Titus Wormer
 * @license MIT
 * @module nlcst:search
 * @fileoverview Search for patterns in an NLCST tree.
 */

'use strict';

/* eslint-env commonjs */

/*
 * Dependencies.
 */

var visit = require('unist-util-visit');
var normalize = require('nlcst-normalize');
var isLiteral = require('nlcst-is-literal');

/*
 * Methods.
 */

var has = Object.prototype.hasOwnProperty;

/*
 * Constants (characters).
 */

var C_SPACE = ' ';

/*
 * Constants (types).
 */

var T_WORD = 'WordNode';
var T_WHITE_SPACE = 'WhiteSpaceNode';

/**
 * Search.
 *
 * @param {Node} tree - NLCST node.
 * @param {Object|Array.<string>} phrases - Phrases to
 *   search for.  When `object`, searches for its keys.
 * @param {Function} handler - Handler.
 * @param {boolean} allowApostrophes - Do not strip
 *   apostrophes, normalize them.
 */
function search(tree, phrases, handler, allowApostrophes) {
    var apos = allowApostrophes;
    var byWord = {};
    var length;
    var index;
    var key;
    var firstWord;

    /**
     * Handle a phrase.
     *
     * @param {string} phrase - Phrase to search for.
     */
    function handlePhrase(phrase) {
        firstWord = normalize(phrase.split(C_SPACE, 1)[0], apos);

        if (has.call(byWord, firstWord)) {
            byWord[firstWord].push(phrase);
        } else {
            byWord[firstWord] = [phrase];
        }
    }

    if (!tree || !tree.type) {
        throw new Error('Expected node');
    }

    if (typeof phrases !== 'object') {
        throw new Error('Expected object for phrases');
    }

    length = phrases.length;
    index = -1;

    if ('length' in phrases) {
        while (++index < length) {
            handlePhrase(phrases[index]);
        }
    } else {
        for (key in phrases) {
            handlePhrase(key);
        }
    }

    /**
     * Test a phrase.
     *
     * @param {string} phrase - Phrase to search for.
     * @param {number} position - Position at which the
     *   first word of `phrase` exists.
     * @param {Node} parent - Parent of `node`.
     */
    function test(phrase, position, parent) {
        var siblings = parent.children;
        var node = siblings[position];
        var count = siblings.length;
        var queue = [node];
        var expression = phrase.split(C_SPACE).slice(1);
        var length = expression.length;
        var index = -1;

        /*
         * Move one position forward.
         */

        position++;

        /*
         * Iterate over `expression`.
         */

        while (++index < length) {
            /*
             * Allow joining white-space.
             */

            while (position < count) {
                node = siblings[position];

                if (node.type !== T_WHITE_SPACE) {
                    break;
                }

                queue.push(node);
                position++;
            }

            node = siblings[position];

            /*
             * Exit if there are no nodes left, if the
             * current node is not a word, or if the
             * current word does not match the search for
             * value.
             */

            if (
                !node ||
                node.type !== T_WORD ||
                normalize(expression[index], apos) !== normalize(node, apos)
            ) {
                return null;
            }

            queue.push(node);
            position++;
        }

        return queue;
    }

    /**
     * Visitor for `WordNode`s.
     *
     * @param {Node} node - Word.
     * @param {number} position - Position of `node` in
     *   `parent`.
     * @param {Node} parent - Parent of `node`.
     */
    function visitor(node, position, parent) {
        var word;
        var phrases;
        var length;
        var index;
        var result;

        if (isLiteral(parent, position)) {
            return;
        }

        word = normalize(node);
        phrases = has.call(byWord, word) ? byWord[word] : [];
        length = phrases.length;
        index = -1;

        while (++index < length) {
            result = test(phrases[index], position, parent);

            if (result) {
                handler(result, position, parent, phrases[index]);
            }
        }
    }

    /*
     * Search the tree.
     */

    visit(tree, T_WORD, visitor);
}

/*
 * Expose.
 */

module.exports = search;
<commit_msg>Fix bug where apotrophes were not normalised<commit_after>/**
 * @author Titus Wormer
 * @copyright 2016 Titus Wormer
 * @license MIT
 * @module nlcst:search
 * @fileoverview Search for patterns in an NLCST tree.
 */

'use strict';

/* eslint-env commonjs */

/*
 * Dependencies.
 */

var visit = require('unist-util-visit');
var normalize = require('nlcst-normalize');
var isLiteral = require('nlcst-is-literal');

/*
 * Methods.
 */

var has = Object.prototype.hasOwnProperty;

/*
 * Constants (characters).
 */

var C_SPACE = ' ';

/*
 * Constants (types).
 */

var T_WORD = 'WordNode';
var T_WHITE_SPACE = 'WhiteSpaceNode';

/**
 * Search.
 *
 * @param {Node} tree - NLCST node.
 * @param {Object|Array.<string>} phrases - Phrases to
 *   search for.  When `object`, searches for its keys.
 * @param {Function} handler - Handler.
 * @param {boolean} allowApostrophes - Do not strip
 *   apostrophes, normalize them.
 */
function search(tree, phrases, handler, allowApostrophes) {
    var apos = allowApostrophes;
    var byWord = {};
    var length;
    var index;
    var key;
    var firstWord;

    /**
     * Handle a phrase.
     *
     * @param {string} phrase - Phrase to search for.
     */
    function handlePhrase(phrase) {
        firstWord = normalize(phrase.split(C_SPACE, 1)[0], apos);

        if (has.call(byWord, firstWord)) {
            byWord[firstWord].push(phrase);
        } else {
            byWord[firstWord] = [phrase];
        }
    }

    if (!tree || !tree.type) {
        throw new Error('Expected node');
    }

    if (typeof phrases !== 'object') {
        throw new Error('Expected object for phrases');
    }

    length = phrases.length;
    index = -1;

    if ('length' in phrases) {
        while (++index < length) {
            handlePhrase(phrases[index]);
        }
    } else {
        for (key in phrases) {
            handlePhrase(key);
        }
    }

    /**
     * Test a phrase.
     *
     * @param {string} phrase - Phrase to search for.
     * @param {number} position - Position at which the
     *   first word of `phrase` exists.
     * @param {Node} parent - Parent of `node`.
     */
    function test(phrase, position, parent) {
        var siblings = parent.children;
        var node = siblings[position];
        var count = siblings.length;
        var queue = [node];
        var expression = phrase.split(C_SPACE).slice(1);
        var length = expression.length;
        var index = -1;

        /*
         * Move one position forward.
         */

        position++;

        /*
         * Iterate over `expression`.
         */

        while (++index < length) {
            /*
             * Allow joining white-space.
             */

            while (position < count) {
                node = siblings[position];

                if (node.type !== T_WHITE_SPACE) {
                    break;
                }

                queue.push(node);
                position++;
            }

            node = siblings[position];

            /*
             * Exit if there are no nodes left, if the
             * current node is not a word, or if the
             * current word does not match the search for
             * value.
             */

            if (
                !node ||
                node.type !== T_WORD ||
                normalize(expression[index], apos) !== normalize(node, apos)
            ) {
                return null;
            }

            queue.push(node);
            position++;
        }

        return queue;
    }

    /**
     * Visitor for `WordNode`s.
     *
     * @param {Node} node - Word.
     * @param {number} position - Position of `node` in
     *   `parent`.
     * @param {Node} parent - Parent of `node`.
     */
    function visitor(node, position, parent) {
        var word;
        var phrases;
        var length;
        var index;
        var result;

        if (isLiteral(parent, position)) {
            return;
        }

        word = normalize(node, apos);
        phrases = has.call(byWord, word) ? byWord[word] : [];
        length = phrases.length;
        index = -1;

        while (++index < length) {
            result = test(phrases[index], position, parent);

            if (result) {
                handler(result, position, parent, phrases[index]);
            }
        }
    }

    /*
     * Search the tree.
     */

    visit(tree, T_WORD, visitor);
}

/*
 * Expose.
 */

module.exports = search;
<|endoftext|>


<commit_before>const winston = require('winston');
const Telegraf = require('telegraf');
const commandParts = require('telegraf-command-parts');
const CronJob = require('cron').CronJob;
const secrets = require('./lib/secrets').load();
const {getUnreadMessages} = require('./lib/scraper');
const hashTracker = require('./lib/hashTracker');

let job;

const webmailLinkKeyboard = Telegraf.Extra
  .markdown()
  .markup((m) => m.inlineKeyboard([
    Telegraf.Markup.urlButton('Apri WebMail', 'https://webmail.studenti.unipi.it/horde/imp/')
  ]));

async function checkSecrets() {
  if (!secrets.telegram_token) {
    throw 'Non hai configurato il token del bot Telegram.';
  }
  if (!secrets.telegram_password) {
    throw 'Non hai configurato la password per il bot Telegram.';
  }
}

function formatNewMessage(message) {
  return 'Hai un nuovo messaggio! 📬\n\n' +
    `*Mittente*: ${message.from}\n` +
    `*Oggetto*: ${message.subject}\n` +
    `*Dimensione*: ${message.size}`
}

function setCronjob(bot, chatid) {
  async function doCronjob() {
    winston.info('Running cronjob for chat ID', chatid, '...');
    let unseen = (await getUnreadMessages(secrets));
    if (unseen.length > 0) {
      for (let i = 0; i < unseen.length; i++) {
        let msg = formatNewMessage(unseen[i]);
        let msgHash = hashTracker.md5(msg);
        if (!hashTracker.isSeen(msgHash)) {
          bot.telegram.sendMessage(chatid, msg, webmailLinkKeyboard);
          hashTracker.setSeen(msgHash);
        }
      }
    }
    winston.info('Done running cronjob for chat ID', chatid, '.');
  }

  // noinspection JSUnusedGlobalSymbols
  job = new CronJob({
    cronTime: '0 0 * * * *',
    onTick: doCronjob,
  });
  job.start();
}

checkSecrets()
  .then(() => {
    const bot = new Telegraf(secrets.telegram_token);

    bot.use(commandParts());

    bot.command('start', (ctx) => {
      let isPasswordOk = (ctx.state.command.args || '') === secrets.telegram_password;
      winston.info(ctx.chat.id, ctx.from.username, '/start', isPasswordOk ? 'PASS OK' : 'PASS KO');
      ctx.reply(isPasswordOk ? '👍✅ ⇒ 🔛' : '👎🚫');
      if (isPasswordOk) {
        setCronjob(bot, ctx.chat.id);
      }
    });

    bot.command('stop', (ctx) => {
      let isPasswordOk = (ctx.state.command.args || '') === secrets.telegram_password;
      winston.info(ctx.chat.id, ctx.from.username, '/stop', isPasswordOk ? 'PASS OK' : 'PASS KO');
      ctx.reply(isPasswordOk ? '👍✅ ⇒ 📴' : '👎🚫');
      if (isPasswordOk) {
        cleanup(false);
      }
    });

    bot.command('ping', (ctx) => {
      winston.info(ctx.chat.id, ctx.from.username, '/ping');
      ctx.reply('pong!');
    });

    bot.startPolling();
  })
  .catch((e) => {
    winston.error(e);
  });

// Cleanups & Promises handling

function cleanup(exit) {
  if (job && job.running) job.stop();
  if (exit) process.exit();
}

process.on('exit', () => {
  cleanup(true);
});
process.on('SIGINT', () => {
  cleanup(true);
});
process.on('SIGUSR1', () => {
  cleanup(true);
});
process.on('SIGUSR2', () => {
  cleanup(true);
});
process.on('uncaughtException', () => {
  cleanup(true);
});

process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
<commit_msg>Invocazione immediata del controllo email su start<commit_after>const winston = require('winston');
const Telegraf = require('telegraf');
const commandParts = require('telegraf-command-parts');
const CronJob = require('cron').CronJob;
const secrets = require('./lib/secrets').load();
const {getUnreadMessages} = require('./lib/scraper');
const hashTracker = require('./lib/hashTracker');

let job;

const webmailLinkKeyboard = Telegraf.Extra
  .markdown()
  .markup((m) => m.inlineKeyboard([
    Telegraf.Markup.urlButton('Apri WebMail', 'https://webmail.studenti.unipi.it/horde/imp/')
  ]));

async function checkSecrets() {
  if (!secrets.telegram_token) {
    throw 'Non hai configurato il token del bot Telegram.';
  }
  if (!secrets.telegram_password) {
    throw 'Non hai configurato la password per il bot Telegram.';
  }
}

function formatNewMessage(message) {
  return 'Hai un nuovo messaggio! 📬\n\n' +
    `*Mittente*: ${message.from}\n` +
    `*Oggetto*: ${message.subject}\n` +
    `*Dimensione*: ${message.size}`
}

async function setCronjob(bot, chatid) {
  async function doCronjob() {
    winston.info('Running cronjob for chat ID', chatid, '...');
    let unseen = (await getUnreadMessages(secrets));
    if (unseen.length > 0) {
      for (let i = 0; i < unseen.length; i++) {
        let msg = formatNewMessage(unseen[i]);
        let msgHash = hashTracker.md5(msg);
        if (!hashTracker.isSeen(msgHash)) {
          bot.telegram.sendMessage(chatid, msg, webmailLinkKeyboard);
          hashTracker.setSeen(msgHash);
        }
      }
    }
    winston.info('Done running cronjob for chat ID', chatid, '.');
  }

  // noinspection JSUnusedGlobalSymbols
  job = new CronJob({
    cronTime: '0 0 * * * *',
    onTick: await doCronjob,
  });
  job.start();
  await doCronjob();
}

checkSecrets()
  .then(() => {
    const bot = new Telegraf(secrets.telegram_token);

    bot.use(commandParts());

    bot.command('start', (ctx) => {
      let isPasswordOk = (ctx.state.command.args || '') === secrets.telegram_password;
      winston.info(ctx.chat.id, ctx.from.username, '/start', isPasswordOk ? 'PASS OK' : 'PASS KO');
      ctx.reply(isPasswordOk ? '👍✅ ⇒ 🔛' : '👎🚫');
      if (isPasswordOk) {
        setCronjob(bot, ctx.chat.id);
      }
    });

    bot.command('stop', (ctx) => {
      let isPasswordOk = (ctx.state.command.args || '') === secrets.telegram_password;
      winston.info(ctx.chat.id, ctx.from.username, '/stop', isPasswordOk ? 'PASS OK' : 'PASS KO');
      ctx.reply(isPasswordOk ? '👍✅ ⇒ 📴' : '👎🚫');
      if (isPasswordOk) {
        cleanup(false);
      }
    });

    bot.command('ping', (ctx) => {
      winston.info(ctx.chat.id, ctx.from.username, '/ping');
      ctx.reply('pong!');
    });

    bot.startPolling();
  })
  .catch((e) => {
    winston.error(e);
  });

// Cleanups & Promises handling

function cleanup(exit) {
  if (job && job.running) job.stop();
  if (exit) process.exit();
}

process.on('exit', () => {
  cleanup(true);
});
process.on('SIGINT', () => {
  cleanup(true);
});
process.on('SIGUSR1', () => {
  cleanup(true);
});
process.on('SIGUSR2', () => {
  cleanup(true);
});
process.on('uncaughtException', () => {
  cleanup(true);
});

process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
<|endoftext|>


<commit_before>'use strict';

const helpers = require('../../../../../../helpers');

/**
 * Upon saving url to draft, asks for a caption.
 */
const urlKey = helpers.topic.getPhotoPostDraftSubmissionValuesMap().url;

module.exports = function draftPhoto() {
  return async (req, res, next) => {
    try {
      if (!helpers.topic.isPhotoPostConfig(req.topic)) {
        return next();
      }

      if (helpers.request.hasDraftSubmissionValue(req, urlKey)) {
        return next();
      }

      if (req.mediaUrl) {
        await helpers.request.saveDraftSubmissionValue(req, urlKey, req.mediaUrl);

        if (helpers.topic.isVolunteerCredit(req.topic)) {
          return await helpers.replies.askHoursSpent(req, res);
        }

        if (await helpers.request.hasSignupWithWhyParticipated(req)) {
          return next();
        }

        return await helpers.replies.askWhyParticipated(req, res);
      }

      return await helpers.replies.invalidPhoto(req, res);
    } catch (err) {
      return helpers.sendErrorResponse(res, err);
    }
  };
};
<commit_msg>updates description on draft photo<commit_after>'use strict';

const helpers = require('../../../../../../helpers');

/**
 * Upon saving url to draft, asks for a why participated.
 */
const urlKey = helpers.topic.getPhotoPostDraftSubmissionValuesMap().url;

module.exports = function draftPhoto() {
  return async (req, res, next) => {
    try {
      if (!helpers.topic.isPhotoPostConfig(req.topic)) {
        return next();
      }

      if (helpers.request.hasDraftSubmissionValue(req, urlKey)) {
        return next();
      }

      if (req.mediaUrl) {
        await helpers.request.saveDraftSubmissionValue(
          req,
          urlKey,
          req.mediaUrl
        );

        if (helpers.topic.isVolunteerCredit(req.topic)) {
          return await helpers.replies.askHoursSpent(req, res);
        }

        if (await helpers.request.hasSignupWithWhyParticipated(req)) {
          return next();
        }

        return await helpers.replies.askWhyParticipated(req, res);
      }

      return await helpers.replies.invalidPhoto(req, res);
    } catch (err) {
      return helpers.sendErrorResponse(res, err);
    }
  };
};
<|endoftext|>


<commit_before>var msaUser = module.exports = Msa.module("user")

// deps
const md5 = require('md5')
const cookieParser = require('cookie-parser')
const session = require('express-session')

// params
Msa.params.user = {
	secret: "TODO"
}

// Msa app
msaUser.mdw = Msa.express.Router()
msaUser.mdw.use(cookieParser())
msaUser.mdw.use(session({ secret:Msa.params.user.secret, resave:false, saveUninitialized:false }))

// partials /////////////////////////////////////////////////////////////
msaUser.app.getAsPartial('/login', { wel: '/user/msa-user-login.html' })
msaUser.app.getAsPartial('/register', { wel: '/user/msa-user-register.html' })

// checkUser ///////////////////////////////////////////////////////

var checkUser = msaUser.checkUser = function(user, expr, next) {
	if(_checkUser(user, expr)) {
		return true
	} else {
		next && next(user ? 403 : 401) // Forbidden : Unauthorized
		return false
	}
}
var _checkUser = function(user, expr) {	return true // TMP	var type = typeof expr
	if(type==='function') return expr(user)
	if(type==='boolean') return expr
	if(type==='object') return _checkUserObj(user, expr)
	// nothing matched
	return false
}
var _checkUserObj = function(user, expr) {
	// TODO: arrange this code to make it mongo query compliant as most as possible
	if(!user) {
		// not logged
		if(expr===false) return true
	} else {
		//logged
		if(expr===true) return true
		// name
		var name = expr.name
		if(name) return user.name==name
		// group
		var group = expr.group, userGroups = user.groups
		if(group) return (userGroups && userGroups.indexOf(group)!=-1)
		// not
		var not = expr.not
		if(not) return (!_checkUserObj(user, not))
		// and
		var and = expr.and
		if(and) {
			for(var i=0, len=and.length; i<len; ++i)
				if(!_checkUserObj(user, and[i])) return false
			return true
		}
		// or
		var or = expr.or
		if(or) {
			for(var i=0, len=or.length; i<len; ++i)
				if(_checkUserObj(user, or[i])) return true
			return false
		}
	}
}

var checkUserMdw = msaUser.checkUserMdw = function(expr) {
  var mdw = Msa.express.Router()
  mdw.use(msaUser.mdw)
  mdw.use(function(req, res, next) {
		_checkUserMdw(req, expr, next)
	})
  return mdw
}
var checkAdminUserMdw = msaUser.checkAdminUserMdw = checkUserMdw({group:'admin'})
var _checkUserMdw = function(req, expr, next) {
	checkUser(req.session.user, expr, next) && next()
}

// entry ////////////////////////////////////////////////////////////////

var usersCol = Msa.require("db").collection("users")

// replies
var replyUser = function(req, res) { res.json(req.session.user || {}) }
var replyDone = function(req, res) { res.json({done:true}) }

// islog
msaUser.app.get('/islog', msaUser.mdw, replyUser)

// logout
var logout = msaUser.logout = function(req) {
	delete req.session.user
}
var logoutMdw = function(req, res, next){
	logout(req)
	next()
}
msaUser.app.post('/logout', msaUser.mdw, logoutMdw, replyUser)

// getPartial
msaUser.getPartial = Msa.express.Router()
msaUser.getPartial.use(msaUser.mdw)
msaUser.getPartial.use(function(req, res, next) {
	res.partial = { head:
""
	}
	next()
})

// login
var login = Msa.login = function(req, name, pass, next){
	usersCol.findOne({name:name}, function(err, dbUser) {
		if (err) return next(err)
		_login(req, name, pass, dbUser, next)
	})
}
var _login = function(req, name, pass, dbUser, next){
	if (!dbUser) return next('Incorrect username.')
	var epass = md5(pass)
	if (dbUser.epass!=epass) return next('Incorrect password.')
	var user = req.session.user = {}
	user.name = dbUser.name
	user.groups = dbUser.groups
	next()
}
var loginMdw = function(req, res, next) {
	var auth = req.headers.authorization, body = req.body
	if(auth){
		var namepass = auth.split(' ')[1].split(':')
		var name = namepass[0], pass = namepass[1]
	} else if(body) {
		var name = body.name, pass = body.pass
	} else return next(400) // Bad Request
	login(req, name, pass, next)
}
msaUser.app.post('/login', msaUser.mdw, loginMdw, replyUser)

// register
var register = msaUser.register = function(name, pass, arg1, arg2) {
	if(arg2===undefined) { var next=arg1 }
	else { var args=arg1, next=arg2 }
	// check if the user already exists
	usersCol.findOne(name, function(err, item) {
		if(err) return next(err)
		_register2(name, pass, args, item, next)
	})
}
var _register2 = function(name, pass, args, item, next) {
	if(item) return next("User id already exists.")
	// encrypt pass & transform a little bit the args
	var email = args && args.email
	var user = {
		name : name,
		email : email,
		epass : md5(pass),
		groups : []
	}
	// insert user in DB
	usersCol.insert(user, next)
}
var registerMdw = function(req, res, next) {
	var args = req.body
	register(args.name, args.pass, args, next)
}
msaUser.app.post('/register', msaUser.mdw, registerMdw, loginMdw, replyUser)

// addGroup
var addGroup = msaUser.addGroup = function(name, group, next) {
	usersCol.findOne({ name:name }, function(err, item) {
		if(err) return next(err)
		_addGroup2(name, group, item, next)
	})
}
var _addGroup2 = function(name, group, item, next) {
	if(!item) return next("User does not exist.")
	// add group, if it does not exist yet
	var group = group
	var groups = item.groups
	if(!(group in groups)) {
		groups.push(group)
		// update user in DB
		usersCol.update({name:name}, {$set: {groups:groups}}, next)
	}
}
var addGroupMdw = function(req, res, next) {
	var args = req.body
	addGroup(args.name, args.group, next)
}
msaUser.app.post('/addGroup', msaUser.mdw, checkAdminUserMdw, addGroupMdw, replyDone)

// first register

msaUser.app.getAsPartial('/firstregister', { wel: '/user/msa-user-first-register.html' })

var getOneAdminUser = function(next) {
	usersCol.findOne({groups: {"$in":["admin"]}}, next)
}
var checkNoAdminUserMdw = function(req, res, next) {
	getOneAdminUser(function(err, adminUser) {
		if(err) return next(err)
		if(adminUser) return next('There is already an admin user.')
		next()
	})
}
var addAdminGroupMdw = function(req, res, next) {
	var args = req.body
	addGroup(args.name, 'admin', next)
}
var firstRegisterMdw = function(req, res, next) {
	if(msaUser.onFirstRegister) msaUser.onFirstRegister(next)
	else next()
}
msaUser.app.post('/firstregister', msaUser.mdw, checkNoAdminUserMdw, registerMdw, addAdminGroupMdw, loginMdw, firstRegisterMdw, replyUser)

msaUser.isFirstRegisterDone = function(next) {
	getOneAdminUser(function(err, user) {
		if(err) return next(err)
		user ? next(null, true) : next(null, false)
	})
}

// sheet box /////////////////////////////////////////////////////////
/*
var sheetApp = Msa.require("msa-sheet")

sheetApp.registerTemplate("msa-user-login", { wel: compUrl+'/msa-user-login-box.html' }, {
	img: ""
})
*/
<commit_msg>migrate to sqlite<commit_after>var msaUser = module.exports = Msa.module("user")

// deps
const { promisify: prm } = require('util')
const md5 = require('md5')
const cookieParser = require('cookie-parser')
const session = require('express-session')

// params
Msa.params.user = {
	secret: "TODO"
}

// Msa app
msaUser.mdw = Msa.express.Router()
msaUser.mdw.use(cookieParser())
msaUser.mdw.use(session({ secret:Msa.params.user.secret, resave:false, saveUninitialized:false }))

// partials /////////////////////////////////////////////////////////////
msaUser.app.getAsPartial('/login', { wel: '/user/msa-user-login.html' })
msaUser.app.getAsPartial('/register', { wel: '/user/msa-user-register.html' })

// checkUser ///////////////////////////////////////////////////////

var checkUser = msaUser.checkUser = function(user, expr, next) {
	if(_checkUser(user, expr)) {
		return true
	} else {
		next && next(user ? 403 : 401) // Forbidden : Unauthorized
		return false
	}
}
var _checkUser = function(user, expr) {	return true // TMP	var type = typeof expr
	if(type==='function') return expr(user)
	if(type==='boolean') return expr
	if(type==='object') return _checkUserObj(user, expr)
	// nothing matched
	return false
}
var _checkUserObj = function(user, expr) {
	// TODO: arrange this code to make it mongo query compliant as most as possible
	if(!user) {
		// not logged
		if(expr===false) return true
	} else {
		//logged
		if(expr===true) return true
		// name
		var name = expr.name
		if(name) return user.name==name
		// group
		var group = expr.group, userGroups = user.groups
		if(group) return (userGroups && userGroups.indexOf(group)!=-1)
		// not
		var not = expr.not
		if(not) return (!_checkUserObj(user, not))
		// and
		var and = expr.and
		if(and) {
			for(var i=0, len=and.length; i<len; ++i)
				if(!_checkUserObj(user, and[i])) return false
			return true
		}
		// or
		var or = expr.or
		if(or) {
			for(var i=0, len=or.length; i<len; ++i)
				if(_checkUserObj(user, or[i])) return true
			return false
		}
	}
}

var checkUserMdw = msaUser.checkUserMdw = function(expr) {
  var mdw = Msa.express.Router()
  mdw.use(msaUser.mdw)
  mdw.use(function(req, res, next) {
		_checkUserMdw(req, expr, next)
	})
  return mdw
}
var checkAdminUserMdw = msaUser.checkAdminUserMdw = checkUserMdw({group:'admin'})
var _checkUserMdw = function(req, expr, next) {
	checkUser(req.session.user, expr, next) && next()
}

// DB //////////////////////////////////////////////////////

// DB model
const { orm, Orm } = Msa.require("db")
const UsersDb = orm.define('users', {
	name: { type: Orm.STRING, primaryKey: true },
	epass: Orm.STRING,
	email: Orm.STRING,
	groups: { type: Orm.TEXT,
		get() { const val = this.getDataValue('groups'); return val ? val.split(','): val },
		set(val) { if(val) val = val.join(','); this.setDataValue('groups', val) }
	}
})

// creqtqe table in DB
UsersDb.sync()

// entry ////////////////////////////////////////////////////////////////

// replies
var replyUser = function(req, res) { res.json(req.session.user || {}) }
var replyDone = function(req, res) { res.json({done:true}) }

// islog
msaUser.app.get('/islog', msaUser.mdw, replyUser)

// logout
var logout = msaUser.logout = function(req) {
	delete req.session.user
}
var logoutMdw = function(req, res, next){
	logout(req)
	next()
}
msaUser.app.post('/logout', msaUser.mdw, logoutMdw, replyUser)

// getPartial
msaUser.getPartial = Msa.express.Router()
msaUser.getPartial.use(msaUser.mdw)
msaUser.getPartial.use(function(req, res, next) {
	res.partial = { head:
""
	}
	next()
})

// login
var login = Msa.login = async function(req, name, pass, next){
	try {
		const dbUser = await UsersDb.findById(name)
		if (!dbUser) return next('Incorrect username.')
		var epass = md5(pass)
		if (dbUser.epass!=epass) return next('Incorrect password.')
		var user = req.session.user = {}
		user.name = dbUser.name
		user.groups = dbUser.groups
		next()
	} catch(err){ next(err) }
}
var loginMdw = function(req, res, next) {
	var auth = req.headers.authorization, body = req.body
	if(auth){
		var namepass = auth.split(' ')[1].split(':')
		var name = namepass[0], pass = namepass[1]
	} else if(body) {
		var name = body.name, pass = body.pass
	} else return next(400) // Bad Request
	login(req, name, pass, next)
}
msaUser.app.post('/login', msaUser.mdw, loginMdw, replyUser)

// register
var register = msaUser.register = async function(name, pass, arg1, arg2) {
	try {
		if(arg2===undefined) { var next=arg1 }
		else { var args=arg1, next=arg2 }
		// check if the user already exists
		const dbUser = await UsersDb.findById(name)
		if(dbUser) return next("User id already exists.")
		// encrypt pass & transform a little bit the args
		var email = args && args.email
		var user = {
			name : name,
			email : email,
			epass : md5(pass),
			groups : []
		}
		// insert user in DB
		await UsersDb.create(user)
		next()
	} catch(err){ next(err) }
}
var registerMdw = function(req, res, next) {
	var args = req.body
	register(args.name, args.pass, args, next)
}
msaUser.app.post('/register', msaUser.mdw, registerMdw, loginMdw, replyUser)

// addGroup
var addGroup = msaUser.addGroup = async function(name, group, next) {
	try {
		const dbUser = await UsersDb.findById(name)
		if(!dbUser) return next("User does not exist.")
		// add group, if it does not exist yet
		var group = group
		var groups = item.groups
		if(!(group in groups)) {
			groups.push(group)
			// update user in DB
			const nbRows = await UsersDb.update({ groups:groups }, { where:name })
			if(nbRows === 0) return next("Could not update user.")
		}
		next()
	} catch(err){ next(err) }
}
var addGroupMdw = function(req, res, next) {
	var args = req.body
	addGroup(args.name, args.group, next)
}
msaUser.app.post('/addGroup', msaUser.mdw, checkAdminUserMdw, addGroupMdw, replyDone)

// first register

msaUser.app.getAsPartial('/firstregister', { wel: '/user/msa-user-first-register.html' })

const getOneAdminUser = async function(next) {
	try {
		return await UsersDb.findAll({ where:{ groups:{ "like":"%admin%" }}})
			.filter(user => user.groups.indexOf("admin") > -1)
			[0]
	} catch(err){ next(err) }
}
const getOneAdminUserPrm = prm(getOneAdminUser)
const checkNoAdminUserMdw = async function(req, res, next) {
	try {
		const adminUser = await getOneAdminUserPrm()
		next(adminUser ? 'There is already an admin user.' : null)
	} catch(err){ next(err) }
}
const addAdminGroupMdw = function(req, res, next) {
	const args = req.body
	addGroup(args.name, 'admin', next)
}
const firstRegisterMdw = function(req, res, next) {
	if(msaUser.onFirstRegister) msaUser.onFirstRegister(next)
	else next()
}
msaUser.app.post('/firstregister', msaUser.mdw, checkNoAdminUserMdw, registerMdw, addAdminGroupMdw, loginMdw, firstRegisterMdw, replyUser)

msaUser.isFirstRegisterDone = async function(next) {
	try {
		const user = await getOneAdminUserPrm()
		user ? next(null, true) : next(null, false)
	} catch(err){ next(err) }
}

// sheet box /////////////////////////////////////////////////////////
/*
var sheetApp = Msa.require("msa-sheet")

sheetApp.registerTemplate("msa-user-login", { wel: compUrl+'/msa-user-login-box.html' }, {
	img: ""
})
*/
<|endoftext|>


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

/*  Hack an instance of Argv with process.argv into Argv
    so people can do
        require('optimist')(['--beeble=1','-z','zizzle']).argv
    to parse a list of args and
        require('optimist').argv
    to get a parsed version of process.argv.
*/

var inst = Argv(process.argv.slice(2));
Object.keys(inst).forEach(function (key) {
    Argv[key] = typeof inst[key] == 'function'
        ? inst[key].bind(inst)
        : inst[key];
});

var exports = module.exports = Argv;
function Argv (args, cwd) {
    var self = {};
    if (!cwd) cwd = process.cwd();

    self.$0 = process.argv
        .slice(0,2)
        .map(function (x) {
            var b = rebase(cwd, x);
            return x.match(/^\//) && b.length < x.length
                ? b : x
        })
        .join(' ')
    ;

    if (process.env._ != undefined && process.argv[1] == process.env._) {
        self.$0 = process.env._.replace(
            path.dirname(process.execPath) + '/', ''
        );
    }

    var flags = { bools : {}, strings : {} };

    self.boolean = function (bools) {
        if (!Array.isArray(bools)) {
            bools = [].slice.call(arguments);
        }

        bools.forEach(function (name) {
            flags.bools[name] = true;
        });

        return self;
    };

    self.string = function (strings) {
        if (!Array.isArray(strings)) {
            strings = [].slice.call(arguments);
        }

        strings.forEach(function (name) {
            flags.strings[name] = true;
        });

        return self;
    };

    var aliases = {};
    self.alias = function (x, y) {
        if (typeof x === 'object') {
            Object.keys(x).forEach(function (key) {
                self.alias(key, x[key]);
            });
        }
        else if (Array.isArray(y)) {
            y.forEach(function (yy) {
                self.alias(x, yy);
            });
        }
        else {
            var zs = (aliases[x] || []).concat(aliases[y] || []).concat(x, y);
            aliases[x] = zs.filter(function (z) { return z != x });
            aliases[y] = zs.filter(function (z) { return z != y });
        }

        return self;
    };

    var demanded = {};
    self.demand = function (keys) {
        if (typeof keys == 'number') {
            if (!demanded._) demanded._ = 0;
            demanded._ += keys;
        }
        else if (Array.isArray(keys)) {
            keys.forEach(function (key) {
                self.demand(key);
            });
        }
        else {
            demanded[keys] = true;
        }

        return self;
    };

    var usage;
    self.usage = function (msg, opts) {
        if (!opts && typeof msg === 'object') {
            opts = msg;
            msg = null;
        }

        usage = msg;

        if (opts) self.options(opts);

        return self;
    };

    function fail (msg) {
        self.showHelp();
        if (msg) console.error(msg);
        process.exit(1);
    }

    var checks = [];
    self.check = function (f) {
        checks.push(f);
        return self;
    };

    var defaults = {};
    self.default = function (key, value) {
        if (typeof key === 'object') {
            Object.keys(key).forEach(function (k) {
                self.default(k, key[k]);
            });
        }
        else {
            defaults[key] = value;
        }

        return self;
    };

    var descriptions = {};
    self.describe = function (key, desc) {
        if (typeof key === 'object') {
            Object.keys(key).forEach(function (k) {
                self.describe(k, key[k]);
            });
        }
        else {
            descriptions[key] = desc;
        }
        return self;
    };

    self.parse = function (args) {
        return Argv(args).argv;
    };

    self.option = self.options = function (key, opt) {
        if (typeof key === 'object') {
            Object.keys(key).forEach(function (k) {
                self.options(k, key[k]);
            });
        }
        else {
            if (opt.alias) self.alias(key, opt.alias);
            if (opt.demand) self.demand(key);
            if (typeof opt.default !== 'undefined') {
                self.default(key, opt.default);
            }

            if (opt.boolean || opt.type === 'boolean') {
                self.boolean(key);
            }
            if (opt.string || opt.type === 'string') {
                self.string(key);
            }

            var desc = opt.describe || opt.description || opt.desc;
            if (desc) {
                self.describe(key, desc);
            }
        }

        return self;
    };

    var wrap = null;
    self.wrap = function (cols) {
        wrap = cols;
        return self;
    };

    self.showHelp = function (fn) {
        if (!fn) fn = console.error;
        fn(self.help());
    };

    self.help = function () {
        var keys = Object.keys(
            Object.keys(descriptions)
            .concat(Object.keys(demanded))
            .concat(Object.keys(defaults))
            .reduce(function (acc, key) {
                if (key !== '_') acc[key] = true;
                return acc;
            }, {})
        );

        var help = keys.length ? [ 'Options:' ] : [];

        if (usage) {
            help.unshift(usage.replace(/\$0/g, self.$0), '');
        }

        var switches = keys.reduce(function (acc, key) {
            acc[key] = [ key ].concat(aliases[key] || [])
                .map(function (sw) {
                    return (sw.length > 1 ? '--' : '-') + sw
                })
                .join(', ')
            ;
            return acc;
        }, {});

        var switchlen = longest(Object.keys(switches).map(function (s) {
            return switches[s] || '';
        }));

        var desclen = longest(Object.keys(descriptions).map(function (d) {
            return descriptions[d] || '';
        }));

        keys.forEach(function (key) {
            var kswitch = switches[key];
            var desc = descriptions[key] || '';

            if (wrap) {
                desc = wordwrap(switchlen + 4, wrap)(desc)
                    .slice(switchlen + 4)
                ;
            }

            var spadding = new Array(
                Math.max(switchlen - kswitch.length + 3, 0)
            ).join(' ');

            var dpadding = new Array(
                Math.max(desclen - desc.length + 1, 0)
            ).join(' ');

            var type = null;

            if (flags.bools[key]) type = '[boolean]';
            if (flags.strings[key]) type = '[string]';

            if (!wrap && dpadding.length > 0) {
                desc += dpadding;
            }

            var prelude = '  ' + kswitch + spadding;
            var extra = [
                type,
                demanded[key]
                    ? '[required]'
                    : null
                ,
                defaults[key] !== undefined
                    ? '[default: ' + JSON.stringify(defaults[key]) + ']'
                    : null
                ,
            ].filter(Boolean).join('  ');

            var body = [ desc, extra ].filter(Boolean).join('  ');

            if (wrap) {
                var dlines = desc.split('\n');
                var dlen = dlines.slice(-1)[0].length
                    + (dlines.length === 1 ? prelude.length : 0)

                body = desc + (dlen + extra.length > wrap - 2
                    ? '\n'
                        + new Array(wrap - extra.length + 1).join(' ')
                        + extra
                    : new Array(wrap - extra.length - dlen + 1).join(' ')
                        + extra
                );
            }

            help.push(prelude + body);
        });

        help.push('');
        return help.join('\n');
    };

    Object.defineProperty(self, 'argv', {
        get : parseArgs,
        enumerable : true,
    });

    function parseArgs () {
        var argv = { _ : [], $0 : self.$0 };
        Object.keys(flags.bools).forEach(function (key) {
            setArg(key, defaults[key] || false);
        });

        function setArg (key, val) {
            var num = Number(val);
            var value = typeof val !== 'string' || isNaN(num) ? val : num;
            if (flags.strings[key]) value = val;

            setKey(argv, key.split('.'), value);

            (aliases[key] || []).forEach(function (x) {
                argv[x] = argv[key];
            });
        }

        for (var i = 0; i < args.length; i++) {
            var arg = args[i];

            if (arg === '--') {
                argv._.push.apply(argv._, args.slice(i + 1));
                break;
            }
            else if (arg.match(/^--.+=/)) {
                // Using [\s\S] instead of . because js doesn't support the
                // 'dotall' regex modifier. See:
                // http://stackoverflow.com/a/1068308/13216
                var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
                setArg(m[1], m[2]);
            }
            else if (arg.match(/^--no-.+/)) {
                var key = arg.match(/^--no-(.+)/)[1];
                setArg(key, false);
            }
            else if (arg.match(/^--.+/)) {
                var key = arg.match(/^--(.+)/)[1];
                var next = args[i + 1];
                if (next !== undefined && !next.match(/^-/)
                && !flags.bools[key]
                && (aliases[key] ? !flags.bools[aliases[key]] : true)) {
                    setArg(key, next);
                    i++;
                }
                else if (/^(true|false)$/.test(next)) {
                    setArg(key, next === 'true');
                    i++;
                }
                else {
                    setArg(key, true);
                }
            }
            else if (arg.match(/^-[^-]+/)) {
                var letters = arg.slice(1,-1).split('');

                var broken = false;
                for (var j = 0; j < letters.length; j++) {
                    if (letters[j+1] && letters[j+1].match(/\W/)) {
                        setArg(letters[j], arg.slice(j+2));
                        broken = true;
                        break;
                    }
                    else {
                        setArg(letters[j], true);
                    }
                }

                if (!broken) {
                    var key = arg.slice(-1)[0];

                    if (args[i+1] && !args[i+1].match(/^-/)
                    && !flags.bools[key]
                    && (aliases[key] ? !flags.bools[aliases[key]] : true)) {
                        setArg(key, args[i+1]);
                        i++;
                    }
                    else if (args[i+1] && /true|false/.test(args[i+1])) {
                        setArg(key, args[i+1] === 'true');
                        i++;
                    }
                    else {
                        setArg(key, true);
                    }
                }
            }
            else {
                var n = Number(arg);
                argv._.push(flags.strings['_'] || isNaN(n) ? arg : n);
            }
        }

        Object.keys(defaults).forEach(function (key) {
            if (!(key in argv)) {
                argv[key] = defaults[key];
                if (key in aliases) {
                    argv[aliases[key]] = defaults[key];
                }
            }
        });

        if (demanded._ && argv._.length < demanded._) {
            fail('Not enough non-option arguments: got '
                + argv._.length + ', need at least ' + demanded._
            );
        }

        var missing = [];
        Object.keys(demanded).forEach(function (key) {
            if (!argv[key]) missing.push(key);
        });

        if (missing.length) {
            fail('Missing required arguments: ' + missing.join(', '));
        }

        checks.forEach(function (f) {
            try {
                if (f(argv) === false) {
                    fail('Argument check failed: ' + f.toString());
                }
            }
            catch (err) {
                fail(err)
            }
        });

        return argv;
    }

    function longest (xs) {
        return Math.max.apply(
            null,
            xs.map(function (x) { return x.length })
        );
    }

    return self;
};

// rebase an absolute path to a relative one with respect to a base directory
// exported for tests
exports.rebase = rebase;
function rebase (base, dir) {
    var ds = path.normalize(dir).split('/').slice(1);
    var bs = path.normalize(base).split('/').slice(1);

    for (var i = 0; ds[i] && ds[i] == bs[i]; i++);
    ds.splice(0, i); bs.splice(0, i);

    var p = path.normalize(
        bs.map(function () { return '..' }).concat(ds).join('/')
    ).replace(/\/$/,'').replace(/^$/, '.');
    return p.match(/^[.\/]/) ? p : './' + p;
};

function setKey (obj, keys, value) {
    var o = obj;
    keys.slice(0,-1).forEach(function (key) {
        if (o[key] === undefined) o[key] = {};
        o = o[key];
    });

    var key = keys[keys.length - 1];
    if (o[key] === undefined || typeof o[key] === 'boolean') {
        o[key] = value;
    }
    else if (Array.isArray(o[key])) {
        o[key].push(value);
    }
    else {
        o[key] = [ o[key], value ];
    }
}
<commit_msg>-n123 test passes<commit_after>var path = require('path');
var wordwrap = require('wordwrap');

/*  Hack an instance of Argv with process.argv into Argv
    so people can do
        require('optimist')(['--beeble=1','-z','zizzle']).argv
    to parse a list of args and
        require('optimist').argv
    to get a parsed version of process.argv.
*/

var inst = Argv(process.argv.slice(2));
Object.keys(inst).forEach(function (key) {
    Argv[key] = typeof inst[key] == 'function'
        ? inst[key].bind(inst)
        : inst[key];
});

var exports = module.exports = Argv;
function Argv (args, cwd) {
    var self = {};
    if (!cwd) cwd = process.cwd();

    self.$0 = process.argv
        .slice(0,2)
        .map(function (x) {
            var b = rebase(cwd, x);
            return x.match(/^\//) && b.length < x.length
                ? b : x
        })
        .join(' ')
    ;

    if (process.env._ != undefined && process.argv[1] == process.env._) {
        self.$0 = process.env._.replace(
            path.dirname(process.execPath) + '/', ''
        );
    }

    var flags = { bools : {}, strings : {} };

    self.boolean = function (bools) {
        if (!Array.isArray(bools)) {
            bools = [].slice.call(arguments);
        }

        bools.forEach(function (name) {
            flags.bools[name] = true;
        });

        return self;
    };

    self.string = function (strings) {
        if (!Array.isArray(strings)) {
            strings = [].slice.call(arguments);
        }

        strings.forEach(function (name) {
            flags.strings[name] = true;
        });

        return self;
    };

    var aliases = {};
    self.alias = function (x, y) {
        if (typeof x === 'object') {
            Object.keys(x).forEach(function (key) {
                self.alias(key, x[key]);
            });
        }
        else if (Array.isArray(y)) {
            y.forEach(function (yy) {
                self.alias(x, yy);
            });
        }
        else {
            var zs = (aliases[x] || []).concat(aliases[y] || []).concat(x, y);
            aliases[x] = zs.filter(function (z) { return z != x });
            aliases[y] = zs.filter(function (z) { return z != y });
        }

        return self;
    };

    var demanded = {};
    self.demand = function (keys) {
        if (typeof keys == 'number') {
            if (!demanded._) demanded._ = 0;
            demanded._ += keys;
        }
        else if (Array.isArray(keys)) {
            keys.forEach(function (key) {
                self.demand(key);
            });
        }
        else {
            demanded[keys] = true;
        }

        return self;
    };

    var usage;
    self.usage = function (msg, opts) {
        if (!opts && typeof msg === 'object') {
            opts = msg;
            msg = null;
        }

        usage = msg;

        if (opts) self.options(opts);

        return self;
    };

    function fail (msg) {
        self.showHelp();
        if (msg) console.error(msg);
        process.exit(1);
    }

    var checks = [];
    self.check = function (f) {
        checks.push(f);
        return self;
    };

    var defaults = {};
    self.default = function (key, value) {
        if (typeof key === 'object') {
            Object.keys(key).forEach(function (k) {
                self.default(k, key[k]);
            });
        }
        else {
            defaults[key] = value;
        }

        return self;
    };

    var descriptions = {};
    self.describe = function (key, desc) {
        if (typeof key === 'object') {
            Object.keys(key).forEach(function (k) {
                self.describe(k, key[k]);
            });
        }
        else {
            descriptions[key] = desc;
        }
        return self;
    };

    self.parse = function (args) {
        return Argv(args).argv;
    };

    self.option = self.options = function (key, opt) {
        if (typeof key === 'object') {
            Object.keys(key).forEach(function (k) {
                self.options(k, key[k]);
            });
        }
        else {
            if (opt.alias) self.alias(key, opt.alias);
            if (opt.demand) self.demand(key);
            if (typeof opt.default !== 'undefined') {
                self.default(key, opt.default);
            }

            if (opt.boolean || opt.type === 'boolean') {
                self.boolean(key);
            }
            if (opt.string || opt.type === 'string') {
                self.string(key);
            }

            var desc = opt.describe || opt.description || opt.desc;
            if (desc) {
                self.describe(key, desc);
            }
        }

        return self;
    };

    var wrap = null;
    self.wrap = function (cols) {
        wrap = cols;
        return self;
    };

    self.showHelp = function (fn) {
        if (!fn) fn = console.error;
        fn(self.help());
    };

    self.help = function () {
        var keys = Object.keys(
            Object.keys(descriptions)
            .concat(Object.keys(demanded))
            .concat(Object.keys(defaults))
            .reduce(function (acc, key) {
                if (key !== '_') acc[key] = true;
                return acc;
            }, {})
        );

        var help = keys.length ? [ 'Options:' ] : [];

        if (usage) {
            help.unshift(usage.replace(/\$0/g, self.$0), '');
        }

        var switches = keys.reduce(function (acc, key) {
            acc[key] = [ key ].concat(aliases[key] || [])
                .map(function (sw) {
                    return (sw.length > 1 ? '--' : '-') + sw
                })
                .join(', ')
            ;
            return acc;
        }, {});

        var switchlen = longest(Object.keys(switches).map(function (s) {
            return switches[s] || '';
        }));

        var desclen = longest(Object.keys(descriptions).map(function (d) {
            return descriptions[d] || '';
        }));

        keys.forEach(function (key) {
            var kswitch = switches[key];
            var desc = descriptions[key] || '';

            if (wrap) {
                desc = wordwrap(switchlen + 4, wrap)(desc)
                    .slice(switchlen + 4)
                ;
            }

            var spadding = new Array(
                Math.max(switchlen - kswitch.length + 3, 0)
            ).join(' ');

            var dpadding = new Array(
                Math.max(desclen - desc.length + 1, 0)
            ).join(' ');

            var type = null;

            if (flags.bools[key]) type = '[boolean]';
            if (flags.strings[key]) type = '[string]';

            if (!wrap && dpadding.length > 0) {
                desc += dpadding;
            }

            var prelude = '  ' + kswitch + spadding;
            var extra = [
                type,
                demanded[key]
                    ? '[required]'
                    : null
                ,
                defaults[key] !== undefined
                    ? '[default: ' + JSON.stringify(defaults[key]) + ']'
                    : null
                ,
            ].filter(Boolean).join('  ');

            var body = [ desc, extra ].filter(Boolean).join('  ');

            if (wrap) {
                var dlines = desc.split('\n');
                var dlen = dlines.slice(-1)[0].length
                    + (dlines.length === 1 ? prelude.length : 0)

                body = desc + (dlen + extra.length > wrap - 2
                    ? '\n'
                        + new Array(wrap - extra.length + 1).join(' ')
                        + extra
                    : new Array(wrap - extra.length - dlen + 1).join(' ')
                        + extra
                );
            }

            help.push(prelude + body);
        });

        help.push('');
        return help.join('\n');
    };

    Object.defineProperty(self, 'argv', {
        get : parseArgs,
        enumerable : true,
    });

    function parseArgs () {
        var argv = { _ : [], $0 : self.$0 };
        Object.keys(flags.bools).forEach(function (key) {
            setArg(key, defaults[key] || false);
        });

        function setArg (key, val) {
            var num = Number(val);
            var value = typeof val !== 'string' || isNaN(num) ? val : num;
            if (flags.strings[key]) value = val;

            setKey(argv, key.split('.'), value);

            (aliases[key] || []).forEach(function (x) {
                argv[x] = argv[key];
            });
        }

        for (var i = 0; i < args.length; i++) {
            var arg = args[i];

            if (arg === '--') {
                argv._.push.apply(argv._, args.slice(i + 1));
                break;
            }
            else if (arg.match(/^--.+=/)) {
                // Using [\s\S] instead of . because js doesn't support the
                // 'dotall' regex modifier. See:
                // http://stackoverflow.com/a/1068308/13216
                var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
                setArg(m[1], m[2]);
            }
            else if (arg.match(/^--no-.+/)) {
                var key = arg.match(/^--no-(.+)/)[1];
                setArg(key, false);
            }
            else if (arg.match(/^--.+/)) {
                var key = arg.match(/^--(.+)/)[1];
                var next = args[i + 1];
                if (next !== undefined && !next.match(/^-/)
                && !flags.bools[key]
                && (aliases[key] ? !flags.bools[aliases[key]] : true)) {
                    setArg(key, next);
                    i++;
                }
                else if (/^(true|false)$/.test(next)) {
                    setArg(key, next === 'true');
                    i++;
                }
                else {
                    setArg(key, true);
                }
            }
            else if (arg.match(/^-[^-]+/)) {
                var letters = arg.slice(1,-1).split('');

                var broken = false;
                for (var j = 0; j < letters.length; j++) {
                    var next = arg.slice(j+2);
                    if (/[A-Za-z]/.test(letters[j])
                    && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
                        setArg(letters[j], next);
                        break;
                    }

                    if (letters[j+1] && letters[j+1].match(/\W/)) {
                        setArg(letters[j], arg.slice(j+2));
                        broken = true;
                        break;
                    }
                    else {
                        setArg(letters[j], true);
                    }
                }

                if (!broken) {
                    var key = arg.slice(-1)[0];

                    if (args[i+1] && !args[i+1].match(/^-/)
                    && !flags.bools[key]
                    && (aliases[key] ? !flags.bools[aliases[key]] : true)) {
                        setArg(key, args[i+1]);
                        i++;
                    }
                    else if (args[i+1] && /true|false/.test(args[i+1])) {
                        setArg(key, args[i+1] === 'true');
                        i++;
                    }
                    else {
                        setArg(key, true);
                    }
                }
            }
            else {
                var n = Number(arg);
                argv._.push(flags.strings['_'] || isNaN(n) ? arg : n);
            }
        }

        Object.keys(defaults).forEach(function (key) {
            if (!(key in argv)) {
                argv[key] = defaults[key];
                if (key in aliases) {
                    argv[aliases[key]] = defaults[key];
                }
            }
        });

        if (demanded._ && argv._.length < demanded._) {
            fail('Not enough non-option arguments: got '
                + argv._.length + ', need at least ' + demanded._
            );
        }

        var missing = [];
        Object.keys(demanded).forEach(function (key) {
            if (!argv[key]) missing.push(key);
        });

        if (missing.length) {
            fail('Missing required arguments: ' + missing.join(', '));
        }

        checks.forEach(function (f) {
            try {
                if (f(argv) === false) {
                    fail('Argument check failed: ' + f.toString());
                }
            }
            catch (err) {
                fail(err)
            }
        });

        return argv;
    }

    function longest (xs) {
        return Math.max.apply(
            null,
            xs.map(function (x) { return x.length })
        );
    }

    return self;
};

// rebase an absolute path to a relative one with respect to a base directory
// exported for tests
exports.rebase = rebase;
function rebase (base, dir) {
    var ds = path.normalize(dir).split('/').slice(1);
    var bs = path.normalize(base).split('/').slice(1);

    for (var i = 0; ds[i] && ds[i] == bs[i]; i++);
    ds.splice(0, i); bs.splice(0, i);

    var p = path.normalize(
        bs.map(function () { return '..' }).concat(ds).join('/')
    ).replace(/\/$/,'').replace(/^$/, '.');
    return p.match(/^[.\/]/) ? p : './' + p;
};

function setKey (obj, keys, value) {
    var o = obj;
    keys.slice(0,-1).forEach(function (key) {
        if (o[key] === undefined) o[key] = {};
        o = o[key];
    });

    var key = keys[keys.length - 1];
    if (o[key] === undefined || typeof o[key] === 'boolean') {
        o[key] = value;
    }
    else if (Array.isArray(o[key])) {
        o[key].push(value);
    }
    else {
        o[key] = [ o[key], value ];
    }
}
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var tape = require( 'tape' );
var floor = require( '@stdlib/math/base/special/floor' );
var daxpy = require( './../lib/daxpy.js' );

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.strictEqual( typeof daxpy, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function has an arity of 6', function test( t ) {
	t.strictEqual( daxpy.length, 6, 'arity of 6' );
	t.end();
});

tape( 'the function multiplies `x` by a constant and adds the result to `y`', function test( t ) {
	var expected;
	var alpha;
	var x;
	var y;

	alpha = 2.0;
	x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
	y = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0 ] );

	expected = new Float64Array( [ 3.0, 5.0, 7.0, 9.0, 11.0 ] );

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );

	// Short datasets:
	x = new Float64Array( [ 1.0, 2.0 ] );
	y = new Float64Array( [ 1.0, 1.0 ] );

	expected = new Float64Array( [ 3.0, 5.0 ] );

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );

	t.end();
});

tape( 'the function efficiently handles the case where `alpha` is `0`', function test( t ) {
	var expected;
	var alpha;
	var x;
	var y;

	x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
	y = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0 ] );
	alpha = 0.0;

	expected = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0 ] );

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function supports an `x` stride', function test( t ) {
	var expected;
	var x;
	var y;
	var N;

	x = new Float64Array([
		1.0, // 0
		2.0,
		3.0, // 1
		4.0,
		5.0  // 2
	]);
	y = new Float64Array([
		1.0, // 0
		1.0, // 1
		1.0, // 2
		1.0,
		1.0
	]);
	N = 3;

	daxpy( N, 2.0, x, 2, y, 1 );

	expected = new Float64Array( [ 3.0, 7.0, 11.0, 1.0, 1.0 ] );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function supports a `y` stride', function test( t ) {
	var expected;
	var x;
	var y;
	var N;

	x = new Float64Array([
		1.0, // 0
		2.0, // 1
		3.0, // 2
		4.0,
		5.0
	]);
	y = new Float64Array([
		1.0, // 0
		1.0,
		1.0, // 1
		1.0,
		1.0  // 2
	]);
	N = 3;

	daxpy( N, 2, x, 1, y, 2 );

	expected = new Float64Array( [ 3.0, 1.0, 5.0, 1.0, 7.0 ] );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function returns a reference to the destination array', function test( t ) {
	var x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
	var y = new Float64Array( [ 6.0, 7.0, 8.0, 9.0, 10.0 ] );

	var out = daxpy( x.length, 3.0, x, 1, y, 1 );

	t.strictEqual( out, y, 'same reference' );
	t.end();
});

tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged', function test( t ) {
	var expected;
	var x;
	var y;

	x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
	y = new Float64Array( [ 6.0, 7.0, 8.0, 9.0, 10.0 ] );

	expected = new Float64Array( [ 6.0, 7.0, 8.0, 9.0, 10.0 ] );

	daxpy( -1, 3.0, x, 1, y, 1 );
	t.deepEqual( y, expected, 'returns `y` unchanged' );

	daxpy( 0, 3.0, x, 1, y, 1 );
	t.deepEqual( y, expected, 'returns `y` unchanged' );

	t.end();
});

tape( 'the function supports negative strides', function test( t ) {
	var expected;
	var x;
	var y;
	var N;

	x = new Float64Array([
		1.0, // 2
		2.0,
		3.0, // 1
		4.0,
		5.0  // 0
	]);
	y = new Float64Array([
		6.0, // 2
		7.0, // 1
		8.0, // 0
		9.0,
		10.0
	]);
	N = 3;

	daxpy( N, 3.0, x, -2, y, -1 );

	expected = new Float64Array( [ 9.0, 16.0, 23.0, 9.0, 10.0 ] );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function supports complex access patterns', function test( t ) {
	var expected;
	var x;
	var y;
	var N;

	x = new Float64Array([
		1.0, // 0
		2.0,
		3.0, // 1
		4.0,
		5.0, // 2
		6.0
	]);
	y = new Float64Array([
		7.0,  // 2
		8.0,  // 1
		9.0,  // 0
		10.0,
		11.0,
		12.0
	]);
	N = 3;

	daxpy( N, 3.0, x, 2, y, -1 );

	expected = new Float64Array( [ 22.0, 17.0, 12.0, 10.0, 11.0, 12.0 ] );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function supports view offsets', function test( t ) {
	var expected;
	var x0;
	var y0;
	var x1;
	var y1;
	var N;

	// Initial arrays...
	x0 = new Float64Array([
		1.0,
		2.0, // 2
		3.0,
		4.0, // 1
		5.0,
		6.0  // 0
	]);
	y0 = new Float64Array([
		7.0,
		8.0,
		9.0,
		10.0, // 0
		11.0, // 1
		12.0  // 2
	]);

	// Create offset views...
	x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // begin at 2nd element
	y1 = new Float64Array( y0.buffer, y0.BYTES_PER_ELEMENT*3 ); // begin at the 4th element

	N = floor( x0.length / 2 );

	daxpy( N, 3.0, x1, -2, y1, 1 );
	expected = new Float64Array([
		7.0,
		8.0,
		9.0,
		28.0,
		23.0,
		18.0
	]);

	t.deepEqual( y0, expected, 'deep equal' );
	t.end();
});

tape( 'if both strides are equal to `1`, the function efficiently multiplies `x` by a constant and adds to `y`', function test( t ) {
	var expected;
	var alpha;
	var x;
	var y;
	var i;

	alpha = 3.0;

	x = new Float64Array( 100 );
	y = new Float64Array( x.length );
	expected = new Float64Array( x.length );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = i;
		y[ i ] = x.length - i;
		expected[ i ] = ( x[i]*alpha ) + y[i];
	}

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );

	x = new Float64Array( 123 );
	y = new Float64Array( x.length );
	expected = new Float64Array( x.length );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = i*2;
		y[ i ] = x.length - i;
		expected[ i ] = ( x[i]*alpha ) + y[i];
	}

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );

	t.end();
});
<commit_msg>Add decimal point<commit_after>'use strict';

// MODULES //

var tape = require( 'tape' );
var floor = require( '@stdlib/math/base/special/floor' );
var daxpy = require( './../lib/daxpy.js' );

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.strictEqual( typeof daxpy, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function has an arity of 6', function test( t ) {
	t.strictEqual( daxpy.length, 6, 'arity of 6' );
	t.end();
});

tape( 'the function multiplies `x` by a constant and adds the result to `y`', function test( t ) {
	var expected;
	var alpha;
	var x;
	var y;

	alpha = 2.0;
	x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
	y = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0 ] );

	expected = new Float64Array( [ 3.0, 5.0, 7.0, 9.0, 11.0 ] );

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );

	// Short datasets:
	x = new Float64Array( [ 1.0, 2.0 ] );
	y = new Float64Array( [ 1.0, 1.0 ] );

	expected = new Float64Array( [ 3.0, 5.0 ] );

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );

	t.end();
});

tape( 'the function efficiently handles the case where `alpha` is `0`', function test( t ) {
	var expected;
	var alpha;
	var x;
	var y;

	x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
	y = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0 ] );
	alpha = 0.0;

	expected = new Float64Array( [ 1.0, 1.0, 1.0, 1.0, 1.0 ] );

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function supports an `x` stride', function test( t ) {
	var expected;
	var x;
	var y;
	var N;

	x = new Float64Array([
		1.0, // 0
		2.0,
		3.0, // 1
		4.0,
		5.0  // 2
	]);
	y = new Float64Array([
		1.0, // 0
		1.0, // 1
		1.0, // 2
		1.0,
		1.0
	]);
	N = 3;

	daxpy( N, 2.0, x, 2, y, 1 );

	expected = new Float64Array( [ 3.0, 7.0, 11.0, 1.0, 1.0 ] );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function supports a `y` stride', function test( t ) {
	var expected;
	var x;
	var y;
	var N;

	x = new Float64Array([
		1.0, // 0
		2.0, // 1
		3.0, // 2
		4.0,
		5.0
	]);
	y = new Float64Array([
		1.0, // 0
		1.0,
		1.0, // 1
		1.0,
		1.0  // 2
	]);
	N = 3;

	daxpy( N, 2.0, x, 1, y, 2 );

	expected = new Float64Array( [ 3.0, 1.0, 5.0, 1.0, 7.0 ] );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function returns a reference to the destination array', function test( t ) {
	var x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
	var y = new Float64Array( [ 6.0, 7.0, 8.0, 9.0, 10.0 ] );

	var out = daxpy( x.length, 3.0, x, 1, y, 1 );

	t.strictEqual( out, y, 'same reference' );
	t.end();
});

tape( 'if provided an `N` parameter less than or equal to `0`, the function returns `y` unchanged', function test( t ) {
	var expected;
	var x;
	var y;

	x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
	y = new Float64Array( [ 6.0, 7.0, 8.0, 9.0, 10.0 ] );

	expected = new Float64Array( [ 6.0, 7.0, 8.0, 9.0, 10.0 ] );

	daxpy( -1, 3.0, x, 1, y, 1 );
	t.deepEqual( y, expected, 'returns `y` unchanged' );

	daxpy( 0, 3.0, x, 1, y, 1 );
	t.deepEqual( y, expected, 'returns `y` unchanged' );

	t.end();
});

tape( 'the function supports negative strides', function test( t ) {
	var expected;
	var x;
	var y;
	var N;

	x = new Float64Array([
		1.0, // 2
		2.0,
		3.0, // 1
		4.0,
		5.0  // 0
	]);
	y = new Float64Array([
		6.0, // 2
		7.0, // 1
		8.0, // 0
		9.0,
		10.0
	]);
	N = 3;

	daxpy( N, 3.0, x, -2, y, -1 );

	expected = new Float64Array( [ 9.0, 16.0, 23.0, 9.0, 10.0 ] );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function supports complex access patterns', function test( t ) {
	var expected;
	var x;
	var y;
	var N;

	x = new Float64Array([
		1.0, // 0
		2.0,
		3.0, // 1
		4.0,
		5.0, // 2
		6.0
	]);
	y = new Float64Array([
		7.0,  // 2
		8.0,  // 1
		9.0,  // 0
		10.0,
		11.0,
		12.0
	]);
	N = 3;

	daxpy( N, 3.0, x, 2, y, -1 );

	expected = new Float64Array( [ 22.0, 17.0, 12.0, 10.0, 11.0, 12.0 ] );

	t.deepEqual( y, expected, 'deep equal' );
	t.end();
});

tape( 'the function supports view offsets', function test( t ) {
	var expected;
	var x0;
	var y0;
	var x1;
	var y1;
	var N;

	// Initial arrays...
	x0 = new Float64Array([
		1.0,
		2.0, // 2
		3.0,
		4.0, // 1
		5.0,
		6.0  // 0
	]);
	y0 = new Float64Array([
		7.0,
		8.0,
		9.0,
		10.0, // 0
		11.0, // 1
		12.0  // 2
	]);

	// Create offset views...
	x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // begin at 2nd element
	y1 = new Float64Array( y0.buffer, y0.BYTES_PER_ELEMENT*3 ); // begin at the 4th element

	N = floor( x0.length / 2 );

	daxpy( N, 3.0, x1, -2, y1, 1 );
	expected = new Float64Array([
		7.0,
		8.0,
		9.0,
		28.0,
		23.0,
		18.0
	]);

	t.deepEqual( y0, expected, 'deep equal' );
	t.end();
});

tape( 'if both strides are equal to `1`, the function efficiently multiplies `x` by a constant and adds to `y`', function test( t ) {
	var expected;
	var alpha;
	var x;
	var y;
	var i;

	alpha = 3.0;

	x = new Float64Array( 100 );
	y = new Float64Array( x.length );
	expected = new Float64Array( x.length );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = i;
		y[ i ] = x.length - i;
		expected[ i ] = ( x[i]*alpha ) + y[i];
	}

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );

	x = new Float64Array( 123 );
	y = new Float64Array( x.length );
	expected = new Float64Array( x.length );
	for ( i = 0; i < x.length; i++ ) {
		x[ i ] = i*2;
		y[ i ] = x.length - i;
		expected[ i ] = ( x[i]*alpha ) + y[i];
	}

	daxpy( x.length, alpha, x, 1, y, 1 );

	t.deepEqual( y, expected, 'deep equal' );

	t.end();
});
<|endoftext|>


<commit_before>/* jshint esnext:true */
/* Copyright 2016 Paul Brewer, Economic & Financial Technology Consulting LLC */
/* module source code for PartialIndex */
/* Open Source License: The MIT License */

(function(){
    'use strict';

    function sort1(i1,d1){
	return function(a,b){
	    return d1*(+a[i1]-b[i1]);
	};
    }

    function sort2(i1,d1,i2,d2){
	return function(a,b){
	    var c1 = +a[i1]-b[i1];
	    if (0===c1) return d2*(+a[i2]-b[i2]);
	    return d1*c1;
	};
    }

    function sort3(i1,d1,i2,d2,i3,d3){
	var func2 = sort2(i2,d2,i3,d3);
	return function(a,b){
	    var c1 = +a[i1]-b[i1];
	    if (0===c1) return func2(a,b);
	    return d1*c1;
	};
    }

    function makeSorter(prop1,dir1,prop2,dir2,prop3,dir3){
	if (dir3){
	    return sort3(prop1,dir1,prop2,dir2,prop3,dir3);
	} else if (dir2) {
	    return sort2(prop1,dir1,prop2,dir2);
	} else if (dir1) {
	    return sort1(prop1,dir1);
	} else {
	    return sort1(prop1,1);
	}
    }

    function makeFilter(prop1,dir1,prop2,dir2,prop3,dir3){
	if (dir3){
	    return function(item){
		return (item && (item[prop3]>0) && (item[prop2]>0) && (item[prop1]>0));
	    };
	} else if (dir2){
	    return function(item){
		return (item && (item[prop2]>0) && (item[prop1]>0));
	    };
	} else
	    return function(item){
		return (item && (item[prop1]>0));
	    };
    }

    function idxByBisection(sorted,v,comp){
	var find = sorted.indexOf(v);
	var cmp;
	var left,right,mid,midval;
	if (find!==-1) return find;
	if (!comp){
	    if (v>sorted[sorted.length-1]) return sorted.length;
	    if (v<sorted[0]) return 0;
	    left = 0;
	    right = sorted.length-1;
	    while( (right-left)>1 ){
		mid = Math.floor((left+right)/2);
		midval = sorted[mid];
		if (v>midval)
		    left = mid;
		else if (v<midval)
		    right = mid;
		else if (v===midval){
		    left = mid;
		    right = mid;
		}
	    }
	    return right;
	} else {
	    if (comp(v,sorted[sorted.length-1])>0) return sorted.length;
	    if (comp(v,sorted[0])<0) return 0;
	    left = 0;
	    right = sorted.length-1;
	    while( (right-left)>1 ){
		mid = Math.floor((left+right)/2);
		midval = sorted[mid];
		cmp = comp(v,midval);
		if (cmp>0)
		    left = mid;
		else if (cmp<0)
		    right = mid;
		else if (0===cmp){
		    left = mid;
		    right = mid;
		}
	    }
	    return right;
	}
    }

    var PartialIndex =
	function(data, limit, prop1, dir1, prop2, dir2, prop3, dir3){
	this.data = data;
	this.limit = limit;
	this.idx = [];
	this.datafilter = makeFilter(prop1,dir1,prop2,dir2,prop3,dir3);
	this.datacomp = makeSorter(prop1,dir1,prop2,dir2,prop3,dir3);
	var that = this;
	this.idxcomp = function(a,b){ var d=that.data; return that.datacomp(d[a],d[b]); };
	this.idxfilter = function(i){ return that.datafilter(that.data[i]); };
	if (this.data.length) this.needScan = 1;
    };

    PartialIndex.prototype.scan = function(){
	var i,l;
	this.idx = [];
	var idx = this.idx, limit=this.limit, datalength=this.data.length, data=this.data, f=this.datafilter;
	var idxcomp = this.idxcomp;
	var loc;
	this.needScan = 0;
	if (0===limit) return;
	i=0;
	while((i<datalength) && (idx.length<limit)){
	    if (f(data[i]))
		idx.push(i);
	    ++i;
	}
	idx.sort(this.idxcomp);
	if (datalength<=limit) return;
	while(i<datalength){
	    if (f(data[i])){
		loc = idxByBisection(idx,i,idxcomp);
		idx.splice(loc,0,i);
		idx.splice(limit,1);
	    }
	    ++i;
	}
    };

    PartialIndex.prototype.syncLast = function(){
	var lastdataidx = this.data.length-1;
	var loc;
	var idx = this.idx;
	var limit = this.limit;
	if (!limit) return;
	if (this.idxfilter(lastdataidx)){
	    if (this.needScan) return this.scan();
	    if (idx.length<limit){
		idx.push(lastdataidx);
		idx.sort(this.idxcomp);
	    } else {
		loc = idxByBisection(idx,lastdataidx,this.idxcomp);
		if (loc<limit){
		    idx.splice(loc,0,lastdataidx);
		    idx.splice(limit,1);
		}
	    }
	}
    };

    PartialIndex.prototype.remove = function(rmidxs){
	var i=rmidxs.length,l;
	var idx = this.idx;
	var loc;
	var removed=0;
	if (0===rmidxs.length) return;
	while(i-->1){
	    if (rmidxs[i-1]<=rmidxs[i])
		throw "PartialIndex.remove called with unsorted list of indexes. List of indexes to be removed must be ascending.";
	}
	i = rmidxs.length;
	while(i-->0){
	    loc = idx.indexOf(rmidxs[i]);
	    if (loc>=0){
		idx.splice(loc,1);
		++removed;
	    }
	}
	if (removed) this.needScan=1;
	for(i=0,l=idx.length;i<l;++i)
	    idx[i] -= idxByBisection(rmidxs, idx[i]);
    };

    module.exports = PartialIndex;

})();

<commit_msg>fix order in filter function<commit_after>/* jshint esnext:true */
/* Copyright 2016 Paul Brewer, Economic & Financial Technology Consulting LLC */
/* module source code for PartialIndex */
/* Open Source License: The MIT License */

(function(){
    'use strict';

    function sort1(i1,d1){
	return function(a,b){
	    return d1*(+a[i1]-b[i1]);
	};
    }

    function sort2(i1,d1,i2,d2){
	return function(a,b){
	    var c1 = +a[i1]-b[i1];
	    if (0===c1) return d2*(+a[i2]-b[i2]);
	    return d1*c1;
	};
    }

    function sort3(i1,d1,i2,d2,i3,d3){
	var func2 = sort2(i2,d2,i3,d3);
	return function(a,b){
	    var c1 = +a[i1]-b[i1];
	    if (0===c1) return func2(a,b);
	    return d1*c1;
	};
    }

    function makeSorter(prop1,dir1,prop2,dir2,prop3,dir3){
	if (dir3){
	    return sort3(prop1,dir1,prop2,dir2,prop3,dir3);
	} else if (dir2) {
	    return sort2(prop1,dir1,prop2,dir2);
	} else if (dir1) {
	    return sort1(prop1,dir1);
	} else {
	    return sort1(prop1,1);
	}
    }

    function makeFilter(prop1,dir1,prop2,dir2,prop3,dir3){
	if (dir3){
	    return function(item){
		return (item && (item[prop1]>0) && (item[prop2]>0) && (item[prop3]>0));
	    };
	} else if (dir2){
	    return function(item){
		return (item && (item[prop1]>0) && (item[prop2]>0));
	    };
	} else
	    return function(item){
		return (item && (item[prop1]>0));
	    };
    }

    function idxByBisection(sorted,v,comp){
	var find = sorted.indexOf(v);
	var cmp;
	var left,right,mid,midval;
	if (find!==-1) return find;
	if (!comp){
	    if (v>sorted[sorted.length-1]) return sorted.length;
	    if (v<sorted[0]) return 0;
	    left = 0;
	    right = sorted.length-1;
	    while( (right-left)>1 ){
		mid = Math.floor((left+right)/2);
		midval = sorted[mid];
		if (v>midval)
		    left = mid;
		else if (v<midval)
		    right = mid;
		else if (v===midval){
		    left = mid;
		    right = mid;
		}
	    }
	    return right;
	} else {
	    if (comp(v,sorted[sorted.length-1])>0) return sorted.length;
	    if (comp(v,sorted[0])<0) return 0;
	    left = 0;
	    right = sorted.length-1;
	    while( (right-left)>1 ){
		mid = Math.floor((left+right)/2);
		midval = sorted[mid];
		cmp = comp(v,midval);
		if (cmp>0)
		    left = mid;
		else if (cmp<0)
		    right = mid;
		else if (0===cmp){
		    left = mid;
		    right = mid;
		}
	    }
	    return right;
	}
    }

    var PartialIndex =
	function(data, limit, prop1, dir1, prop2, dir2, prop3, dir3){
	this.data = data;
	this.limit = limit;
	this.idx = [];
	this.datafilter = makeFilter(prop1,dir1,prop2,dir2,prop3,dir3);
	this.datacomp = makeSorter(prop1,dir1,prop2,dir2,prop3,dir3);
	var that = this;
	this.idxcomp = function(a,b){ var d=that.data; return that.datacomp(d[a],d[b]); };
	this.idxfilter = function(i){ return that.datafilter(that.data[i]); };
	if (this.data.length) this.needScan = 1;
    };

    PartialIndex.prototype.scan = function(){
	var i,l;
	this.idx = [];
	var idx = this.idx, limit=this.limit, datalength=this.data.length, data=this.data, f=this.datafilter;
	var idxcomp = this.idxcomp;
	var loc;
	this.needScan = 0;
	if (0===limit) return;
	i=0;
	while((i<datalength) && (idx.length<limit)){
	    if (f(data[i]))
		idx.push(i);
	    ++i;
	}
	idx.sort(this.idxcomp);
	if (datalength<=limit) return;
	while(i<datalength){
	    if (f(data[i])){
		loc = idxByBisection(idx,i,idxcomp);
		idx.splice(loc,0,i);
		idx.splice(limit,1);
	    }
	    ++i;
	}
    };

    PartialIndex.prototype.syncLast = function(){
	var lastdataidx = this.data.length-1;
	var loc;
	var idx = this.idx;
	var limit = this.limit;
	if (!limit) return;
	if (this.idxfilter(lastdataidx)){
	    if (this.needScan) return this.scan();
	    if (idx.length<limit){
		idx.push(lastdataidx);
		idx.sort(this.idxcomp);
	    } else {
		loc = idxByBisection(idx,lastdataidx,this.idxcomp);
		if (loc<limit){
		    idx.splice(loc,0,lastdataidx);
		    idx.splice(limit,1);
		}
	    }
	}
    };

    PartialIndex.prototype.remove = function(rmidxs){
	var i=rmidxs.length,l;
	var idx = this.idx;
	var loc;
	var removed=0;
	if (0===rmidxs.length) return;
	while(i-->1){
	    if (rmidxs[i-1]<=rmidxs[i])
		throw "PartialIndex.remove called with unsorted list of indexes. List of indexes to be removed must be ascending.";
	}
	i = rmidxs.length;
	while(i-->0){
	    loc = idx.indexOf(rmidxs[i]);
	    if (loc>=0){
		idx.splice(loc,1);
		++removed;
	    }
	}
	if (removed) this.needScan=1;
	for(i=0,l=idx.length;i<l;++i)
	    idx[i] -= idxByBisection(rmidxs, idx[i]);
    };

    module.exports = PartialIndex;

})();

<|endoftext|>


<commit_before>'use strict';

const AWS = require('aws-sdk');
const AWS_CREDS = require('./aws_creds.json');
const Image = require('./models/Image.js');
/////////////////////////////////////////

// Update AWS config with user credentials
AWS.config.update({
  secretAccessKey: process.env.AWSCREDS_BETA || AWS_CREDS.credentials.beta,
  accessKeyId: process.env.AWSCREDS_ALPHA || AWS_CREDS.credentials.alpha,
  region: 'eu-central-1'
});

// Create a new instance of existing bucket
let s3Bucket = new AWS.S3({ params: {
  Bucket: 'spyonfido'
}});

/////////////////////////////////////////
module.exports.uploadPhoto = (req, res) => {

  // Get user info here
  let randomImageName = `image${Math.floor(Math.random() * (10000 - 0 + 1) + 0)}.jpg`;
  let imageUrl = null;

  console.log(new Date() + "Image received");

  // Upload image to AWS S3
  s3Bucket.upload({ Body: req,
    Key: randomImageName,
    ACL: 'public-read' })
  .send((err, data) => {
    // Save new image doc in db with imageUrl
    Image
    .create({
      ownerId: '12345',
      ownerName: 'greg2g',
      timeStamp: new Date(),
      imgUrl: data.Location
    })
    .then((newImage) => {
      if (newImage) {
        console.log(new Date() + `Image has been saved in database at ${newImage.imgUrl}`);
        res.send({ msg: 'Message was created' });
      } else {
        res.send({ msg: 'Image was not created.' });
      }
    })
    .catch((err) => {
      res.send({msg: 'ERROR: Image could not be created'});
    });
  });

};
<commit_msg>Ignored local awsConfig requirement for deployment<commit_after>'use strict';

const AWS = require('aws-sdk');
// const AWS_CREDS = require('./aws_creds.json');
const Image = require('./models/Image.js');
/////////////////////////////////////////

// Update AWS config with user credentials
AWS.config.update({
  secretAccessKey: process.env.AWSCREDS_BETA;
  //  || AWS_CREDS.credentials.beta,
  accessKeyId: process.env.AWSCREDS_ALPHA;
  // || AWS_CREDS.credentials.alpha,
  region: 'eu-central-1'
});

// Create a new instance of existing bucket
let s3Bucket = new AWS.S3({ params: {
  Bucket: 'spyonfido'
}});

/////////////////////////////////////////
module.exports.uploadPhoto = (req, res) => {

  // Get user info here
  let randomImageName = `image${Math.floor(Math.random() * (10000 - 0 + 1) + 0)}.jpg`;
  let imageUrl = null;

  console.log(new Date() + "Image received");

  // Upload image to AWS S3
  s3Bucket.upload({ Body: req,
    Key: randomImageName,
    ACL: 'public-read' })
  .send((err, data) => {
    // Save new image doc in db with imageUrl
    Image
    .create({
      ownerId: '12345',
      ownerName: 'greg2g',
      timeStamp: new Date(),
      imgUrl: data.Location
    })
    .then((newImage) => {
      if (newImage) {
        console.log(new Date() + `Image has been saved in database at ${newImage.imgUrl}`);
        res.send({ msg: 'Message was created' });
      } else {
        res.send({ msg: 'Image was not created.' });
      }
    })
    .catch((err) => {
      res.send({msg: 'ERROR: Image could not be created'});
    });
  });

};
<|endoftext|>