<commit_before>'use strict';

const program = require('commander');
const Promise = require("bluebird");
const fsa = Promise.promisifyAll(require("fs"));
const archiver = require('archiver');
const path = require('path');

const mkdirpAsync = Promise.promisify(require('mkdirp'));
const zipFileUtils = require('../servers/lib/zipFileUtils.js');

//const defaultPort =  29015; // true default
const defaultPort =  30815; // localhost version

let parameters = getControlParameters();

var port = parameters.port;
var base = parameters.base;
var zipbase = parameters.zipbase;
var replace = !!parameters.replace;
var idList = parameters.id;
var all = !!parameters.all;
var numberProcessed = 0;
var totalNumberToProcess = 0;

main();

function main() {

    verifyParameters();

    reportParameters();

    if (base) {
        zipFileUtils.setBase(base);
    }
    if (zipbase){
        zipFileUtils.setZipDirPath(zipbase);
    }

    Promise.all(Promise.coroutine(buildZipFiles)).then(
        () => os.exit(0);
    );
}

function* buildZipFiles() {
    try {
        console.log("setup");
        var r = require('rethinkdbdash')({
            db: 'materialscommons',
            port: port
        });
        console.log("setup done");

        var idSet = new Set(idList);
        var ids = (idList.length > 0);

        let allDatasetIds = yield r.db('materialscommons').table('datasets').pluck(["id","published"]);

        var idsToProcess = [];
        allDatasetIds.forEach(record => {
            let id = record['id'];
            if (all || (ids && (idSet.has(id)))) {
                if (record['published']) {
                    idsToProcess.push(id);
                } else {
                    console.log("No zip will be created for unpublished dataset: " + id);
                }
            }
        });

        console.log("Zip files to be created for " + idsToProcess.length + " datasets");

        if (idsToProcess.length == 0) {
            return Promise.reject("Error: no dataset id values to process");
        }

        totalNumberToProcess = idsToProcess.length;

        for (var i = 0; i < idsToProcess.length; i++) {
            var id = idsToProcess[i];
            Promise.coroutine(
                publishDatasetZipFile
            )(r, id);
        }

    } catch (error) {
        console.log("Error in buildZipFiles: ", error)
    }
}

function* publishDatasetZipFile(r, datasetId) {
    try {
        console.log("zip", datasetId);
        let ds = yield r.db('materialscommons').table('datasets').get(datasetId);
        let zipDirPath = zipFileUtils.zipDirPath(ds);
        let fillPathAndFilename = zipFileUtils.fullPathAndFilename(ds);

        console.log("full path and filename: ", fillPathAndFilename);

        let ds2dfEntries = yield r.db('materialscommons').table('dataset2datafile')
            .getAll(datasetId, {index: 'dataset_id'}).coerceTo('array');

        if (!ds2dfEntries.length) {
            numberProcessed++;
            console.log('no zip for id = ' + datasetId);
            console.log('total number of zip files processed: ' + numberProcessed + " of " + totalNumberToProcess);
            return new Promise(function(resolve, reject){resolve()});
        }

        yield mkdirpAsync(zipDirPath);

        let datafileIds = ds2dfEntries.map(entry => entry.datafile_id);
        let datafiles = yield r.table('datafiles').getAll(r.args(datafileIds));

        console.log("For id = " + datasetId + ", there are " + datafileIds.length + " files");

        let nameSourceList = [];
        var seenThisOne = {};

        for (var i=0; i < datafiles.length; i++) {
            let df = datafiles[i];

            let zipEntry = zipFileUtils.zipEntry(df); // sets fileName, checksum, sourcePath
            console.log("zipEntry: ", zipEntry);
            let path = zipEntry.sourcePath;
            let name = zipEntry.fileName;
            let checksum = zipEntry.checksum;
            name = resolveZipfileFilenameDuplicates(seenThisOne, name, checksum);
            console.log("before read stream");
            let stream = yield fsa.createReadStreamAsync(path,{
                flags: 'r',
                encoding: null,
                fd: null,
                mode: 0o666,
                autoClose: true
            });
            console.log("after read stream: ", path);
            nameSourceList.push({name: name, source: source});
        }

        console.log("got files to add: " + nameSourceList.length);

        var output = yield fsa.createWriteStreamAsync(fillPathAndFilename);

        console.log("output stream set");

        let retP =  new Promise(function (resolve, reject) {
            var archive = archiver('zip');

            output.on('close', function () {
                console.log('for dataset: ' + datasetId + " with " + archive.pointer() + ' total bytes');
                numberProcessed++;
                console.log('total number of zip files processed: ' + numberProcessed + " of " + totalNumberToProcess);
                resolve();
            });

            archive.on('error', reject);

            archive.pipe(output);

            nameSourceList.forEach(ns => {
                console.log("name: ", ns.name);
                archive.append(ns.source, {name:ns.name} );
            });

            archive.finalize();
        });

        console.log("Got return promise");

        return retP;

    } catch (error) {
        return yield Promise.reject("Error in publishDatasetZipFile: " +  error.message);
    }
}

function resolveZipfileFilenameDuplicates(seenThisOne,name,checksum){
    name = name.toLowerCase();

    if (name.startsWith(".")) {
        name = "dot" + name;
    }

    if (name in seenThisOne) {
        var count = 0;
        if (seenThisOne[name] == checksum) {
            console.log("Seen this file before: " + name);
            return null;
        } else {
            let newName = resolveZipfileFilenameUnique(name, count);
            while (newName in seenThisOne) {
                count++;
                newName = resolveZipfileFilenameUnique(name, count);
            }
            // console.log(name + " --> " + newName);
            name = newName;
        }
    }
    seenThisOne[name] = checksum;
    return name;
}

function resolveZipfileFilenameUnique(name, count) {
    let parts = path.parse(name);
    return parts.name + "_" + count + parts.ext;
}

function verifyParameters() {
    var ids = (idList.length > 0);

    if (!all && !ids) {
        program.help(text => {
            var banner =    "\t--------------------------------\n";
            return banner + "\tOne of --id or --all is required\n"
                + banner + text;
        })
    }

    if (ids && all) {
        console.log("WARNING: --all (or -a) was specified, but one of more id valeus were given\n"
            + "\tThe id values take precident");
    }

    if (ids) {
        all = false;
    }

}

function reportParameters() {
    console.log("use --help for list of parameter options");
    console.log("port = " + port);
    console.log("base = " + base);
    console.log("zipbase = " + zipbase);
    console.log("replace = " + replace);
    if (all) {
        console.log("process all")
    } else {
        console.log("input id(s)");
        idList.forEach(id => {
            console.log("\tid = " + id);
        });
    }
}

function getControlParameters() {
    let accumulateIds = (id,ids) => {
        ids.push(id);
        return ids;
    };

    return program
        .option('-p, --port [port]', 'The RethinkDB port; defaults to ' + defaultPort,defaultPort)
        .option('-b, --base [base]', 'The base path of the datasets directory, optional')
        .option('-z, --zipbase [zipbase]', 'The base path for the zipfile directory, optional')
        .option('-i, --id [id]', 'If given, the id of the dataset to copy, can be repeated',accumulateIds,[])
        .option('-a, --all', 'If given, and no id(s), then copy all datasets, \n\t\tone of --id or --all required')
        .option('-r, --replace','If given, then replace files already generaåted, \n\t\totherwise not; optional')
        .parse(process.argv);
}<commit_msg>does this work?<commit_after>'use strict';

const program = require('commander');
const Promise = require("bluebird");
const fsa = Promise.promisifyAll(require("fs"));
const archiver = require('archiver');
const path = require('path');

const mkdirpAsync = Promise.promisify(require('mkdirp'));
const zipFileUtils = require('../servers/lib/zipFileUtils.js');

//const defaultPort =  29015; // true default
const defaultPort =  30815; // localhost version

let parameters = getControlParameters();

var port = parameters.port;
var base = parameters.base;
var zipbase = parameters.zipbase;
var replace = !!parameters.replace;
var idList = parameters.id;
var all = !!parameters.all;
var numberProcessed = 0;
var totalNumberToProcess = 0;

main();

function main() {

    verifyParameters();

    reportParameters();

    if (base) {
        zipFileUtils.setBase(base);
    }
    if (zipbase){
        zipFileUtils.setZipDirPath(zipbase);
    }

    Promise.all(Promise.coroutine(buildZipFiles)).then(
        () => os.exit(0));
    );
}

function* buildZipFiles() {
    try {
        console.log("setup");
        var r = require('rethinkdbdash')({
            db: 'materialscommons',
            port: port
        });
        console.log("setup done");

        var idSet = new Set(idList);
        var ids = (idList.length > 0);

        let allDatasetIds = yield r.db('materialscommons').table('datasets').pluck(["id","published"]);

        var idsToProcess = [];
        allDatasetIds.forEach(record => {
            let id = record['id'];
            if (all || (ids && (idSet.has(id)))) {
                if (record['published']) {
                    idsToProcess.push(id);
                } else {
                    console.log("No zip will be created for unpublished dataset: " + id);
                }
            }
        });

        console.log("Zip files to be created for " + idsToProcess.length + " datasets");

        if (idsToProcess.length == 0) {
            return Promise.reject("Error: no dataset id values to process");
        }

        totalNumberToProcess = idsToProcess.length;

        for (var i = 0; i < idsToProcess.length; i++) {
            var id = idsToProcess[i];
            Promise.coroutine(
                publishDatasetZipFile
            )(r, id);
        }

    } catch (error) {
        console.log("Error in buildZipFiles: ", error)
    }
}

function* publishDatasetZipFile(r, datasetId) {
    try {
        console.log("zip", datasetId);
        let ds = yield r.db('materialscommons').table('datasets').get(datasetId);
        let zipDirPath = zipFileUtils.zipDirPath(ds);
        let fillPathAndFilename = zipFileUtils.fullPathAndFilename(ds);

        console.log("full path and filename: ", fillPathAndFilename);

        let ds2dfEntries = yield r.db('materialscommons').table('dataset2datafile')
            .getAll(datasetId, {index: 'dataset_id'}).coerceTo('array');

        if (!ds2dfEntries.length) {
            numberProcessed++;
            console.log('no zip for id = ' + datasetId);
            console.log('total number of zip files processed: ' + numberProcessed + " of " + totalNumberToProcess);
            return new Promise(function(resolve, reject){resolve()});
        }

        yield mkdirpAsync(zipDirPath);

        let datafileIds = ds2dfEntries.map(entry => entry.datafile_id);
        let datafiles = yield r.table('datafiles').getAll(r.args(datafileIds));

        console.log("For id = " + datasetId + ", there are " + datafileIds.length + " files");

        let nameSourceList = [];
        var seenThisOne = {};

        for (var i=0; i < datafiles.length; i++) {
            let df = datafiles[i];

            let zipEntry = zipFileUtils.zipEntry(df); // sets fileName, checksum, sourcePath
            console.log("zipEntry: ", zipEntry);
            let path = zipEntry.sourcePath;
            let name = zipEntry.fileName;
            let checksum = zipEntry.checksum;
            name = resolveZipfileFilenameDuplicates(seenThisOne, name, checksum);
            console.log("before read stream");
            let stream = yield fsa.createReadStreamAsync(path,{
                flags: 'r',
                encoding: null,
                fd: null,
                mode: 0o666,
                autoClose: true
            });
            console.log("after read stream: ", path);
            nameSourceList.push({name: name, source: source});
        }

        console.log("got files to add: " + nameSourceList.length);

        var output = yield fsa.createWriteStreamAsync(fillPathAndFilename);

        console.log("output stream set");

        let retP =  new Promise(function (resolve, reject) {
            var archive = archiver('zip');

            output.on('close', function () {
                console.log('for dataset: ' + datasetId + " with " + archive.pointer() + ' total bytes');
                numberProcessed++;
                console.log('total number of zip files processed: ' + numberProcessed + " of " + totalNumberToProcess);
                resolve();
            });

            archive.on('error', reject);

            archive.pipe(output);

            nameSourceList.forEach(ns => {
                console.log("name: ", ns.name);
                archive.append(ns.source, {name:ns.name} );
            });

            archive.finalize();
        });

        console.log("Got return promise");

        return retP;

    } catch (error) {
        return yield Promise.reject("Error in publishDatasetZipFile: " +  error.message);
    }
}

function resolveZipfileFilenameDuplicates(seenThisOne,name,checksum){
    name = name.toLowerCase();

    if (name.startsWith(".")) {
        name = "dot" + name;
    }

    if (name in seenThisOne) {
        var count = 0;
        if (seenThisOne[name] == checksum) {
            console.log("Seen this file before: " + name);
            return null;
        } else {
            let newName = resolveZipfileFilenameUnique(name, count);
            while (newName in seenThisOne) {
                count++;
                newName = resolveZipfileFilenameUnique(name, count);
            }
            // console.log(name + " --> " + newName);
            name = newName;
        }
    }
    seenThisOne[name] = checksum;
    return name;
}

function resolveZipfileFilenameUnique(name, count) {
    let parts = path.parse(name);
    return parts.name + "_" + count + parts.ext;
}

function verifyParameters() {
    var ids = (idList.length > 0);

    if (!all && !ids) {
        program.help(text => {
            var banner =    "\t--------------------------------\n";
            return banner + "\tOne of --id or --all is required\n"
                + banner + text;
        })
    }

    if (ids && all) {
        console.log("WARNING: --all (or -a) was specified, but one of more id valeus were given\n"
            + "\tThe id values take precident");
    }

    if (ids) {
        all = false;
    }

}

function reportParameters() {
    console.log("use --help for list of parameter options");
    console.log("port = " + port);
    console.log("base = " + base);
    console.log("zipbase = " + zipbase);
    console.log("replace = " + replace);
    if (all) {
        console.log("process all")
    } else {
        console.log("input id(s)");
        idList.forEach(id => {
            console.log("\tid = " + id);
        });
    }
}

function getControlParameters() {
    let accumulateIds = (id,ids) => {
        ids.push(id);
        return ids;
    };

    return program
        .option('-p, --port [port]', 'The RethinkDB port; defaults to ' + defaultPort,defaultPort)
        .option('-b, --base [base]', 'The base path of the datasets directory, optional')
        .option('-z, --zipbase [zipbase]', 'The base path for the zipfile directory, optional')
        .option('-i, --id [id]', 'If given, the id of the dataset to copy, can be repeated',accumulateIds,[])
        .option('-a, --all', 'If given, and no id(s), then copy all datasets, \n\t\tone of --id or --all required')
        .option('-r, --replace','If given, then replace files already generaåted, \n\t\totherwise not; optional')
        .parse(process.argv);
}<|endoftext|>


<commit_before>var app = require('../app');
var status = require('http-status');
var request = require('supertest').agent(app.listen());

describe('apikey', function() {
    it('should give a 401 when a no apikey is specified', function(done) {
        request.get('/projects').expect(status.UNAUTHORIZED, done);
    });

    it('should give a 401 when a bad apikey is specified', function(done) {
        request.get('/projects?apikey=123').expect(status.UNAUTHORIZED, done);
    });
});
<commit_msg>Test good apikey.<commit_after>/* jshint expr: true */

var app = require('../app');
var status = require('http-status');
var request = require('supertest').agent(app.listen());

describe('apikey', function() {
    it('should give a 401 when a no apikey is specified', function(done) {
        request.get('/projects').expect(status.UNAUTHORIZED, done);
    });

    it('should give a 401 when a bad apikey is specified', function(done) {
        request.get('/projects?apikey=123').expect(status.UNAUTHORIZED, done);
    });

    it('should return data with a good apikey', function(done) {
        var isProjects = function(res) {
            res.should.be.json;
            res.body.should.be.length(2);
        };
        request.get('/projects?apikey=user1key')
            .expect('Content-Type', /json/)
            .expect(200)
            .expect(isProjects)
            .end(done);
    });
});
<|endoftext|>


<commit_before>user_pref("browser.ctrlTab.previews", true);
user_pref("browser.fixup.alternate.enabled", false);
user_pref("browser.newtab.url", "https://www.google.co.nz");
user_pref("browser.pocket.enabled", false);
user_pref("browser.tabs.tabClipWidth", 1);
user_pref("datareporting.healthreport.service.enabled", false);
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("general.useragent.locale", "en-GB");
user_pref("layout.spellcheckDefault", 2);
user_pref("loop.enabled", false);
user_pref("plugins.click_to_play", true);
user_pref("spellchecker.dictionary", "en-GB");
user_pref("toolkit.telemetry.enabled", false);
<commit_msg>Stopped debug tools from auto clearing.<commit_after>user_pref("browser.ctrlTab.previews", true);
user_pref("browser.fixup.alternate.enabled", false);
user_pref("browser.newtab.url", "https://www.google.co.nz");
user_pref("browser.pocket.enabled", false);
user_pref("browser.tabs.tabClipWidth", 1);
user_pref("datareporting.healthreport.service.enabled", false);
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("devtools.webconsole.persistlog", true);
user_pref("general.useragent.locale", "en-GB");
user_pref("layout.spellcheckDefault", 2);
user_pref("loop.enabled", false);
user_pref("plugins.click_to_play", true);
user_pref("spellchecker.dictionary", "en-GB");
user_pref("toolkit.telemetry.enabled", false);
<|endoftext|>


<commit_before>"use strict";

(function () {
    angular
        .module("argo")
        .controller("OrderDialog", OrderDialog);

    OrderDialog.$inject = ["$mdDialog", "toastService", "params",
        "quotesService", "ordersService"];
    function OrderDialog($mdDialog, toastService,
                        params, quotesService, ordersService) {
        var vm = this;

        vm.changeMarket = changeMarket;
        vm.changeMeasure = changeMeasure;

        vm.type = "market";
        vm.side = params.side;
        vm.instruments = params.instruments;
        vm.selectedInstrument = params.selectedInstrument;
        vm.changeMarket(vm.selectedInstrument);
        vm.expires = [
            {label: "1 Hour", value: 60 * 60 * 1000},
            {label: "2 Hours", value: 2 * 60 * 60 * 1000},
            {label: "3 Hours", value: 3 * 60 * 60 * 1000},
            {label: "4 Hours", value: 4 * 60 * 60 * 1000},
            {label: "5 Hours", value: 5 * 60 * 60 * 1000},
            {label: "6 Hours", value: 6 * 60 * 60 * 1000},
            {label: "8 Hours", value: 8 * 60 * 60 * 1000},
            {label: "12 Hours", value: 12 * 60 * 60 * 1000},
            {label: "18 Hours", value: 18 * 60 * 60 * 1000},
            {label: "1 Day", value: 60 * 60 * 24 * 1000},
            {label: "2 Days", value: 2 * 60 * 60 * 24 * 1000},
            {label: "1 Week", value: 7 * 60 * 60 * 24 * 1000},
            {label: "1 Month", value: 30 * 60 * 60 * 24 * 1000},
            {label: "2 Months", value: 60 * 60 * 60 * 24 * 1000},
            {label: "3 Months", value: 90 * 60 * 60 * 24 * 1000}
        ];
        vm.selectedExpire = 604800000; // 1 week
        vm.measure = "price";
        vm.isLowerBound = false;
        vm.isUpperBound = false;
        vm.isTakeProfit = false;
        vm.isStopLoss = false;
        vm.isTrailingStop = false;

        function changeMarket(instrument) {
            var price = quotesService.getQuotes()[instrument];

            vm.step = 0.0001;
            if (vm.side === "buy") {
                vm.quote = price && price.ask;
                vm.takeProfit = vm.quote + vm.step * 10;
                vm.stopLoss = vm.quote - vm.step * 10;
            } else {
                vm.quote = price && price.bid;
                vm.takeProfit = vm.quote - vm.step * 10;
                vm.stopLoss = vm.quote + vm.step * 10;
            }
            vm.lowerBound = vm.quote - vm.step;
            vm.upperBound = vm.quote + vm.step;
            vm.trailingStop = 25;
        }

        function changeMeasure(measure) {
            if (measure === "price") {
                changeMarket(vm.selectedInstrument);
            } else {
                vm.lowerBound = 1;
                vm.upperBound = 1;
                vm.takeProfit = 10;
                vm.stopLoss = 10;
                vm.trailingStop = 25;
                vm.step = 1;
            }
        }

        vm.hide = function () {
            $mdDialog.hide();
        };

        vm.cancel = function () {
            $mdDialog.cancel();
        };

        vm.answer = function (action) {
            var order = {};

            $mdDialog.hide(action);

            order.instrument = vm.selectedInstrument;
            order.units = vm.units;
            order.side = vm.side;
            order.type = vm.type;

            if (order.type === "limit") {
                order.price = vm.quote;
                order.expiry = new Date(Date.now() + vm.selectedExpire);
            }

            if (vm.isLowerBound) {
                order.lowerBound = vm.lowerBound.toFixed(4);
            }
            if (vm.isUpperBound) {
                order.upperBound = vm.upperBound.toFixed(4);
            }
            if (vm.isStopLoss) {
                order.stopLoss = vm.stopLoss.toFixed(4);
            }
            if (vm.isTakeProfit) {
                order.takeProfit = vm.takeProfit.toFixed(4);
            }
            if (vm.isTrailingStop) {
                order.trailingStop = vm.trailingStop;
            }

            if (action === "submit") {
                ordersService.putOrder(order).then(function (transaction) {
                    var opened = transaction.tradeOpened ||
                                transaction.orderOpened,
                        message = opened.side + " " +
                        transaction.instrument +
                        " #" + opened.id +
                        " @" + transaction.price +
                        " for " + opened.units;

                    toastService.show(message);
                });
            }
        };
    }

}());
<commit_msg>Add handling error for sending order.<commit_after>"use strict";

(function () {
    angular
        .module("argo")
        .controller("OrderDialog", OrderDialog);

    OrderDialog.$inject = ["$mdDialog", "toastService", "params",
        "quotesService", "ordersService"];
    function OrderDialog($mdDialog, toastService,
                        params, quotesService, ordersService) {
        var vm = this;

        vm.changeMarket = changeMarket;
        vm.changeMeasure = changeMeasure;

        vm.type = "market";
        vm.side = params.side;
        vm.instruments = params.instruments;
        vm.selectedInstrument = params.selectedInstrument;
        vm.changeMarket(vm.selectedInstrument);
        vm.expires = [
            {label: "1 Hour", value: 60 * 60 * 1000},
            {label: "2 Hours", value: 2 * 60 * 60 * 1000},
            {label: "3 Hours", value: 3 * 60 * 60 * 1000},
            {label: "4 Hours", value: 4 * 60 * 60 * 1000},
            {label: "5 Hours", value: 5 * 60 * 60 * 1000},
            {label: "6 Hours", value: 6 * 60 * 60 * 1000},
            {label: "8 Hours", value: 8 * 60 * 60 * 1000},
            {label: "12 Hours", value: 12 * 60 * 60 * 1000},
            {label: "18 Hours", value: 18 * 60 * 60 * 1000},
            {label: "1 Day", value: 60 * 60 * 24 * 1000},
            {label: "2 Days", value: 2 * 60 * 60 * 24 * 1000},
            {label: "1 Week", value: 7 * 60 * 60 * 24 * 1000},
            {label: "1 Month", value: 30 * 60 * 60 * 24 * 1000},
            {label: "2 Months", value: 60 * 60 * 60 * 24 * 1000},
            {label: "3 Months", value: 90 * 60 * 60 * 24 * 1000}
        ];
        vm.selectedExpire = 604800000; // 1 week
        vm.measure = "price";
        vm.isLowerBound = false;
        vm.isUpperBound = false;
        vm.isTakeProfit = false;
        vm.isStopLoss = false;
        vm.isTrailingStop = false;

        function changeMarket(instrument) {
            var price = quotesService.getQuotes()[instrument];

            vm.step = 0.0001;
            if (vm.side === "buy") {
                vm.quote = price && price.ask;
                vm.takeProfit = vm.quote + vm.step * 10;
                vm.stopLoss = vm.quote - vm.step * 10;
            } else {
                vm.quote = price && price.bid;
                vm.takeProfit = vm.quote - vm.step * 10;
                vm.stopLoss = vm.quote + vm.step * 10;
            }
            vm.lowerBound = vm.quote - vm.step;
            vm.upperBound = vm.quote + vm.step;
            vm.trailingStop = 25;
        }

        function changeMeasure(measure) {
            if (measure === "price") {
                changeMarket(vm.selectedInstrument);
            } else {
                vm.lowerBound = 1;
                vm.upperBound = 1;
                vm.takeProfit = 10;
                vm.stopLoss = 10;
                vm.trailingStop = 25;
                vm.step = 1;
            }
        }

        vm.hide = function () {
            $mdDialog.hide();
        };

        vm.cancel = function () {
            $mdDialog.cancel();
        };

        vm.answer = function (action) {
            var order = {};

            $mdDialog.hide(action);

            order.instrument = vm.selectedInstrument;
            order.units = vm.units;
            order.side = vm.side;
            order.type = vm.type;

            if (order.type === "limit") {
                order.price = vm.quote;
                order.expiry = new Date(Date.now() + vm.selectedExpire);
            }

            if (vm.isLowerBound) {
                order.lowerBound = vm.lowerBound.toFixed(4);
            }
            if (vm.isUpperBound) {
                order.upperBound = vm.upperBound.toFixed(4);
            }
            if (vm.isStopLoss) {
                order.stopLoss = vm.stopLoss.toFixed(4);
            }
            if (vm.isTakeProfit) {
                order.takeProfit = vm.takeProfit.toFixed(4);
            }
            if (vm.isTrailingStop) {
                order.trailingStop = vm.trailingStop;
            }

            if (action === "submit") {
                ordersService.putOrder(order).then(function (transaction) {
                    var opened,
                        message;

                    if (transaction.code && transaction.message) {
                        message = "ERROR " +
                            transaction.code + " " +
                            transaction.message;

                        toastService.show(message);
                    } else {
                        opened = transaction.tradeOpened ||
                            transaction.orderOpened;
                        message = opened.side + " " +
                            transaction.instrument +
                            " #" + opened.id +
                            " @" + transaction.price +
                            " for " + opened.units;

                        toastService.show(message);
                    }
                });
            }
        };
    }

}());
<|endoftext|>


<commit_before>// Forward to an SMTP server as a proxy.
// Opens the connection to the ongoing SMTP server at MAIL FROM time
// and passes back any errors seen on the ongoing server to the originating server.

var sock = require('./line_socket');
var smtp_regexp = /^([0-9]{3})([ -])(.*)/;

exports.register = function () {
    this.inherits('queue/conn_pool_base');
}

exports.hook_mail = function (next, connection, params) {
    connection.loginfo(this, "proxying");
    var self = this;
    var mail_from = params[0];
    var data_marker = 0;
    var config = self.config.get('smtp_proxy.ini');
    var host = (config.main.host) ? config.main.host : 'localhost';
    var port = (config.main.port) ? config.main.port : 25;
    var timeout = (config.main.timeout || config.main.timeout == 0) ?
        config.main.timeout : 300;
    var smtp_proxy = self.conn_get(self, next, connection, host, port, timeout);
    var in_write = false;
    var dot_pending = true;

    if (!smtp_proxy.pool_connection) {
        smtp_proxy.command = 'connect';
    }

    smtp_proxy.send_data = function () {
        var wrote_all = true;
        while (wrote_all &&
              (data_marker < connection.transaction.data_lines.length)) {
            var line = connection.transaction.data_lines[data_marker];
            data_marker++;
            connection.logdata(self, "C: " + line);
            // this protection is due to bug #
            in_write = true;
            wrote_all =smtp_proxy.socket.write(
                line.replace(/^\./, '..').replace(/\r?\n/g, '\r\n'));
            in_write = false;
            if (!wrote_all) {
                return;
            }
        }
        // we get here if wrote_all still true, and we got to end of data_lines
        if (dot_pending) {
            dot_pending = false;
            smtp_proxy.socket.send_command('dot');
        }
    }

    // Add socket event listeners.
    smtp_proxy.socket.on('drain', function() {
        if (dot_pending && smtp_proxy.command === 'mailbody') {
            process.nextTick(function () { smtp_proxy.send_data() });
        }
    });

    // Call this in the case of socket error, or the socket throws an error.
    var socket_error = function (err) {
        connection.logdebug(self, "Ongoing connection failed: " + err);

        if (smtp_proxy) {
            smtp_proxy.next(DENYSOFT,'Proxy connection failed');
        }

        self.conn_destroy(self, connection, smtp_proxy);
    };

    smtp_proxy.socket.on('error', socket_error);

    smtp_proxy.socket.on('timeout', function () {
        connection.logdebug(self, "Ongoing connection timed out");
    });

    smtp_proxy.socket.on('close', function (had_error) {
        connection.logdebug(self, "Ongoing connection closed");
    });

    smtp_proxy.socket.on('connect', function () {
        connection.logdebug(self, "Ongoing connection established");
    });

    smtp_proxy.socket.send_command = function (cmd, data) {
        var line = cmd + (data ? (' ' + data) : '');

        if (cmd === 'dot') {
            line = '.';
        }

        connection.logprotocol(self, "C: " + line);

        try {
            this.write(line + "\r\n");
        }
        catch (err) {
            socket_error(err);
            return;
        }

        smtp_proxy.command = cmd.toLowerCase();
        smtp_proxy.response = [];
    };

    smtp_proxy.socket.on('line', function (line) {
        var matches;
        connection.logprotocol(self, "S: " + line);
        if (matches = smtp_regexp.exec(line)) {
            var code = matches[1],
                cont = matches[2],
                rest = matches[3];
            smtp_proxy.response.push(rest);
            if (cont === ' ') {
                if (smtp_proxy.command === 'ehlo') {
                    // Handle fallback to HELO if EHLO is rejected
                    if (code.match(/^5/)) {
                        if (smtp_proxy.xclient) {
                            smtp_proxy.socket.send_command('HELO',
                                connection.hello_host);
                        }
                        else {
                            smtp_proxy.socket.send_command('HELO',
                                self.config.get('me'));
                        }
                        return;
                    }
                    // Parse CAPABILITIES
                    for (var i in smtp_proxy.response) {
                        if (smtp_proxy.response[i].match(/^XCLIENT/)) {
                            if (!smtp_proxy.xclient) {
                                smtp_proxy.socket.send_command('XCLIENT',
                                    'ADDR=' + connection.remote_ip);
                                return;
                            }
                        }
                        if (smtp_proxy.response[i].match(/^STARTTLS/)) {
                            var key = self.config.get(
                                'tls_key.pem', 'data').join("\n");
                            var cert = self.config.get(
                                'tls_cert.pem', 'data').join("\n");
                            if (key && cert && (/(true|yes|1)/i.exec(
                                smtp_proxy.config.main.enable_tls))) {
                                this.on('secure', function () {
                                    smtp_proxy.socket.send_command('EHLO',
                                        self.config.get('me'));
                                });
                                smtp_proxy.socket.send_command('STARTTLS');
                                return;
                            }
                        }
                    }
                }
                if (smtp_proxy.command === 'xclient' && code.match(/^5/)) {
                    // XCLIENT rejected; continue without it
                    smtp_proxy.command = 'helo';
                }
                else if (code.match(/^[45]/)) {
                    var response_array = smtp_proxy.response.slice();
                    if (smtp_proxy.command !== 'rcpt') {
                        // errors are OK for rcpt, but nothing else
                        // this can also happen if the destination server
                        // times out, but that is okay.
                        connection.loginfo(self,
                           "message denied, proxying failed");
                        smtp_proxy.socket.send_command('RSET');
                    }

                    if (smtp_proxy) {
                        return smtp_proxy.next(code.match(/^4/) ?
                            DENYSOFT : DENY, response_array);
                    }
                    else {
                        return;
                    }
                }
                switch (smtp_proxy.command) {
                    case 'xclient':
                        smtp_proxy.xclient = true;
                        smtp_proxy.socket.send_command('EHLO',
                            connection.hello_host);
                        break;
                    case 'starttls':
                        var tls_options = { key: key, cert: cert };
                        smtp_proxy.socket.upgrade(tls_options);
                        break;
                    case 'connect':
                        smtp_proxy.socket.send_command('EHLO',
                            self.config.get('me'));
                        break;
                    case 'ehlo':
                    case 'helo':
                        smtp_proxy.socket.send_command('MAIL',
                            'FROM:' + mail_from);
                        break;
                    case 'mail':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'rcpt':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'data':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'dot':
                        connection.loginfo(self,
                            "message delivered, proxying complete");
                        if (smtp_proxy) {
                            smtp_proxy.next(OK, smtp_proxy.response + ' (' +
                                connection.transaction.uuid + ')');
                            smtp_proxy.socket.send_command('RSET');
                        }
                        break;
                    case 'rset':
                        // We do not call next() here because many paths
                        // lead to this conclusion, and next() is called
                        // on a case-by-case basis.
                        self.conn_idle(self, connection);
                        break;
                    default:
                        throw "Unknown command: " + smtp_proxy.command;
                }
            }
        }
        else {
            // Unrecognised response.
            connection.logerror(self,
                "Unrecognised response from upstream server: " + line);
            connection.loginfo(self, "message denied, proxying failed");
            smtp_proxy.socket.send_command('RSET');
            if (smtp_proxy) return smtp_proxy.next(DENYSOFT);
        }
    });

    if (smtp_proxy.pool_connection) {
        // If we used XCLIENT earlier; we *must* re-send it again
        // To update the proxy with the new client details.
        if (smtp_proxy.xclient) {
            smtp_proxy.socket.send_command('XCLIENT',
                'ADDR=' + connection.remote_ip);
        }
        else {
            smtp_proxy.socket.send_command('MAIL', 'FROM:' + mail_from);
        }
    }
};

exports.hook_rcpt_ok = function (next, connection, recipient) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.next = next;
    smtp_proxy.socket.send_command('RCPT', 'TO:' + recipient);
};

exports.hook_data = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.next = next;
    smtp_proxy.socket.send_command("DATA");
};

exports.hook_queue = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.command = 'mailbody';
    smtp_proxy.next = next;
    smtp_proxy.send_data();
};

exports.hook_rset = function (next, connection) {
    this.rset_proxy(next, connection);
}

exports.hook_quit = function (next, connection) {
    this.rset_proxy(next, connection);
}

exports.hook_disconnect = function (next, connection) {
    this.rset_proxy(next, connection);
};

exports.rset_proxy = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.socket.send_command("RSET");
    next();
};
<commit_msg>Close off next() in the case where the client disconnects.  Then call RSET to reset the connection.<commit_after>// Forward to an SMTP server as a proxy.
// Opens the connection to the ongoing SMTP server at MAIL FROM time
// and passes back any errors seen on the ongoing server to the originating server.

var sock = require('./line_socket');
var smtp_regexp = /^([0-9]{3})([ -])(.*)/;

exports.register = function () {
    this.inherits('queue/conn_pool_base');
}

exports.hook_mail = function (next, connection, params) {
    connection.loginfo(this, "proxying");
    var self = this;
    var mail_from = params[0];
    var data_marker = 0;
    var config = self.config.get('smtp_proxy.ini');
    var host = (config.main.host) ? config.main.host : 'localhost';
    var port = (config.main.port) ? config.main.port : 25;
    var timeout = (config.main.timeout || config.main.timeout == 0) ?
        config.main.timeout : 300;
    var smtp_proxy = self.conn_get(self, next, connection, host, port, timeout);
    var in_write = false;
    var dot_pending = true;

    if (!smtp_proxy.pool_connection) {
        smtp_proxy.command = 'connect';
    }

    smtp_proxy.send_data = function () {
        var wrote_all = true;
        while (wrote_all &&
              (data_marker < connection.transaction.data_lines.length)) {
            var line = connection.transaction.data_lines[data_marker];
            data_marker++;
            connection.logdata(self, "C: " + line);
            // this protection is due to bug #
            in_write = true;
            wrote_all =smtp_proxy.socket.write(
                line.replace(/^\./, '..').replace(/\r?\n/g, '\r\n'));
            in_write = false;
            if (!wrote_all) {
                return;
            }
        }
        // we get here if wrote_all still true, and we got to end of data_lines
        if (dot_pending) {
            dot_pending = false;
            smtp_proxy.socket.send_command('dot');
        }
    }

    // Add socket event listeners.
    smtp_proxy.socket.on('drain', function() {
        if (dot_pending && smtp_proxy.command === 'mailbody') {
            process.nextTick(function () { smtp_proxy.send_data() });
        }
    });

    // Call this in the case of socket error, or the socket throws an error.
    var socket_error = function (err) {
        connection.logdebug(self, "Ongoing connection failed: " + err);

        if (smtp_proxy) {
            smtp_proxy.next(DENYSOFT,'Proxy connection failed');
        }

        self.conn_destroy(self, connection, smtp_proxy);
    };

    smtp_proxy.socket.on('error', socket_error);

    smtp_proxy.socket.on('timeout', function () {
        connection.logdebug(self, "Ongoing connection timed out");
    });

    smtp_proxy.socket.on('close', function (had_error) {
        connection.logdebug(self, "Ongoing connection closed");
    });

    smtp_proxy.socket.on('connect', function () {
        connection.logdebug(self, "Ongoing connection established");
    });

    smtp_proxy.socket.send_command = function (cmd, data) {
        var line = cmd + (data ? (' ' + data) : '');

        if (cmd === 'dot') {
            line = '.';
        }

        connection.logprotocol(self, "C: " + line);

        try {
            this.write(line + "\r\n");
        }
        catch (err) {
            socket_error(err);
            return;
        }

        smtp_proxy.command = cmd.toLowerCase();
        smtp_proxy.response = [];
    };

    smtp_proxy.socket.on('line', function (line) {
        var matches;
        connection.logprotocol(self, "S: " + line);
        if (matches = smtp_regexp.exec(line)) {
            var code = matches[1],
                cont = matches[2],
                rest = matches[3];
            smtp_proxy.response.push(rest);
            if (cont === ' ') {
                if (smtp_proxy.command === 'ehlo') {
                    // Handle fallback to HELO if EHLO is rejected
                    if (code.match(/^5/)) {
                        if (smtp_proxy.xclient) {
                            smtp_proxy.socket.send_command('HELO',
                                connection.hello_host);
                        }
                        else {
                            smtp_proxy.socket.send_command('HELO',
                                self.config.get('me'));
                        }
                        return;
                    }
                    // Parse CAPABILITIES
                    for (var i in smtp_proxy.response) {
                        if (smtp_proxy.response[i].match(/^XCLIENT/)) {
                            if (!smtp_proxy.xclient) {
                                smtp_proxy.socket.send_command('XCLIENT',
                                    'ADDR=' + connection.remote_ip);
                                return;
                            }
                        }
                        if (smtp_proxy.response[i].match(/^STARTTLS/)) {
                            var key = self.config.get(
                                'tls_key.pem', 'data').join("\n");
                            var cert = self.config.get(
                                'tls_cert.pem', 'data').join("\n");
                            if (key && cert && (/(true|yes|1)/i.exec(
                                smtp_proxy.config.main.enable_tls))) {
                                this.on('secure', function () {
                                    smtp_proxy.socket.send_command('EHLO',
                                        self.config.get('me'));
                                });
                                smtp_proxy.socket.send_command('STARTTLS');
                                return;
                            }
                        }
                    }
                }
                if (smtp_proxy.command === 'xclient' && code.match(/^5/)) {
                    // XCLIENT rejected; continue without it
                    smtp_proxy.command = 'helo';
                }
                else if (code.match(/^[45]/)) {
                    var response_array = smtp_proxy.response.slice();
                    if (smtp_proxy.command !== 'rcpt') {
                        // errors are OK for rcpt, but nothing else
                        // this can also happen if the destination server
                        // times out, but that is okay.
                        connection.loginfo(self,
                           "message denied, proxying failed");
                        smtp_proxy.socket.send_command('RSET');
                    }

                    if (smtp_proxy) {
                        return smtp_proxy.next(code.match(/^4/) ?
                            DENYSOFT : DENY, response_array);
                    }
                    else {
                        return;
                    }
                }
                switch (smtp_proxy.command) {
                    case 'xclient':
                        smtp_proxy.xclient = true;
                        smtp_proxy.socket.send_command('EHLO',
                            connection.hello_host);
                        break;
                    case 'starttls':
                        var tls_options = { key: key, cert: cert };
                        smtp_proxy.socket.upgrade(tls_options);
                        break;
                    case 'connect':
                        smtp_proxy.socket.send_command('EHLO',
                            self.config.get('me'));
                        break;
                    case 'ehlo':
                    case 'helo':
                        smtp_proxy.socket.send_command('MAIL',
                            'FROM:' + mail_from);
                        break;
                    case 'mail':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'rcpt':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'data':
                        if (smtp_proxy) smtp_proxy.next();
                        break;
                    case 'dot':
                        connection.loginfo(self,
                            "message delivered, proxying complete");
                        if (smtp_proxy) {
                            smtp_proxy.next(OK, smtp_proxy.response + ' (' +
                                connection.transaction.uuid + ')');
                            smtp_proxy.socket.send_command('RSET');
                        }
                        break;
                    case 'rset':
                        // We do not call next() here because many paths
                        // lead to this conclusion, and next() is called
                        // on a case-by-case basis.
                        self.conn_idle(self, connection);
                        break;
                    default:
                        throw "Unknown command: " + smtp_proxy.command;
                }
            }
        }
        else {
            // Unrecognised response.
            connection.logerror(self,
                "Unrecognised response from upstream server: " + line);
            connection.loginfo(self, "message denied, proxying failed");
            smtp_proxy.socket.send_command('RSET');
            if (smtp_proxy) return smtp_proxy.next(DENYSOFT);
        }
    });

    if (smtp_proxy.pool_connection) {
        // If we used XCLIENT earlier; we *must* re-send it again
        // To update the proxy with the new client details.
        if (smtp_proxy.xclient) {
            smtp_proxy.socket.send_command('XCLIENT',
                'ADDR=' + connection.remote_ip);
        }
        else {
            smtp_proxy.socket.send_command('MAIL', 'FROM:' + mail_from);
        }
    }
};

exports.hook_rcpt_ok = function (next, connection, recipient) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.next = next;
    smtp_proxy.socket.send_command('RCPT', 'TO:' + recipient);
};

exports.hook_data = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.next = next;
    smtp_proxy.socket.send_command("DATA");
};

exports.hook_queue = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.command = 'mailbody';
    smtp_proxy.next = next;
    smtp_proxy.send_data();
};

exports.hook_rset = function (next, connection) {
    this.rset_proxy(next, connection);
}

exports.hook_quit = function (next, connection) {
    this.rset_proxy(next, connection);
}

exports.hook_disconnect = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (smtp_proxy) {
        switch (smtp_proxy.command) {
            case 'mail':
            case 'rcpt':
            case 'data':
                smtp_proxy.next();
                break;
            default:
                break;
        }
    }
    this.rset_proxy(next, connection);
};

exports.rset_proxy = function (next, connection) {
    var smtp_proxy = connection.notes.conn;
    if (!smtp_proxy) return next();
    smtp_proxy.socket.send_command("RSET");
    next();
};
<|endoftext|>


<commit_before>var fs = require('fs')
var url = require('url')
var http = require('http')
var https = require('https')
var level = require('level')
var _ = require('underscore')
var emitter = require('events').EventEmitter
var livestream = require('level-live-stream')
var engineServer = require('engine.io-stream')
var websocServer = require('ws').Server
var wsStream = require('websocket-stream')
var asyncMap = require('slide').asyncMap
var hash = require('crypto').createHash
var multiLevel = require('multilevel')
var browserify = require('browserify')
var formidable = require('formidable')
var uglify = require('uglify-js')
var through = require('through2')
var path = require('path')
var cuid = require('cuid')
var st = require('st')

var sessions = {edit:[]}
var users = {}
var pass

// allow websock \ swap (engine.io or ws)
module.exports.boot = boot
module.exports.cli = through.obj(cli) // new brico then pipe into process
module.exports.compile = compile
module.exports.upload = fileUpload
module.exports.auth = auth

var db

function cli (d, enc, n) {}

function auth (user, cb) { // client makes id
  if (!user.pass||!user.name) {
    var e = new Error('bad login!')
    e.code = 1
    cb(e, null)
    return false
  }
  if (!isCuid(user.pass)) {
    var sess = cuid()
    sessions[user.name].push(sess)
    cb(null, {key:'@'+user.name,value:sess})
  } else {
    if (_.find(sessions[user.name],function (s){return s===user.pass})) {
      cb(null, {key:'@'+user.name,value:user.pass})
    } else {
      var e = new Error('bad login!')
      e.code = 1
      cb(e, null)
    }
  }
}

function boot (conf, cb) {
  var h = hash('SHA256').update('nimoy').digest('hex')

  // write index
  fs.writeFileSync(__dirname+'/static/index.html',
    '<!doctype html>' +
    '' +
    '<meta charset="utf-8">' +
    '' +
    '<title></title>' +
    '<link rel="stylesheet" href="/style.css">' +
    '' +
    '' +
    '' +
    '' +
    ''
  )

  startServer(conf, db, function () {
    cb(server.close)
  })
}

function compile (conf, cb) {
  if (!fs.existsSync(__dirname+'/static')) fs.mkdir(__dirname+'/static')
  if (!fs.existsSync(__dirname+'/static/files'))fs.mkdir(__dirname+'/static/files')

  db = level(__dirname+'/'+conf.host)
             .on('error', handleErrs)
  livestream.install(db)
  multiLevel.writeManifest(db, __dirname+'/static/manifest.json')

  var IN = __dirname + '/_client.js'
  var OUT = __dirname + '/'+conf.path_static+'/bundle.js'
  var b = browserify(IN)
  var library  = {}

  var folders = fs.readdirSync(__dirname+'/node_modules')

  // also compile the core lib

  asyncMap(folders, function compileModule (dir, next) {
    var folder = __dirname +'/node_modules/'+dir

    if (dir[0]!=='.') {
      var pkg = (fs.existsSync(folder))
        ? JSON.parse(fs.readFileSync(folder+'/package.json',{encoding:'utf8'}))
        : null

      if (pkg.nimoy) {
        library[pkg.name] = pkg
        b.require(folder+'/'+pkg.main, {expose: pkg.name})
      }
    }
    next()
  }, function end () {
    library.env = {port: conf.port, host: conf.host}
    fs.writeFileSync(__dirname+'/library.json', JSON.stringify(library))
    var bundleJS = fs.createWriteStream(OUT)
    b.transform('brfs')
    cb(null,b.bundle())
  })
}

function startServer (conf, db, cb) {
  var mount = st({
    index: 'index.html',
    path: __dirname+'/'+conf.path_static,
    url: '/',
    passthrough: true
  })

  if (!conf.ssl) {
    server = http.createServer(handleHttp)
  } else {
    server = https.createServer({
      honorCipherOrder : true,
      key : fs.readFileSync(conf.ssl.key),
      cert : fs.readFileSync(conf.ssl.cert),
      cipher : 'ecdh+aesgcm:dh+aesgcm:ecdh+aes256:dh+aes256:' +
               'ecdh+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:' +
               'RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'
    }, handleHttp)
  }

  function handleHttp (req, res) {
    res.setHeader('X-Frame-Options', 'Deny')
    if (conf.ssl)
      res.setHeader('Strict-Transport-Security','max-age=31536000')
    if (req.url === '/upload' && req.method === 'POST') {
      fileUpload(req, res)
    } else {
      mount(req, res, function err () {
        res.end('')
      })
    }
  }

  function handleSoc (soc) {
    soc.pipe(multiLevel.server(db, {
    auth: auth,
    access: function access (user, db, method, args) {
      if (!user || user.name !== 'edit') {
        if (/^put|^del|^batch|write/i.test(method)) { // no write access!
          throw new Error('read-only access');
        }
      }
    }})).pipe(soc)
    soc.on('error', console.error)
  }

  server.listen(conf.port, conf.host, cb)

  if (conf.soc==='engine') {
    engineServer(handleSoc, {cookie:false})
      .attach(server, '/ws')
  } else if (conf.soc==='ws' || !conf.soc) {
    var wss = new websocServer({server:server})
    wss.on('connection', function (soc) {
      var s = wsStream(soc)
      handleSoc(s)
    })
  }
}

function fileUpload (req, res) { // replace w. external!?
  var form = new formidable.IncomingForm()
  form.parse(req, function(err, fields, files) {
    var filePath = __dirname+'/static/files/'+fields.file
    var blob = fields.blob.split(',')[1]
    res.writeHead(200, {'content-type': 'text/plain'})
    res.write('received upload:\n\n')
    res.end()
    fs.writeFile(filePath, blob, {encoding:'base64'}, function (e) {
      if (!e) db.put('file:'+fields.id, '/files/'+fields.file)
    })
  })
}

function handleErrs (e) { console.error(e) }

function isCuid (id) {
  var r = (typeof id==='string' && id.length===25 && id[0]==='c')
    ? true : false
  return r
}
<commit_msg>nimoy saves bundle to file instead of streaming weirdness<commit_after>var fs = require('fs')
var url = require('url')
var http = require('http')
var https = require('https')
var level = require('level')
var _ = require('underscore')
var emitter = require('events').EventEmitter
var livestream = require('level-live-stream')
var engineServer = require('engine.io-stream')
var websocServer = require('ws').Server
var wsStream = require('websocket-stream')
var asyncMap = require('slide').asyncMap
var hash = require('crypto').createHash
var multiLevel = require('multilevel')
var browserify = require('browserify')
var formidable = require('formidable')
var uglify = require('uglify-js')
var through = require('through2')
var path = require('path')
var cuid = require('cuid')
var st = require('st')

var sessions = {edit:[]}
var users = {}
var pass

// allow websock \ swap (engine.io or ws)
module.exports.boot = boot
module.exports.cli = through.obj(cli) // new brico then pipe into process
module.exports.compile = compile
module.exports.upload = fileUpload
module.exports.auth = auth

var db

function cli (d, enc, n) {}

function auth (user, cb) { // client makes id
  if (!user.pass||!user.name) {
    var e = new Error('bad login!')
    e.code = 1
    cb(e, null)
    return false
  }
  if (!isCuid(user.pass)) {
    var sess = cuid()
    sessions[user.name].push(sess)
    cb(null, {key:'@'+user.name,value:sess})
  } else {
    if (_.find(sessions[user.name],function (s){return s===user.pass})) {
      cb(null, {key:'@'+user.name,value:user.pass})
    } else {
      var e = new Error('bad login!')
      e.code = 1
      cb(e, null)
    }
  }
}

function boot (conf, cb) {
  if (!fs.existsSync(__dirname+'/static')) fs.mkdir(__dirname+'/static')
  if (!fs.existsSync(__dirname+'/static/files'))fs.mkdir(__dirname+'/static/files')

  db = level(__dirname+'/'+conf.host)
             .on('error', handleErrs)
  livestream.install(db)
  multiLevel.writeManifest(db, __dirname+'/static/manifest.json')

  var h = hash('SHA256').update('nimoy').digest('hex')

  // write index
  fs.writeFileSync(__dirname+'/static/index.html',
    '<!doctype html>' +
    '' +
    '<meta charset="utf-8">' +
    '' +
    '<title></title>' +
    '<link rel="stylesheet" href="/style.css">' +
    '' +
    '' +
    '' +
    '' +
    ''
  )

  startServer(conf, db, function () {
    cb(server.close)
  })
}

function compile (conf, cb) {
  var IN = __dirname + '/_client.js'
  var OUT = __dirname + '/'+conf.path_static+'/bundle.js'
  var MODULES = __dirname + '/' + conf.path_modules
  var b = browserify(IN)
  var library  = {}

  var folders = fs.readdirSync(MODULES)

  // also compile the core lib
  asyncMap(folders, function compileModule (dir, next) {
    var folder = __dirname +'/'+conf.path_modules+dir
    if (!fs.statSync(folder).isDirectory()) {next();return false}
    if (dir[0]!=='.') {
      var pkg = (fs.existsSync(folder))
        ? JSON.parse(fs.readFileSync(folder+'/package.json',{encoding:'utf8'}))
        : null

      if (pkg && pkg.nimoy) {
        library[pkg.name] = pkg
        b.require(folder+'/'+pkg.main, {expose: pkg.name})
      }
    }
    next()
  }, function end () {
    library.env = {port: conf.port, host: conf.host}
    fs.writeFileSync(__dirname+'/library.json', JSON.stringify(library))
    var bundleJS = fs.createWriteStream(OUT)
    b.transform('brfs')
    b.bundle().pipe(bundleJS)
    bundleJS.on('finish', cb)
  })
}

function startServer (conf, db, cb) {
  var mount = st({
    index: 'index.html',
    path: __dirname+'/'+conf.path_static,
    url: '/',
    passthrough: true
  })

  if (!conf.ssl) {
    server = http.createServer(handleHttp)
  } else {
    server = https.createServer({
      honorCipherOrder : true,
      key : fs.readFileSync(conf.ssl.key),
      cert : fs.readFileSync(conf.ssl.cert),
      cipher : 'ecdh+aesgcm:dh+aesgcm:ecdh+aes256:dh+aes256:' +
               'ecdh+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:' +
               'RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'
    }, handleHttp)
  }

  function handleHttp (req, res) {
    res.setHeader('X-Frame-Options', 'Deny')
    if (conf.ssl)
      res.setHeader('Strict-Transport-Security','max-age=31536000')
    if (req.url === '/upload' && req.method === 'POST') {
      fileUpload(req, res)
    } else {
      mount(req, res, function err () {
        res.end('')
      })
    }
  }

  function handleSoc (soc) {
    soc.pipe(multiLevel.server(db, {
    auth: auth,
    access: function access (user, db, method, args) {
      if (!user || user.name !== 'edit') {
        if (/^put|^del|^batch|write/i.test(method)) { // no write access!
          throw new Error('read-only access');
        }
      }
    }})).pipe(soc)
    soc.on('error', console.error)
  }

  server.listen(conf.port, conf.host, cb)

  if (conf.soc==='engine') {
    engineServer(handleSoc, {cookie:false})
      .attach(server, '/ws')
  } else if (conf.soc==='ws' || !conf.soc) {
    var wss = new websocServer({server:server})
    wss.on('connection', function (soc) {
      var s = wsStream(soc)
      handleSoc(s)
    })
  }
}

function fileUpload (req, res) { // replace w. external!?
  var form = new formidable.IncomingForm()
  form.parse(req, function(err, fields, files) {
    var filePath = __dirname+'/static/files/'+fields.file
    var blob = fields.blob.split(',')[1]
    res.writeHead(200, {'content-type': 'text/plain'})
    res.write('received upload:\n\n')
    res.end()
    fs.writeFile(filePath, blob, {encoding:'base64'}, function (e) {
      if (!e) db.put('file:'+fields.id, '/files/'+fields.file)
    })
  })
}

function handleErrs (e) { console.error(e) }

function isCuid (id) {
  var r = (typeof id==='string' && id.length===25 && id[0]==='c')
    ? true : false
  return r
}
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var isCustomDelimiter = function(str) {
    return str[0] === '/' && str[1] === '/';
};

var stripDelimiter = function(str) {
    return isCustomDelimiter(str) ? str.substr(4) : str;
};

var getDelimiter = function(str) {
    return isCustomDelimiter(str) ? str[2] : ',';
};

var sumValues = function(str, delim) {
    var sum = 0;
    var nums = str.split(delim);

    var invalidValues = [];

    for (var i=0;i<nums.length;++i) {
	var num = nums[i]|0;

	if (num < 0) invalidValues.push(num);

	sum += num;
    }

    if (invalidValues.length !== 0)
	throw new Error('negatives not allowed: ' + num);

    return sum;
};

var stripInvalidCharacters = function(str) {
    return str.replace(/\n/,',');
};

var add = function(str) {
    str = stripInvalidCharacters(str);
    var delim = getDelimiter(str);
    str = stripDelimiter(str);

    return sumValues(str,delim);
};

describe('string calculator', function() {
    describe('add', function() {
	it('should return a 0 for empty string', function() {
	    assert.equal(0, add(''));
	});

	it('should return identity for a single number', function() {
	    assert.equal(1, add('1'));
	});

	it('should return sum for numbers separated by ,', function() {
	    assert.equal(3, add('1,2'));
	});

	it('should handle numbers spparated by newlines', function() {
	    assert.equal(3, add('1\n2'));
	});

	it('should support different delimiters', function() {
	    assert.equal(3, add('//;\n1;2'));
	});

	it('should not support negative numbers', function() {
	    assert.throws(function() {
		add('-1');
	    }, function(err) {
		assert(err.message.indexOf('-1') !== -1);
		return true;
	    });
	});

	it('should display all negative numbers', function() {
	    assert.throws(function() { add('-1,-2'); },
			  function(err) {
			      assert(err.message.indexOf('-1') !== -1);
			      assert(err.message.indexOf('-2') !== -1);
			      return true;
			  });
	});
    });
});

<commit_msg>displays all invalid things<commit_after>"use strict";

var assert = require('assert');

var isCustomDelimiter = function(str) {
    return str[0] === '/' && str[1] === '/';
};

var stripDelimiter = function(str) {
    return isCustomDelimiter(str) ? str.substr(4) : str;
};

var getDelimiter = function(str) {
    return isCustomDelimiter(str) ? str[2] : ',';
};

var sumValues = function(str, delim) {
    var sum = 0;
    var nums = str.split(delim);

    var invalidValues = [];

    for (var i=0;i<nums.length;++i) {
	var num = nums[i]|0;

	if (num < 0) invalidValues.push(num);

	sum += num;
    }

    if (invalidValues.length !== 0)
	throw new Error('negatives not allowed: ' + invalidValues);

    return sum;
};

var stripInvalidCharacters = function(str) {
    return str.replace(/\n/,',');
};

var add = function(str) {
    str = stripInvalidCharacters(str);
    var delim = getDelimiter(str);
    str = stripDelimiter(str);

    return sumValues(str,delim);
};

describe('string calculator', function() {
    describe('add', function() {
	it('should return a 0 for empty string', function() {
	    assert.equal(0, add(''));
	});

	it('should return identity for a single number', function() {
	    assert.equal(1, add('1'));
	});

	it('should return sum for numbers separated by ,', function() {
	    assert.equal(3, add('1,2'));
	});

	it('should handle numbers spparated by newlines', function() {
	    assert.equal(3, add('1\n2'));
	});

	it('should support different delimiters', function() {
	    assert.equal(3, add('//;\n1;2'));
	});

	it('should not support negative numbers', function() {
	    assert.throws(function() {
		add('-1');
	    }, function(err) {
		assert(err.message.indexOf('-1') !== -1);
		return true;
	    });
	});

	it('should display all negative numbers', function() {
	    assert.throws(function() { add('-1,-2'); },
			  function(err) {
			      assert(err.message.indexOf('-1') !== -1);
			      assert(err.message.indexOf('-2') !== -1);
			      return true;
			  });
	});
    });
});

<|endoftext|>


<commit_before>var exec = require('cordova/exec');

var AudioPlugin = {
    create: function (successCallback, errorCallback, url) {
        exec(successCallback, errorCallback, 'AudioPlugin', 'play', [url]);
    },
    play: function (successCallback, errorCallback, url) {
        exec(successCallback, errorCallback, 'AudioPlugin', 'play', []);
    },
    pause: function(successCallback, errorCallback) {
        exec(successCallback, errorCallback, 'AudioPlugin', 'pause', []);
    },
    stop: function(successCallback, errorCallback, ) {
        exec(successCallback, errorCallback, 'AudioPlugin', 'stop', []);
    }
};

module.exports = AudioPlugin;

<commit_msg>fix stop method signature syntax error<commit_after>var exec = require('cordova/exec');

var AudioPlugin = {
    create: function (successCallback, errorCallback, url) {
        exec(successCallback, errorCallback, 'AudioPlugin', 'play', [url]);
    },
    play: function (successCallback, errorCallback, url) {
        exec(successCallback, errorCallback, 'AudioPlugin', 'play', []);
    },
    pause: function(successCallback, errorCallback) {
        exec(successCallback, errorCallback, 'AudioPlugin', 'pause', []);
    },
    stop: function(successCallback, errorCallback) {
        exec(successCallback, errorCallback, 'AudioPlugin', 'stop', []);
    }
};

module.exports = AudioPlugin;

<|endoftext|>


<commit_before>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

// Functions

// Complete the `minimum` exercise.

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.
<commit_msg>Finish 7.2<commit_after>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.

var name = "Jon";
console.log(name);

// Write a short program that asks for a user to input their favorite food. After they hit return, have the program respond with "Hey! That's my favorite too!" (You will probably need to run this in the Chrome console (Links to an external site.) rather than node since node does not support prompt or alert). Paste your program into the eloquent.js file.

prompt("What is your favorite food?");
alert("That's my favorite food too!");

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

// Triangle

for (var i = 1; i <= 7; i++){
  var hashes = "";
  for (var j = 1; j <= i; j++){
    hashes += "#";
  }
  console.log(hashes);
}

// FizzBuzz

// Iterate from 1 through 100
// When the modulo of 15 is zero, print FizzBuzz
// When the modulo of 5 is zero, print Buzz
// When the modulo of 3 is zero, print Fizz
// Otherwise print the number

for (var i = 1; i <= 100; i++){
  if ((i % 5 === 0) && (i % 3 === 0))
    console.log("FizzBuzz");
  else if (i % 5 === 0)
    console.log("Buzz");
  else if (i % 3 === 0)
    console.log("Fizz");
  else
    console.log(i);
}

// Functions

// Complete the `minimum` exercise.

function min(num1, num2){
  if (num1 < num2)
    return num1;
  else
    return num2;
}

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.

var me = {
  name: "Jon",
  age: 29,
  favoriteFoods: ["Pomelo", "Burrata", "Ribeye"],
  quirk: "Warren Buffett is my hero"
};
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var sumArrayOfStringsAsInts = function(n) {
    var sum = 0;

    var errors = [];

    for (var i=0;i<n.length;++i) {
      var num = n[i]|0;
      if (num < 0) {
        errors.push(num);
      }

      if (num < 1000) {
        sum += num;
      }
    }

    if (errors.length) { throw Error('negatives not allowed: ' + errors); }

    return sum;
};

var tokenize = function(s, delim) {
  s = s.replace(/\n/g, delim);
  return s.split(delim);
};

var StringCalculator = function() {
  StringCalculator.prototype.add = function(s) {
    if (s.length === 0) {
      return 0;
    }

    var result = getDelimiter(s);
    var tokens = tokenize(result.line,result.delimiter);
    return sumArrayOfStringsAsInts(tokens);
  };
  return this;
};

var hasCustomDelimiter = function(s) {
  return s.indexOf('//') === 0;
};

var getDelimiter = function(s) {
  if (hasCustomDelimiter(s)) {
    return {
      delimiter: s.substr(2, s.indexOf('\n') - 2),
      line: s.substr(s.indexOf('\n') + 1)
    };
  }

  return { delimiter: ',', line: s };
};

describe('string calculator', function() {
  it('exists', function() {
    assert(new StringCalculator());
  });

  it('has an add method', function() {
    assert(new StringCalculator().add);
  });

  describe('delimiters', function() {
    it('knows about custom delimters', function() {
      assert(hasCustomDelimiter('//q\n1q2q3'));
    });

    it('ignores normal delimters', function() {
      assert(!hasCustomDelimiter('1,2,3'));
    });

    it('returns delimiter', function() {
      var s = getDelimiter('//q\n1q2q3');
      assert('q', s.delimiter);
    });

    it('returns default delimiters', function() {
      var s = getDelimiter('1,2,3');
      assert(',', s.delimiter);
    });

    it('consumes some of the string', function() {
      assert.equal('1,2,3', getDelimiter('1,2,3').line);
      assert.equal('1q2q3', getDelimiter('//q\n1q2q3').line);
    });
  });

  describe('add method', function() {
    var stringCalculator = new StringCalculator();

    it('0 args', function() {
      assert.equal(0, stringCalculator.add(''));
    });

    it('1 arg', function() {
      assert.equal(55, stringCalculator.add('55'));
    });

    it('2 args', function() {
      assert.equal(74, stringCalculator.add('69,5'));
    });

    it('n args', function() {
      assert.equal(1+2+3+4+5, stringCalculator.add('1,2,3,4,5'));
    });

    it('handles new lines as separators', function() {
      assert.equal(1+2+3, stringCalculator.add('1\n2\n3'));
    });

    it('supports delimiters', function() {
      assert.equal(1+2+3, stringCalculator.add('//q\n1q2q3'));
    });

    it('dislikes negatives', function() {
      assert.throws(function() {
        stringCalculator.add('1,-2,3');
      });
    });

    it('lists all negatives', function() {
      assert.throws(function() { stringCalculator.add('-1,-2,-3'); }, function(e) { return e.message.indexOf('-1,-2,-3') !== -1; });
    });

    it('numbers > 1000 ignored', function() {
      assert.equal(0, stringCalculator.add('1001'));
    });

    it('supports delims of any length', function() {
      assert.equal(6, stringCalculator.add('//[***]\n1***2***3'));
    });
  });
});<commit_msg>time for a quick string calculator kata<commit_after><|endoftext|>


<commit_before>---
---

var healthApp = angular.module("healthApp", ['ngRoute'])
.config(function($routeProvider, $locationProvider){
    $routeProvider.when("/help", {
        templateUrl: "help.html",
        controller: "IndexCtrl",
    });

    $routeProvider.when("/about", {
        templateUrl: "about.html",
        controller: "IndexCtrl",
    });

    $routeProvider.when("/sms", {
        templateUrl: "sms.html",
        controller: "IndexCtrl",
    });

    $routeProvider.when("/", {
        templateUrl: "search.html",
        controller: "SearchCtrl",
    });
});

healthApp.controller('IndexCtrl', ['$scope', '$http', function($scope, $http){

}]);

healthApp.controller('SearchCtrl', ['$scope', '$http', '$location', function($scope, $http, $location){
    $scope.searchLocation = ($location.search()).l;
    $scope.geocodeError = false;
    $scope.noResultsError = false;
    $scope.lat = ($location.search()).lat;
    $scope.lon = ($location.search()).lon;
    $scope.dist = ($location.search()).d || 1609;
    $scope.searchType = ($location.search()).typ;

    // $scope.map = new google.maps.Map(document.getElementById("map-canvas"), {zoom: 12, mapTypeId: google.maps.MapTypeId.ROADMAP});

    $scope.doGeocode = function(){
        // hit google for lat/lng
        var geocoder = new google.maps.Geocoder();

        geocoder.geocode( { 'address': $scope.searchLocation + " chicago, il"}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                $scope.lat = results[0].geometry.location.ob;
                $scope.lon = results[0].geometry.location.pb;

                $scope.doSearch();

                // $scope.map.setCenter(results[0].geometry.location);
                //                     $scope.map.setZoom(14)
                //                     var marker = new google.maps.Marker({
                //                         map: $scope.map,
                //                         position: results[0].geometry.location
                //                     });
                $scope.geocodeError = false
            } else {
                $scope.geocodeError = true
                console.log("Geocode was not successful for the following reason: " + status);
            }

            $scope.updatePath();
        });
    };

    if($location.search().s == "1"){ $scope.doGeocode() };

    $scope.updatePath = function(){
        $location.path("/").search({
            l: $scope.searchLocation,
            typ: $scope.searchType,
            lat: $scope.lat,
            lon: $scope.lon,
            d: $scope.dist,
            s: 1
        });
    }

    $scope.doSearch = function(){

        // hit API for nearby health providers
        $http.jsonp("{{ site.api_url }}/search",
                    { params: {
                        lat: $scope.lat,
                        lon: $scope.lon,
                        dist: $scope.dist,
                        searchType: $scope.searchType,
                        callback: "JSON_CALLBACK" } }
        )
        .success(function(data){
            $scope.noResultsError = false;
            $scope.searchResults = angular.copy(data);
        })
        .error(function(data, status, headers, config){
            $scope.noResultsError = true;
            $scope.searchResults = []
        });
    };
}]);<commit_msg>adding proper GA tracking for angular<commit_after>---
---

// h/t http://stackoverflow.com/a/12262820/1247272
angular.module('analytics', ['ng']).service('analytics', [
      '$rootScope', '$window', '$location', function($rootScope, $window, $location) {
        var track = function() {
            ga('send', 'pageview', {'page': $location.path()});
        };
      $rootScope.$on('$routeChangeSuccess', track);
    }
]);

var healthApp = angular.module("healthApp", ['ngRoute', 'analytics'])
.config(function($routeProvider, $locationProvider){
    $routeProvider.when("/help", {
        templateUrl: "help.html",
        controller: "IndexCtrl",
    });

    $routeProvider.when("/about", {
        templateUrl: "about.html",
        controller: "IndexCtrl",
    });

    $routeProvider.when("/sms", {
        templateUrl: "sms.html",
        controller: "IndexCtrl",
    });

    $routeProvider.when("/", {
        templateUrl: "search.html",
        controller: "SearchCtrl",
    });
});

healthApp.controller('IndexCtrl', ['$scope', '$http', 'analytics', function($scope, $http, analytics){

}]);

healthApp.controller('SearchCtrl', ['$scope', '$http', '$location', 'analytics', function($scope, $http, $location, analytics){
    $scope.searchLocation = ($location.search()).l;
    $scope.geocodeError = false;
    $scope.noResultsError = false;
    $scope.lat = ($location.search()).lat;
    $scope.lon = ($location.search()).lon;
    $scope.dist = ($location.search()).d || 1609;
    $scope.searchType = ($location.search()).typ;

    // $scope.map = new google.maps.Map(document.getElementById("map-canvas"), {zoom: 12, mapTypeId: google.maps.MapTypeId.ROADMAP});

    $scope.doGeocode = function(){
        // hit google for lat/lng
        var geocoder = new google.maps.Geocoder();

        geocoder.geocode( { 'address': $scope.searchLocation + " chicago, il"}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                $scope.lat = results[0].geometry.location.ob;
                $scope.lon = results[0].geometry.location.pb;

                $scope.doSearch();

                // $scope.map.setCenter(results[0].geometry.location);
                //                     $scope.map.setZoom(14)
                //                     var marker = new google.maps.Marker({
                //                         map: $scope.map,
                //                         position: results[0].geometry.location
                //                     });
                $scope.geocodeError = false
            } else {
                $scope.geocodeError = true
                console.log("Geocode was not successful for the following reason: " + status);
            }

            $scope.updatePath();
        });
    };

    if($location.search().s == "1"){ $scope.doGeocode() };

    $scope.updatePath = function(){
        $location.path("/").search({
            l: $scope.searchLocation,
            typ: $scope.searchType,
            lat: $scope.lat,
            lon: $scope.lon,
            d: $scope.dist,
            s: 1
        });
    }

    $scope.doSearch = function(){

        // hit API for nearby health providers
        $http.jsonp("{{ site.api_url }}/search",
                    { params: {
                        lat: $scope.lat,
                        lon: $scope.lon,
                        dist: $scope.dist,
                        searchType: $scope.searchType,
                        callback: "JSON_CALLBACK" } }
        )
        .success(function(data){
            $scope.noResultsError = false;
            $scope.searchResults = angular.copy(data);
        })
        .error(function(data, status, headers, config){
            $scope.noResultsError = true;
            $scope.searchResults = []
        });
    };
}]);<|endoftext|>


<commit_before>function debounce(func, wait, immediate) {
  var timeout;
  return function() {
    var context = this,
      args = arguments;
    var later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
}

function throttle(func, wait, scope) {
  wait || (wait = 250);
  var last, deferTimer;
  return function() {
    var context = scope || this;

    var now = +new Date(),
      args = arguments;
    if (last && now < last + wait) {
      clearTimeout(deferTimer);
      deferTimer = setTimeout(function() {
        last = now;
        func.apply(context, args);
      }, wait);
    } else {
      last = now;
      func.apply(context, args);
    }
  };
}

var toggleScrollClass = throttle(function() {
  theHeader = document.getElementsByClassName('storefront-docs-header');
  if (window.scrollY > 100) {
    theHeader[0].classList.add('scrolled');
  } else {
    theHeader[0].classList.remove('scrolled');
  }
}, 250);

window.addEventListener('load', toggleScrollClass);
window.addEventListener('scroll', toggleScrollClass);
<commit_msg>fix: remove storefront.js file recently removed on master<commit_after><|endoftext|>