<commit_before>/* global CloudCmd */
/* global Util */
/* global DOM */
/* global spero */
/* global remedy */
/* global ishtar */
/* global salam */
/* global omnes */

'use strict';

CloudCmd.Operation = OperationProto;

const currify = require('currify/legacy');
const exec = require('execon');

const RESTful = require('../dom/rest');

function OperationProto(operation, data) {
    const Name = 'Operation';
    const TITLE = CloudCmd.TITLE;
    const {config} = CloudCmd;
    const {Dialog, Images} = DOM;

    let Loaded;

    let {
        cp: copyFn,
        mv: moveFn,
        pack: packFn,
        delete: deleteFn,
        extract: extractFn,
    } = RESTful;

    const Info = DOM.CurrentInfo;
    const showLoad = Images.show.load.bind(null, 'top');
    const Operation = this;

    function init() {
        showLoad();

        exec.series([
            DOM.loadSocket,
            (callback) => {
                if (config('progress'))
                    load((callback) => {
                        create(CloudCmd.PREFIX, callback);
                    });

                callback();
            },
            function() {
                Loaded = true;
                Images.hide();
                Operation.show(operation, data);
            }
        ]);
    }

    function authCheck(spawn, ok) {
        if (!config('auth'))
            return ok();

        spawn.on('accept', ok);
        spawn.on('reject', function() {
            Dialog.alert(TITLE, 'Wrong credentials!');
        });

        spawn.emit('auth', config('username'), config('password'));
    }

    function _initSpero(prefix, fn) {
        spero(prefix + '/spero', prefix, function(copier) {
            fn();

            copier.on('connect', function() {
                authCheck(copier, function() {
                    copyFn = function(data, callback) {
                        setListeners(copier, callback);
                        copier.copy(data.from, data.to, data.names);
                    };
                });
            });

            copier.on('disconnect', function() {
                copyFn = RESTful.cp;
            });
        });
    }

    function _initRemedy(prefix, fn) {
        remedy(prefix + '/remedy', prefix, function(remover) {
            fn();
            remover.on('connect', function() {
                authCheck(remover, function() {
                    deleteFn = function(from, files, callback) {
                        setListeners(remover, callback);
                        from = from.replace(/\?.*/, '');
                        remover.remove(from, files);
                    };
                });
            });

            remover.on('disconnect', function() {
                deleteFn = RESTful.remove;
            });
        });
    }

    function _setPacker(prefix, name, pack, fn) {
        pack(prefix + '/' + name, prefix, function(packer) {
            fn();
            packer.on('connect', function() {
                authCheck(packer, function() {
                    packFn = function(data, callback) {
                        setListeners(packer, {noContinue: true}, callback);
                        packer.pack(data.from, data.to, data.names);
                    };
                });
            });

            packer.on('disconnect', function() {
                packFn = RESTful.pack;
            });
        });
    }

    function _initPacker(prefix, fn) {
        if (config('packer') === 'zip')
            return _setPacker(prefix, 'salam', salam, fn);

        _setPacker(prefix, 'ishtar', ishtar, fn);
    }

    function _initExtractor(prefix, fn) {
        omnes(prefix + '/omnes', prefix, function(packer) {
            fn();
            packer.on('connect', function() {
                authCheck(packer, function() {
                    extractFn = function(data, callback) {
                        setListeners(packer, {noContinue: true}, callback);
                        packer.extract(data.from, data.to);
                    };
                });
            });

            packer.on('disconnect', function() {
                extractFn = RESTful.extract;
            });
        });
    }

    function create(prefix) {
        var initSpero = currify(_initSpero);
        var initRemedy = currify(_initRemedy);
        var initPacker = currify(_initPacker);
        var initExtractor = currify(_initExtractor);

        exec.parallel([
            initSpero(prefix),
            initRemedy(prefix),
            initPacker(prefix),
            initExtractor(prefix)
        ], exec.ret);
    }

    function setListeners(emitter, options, callback) {
        if (!callback) {
            callback = options;
            options = {};
        }

        let done;
        let lastError;

        const listeners = {
            progress: (value) => {
                done = value === 100;
                Images.setProgress(value);
            },

            end: () => {
                Images
                    .hide()
                    .clearProgress();

                Object.keys(listeners).forEach((name) => {
                    emitter.removeListener(name, listeners[name]);
                });

                if (lastError || done)
                    callback(lastError);
            },

            error: (error) => {
                lastError = error;

                if (options.noContinue) {
                    listeners.end(error);
                    Dialog.alert(TITLE, error);
                } else {
                    Dialog.confirm(TITLE, error + '\n Continue?')
                        .then(() => {
                            emitter.continue();
                        }, () => {
                            emitter.abort();
                        });
                }
            }
        };

        const events = Object.keys(listeners);

        events.forEach((name) => {
            emitter.on(name, listeners[name]);
        });
    }

    this.hide   = function() {
        CloudCmd.View.hide();
    };

    this.show = function(operation, data) {
        if (Loaded)
            switch(operation) {
            case 'copy':
                Operation.copy(data);
                break;

            case 'move':
                Operation.move(data);
                break;

            case 'delete':
                Operation.delete();
                break;

            case 'delete:silent':
                Operation.deleteSilent();
                break;

            case 'pack':
                Operation.pack();
                break;

            case 'extract':
                Operation.extract();
                break;
            }
    };

    this.copy           = function(data) {
        processFiles(data, copyFn, message('Copy'));
    };

    this.move           = function(data) {
        processFiles(data, moveFn, message('Rename/Move'));
    };

    this.delete         = function() {
        promptDelete();
    };

    this.deleteSilent   = function() {
        deleteSilent();
    };

    this.pack           = function() {
        var isZip = config('packer') === 'zip';
        twopack('pack', isZip ? 'zip' : 'tar');
    };

    this.extract        = function() {
        var isZip = config('packer') === 'zip';
        twopack('extract', isZip ? 'zip' : 'tar');
    };

     /**
     * prompt and delete current file or selected files
     *
     * @currentFile
     */
    function promptDelete() {
        var type, isDir, msg,
            name        = '',
            msgAsk      = 'Do you really want to delete the ',
            msgSel      = 'selected ',
            files       = DOM.getSelectedFiles(),
            names       = DOM.getFilenames(files),
            i,
            n           = names.length,
            current     = DOM.getCurrentFile();

        if (n) {
            for (i = 0; i < 5 && i < n; i++)
                name += '\n' + names[i];

            if (n >= 5)
                name   += '\n...';

            msg    = msgAsk + msgSel + n + ' files/directories?\n' + name ;
        } else {
            isDir       = DOM.isCurrentIsDir(current);

            if (isDir)
                type    = 'directory';
            else
                type    = 'file';

            type += ' ';

            name   = DOM.getCurrentName(current);
            msg    = msgAsk + msgSel + type + name + '?';
        }

        if (name === '..')
            return Dialog.alert.noFiles(TITLE);

        Dialog.confirm(TITLE, msg, {cancel: false}).then(function() {
            deleteSilent(files);
        });
    }

    /**
     * delete current or selected files
     *
     * @files
     */
    function deleteSilent(files) {
        var n, names,
            query       = '?files',
            path        = Info.dirPath,
            name        = Info.name;

        if (name === '..')
            return Dialog.alert.noFiles(TITLE);

        showLoad();

        if (!files)
            files       = DOM.getSelectedFiles();

        names       = DOM.getFilenames(files),
        n           = names.length;

        if (!n)
            names = [Info.name];

        deleteFn(path + query, names, function(error) {
            var Storage     = DOM.Storage,
                dirPath     = Info.dirPath,
                delCurrent  = DOM.deleteCurrent,
                delSelected = DOM.deleteSelected,
                getByName   = DOM.getCurrentByName;

            if (!error) {
                if (n > 1)
                    delSelected(files);
                else
                    delCurrent(getByName(name));

                Storage.removeMatch(dirPath);
            }
        });
    }

    /*
     * process files (copy or move)
     * @param data
     * @param operation
     */
    function processFiles(data, operation, message) {
        var name, selFiles, files,
            panel,
            shouldAsk,
            sameName,
            ok,

            from        = '',
            to          = '',

            names       = [];

        if (data) {
            from        = data.from;
            to          = data.to;
            names       = data.names;
            panel       = Info.panel;
        } else {
            from        = Info.dirPath;
            to          = DOM.getNotCurrentDirPath();
            selFiles    = DOM.getSelectedFiles();
            names       = DOM.getFilenames(selFiles);
            data        = {};
            shouldAsk   = true;
            panel       = Info.panelPassive;
        }

        if (!names.length)
            names.push(DOM.getCurrentName());

        name = names[0];

        sameName = !!DOM.getCurrentByName(name, panel);

        if (name === '..')
            return Dialog.alert.noFiles(TITLE);

        if (shouldAsk)
            return message(to, names).then(ask);

        ask(to);

        function ask(to) {
            ok = from !== to && to;

            if (ok && !shouldAsk || !sameName)
                return go();

            const str = `"${ name }" already exist. Overwrite?`;
            const cancel = false;

            Dialog.confirm(TITLE, str, {cancel}).then(go);

            function go() {
                showLoad();

                files   = {
                    from    : from,
                    to      : to,
                    names   : names
                };

                operation(files, function(error) {
                    !error && DOM.Storage.remove(from, function() {
                        var panel           = Info.panel,
                            panelPassive    = Info.panelPassive,
                            setCurrent      = function() {
                                if (!name)
                                    name = data.names[0];

                                DOM.setCurrentByName(name);
                            };

                        if (!Info.isOnePanel)
                            CloudCmd.refresh({
                                panel: panelPassive,
                                noCurrent: true,
                            });

                        CloudCmd.refresh({panel}, setCurrent);
                    });
                });
            }
        }
    }

    function getTypeReg(type) {
        if (type === 'zip')
            return /\.zip$/;

        return /\.tar\.gz$/;
    }

    function checkEmpty(name, operation) {
        if (!operation)
            throw Error(name + ' could not be empty!');
    }

    function twopack(operation, type) {
        let op;
        let fileFrom;
        let currentName = Info.name;

        const Images = DOM.Images;
        const path = Info.path;
        const dirPath = Info.dirPath;
        const activeFiles = DOM.getActiveFiles();
        const names = DOM.getFilenames(activeFiles);

        checkEmpty('operation', operation);

        if (!names.length)
            return Dialog.alert.noFiles(TITLE);

        switch(operation) {
        case 'extract':
            op = extractFn;

            fileFrom   = {
                from    : path,
                to      : dirPath
            };

            currentName = currentName.replace(getTypeReg(type), '');

            break;

        case 'pack':
            op = packFn;

            if (names.length > 1)
                currentName  = Info.dir;

            currentName += DOM.getPackerExt(type);

            fileFrom = {
                from: dirPath,
                to: dirPath + currentName,
                names,
            };
            break;
        }

        Images.show.load('top');

        op(fileFrom, (error) => {
            !error && CloudCmd.refresh({
                currentName
            });
        });
    }

    function message(msg) {
        return function(to, names) {
            var promise,
                n       = names.length,
                name    = names[0];

            msg += ' ';

            if (names.length > 1)
                msg     += n + ' file(s)';
            else
                msg     += '"' + name + '"';

            msg         += ' to';

            promise = Dialog.prompt(TITLE, msg, to, {cancel: false});

            return promise;
        };
    }

    function load(callback) {
        const prefix = CloudCmd.PREFIX;
        const files = [
            '/spero/spero.js',
            '/remedy/remedy.js',
            '/ishtar/ishtar.js',
            '/salam/salam.js',
            '/omnes/omnes.js'
        ].map((name) => {
            return prefix + name;
        });

        DOM.load.parallel(files, (error) => {
            if (error)
                return Dialog.alert(TITLE, error.message);

            Loaded = true;
            Util.timeEnd(Name + ' load');
            exec(callback);
        });

        Util.time(Name + ' load');
    }

    init();
}

<commit_msg>chore(operation) function -> arrow function<commit_after>/* global CloudCmd */
/* global Util */
/* global DOM */
/* global spero */
/* global remedy */
/* global ishtar */
/* global salam */
/* global omnes */

'use strict';

CloudCmd.Operation = OperationProto;

const currify = require('currify/legacy');
const exec = require('execon');

const RESTful = require('../dom/rest');

function OperationProto(operation, data) {
    const Name = 'Operation';
    const TITLE = CloudCmd.TITLE;
    const {config} = CloudCmd;
    const {Dialog, Images} = DOM;

    let Loaded;

    let {
        cp: copyFn,
        mv: moveFn,
        pack: packFn,
        delete: deleteFn,
        extract: extractFn,
    } = RESTful;

    const Info = DOM.CurrentInfo;
    const showLoad = Images.show.load.bind(null, 'top');
    const Operation = this;

    function init() {
        showLoad();

        exec.series([
            DOM.loadSocket,
            (callback) => {
                if (config('progress'))
                    load((callback) => {
                        create(CloudCmd.PREFIX, callback);
                    });

                callback();
            },
            () => {
                Loaded = true;
                Images.hide();
                Operation.show(operation, data);
            }
        ]);
    }

    function authCheck(spawn, ok) {
        if (!config('auth'))
            return ok();

        spawn.on('accept', ok);
        spawn.on('reject', () => {
            Dialog.alert(TITLE, 'Wrong credentials!');
        });

        spawn.emit('auth', config('username'), config('password'));
    }

    function _initSpero(prefix, fn) {
        spero(prefix + '/spero', prefix, (copier) => {
            fn();

            copier.on('connect', () => {
                authCheck(copier, () => {
                    copyFn = (data, callback) => {
                        setListeners(copier, callback);
                        copier.copy(data.from, data.to, data.names);
                    };
                });
            });

            copier.on('disconnect', () => {
                copyFn = RESTful.cp;
            });
        });
    }

    function _initRemedy(prefix, fn) {
        remedy(prefix + '/remedy', prefix, (remover) => {
            fn();
            remover.on('connect', () => {
                authCheck(remover, () => {
                    deleteFn = (from, files, callback) => {
                        setListeners(remover, callback);
                        from = from.replace(/\?.*/, '');
                        remover.remove(from, files);
                    };
                });
            });

            remover.on('disconnect', () => {
                deleteFn = RESTful.remove;
            });
        });
    }

    function _setPacker(prefix, name, pack, fn) {
        pack(prefix + '/' + name, prefix, (packer) => {
            fn();
            packer.on('connect', () => {
                authCheck(packer, () => {
                    packFn = (data, callback) => {
                        setListeners(packer, {noContinue: true}, callback);
                        packer.pack(data.from, data.to, data.names);
                    };
                });
            });

            packer.on('disconnect', () => {
                packFn = RESTful.pack;
            });
        });
    }

    function _initPacker(prefix, fn) {
        if (config('packer') === 'zip')
            return _setPacker(prefix, 'salam', salam, fn);

        _setPacker(prefix, 'ishtar', ishtar, fn);
    }

    function _initExtractor(prefix, fn) {
        omnes(prefix + '/omnes', prefix, (packer) => {
            fn();
            packer.on('connect', () => {
                authCheck(packer, () => {
                    extractFn = (data, callback) => {
                        setListeners(packer, {noContinue: true}, callback);
                        packer.extract(data.from, data.to);
                    };
                });
            });

            packer.on('disconnect', () => {
                extractFn = RESTful.extract;
            });
        });
    }

    function create(prefix) {
        const initSpero = currify(_initSpero);
        const initRemedy = currify(_initRemedy);
        const initPacker = currify(_initPacker);
        const initExtractor = currify(_initExtractor);

        exec.parallel([
            initSpero(prefix),
            initRemedy(prefix),
            initPacker(prefix),
            initExtractor(prefix)
        ], exec.ret);
    }

    function setListeners(emitter, options, callback) {
        if (!callback) {
            callback = options;
            options = {};
        }

        let done;
        let lastError;

        const listeners = {
            progress: (value) => {
                done = value === 100;
                Images.setProgress(value);
            },

            end: () => {
                Images
                    .hide()
                    .clearProgress();

                Object.keys(listeners).forEach((name) => {
                    emitter.removeListener(name, listeners[name]);
                });

                if (lastError || done)
                    callback(lastError);
            },

            error: (error) => {
                lastError = error;

                if (options.noContinue) {
                    listeners.end(error);
                    Dialog.alert(TITLE, error);
                    return;
                }

                Dialog.confirm(TITLE, error + '\n Continue?')
                    .then(() => {
                        emitter.continue();
                    }, () => {
                        emitter.abort();
                    });
            }
        };

        const events = Object.keys(listeners);

        events.forEach((name) => {
            emitter.on(name, listeners[name]);
        });
    }

    this.hide = () => {
        CloudCmd.View.hide();
    };

    this.show = (operation, data) => {
        if (Loaded)
            switch(operation) {
            case 'copy':
                Operation.copy(data);
                break;

            case 'move':
                Operation.move(data);
                break;

            case 'delete':
                Operation.delete();
                break;

            case 'delete:silent':
                Operation.deleteSilent();
                break;

            case 'pack':
                Operation.pack();
                break;

            case 'extract':
                Operation.extract();
                break;
            }
    };

    this.copy = (data) => {
        processFiles(data, copyFn, message('Copy'));
    };

    this.move = (data) => {
        processFiles(data, moveFn, message('Rename/Move'));
    };

    this.delete = () => {
        promptDelete();
    };

    this.deleteSilent = () => {
        deleteSilent();
    };

    this.pack = () => {
        const isZip = config('packer') === 'zip';
        twopack('pack', isZip ? 'zip' : 'tar');
    };

    this.extract = () => {
        const isZip = config('packer') === 'zip';
        twopack('extract', isZip ? 'zip' : 'tar');
    };

     /**
     * prompt and delete current file or selected files
     *
     * @currentFile
     */
    function promptDelete() {
        var type, isDir, msg,
            name        = '',
            msgAsk      = 'Do you really want to delete the ',
            msgSel      = 'selected ',
            files       = DOM.getSelectedFiles(),
            names       = DOM.getFilenames(files),
            i,
            n           = names.length,
            current     = DOM.getCurrentFile();

        if (n) {
            for (i = 0; i < 5 && i < n; i++)
                name += '\n' + names[i];

            if (n >= 5)
                name   += '\n...';

            msg    = msgAsk + msgSel + n + ' files/directories?\n' + name ;
        } else {
            isDir       = DOM.isCurrentIsDir(current);

            if (isDir)
                type    = 'directory';
            else
                type    = 'file';

            type += ' ';

            name   = DOM.getCurrentName(current);
            msg    = msgAsk + msgSel + type + name + '?';
        }

        if (name === '..')
            return Dialog.alert.noFiles(TITLE);

        Dialog.confirm(TITLE, msg, {cancel: false}).then(() => {
            deleteSilent(files);
        });
    }

    /**
     * delete current or selected files
     *
     * @files
     */
    function deleteSilent(files) {
        var n, names,
            query       = '?files',
            path        = Info.dirPath,
            name        = Info.name;

        if (name === '..')
            return Dialog.alert.noFiles(TITLE);

        showLoad();

        if (!files)
            files       = DOM.getSelectedFiles();

        names       = DOM.getFilenames(files),
        n           = names.length;

        if (!n)
            names = [Info.name];

        deleteFn(path + query, names, (error) => {
            var Storage     = DOM.Storage,
                dirPath     = Info.dirPath,
                delCurrent  = DOM.deleteCurrent,
                delSelected = DOM.deleteSelected,
                getByName   = DOM.getCurrentByName;

            if (!error) {
                if (n > 1)
                    delSelected(files);
                else
                    delCurrent(getByName(name));

                Storage.removeMatch(dirPath);
            }
        });
    }

    /*
     * process files (copy or move)
     * @param data
     * @param operation
     */
    function processFiles(data, operation, message) {
        var name, selFiles, files,
            panel,
            shouldAsk,
            sameName,
            ok,

            from        = '',
            to          = '',

            names       = [];

        if (data) {
            from        = data.from;
            to          = data.to;
            names       = data.names;
            panel       = Info.panel;
        } else {
            from        = Info.dirPath;
            to          = DOM.getNotCurrentDirPath();
            selFiles    = DOM.getSelectedFiles();
            names       = DOM.getFilenames(selFiles);
            data        = {};
            shouldAsk   = true;
            panel       = Info.panelPassive;
        }

        if (!names.length)
            names.push(DOM.getCurrentName());

        name = names[0];

        sameName = !!DOM.getCurrentByName(name, panel);

        if (name === '..')
            return Dialog.alert.noFiles(TITLE);

        if (shouldAsk)
            return message(to, names).then(ask);

        ask(to);

        function ask(to) {
            ok = from !== to && to;

            if (ok && !shouldAsk || !sameName)
                return go();

            const str = `"${ name }" already exist. Overwrite?`;
            const cancel = false;

            Dialog.confirm(TITLE, str, {cancel}).then(go);

            function go() {
                showLoad();

                files   = {
                    from    : from,
                    to      : to,
                    names   : names
                };

                operation(files, (error) => {
                    !error && DOM.Storage.remove(from, () => {
                        const panel = Info.panel;
                        const panelPassive = Info.panelPassive;
                        const setCurrent = () => {
                            if (!name)
                                name = data.names[0];

                            DOM.setCurrentByName(name);
                        };

                        if (!Info.isOnePanel)
                            CloudCmd.refresh({
                                panel: panelPassive,
                                noCurrent: true,
                            });

                        CloudCmd.refresh({panel}, setCurrent);
                    });
                });
            }
        }
    }

    function getTypeReg(type) {
        if (type === 'zip')
            return /\.zip$/;

        return /\.tar\.gz$/;
    }

    function checkEmpty(name, operation) {
        if (!operation)
            throw Error(name + ' could not be empty!');
    }

    function twopack(operation, type) {
        let op;
        let fileFrom;
        let currentName = Info.name;

        const Images = DOM.Images;
        const path = Info.path;
        const dirPath = Info.dirPath;
        const activeFiles = DOM.getActiveFiles();
        const names = DOM.getFilenames(activeFiles);

        checkEmpty('operation', operation);

        if (!names.length)
            return Dialog.alert.noFiles(TITLE);

        switch(operation) {
        case 'extract':
            op = extractFn;

            fileFrom   = {
                from: path,
                to: dirPath
            };

            currentName = currentName.replace(getTypeReg(type), '');

            break;

        case 'pack':
            op = packFn;

            if (names.length > 1)
                currentName  = Info.dir;

            currentName += DOM.getPackerExt(type);

            fileFrom = {
                from: dirPath,
                to: dirPath + currentName,
                names,
            };
            break;
        }

        Images.show.load('top');

        op(fileFrom, (error) => {
            !error && CloudCmd.refresh({
                currentName
            });
        });
    }

    function message(msg) {
        return (to, names) => {
            const n = names.length;
            const name = names[0];

            msg += ' ';

            if (names.length > 1)
                msg     += n + ' file(s)';
            else
                msg     += '"' + name + '"';

            msg += ' to';

            const cancel = false;

            return Dialog.prompt(TITLE, msg, to, {cancel});
        };
    }

    function load(callback) {
        const prefix = CloudCmd.PREFIX;
        const files = [
            '/spero/spero.js',
            '/remedy/remedy.js',
            '/ishtar/ishtar.js',
            '/salam/salam.js',
            '/omnes/omnes.js'
        ].map((name) => {
            return prefix + name;
        });

        DOM.load.parallel(files, (error) => {
            if (error)
                return Dialog.alert(TITLE, error.message);

            Loaded = true;
            Util.timeEnd(Name + ' load');
            exec(callback);
        });

        Util.time(Name + ' load');
    }

    init();
}

<|endoftext|>


<commit_before>Udon = (typeof Udon === 'undefined') ? {} : Udon;

Udon.ncurry = function(n) {
    if (typeof n != 'number' || n < 2) n = 2;
    return function(f) {
        var a1 = Array.prototype.slice.call(arguments, 1),
        curry = function() {
            var a2 = a1.concat(Array.prototype.slice.call(arguments, 0));
            if (a2.length < n) {
                a2.unshift(f);
                a1 = a2;
                return _curry;
            } else {
                return f.apply(null, a2);
            }
        };
        return curry;
    };
};

Udon.curry = Udon.ncurry(2);

Udon.compose = function(fs, partial) {
    var composed = function() {
        var i = fs.length - 1, as = Array.prototype.slice.call(arguments, 0), x;
        if (i < 0) return as[0];
        x = fs[i].apply(null, as);
        while (i--) x = fs[i](x);
        return x;
    };
    return partial && fs.length > 1 ? Udon.ncurry(fs.length)(composed) : composed;
};

Udon.foldl = function(f, z, xs) {
    var len = xs.length, i;
    for (i = 0; i < len; i++) z = f(z, xs[i]);
    return z;
};

Udon.foldr = function(f, z, xs) {
    var i = xs.length;
    while (i--) z = f(xs[i], z);
    return z;
};

Udon.map = function(f, xs) {
    var i = xs.length, ys = new Array(i);
    while (i--) ys[i] = f(xs[i]);
    return ys;
};

Udon.filter = function(f, xs) {
    var ys = [], len = xs.length, i, e;
    for (i = 0; i < len; i++) {
        e = xs[i];
        if (f(e)) ys.push(e);
    }
    return ys;
};

Udon.partition = function(f, xs) {
    var ts = [], fs = [], len = xs.length, i, e;
    for (i = 0; i < len; i++) {
        e = xs[i];
        (f(e) ? ts : fs).push(e);
    }
    return [ts, fs];
};

Udon.unfoldr = function(step, seed) {
    var output  = [], result;
    while ((result = step(seed))) {
        output.push(result[0]);
        seed = result[1];
    }
    return output;
};

Udon.zip = function(xs, ys) {
    return Udon.zipWith(function(x, y) { return [x, y]; }, xs, ys);
};

Udon.zipWith = function(f, xs, ys) {
    var xsl = xs.length, ysl = ys.length, i = xsl > ysl ? ysl : xsl,
        zs = new Array(i);
    while (i--) zs[i] = f(xs[i], ys[i]);
    return zs;
};
<commit_msg>Keep line lengths under 80 characters.<commit_after>Udon = (typeof Udon === 'undefined') ? {} : Udon;

Udon.ncurry = function(n) {
    if (typeof n != 'number' || n < 2) n = 2;
    return function(f) {
        var a1 = Array.prototype.slice.call(arguments, 1),
        curry = function() {
            var a2 = a1.concat(Array.prototype.slice.call(arguments, 0));
            if (a2.length < n) {
                a2.unshift(f);
                a1 = a2;
                return _curry;
            } else {
                return f.apply(null, a2);
            }
        };
        return curry;
    };
};

Udon.curry = Udon.ncurry(2);

Udon.compose = function(fs, p) {
    var composed = function() {
        var i  = fs.length - 1, x,
            as = Array.prototype.slice.call(arguments, 0);
        if (i < 0) return as[0];
        x = fs[i].apply(null, as);
        while (i--) x = fs[i](x);
        return x;
    };
    return p && fs.length > 1 ? Udon.ncurry(fs.length)(composed) : composed;
};

Udon.foldl = function(f, z, xs) {
    var len = xs.length, i;
    for (i = 0; i < len; i++) z = f(z, xs[i]);
    return z;
};

Udon.foldr = function(f, z, xs) {
    var i = xs.length;
    while (i--) z = f(xs[i], z);
    return z;
};

Udon.map = function(f, xs) {
    var i = xs.length, ys = new Array(i);
    while (i--) ys[i] = f(xs[i]);
    return ys;
};

Udon.filter = function(f, xs) {
    var ys = [], len = xs.length, i, e;
    for (i = 0; i < len; i++) {
        e = xs[i];
        if (f(e)) ys.push(e);
    }
    return ys;
};

Udon.partition = function(f, xs) {
    var ts = [], fs = [], len = xs.length, i, e;
    for (i = 0; i < len; i++) {
        e = xs[i];
        (f(e) ? ts : fs).push(e);
    }
    return [ts, fs];
};

Udon.unfoldr = function(step, seed) {
    var output  = [], result;
    while ((result = step(seed))) {
        output.push(result[0]);
        seed = result[1];
    }
    return output;
};

Udon.zip = function(xs, ys) {
    return Udon.zipWith(function(x, y) { return [x, y]; }, xs, ys);
};

Udon.zipWith = function(f, xs, ys) {
    var xsl = xs.length, ysl = ys.length, i = xsl > ysl ? ysl : xsl,
        zs = new Array(i);
    while (i--) zs[i] = f(xs[i], ys[i]);
    return zs;
};
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
  Side = mongoose.model('Side'),
  Sauce = mongoose.model('Sauce'),
  Topping = mongoose.model('Topping'),
  Cheese = mongoose.model('Cheese'),
  Bun = mongoose.model('Bun'),
  Meat = mongoose.model('Meat'),
  async = require('async'),
  config = require('meanio').loadConfig();

/**
 * Get Full menu
 */
exports.fullMenu = function(req, res) {
  var menu = {};
  Meat.find()
  .exec(function(err, meats){
    if (err) res.send(err);
    else menu.meats = meats;
  });
  // Other menu items here
  res.status(200).json(menu);
};
<commit_msg>Copied initial functions in the menu controller<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
  Side = mongoose.model('Side'),
  Sauce = mongoose.model('Sauce'),
  Topping = mongoose.model('Topping'),
  Cheese = mongoose.model('Cheese'),
  Bun = mongoose.model('Bun'),
  Meat = mongoose.model('Meat'),
  async = require('async'),
  config = require('meanio').loadConfig();

/**
 * Get Full menu
 */
exports.fullMenu = function(req, res) {
  var menu = {};
  Meat.find()
  .exec(function(err, meats){
    if (err) res.send(err);
    else menu.meats = meats;
  });

 exports.fullMenu = function(req, res) {
  var menu = {};
  Meat.find()
  .exec(function(err, meats){
    if (err) res.send(err);
    else menu.meats = meats;
  });

  // Other menu items here
  res.status(200).json(menu);
};<|endoftext|>


<commit_before>import { browserHistory } from 'react-router';
import actionConstants from './constants/action_constants';
import apiUtils from './utils/api_utils';
import rcsbApiUtils from './utils/rcsb_api_utils';
import workflowUtils from './utils/workflow_utils';

export function initializeWorkflow(workflowId) {
  return async function initializeWorkflowDispatch(dispatch) {
    dispatch({
      type: actionConstants.INITIALIZE_WORKFLOW,
      workflowId,
    });

    let workflow;
    try {
      workflow = await apiUtils.getWorkflow(workflowId);
    } catch (error) {
      return dispatch({
        type: actionConstants.FETCHED_WORKFLOW,
        error,
      });
    }

    return dispatch({
      type: actionConstants.FETCHED_WORKFLOW,
      workflow,
    });
  };
}

export function initializeRun(workflowId, runId) {
  return async function initializeRunDispatch(dispatch) {
    dispatch({
      type: actionConstants.INITIALIZE_WORKFLOW,
      runId,
      workflowId,
    });

    let workflow;
    try {
      workflow = await apiUtils.getRun(runId);
    } catch (error) {
      return dispatch({
        type: actionConstants.FETCHED_RUN,
        error,
      });
    }

    dispatch({
      type: actionConstants.FETCHED_RUN,
      workflow,
    });

    if (workflow.run.inputPdbUrl) {
      apiUtils.getPdb(workflow.run.inputPdbUrl).then(modelData =>
        dispatch({
          type: actionConstants.FETCHED_INPUT_PDB,
          modelData,
        })
      ).catch(error =>
        dispatch({
          type: actionConstants.FETCHED_INPUT_PDB,
          err: error,
        })
      );
    }

    if (workflow.run.outputPdbUrl) {
      apiUtils.getPdb(workflow.run.outputPdbUrl).then(modelData =>
        dispatch({
          type: actionConstants.FETCHED_OUTPUT_PDB,
          modelData,
        })
      ).catch(error =>
        dispatch({
          type: actionConstants.FETCHED_OUTPUT_PDB,
          err: error,
        })
      );
    }

    return true;
  };
}

export function clickNode(nodeId) {
  return {
    type: actionConstants.CLICK_NODE,
    nodeId,
  };
}

// TODO this is unused now that we don't show workflow nodes, but in future?
export function clickWorkflowNode(workflowNodeId) {
  return {
    type: actionConstants.CLICK_WORKFLOW_NODE,
    workflowNodeId,
  };
}

export function clickWorkflowNodeLoad() {
  return {
    type: actionConstants.CLICK_WORKFLOW_NODE_LOAD,
  };
}

export function clickWorkflowNodeEmail() {
  return {
    type: actionConstants.CLICK_WORKFLOW_NODE_EMAIL,
  };
}

export function clickWorkflowNodeResults() {
  return {
    type: actionConstants.CLICK_WORKFLOW_NODE_RESULTS,
  };
}

export function clickRun(workflowId, email, inputPdbUrl) {
  return (dispatch) => {
    dispatch({
      type: actionConstants.CLICK_RUN,
    });

    apiUtils.run(workflowId, email, inputPdbUrl).then((runId) => {
      dispatch({
        type: actionConstants.RUN_SUBMITTED,
        runId,
      });

      browserHistory.push(`/workflow/${workflowId}/${runId}`);
      dispatch(initializeRun(workflowId, runId));
    }).catch((err) => {
      console.error(err);

      dispatch({
        type: actionConstants.RUN_SUBMITTED,
        err,
      });
    });
  };
}

export function selectInputFile(file, workflowId) {
  return (dispatch) => {
    dispatch({
      type: actionConstants.INPUT_FILE,
      file,
    });

    const extension = file.name.split('.').pop();
    if (extension !== 'pdb') {
      return dispatch({
        type: actionConstants.INPUT_FILE_COMPLETE,
        err: 'File must have the .pdb extension',
      });
    }

    let inputPdb;
    let processedPdbUrl;

    return workflowUtils.readPdb(file).then((pdb) => {
      inputPdb = pdb;
      return apiUtils.processInput(workflowId, pdb);
    }).then((pdbUrl) => {
      processedPdbUrl = pdbUrl;

      // If no processing was needed
      if (!processedPdbUrl) {
        return Promise.resolve(inputPdb);
      }

      return apiUtils.getPdb(processedPdbUrl);
    }).then(processedPdb =>
      dispatch({
        type: actionConstants.INPUT_FILE_COMPLETE,
        pdbUrl: processedPdbUrl,
        pdb: processedPdb,
      })
    )
    .catch(err =>
      dispatch({
        type: actionConstants.INPUT_FILE_COMPLETE,
        err: err ? (err.message || err) : null,
      })
    );
  };
}

export function submitPdbId(pdbId, workflowId) {
  return (dispatch) => {
    dispatch({
      type: actionConstants.SUBMIT_PDB_ID,
    });

    let processedPdbUrl;
    let inputPdb;

    rcsbApiUtils.getPdbById(pdbId).then(({ pdb }) => {
      inputPdb = pdb;
      return apiUtils.processInput(workflowId, inputPdb);
    }).then((pdbUrl) => {
      // If no processing was needed
      if (!pdbUrl) {
        return Promise.resolve(inputPdb);
      }
      processedPdbUrl = pdbUrl;
      return apiUtils.getPdb(processedPdbUrl);
    }).then(processedPdb =>
      dispatch({
        type: actionConstants.FETCHED_PDB_BY_ID,
        pdbUrl: processedPdbUrl,
        pdb: processedPdb,
      })
    )
    .catch(err =>
      dispatch({
        type: actionConstants.FETCHED_PDB_BY_ID,
        err: err.message,
      })
    );
  };
}

export function submitEmail(email) {
  return {
    type: actionConstants.SUBMIT_EMAIL,
    email,
  };
}

export function clickAbout() {
  return {
    type: actionConstants.CLICK_ABOUT,
  };
}

export function clickCancel(runId) {
  return (dispatch) => {
    dispatch({
      type: actionConstants.CLICK_CANCEL,
    });

    apiUtils.cancelRun(runId).then(() => {
      dispatch({
        type: actionConstants.SUBMITTED_CANCEL,
      });
    }).catch((err) => {
      dispatch({
        type: actionConstants.SUBMITTED_CANCEL,
        err,
      });
    });
  };
}

export function messageTimeout() {
  return {
    type: actionConstants.MESSAGE_TIMEOUT,
  };
}

export function clickColorize() {
  return {
    type: actionConstants.CLICK_COLORIZE,
  };
}

export function changeMorph(morph) {
  return {
    type: actionConstants.CHANGE_MORPH,
    morph,
  };
}
<commit_msg>async/await for input pdb id and input file<commit_after>import { browserHistory } from 'react-router';
import actionConstants from './constants/action_constants';
import apiUtils from './utils/api_utils';
import rcsbApiUtils from './utils/rcsb_api_utils';
import workflowUtils from './utils/workflow_utils';

export function initializeWorkflow(workflowId) {
  return async function initializeWorkflowDispatch(dispatch) {
    dispatch({
      type: actionConstants.INITIALIZE_WORKFLOW,
      workflowId,
    });

    let workflow;
    try {
      workflow = await apiUtils.getWorkflow(workflowId);
    } catch (error) {
      return dispatch({
        type: actionConstants.FETCHED_WORKFLOW,
        error,
      });
    }

    return dispatch({
      type: actionConstants.FETCHED_WORKFLOW,
      workflow,
    });
  };
}

export function initializeRun(workflowId, runId) {
  return async function initializeRunDispatch(dispatch) {
    dispatch({
      type: actionConstants.INITIALIZE_WORKFLOW,
      runId,
      workflowId,
    });

    let workflow;
    try {
      workflow = await apiUtils.getRun(runId);
    } catch (error) {
      return dispatch({
        type: actionConstants.FETCHED_RUN,
        error,
      });
    }

    dispatch({
      type: actionConstants.FETCHED_RUN,
      workflow,
    });

    if (workflow.run.inputPdbUrl) {
      apiUtils.getPdb(workflow.run.inputPdbUrl).then(modelData =>
        dispatch({
          type: actionConstants.FETCHED_INPUT_PDB,
          modelData,
        })
      ).catch(error =>
        dispatch({
          type: actionConstants.FETCHED_INPUT_PDB,
          err: error,
        })
      );
    }

    if (workflow.run.outputPdbUrl) {
      apiUtils.getPdb(workflow.run.outputPdbUrl).then(modelData =>
        dispatch({
          type: actionConstants.FETCHED_OUTPUT_PDB,
          modelData,
        })
      ).catch(error =>
        dispatch({
          type: actionConstants.FETCHED_OUTPUT_PDB,
          err: error,
        })
      );
    }

    return true;
  };
}

export function clickNode(nodeId) {
  return {
    type: actionConstants.CLICK_NODE,
    nodeId,
  };
}

// TODO this is unused now that we don't show workflow nodes, but in future?
export function clickWorkflowNode(workflowNodeId) {
  return {
    type: actionConstants.CLICK_WORKFLOW_NODE,
    workflowNodeId,
  };
}

export function clickWorkflowNodeLoad() {
  return {
    type: actionConstants.CLICK_WORKFLOW_NODE_LOAD,
  };
}

export function clickWorkflowNodeEmail() {
  return {
    type: actionConstants.CLICK_WORKFLOW_NODE_EMAIL,
  };
}

export function clickWorkflowNodeResults() {
  return {
    type: actionConstants.CLICK_WORKFLOW_NODE_RESULTS,
  };
}

export function clickRun(workflowId, email, inputPdbUrl) {
  return (dispatch) => {
    dispatch({
      type: actionConstants.CLICK_RUN,
    });

    apiUtils.run(workflowId, email, inputPdbUrl).then((runId) => {
      dispatch({
        type: actionConstants.RUN_SUBMITTED,
        runId,
      });

      browserHistory.push(`/workflow/${workflowId}/${runId}`);
      dispatch(initializeRun(workflowId, runId));
    }).catch((err) => {
      console.error(err);

      dispatch({
        type: actionConstants.RUN_SUBMITTED,
        err,
      });
    });
  };
}

export function selectInputFile(file, workflowId) {
  return async function selectInputFileDispatch(dispatch) {
    dispatch({
      type: actionConstants.INPUT_FILE,
      file,
    });

    const extension = file.name.split('.').pop();
    if (extension !== 'pdb') {
      dispatch({
        type: actionConstants.INPUT_FILE_COMPLETE,
        err: 'File must have the .pdb extension',
      });
      return;
    }

    try {
      const inputPdb = await workflowUtils.readPdb(file);
      const processedPdbUrl = await apiUtils.processInput(workflowId, inputPdb);

      let processedPdb;
      if (processedPdbUrl) {
        processedPdb = await apiUtils.getPdb(processedPdbUrl);
      } else {
        processedPdb = inputPdb;
      }

      dispatch({
        type: actionConstants.INPUT_FILE_COMPLETE,
        pdbUrl: processedPdbUrl,
        pdb: processedPdb,
      });
    } catch (err) {
      dispatch({
        type: actionConstants.INPUT_FILE_COMPLETE,
        err: err ? (err.message || err) : null,
      });
    }
  };
}

export function submitPdbId(pdbId, workflowId) {
  return async function submitPdbIdDispatch(dispatch) {
    dispatch({
      type: actionConstants.SUBMIT_PDB_ID,
    });

    try {
      const { pdb: inputPdb } = await rcsbApiUtils.getPdbById(pdbId);
      const processedPdbUrl = await apiUtils.processInput(workflowId, inputPdb);

      let processedPdb;
      if (processedPdbUrl) {
        processedPdb = await apiUtils.getPdb(processedPdbUrl);
      } else {
        processedPdb = inputPdb;
      }

      dispatch({
        type: actionConstants.FETCHED_PDB_BY_ID,
        pdbUrl: processedPdbUrl,
        pdb: processedPdb,
      });
    } catch (err) {
      dispatch({
        type: actionConstants.FETCHED_PDB_BY_ID,
        err: err.message,
      });
    }
  };
}

export function submitEmail(email) {
  return {
    type: actionConstants.SUBMIT_EMAIL,
    email,
  };
}

export function clickAbout() {
  return {
    type: actionConstants.CLICK_ABOUT,
  };
}

export function clickCancel(runId) {
  return (dispatch) => {
    dispatch({
      type: actionConstants.CLICK_CANCEL,
    });

    apiUtils.cancelRun(runId).then(() => {
      dispatch({
        type: actionConstants.SUBMITTED_CANCEL,
      });
    }).catch((err) => {
      dispatch({
        type: actionConstants.SUBMITTED_CANCEL,
        err,
      });
    });
  };
}

export function messageTimeout() {
  return {
    type: actionConstants.MESSAGE_TIMEOUT,
  };
}

export function clickColorize() {
  return {
    type: actionConstants.CLICK_COLORIZE,
  };
}

export function changeMorph(morph) {
  return {
    type: actionConstants.CHANGE_MORPH,
    morph,
  };
}
<|endoftext|>


<commit_before>/**
@module ember
@submodule ember-glimmer
*/

import { assert } from 'ember-debug';
import {
  UNDEFINED_REFERENCE,
  CachedReference,
  ConditionalReference
} from '../utils/references';
import {
  CONSTANT_TAG,
  UpdatableTag,
  combine,
  isConst
} from '@glimmer/reference';

/**
  Use the `if` block helper to conditionally render a block depending on a
  property. If the property is "falsey", for example: `false`, `undefined`,
  `null`, `""`, `0`, `NaN` or an empty array, the block will not be rendered.

  ```handlebars
  {{! will not render if foo is falsey}}
  {{#if foo}}
    Welcome to the {{foo.bar}}
  {{/if}}
  ```

  You can also specify a template to show if the property is falsey by using
  the `else` helper.

  ```handlebars
  {{! is it raining outside?}}
  {{#if isRaining}}
    Yes, grab an umbrella!
  {{else}}
    No, it's lovely outside!
  {{/if}}
  ```

  You are also able to combine `else` and `if` helpers to create more complex
  conditional logic.

  ```handlebars
  {{#if isMorning}}
    Good morning
  {{else if isAfternoon}}
    Good afternoon
  {{else}}
    Good night
  {{/if}}
  ```

  You can use `if` inline to conditionally render a single property or string.
  This helper acts like a ternary operator. If the first property is truthy,
  the second argument will be displayed, if not, the third argument will be
  displayed

  ```handlebars
  {{if useLongGreeting "Hello" "Hi"}} Dave
  ```

  Finally, you can use the `if` helper inside another helper as a subexpression.

  ```handlebars
  {{some-component height=(if isBig "100" "10")}}
  ```

  @method if
  @for Ember.Templates.helpers
  @public
*/

class ConditionalHelperReference extends CachedReference {
  static create(_condRef, _truthyRef, _falsyRef) {
    let condRef = ConditionalReference.create(_condRef);
    let truthyRef = _truthyRef || UNDEFINED_REFERENCE;
    let falsyRef = _falsyRef || UNDEFINED_REFERENCE;

    if (isConst(condRef)) {
      return condRef.value() ? truthyRef : falsyRef;
    } else {
      return new ConditionalHelperReference(condRef, truthyRef, falsyRef);
    }
  }

  constructor(cond, truthy, falsy) {
    super();

    this.branchTag = new UpdatableTag(CONSTANT_TAG);
    this.tag = combine([cond.tag, this.branchTag]);

    this.cond = cond;
    this.truthy = truthy;
    this.falsy = falsy;
  }

  compute() {
    let { cond, truthy, falsy } = this;

    let branch = cond.value() ? truthy : falsy;

    this.branchTag.update(branch.tag);

    return branch.value();
  }
}

/**
  The inline `if` helper conditionally renders a single property or string.
  This helper acts like a ternary operator. If the first property is truthy,
  the second argument will be displayed, otherwise, the third argument will be
  displayed

  ```handlebars
  {{if useLongGreeting "Hello" "Hi"}} Alex
  ```

  You can use the `if` helper inside another helper as a subexpression.

  ```handlebars
  {{some-component height=(if isBig "100" "10")}}
  ```

  @method if
  @for Ember.Templates.helpers
  @public
*/
export function inlineIf(vm, { positional }) {
  switch (positional.length) {
    case 2: return ConditionalHelperReference.create(positional.at(0), positional.at(1), null);
    case 3: return ConditionalHelperReference.create(positional.at(0), positional.at(1), positional.at(2));
    default:
      assert(
        'The inline form of the `if` helper expects two or three arguments, e.g. ' +
        '`{{if trialExpired "Expired" expiryDate}}`.'
      );
  }
}

/**
  The inline `unless` helper conditionally renders a single property or string.
  This helper acts like a ternary operator. If the first property is falsy,
  the second argument will be displayed, otherwise, the third argument will be
  displayed

  ```handlebars
  {{unless useLongGreeting "Hi" "Hello"}} Ben
  ```

  You can use the `unless` helper inside another helper as a subexpression.

  ```handlebars
  {{some-component height=(unless isBig "10" "100")}}
  ```

  @method unless
  @for Ember.Templates.helpers
  @public
*/
export function inlineUnless(vm, { positional }) {
  switch (positional.length) {
    case 2: return ConditionalHelperReference.create(positional.at(0), null, positional.at(1));
    case 3: return ConditionalHelperReference.create(positional.at(0), positional.at(2), positional.at(1));
    default:
      assert(
        'The inline form of the `unless` helper expects two or three arguments, e.g. ' +
        '`{{unless isFirstLogin "Welcome back!"}}`.'
      );
  }
}
<commit_msg>[DOC release] Improve documentation of `if` template helper<commit_after>/**
@module ember
@submodule ember-glimmer
*/

import { assert } from 'ember-debug';
import {
  UNDEFINED_REFERENCE,
  CachedReference,
  ConditionalReference
} from '../utils/references';
import {
  CONSTANT_TAG,
  UpdatableTag,
  combine,
  isConst
} from '@glimmer/reference';

class ConditionalHelperReference extends CachedReference {
  static create(_condRef, _truthyRef, _falsyRef) {
    let condRef = ConditionalReference.create(_condRef);
    let truthyRef = _truthyRef || UNDEFINED_REFERENCE;
    let falsyRef = _falsyRef || UNDEFINED_REFERENCE;

    if (isConst(condRef)) {
      return condRef.value() ? truthyRef : falsyRef;
    } else {
      return new ConditionalHelperReference(condRef, truthyRef, falsyRef);
    }
  }

  constructor(cond, truthy, falsy) {
    super();

    this.branchTag = new UpdatableTag(CONSTANT_TAG);
    this.tag = combine([cond.tag, this.branchTag]);

    this.cond = cond;
    this.truthy = truthy;
    this.falsy = falsy;
  }

  compute() {
    let { cond, truthy, falsy } = this;

    let branch = cond.value() ? truthy : falsy;

    this.branchTag.update(branch.tag);

    return branch.value();
  }
}

/**
  The `if` helper allows you to conditionally render one of two branches,
  depending on the "truthiness" of a property.
  For example the following values are all falsey: `false`, `undefined`, `null`, `""`, `0`, `NaN` or an empty array.

  This helper has two forms, block and inline.

  ## Block form

  You can use the block form of `if` to conditionally render a section of the template.

  To use it, pass the conditional value to the `if` helper,
  using the block form to wrap the section of template you want to conditionally render.
  Like so:

  ```handlebars
  {{! will not render if foo is falsey}}
  {{#if foo}}
    Welcome to the {{foo.bar}}
  {{/if}}
  ```

  You can also specify a template to show if the property is falsey by using
  the `else` helper.

  ```handlebars
  {{! is it raining outside?}}
  {{#if isRaining}}
    Yes, grab an umbrella!
  {{else}}
    No, it's lovely outside!
  {{/if}}
  ```

  You are also able to combine `else` and `if` helpers to create more complex
  conditional logic.

  ```handlebars
  {{#if isMorning}}
    Good morning
  {{else if isAfternoon}}
    Good afternoon
  {{else}}
    Good night
  {{/if}}
  ```

  ## Inline form

  The inline `if` helper conditionally renders a single property or string.

  In this form, the `if` helper receives three arguments, the conditional value,
  the value to render when truthy, and the value to render when falsey.

  For example, if `useLongGreeting` is truthy, the following:

  ```handlebars
  {{if useLongGreeting "Hello" "Hi"}} Alex
  ```

  Will render:

  ```html
  Hello Alex
  ```

  ### Nested `if`

  You can use the `if` helper inside another helper as a nested helper:

  ```handlebars
  {{some-component height=(if isBig "100" "10")}}
  ```

  One detail to keep in mind is that both branches of the `if` helper will be evaluated,
  so if you have `{{if condition "foo" (expensive-operation "bar")`,
  `expensive-operation` will always calculate.

  @method if
  @for Ember.Templates.helpers
  @public
*/
export function inlineIf(vm, { positional }) {
  switch (positional.length) {
    case 2: return ConditionalHelperReference.create(positional.at(0), positional.at(1), null);
    case 3: return ConditionalHelperReference.create(positional.at(0), positional.at(1), positional.at(2));
    default:
      assert(
        'The inline form of the `if` helper expects two or three arguments, e.g. ' +
        '`{{if trialExpired "Expired" expiryDate}}`.'
      );
  }
}

/**
  The inline `unless` helper conditionally renders a single property or string.
  This helper acts like a ternary operator. If the first property is falsy,
  the second argument will be displayed, otherwise, the third argument will be
  displayed

  ```handlebars
  {{unless useLongGreeting "Hi" "Hello"}} Ben
  ```

  You can use the `unless` helper inside another helper as a subexpression.

  ```handlebars
  {{some-component height=(unless isBig "10" "100")}}
  ```

  @method unless
  @for Ember.Templates.helpers
  @public
*/
export function inlineUnless(vm, { positional }) {
  switch (positional.length) {
    case 2: return ConditionalHelperReference.create(positional.at(0), null, positional.at(1));
    case 3: return ConditionalHelperReference.create(positional.at(0), positional.at(2), positional.at(1));
    default:
      assert(
        'The inline form of the `unless` helper expects two or three arguments, e.g. ' +
        '`{{unless isFirstLogin "Welcome back!"}}`.'
      );
  }
}
<|endoftext|>


<commit_before>/* eslint comma-dangle: 0 */

// Thanks to www.fantasynamegenerators.com for some tips

const Names = {};
const RG = require('../src/rg');
const Random = require('../src/random');

const RNG = Random.getRNG();

// There are two kinds of names:
// 1. Generic ones such as Dungeon, City, Town, Vault etc.
// 2. Unique ones such as Everhold or Ebonfell.

/* As the whole purpose of this module is to generate random names, each
 * function will return randomly picked values of course.
 */

Names.place = {};

/* Generic place names are placed here. */
Names.place.generic = {
    branch: [
        'Hand', 'Foot', 'Small', 'Large'
    ],
    dungeon: [
        'Crypt', 'Catacombs', 'Tombs',
        'Dungeon', 'Cells',
        'Cave', 'Grotto', 'Cavern', 'Lair',
        // 'Burrows', 'Delves',
        // 'Haunt', 'Point',
        // 'Vault', 'Tunnels', 'Pits',
        'Labyrinth' // , 'Maze'
    ],

    mountain: [
        'Summit', 'Volcano', 'Tops', 'Peaks',
        'Bluff', 'Highlands', 'Pinnacle', 'Rise', 'Needle', 'Hills',
        'Slopes'
    ],

    face: [
        'Face', 'Buttress', 'Ridge', 'Shoulder', 'Crag', 'Crest', 'Brink',
        'Cairn', 'Col', 'Pass', 'Crown', 'Scree', 'Watershed'
    ],

    forest: [
        'Grove', 'Wilds', 'Woodlands', 'Timberland', 'Forest', 'Covert',
        'Woods', 'Thicket', 'Glade',
    ],

    city: [
        'Town', 'Village', // 'Township', 'Hamlet',
        'Fort',
        // 'Stronghold', 'Fortress', 'Outpost', 'Castle',
        'City', // 'Capital',
        // 'Guard'
    ],
    lake: [
        'Basin', 'Cove', 'Reservoir', 'Depths', 'Gorge', 'Lagoon', 'Domain',
        'Pond', 'Expanse', 'Lake', 'Shallows', 'Loch', 'Falls', 'Rapids',
    ],

    quarter: [
        'Market', 'Bazaar',
        'Plaza', 'Row', 'Works', 'Side', 'Acre',
        'Garden', 'Park',
        'Temple', 'Necropolis', 'Cemetery',
        'Library', 'Arcane',
        'Royal', 'Slum', 'Living',
        'Arena', 'Military', 'Barracks'
    ],
    area: [

    ]

};

Names.place.unique = {
    city: {
        first: [
            'Stag', 'Small', 'Mud', 'Ebon', 'Silk', 'Spirit', 'Basin',
            'Shadow', 'Gold', 'Snow', 'Frost', 'Ice', 'Hound', 'Moon',
            'Dire', 'Ever', 'Iron', 'Ruby', 'Star', 'Crystal', 'Glimmer',
            'Winters', 'Raven', 'Pine', 'Ever', 'Never', 'Rune',
            'Glace', 'Lumen', 'Confer'
        ],
        second: [
            'guard', 'point', 'fell', 'mire', 'shield', 'crest', 'yard',
            'minster', 'swallow', 'grasp', 'cliff', 'cross', 'host', 'barrow',
            'vein', 'view', 'home', 'gard', 'wall'
        ]
    }
};

Names.place.unique.mountain = {
    first: Names.place.unique.city.first,
    second: Names.place.generic.mountain.map(name => ' ' + name.toLowerCase())
};
Names.place.unique.dungeon = {
    first: Names.place.unique.city.first,
    second: Names.place.generic.dungeon.map(name => ' ' + name.toLowerCase())
};

Names.actor = {

};

Names.item = {

};

Names.getVillageType = () => {
    return RNG.arrayGetRand(['Village', 'Hamlet', 'Town', 'Township']);
};

Names.getUniqueName = type => {
    const names = Names.place.unique[type];
    if (names) {
        const first = RNG.arrayGetRand(names.first);
        const second = RNG.arrayGetRand(names.second);
        return first + second;
    }
    else {
        RG.err('name-gen.js', 'Names.getUniqueName',
          `No unique names for type ${type}`);
    }
    return '';
};

Names.getGenericPlaceName = (type) => {
    const arr = Names.place.generic[type];
    return RNG.arrayGetRand(arr);
};

Names.actorCount = 0;
Names.getActorName = () => {
    return 'RandActor' + Names.actorCount++;
};

module.exports = Names;

<commit_msg>Added getBookName().<commit_after>/* eslint comma-dangle: 0 */

// Thanks to www.fantasynamegenerators.com for some tips

const Names = {};
const RG = require('../src/rg');
const Random = require('../src/random');

const RNG = Random.getRNG();

// There are two kinds of names:
// 1. Generic ones such as Dungeon, City, Town, Vault etc.
// 2. Unique ones such as Everhold or Ebonfell.

/* As the whole purpose of this module is to generate random names, each
 * function will return randomly picked values of course.
 */

Names.place = {};

/* Generic place names are placed here. */
Names.place.generic = {
    branch: [
        'Hand', 'Foot', 'Small', 'Large'
    ],
    dungeon: [
        'Crypt', 'Catacombs', 'Tombs',
        'Dungeon', 'Cells',
        'Cave', 'Grotto', 'Cavern', 'Lair',
        // 'Burrows', 'Delves',
        // 'Haunt', 'Point',
        // 'Vault', 'Tunnels', 'Pits',
        'Labyrinth' // , 'Maze'
    ],

    mountain: [
        'Summit', 'Volcano', 'Tops', 'Peaks',
        'Bluff', 'Highlands', 'Pinnacle', 'Rise', 'Needle', 'Hills',
        'Slopes'
    ],

    face: [
        'Face', 'Buttress', 'Ridge', 'Shoulder', 'Crag', 'Crest', 'Brink',
        'Cairn', 'Col', 'Pass', 'Crown', 'Scree', 'Watershed'
    ],

    forest: [
        'Grove', 'Wilds', 'Woodlands', 'Timberland', 'Forest', 'Covert',
        'Woods', 'Thicket', 'Glade',
    ],

    city: [
        'Town', 'Village', // 'Township', 'Hamlet',
        'Fort',
        // 'Stronghold', 'Fortress', 'Outpost', 'Castle',
        'City', // 'Capital',
        // 'Guard'
    ],
    lake: [
        'Basin', 'Cove', 'Reservoir', 'Depths', 'Gorge', 'Lagoon', 'Domain',
        'Pond', 'Expanse', 'Lake', 'Shallows', 'Loch', 'Falls', 'Rapids',
    ],

    quarter: [
        'Market', 'Bazaar',
        'Plaza', 'Row', 'Works', 'Side', 'Acre',
        'Garden', 'Park',
        'Temple', 'Necropolis', 'Cemetery',
        'Library', 'Arcane',
        'Royal', 'Slum', 'Living',
        'Arena', 'Military', 'Barracks'
    ],
    area: [

    ]

};

Names.place.unique = {
    city: {
        first: [
            'Stag', 'Small', 'Mud', 'Ebon', 'Silk', 'Spirit', 'Basin',
            'Shadow', 'Gold', 'Snow', 'Frost', 'Ice', 'Hound', 'Moon',
            'Dire', 'Ever', 'Iron', 'Ruby', 'Star', 'Crystal', 'Glimmer',
            'Winters', 'Raven', 'Pine', 'Ever', 'Never', 'Rune',
            'Glace', 'Lumen', 'Confer'
        ],
        second: [
            'guard', 'point', 'fell', 'mire', 'shield', 'crest', 'yard',
            'minster', 'swallow', 'grasp', 'cliff', 'cross', 'host', 'barrow',
            'vein', 'view', 'home', 'gard', 'wall'
        ]
    }
};

Names.place.unique.mountain = {
    first: Names.place.unique.city.first,
    second: Names.place.generic.mountain.map(name => ' ' + name.toLowerCase())
};
Names.place.unique.dungeon = {
    first: Names.place.unique.city.first,
    second: Names.place.generic.dungeon.map(name => ' ' + name.toLowerCase())
};

Names.actor = {

};

Names.item = {

};

Names.getVillageType = () => {
    return RNG.arrayGetRand(['Village', 'Hamlet', 'Town', 'Township']);
};

Names.getUniqueName = type => {
    const names = Names.place.unique[type];
    if (names) {
        const first = RNG.arrayGetRand(names.first);
        const second = RNG.arrayGetRand(names.second);
        return first + second;
    }
    else {
        RG.err('name-gen.js', 'Names.getUniqueName',
          `No unique names for type ${type}`);
    }
    return '';
};

Names.getGenericPlaceName = (type) => {
    const arr = Names.place.generic[type];
    return RNG.arrayGetRand(arr);
};

Names.actorCount = 0;
Names.getActorName = () => {
    return 'RandActor' + Names.actorCount++;
};

const bookNameGen = {
    prefix: ['old', 'ancient', 'dusty', 'worn', 'well-preserved', 'heavy',
        'light'],
    prefix2: ['rune-covered', 'worm-ridden', 'leather', 'hard-cover',
        'metal-plated', 'decorated', 'exquisite'],
    substantive: ['tome', 'book', 'tract', 'codex', 'opus', 'handbook',
        'volume', 'treatise']
};

Names.bookCount = 0;
Names.getBookName = () => {
    let prefix = RNG.arrayGetRand(bookNameGen.prefix);
    prefix = prefix.capitalize();
    const prefix2 = RNG.arrayGetRand(bookNameGen.prefix2);
    const subst = RNG.arrayGetRand(bookNameGen.substantive);
    return `${prefix} ${prefix2} ${subst}`;
    // return 'Book ' + Names.bookCount++;
};

module.exports = Names;

<|endoftext|>


<commit_before>/**
 * @author Nathan Smith <nathanjosiah@gmail.com>
 * @link https://github.com/nathanjosiah/mobile-pagination
 */
$.widget('nathanjosiah.mobilePagination',{
	options: {
		touchingClass: 'is_touching',
		swipeThreshold: 10,
		swipeTimeThreshold: 300,
		sliderSelector: '> ul',

		//EaseOutQuad http://gizma.com/easing/
		easingFunction: function (t,b,c,d) {
			t /= d;
			return -c * t*(t-2) + b;
		},
		maxEasingPercentage: 0.25,
		isMobile: function() {
			return $(window).width() < 768;
		},
		onChange: null
	},
	$window: $(window),
	$container: null,
	$slider: null,
	bannerCount: null,
	ignoreTouch: false,
	id: null,
	namespace: 'mobilePagination',
	touches: {
		start_time: null,
		start: {},
		start_relative: {},
		delta: {}
	},
	fb: {
		start: {
			scroll: 0,
			container_offset: {}
		},
		slide_index: 1,
		current: {
			scroll: 0
		}
	},
	_create: function() {
		this.$container = $(this.element);
		this.$slider = this.$container.find(this.options.sliderSelector);
		this.bannerCount = this.$slider.children().length;
		this.id = Math.random() * 10000;
		var that = this;

		that.$container
		.on('touchstart.' + this.namespace,function(e) {
			if(!that.options.isMobile()) {
				that.ignoreTouch = true;
				return true;
			}
			that.$slider.addClass(that.options.touchingClass);
			var touch = e.originalEvent.touches[0];
			that.touches.start = {
				x: touch.clientX,
				y: touch.clientY
			};
			that.fb.start.container_offset = that.$container.offset();
			that.fb.start.scroll = that.fb.current.scroll;
			that.touches.start_relative = {
				x: touch.clientX - that.fb.start.container_offset.left + that.fb.start.scroll,
				y: touch.clientY - that.fb.start.container_offset.top
			}
			that.touches.start_time = new Date();
		})
		.on('touchmove.' + this.namespace,function(e) {
			if(that.ignoreTouch) return true;
			var touch = e.originalEvent.touches[0];
			that.touches.delta = {
				x: touch.clientX - that.touches.start.x,
				y: touch.clientY - that.touches.start.y
			};
			// User is trying to scroll vertically
			if(Math.abs(that.touches.delta.x) < Math.abs(that.touches.delta.y)) {
				return true;
			}
			e.preventDefault();
			var scroll_to = that.fb.start.scroll + that.touches.delta.x;

			if(that.options.easingFunction) {
				var container_width = that.$container.width();
				var max_elastic_pull = container_width * that.options.maxEasingPercentage;
				// The user is trying to pull the first or last banner
				if(that.fb.slide_index === that.bannerCount && that.touches.delta.x < 0) {
					scroll_to = that.fb.start.scroll - that.options.easingFunction(that.touches.delta.x * -1,0,max_elastic_pull,container_width);
				}
				else if(that.fb.slide_index === 1 && that.touches.delta.x > 0) {
					scroll_to = that.fb.start.scroll + that.options.easingFunction(that.touches.delta.x,0,max_elastic_pull,container_width);
				}
			}
			that.scrollBanners(scroll_to);
		})
		.on('touchend.mobilePagination touchcancel.' + this.namespace,function() {
			if(that.ignoreTouch) {
				that.ignoreTouch = false;
				return true;
			}
			that.$slider.removeClass(that.options.touchingClass);
			var now = new Date();
			var start_time = that.touches.start_time.getTime();
			var duration = now.getTime() - start_time;

			// Detect a swipe
			if(duration < that.options.swipeTimeThreshold && Math.abs(that.touches.delta.x) > that.options.swipeThreshold) {
				var slide_direction = (that.touches.delta.x < 0 ? 1 : -1);
				var new_index = (slide_direction === -1 ? that.fb.slide_index - 1 : that.fb.slide_index + 1);

				if(new_index === 0) that.gotoBanner(1);
				else if(new_index === that.bannerCount+1) that.gotoBanner(that.bannerCount);
				else that.gotoBanner(new_index);
			}
			// Normal drag
			else {
				var container_width = that.$container.width();
				var total_width = that.$slider.width();
				var half_slide_width = (container_width * 0.5);
				var percentage = parseInt((((that.fb.current.scroll * -1) + half_slide_width) / total_width) * 100);
				var slide_index = Math.ceil(percentage/((container_width / total_width) * 100));

				if(slide_index > that.bannerCount) slide_index = that.bannerCount;
				else if(slide_index < 1) slide_index = 1;
				that.gotoBanner(slide_index);
			}
		});
		this.$window.on('resize.' + this.namespace + this.id + ' orientationchange.' + this.namespace + this.id,function() {
			if(that.options.isMobile()) {
				that.gotoBanner(that.fb.slide_index);
			}
			else {
				that.$slider.css('-webkit-transform','');
				that.$slider.css('transform','');
			}
		});
	},
	_destroy: function() {
		this.$window.off('resize.' + this.namespace + this.id + ' orientationchange.' + this.namespace + this.id);
		this.$container.off('.' + this.namespace);
	},
	gotoBanner: function(new_index) {
		var container_width = this.$container.width();
		this.fb.slide_index = new_index;
		if(this.options.onChange) {
			this.options.onChange.call(this.$container,new_index);
		}
		if(this.options.isMobile()) {
			this.scrollBanners((container_width * (this.fb.slide_index - 1)) * -1);
		}
		else {
			this.$slider.css('-webkit-transform','');
			this.$slider.css('transform','');
		}
	},
	scrollBanners: function(offset) {
		this.$slider.css('-webkit-transform','translate(' + offset + 'px,0)');
		this.$slider.css('transform','translate(' + offset + 'px,0)');
		this.fb.current.scroll = offset;
	}
});<commit_msg>restructured to be more flexible<commit_after>/**
 * @author Nathan Smith <nathanjosiah@gmail.com>
 * @link https://github.com/nathanjosiah/mobile-pagination
 */
$.widget('nathanjosiah.mobilePagination',{
	options: {
		touchingClass: 'is_touching',
		swipeThreshold: 10 * (window.devicePixelRatio || 1),
		swipeTimeThreshold: 300,
		sliderSelector: '> ul',

		//EaseOutQuad http://gizma.com/easing/
		easingFunction: function (t,b,c,d) {
			t /= d;
			return -c * t*(t-2) + b;
		},
		maxEasingPercentage: 0.25,
		isMobile: function() {
			return $(window).width() < 768;
		},
		onChange: null,
		bannerWidth: function(index) {
			var container_width = this.$container.width();
			return (container_width * (index - 1));
		}
	},
	$window: $(window),
	$container: null,
	$slider: null,
	bannerCount: null,
	ignoreTouch: false,
	id: null,
	namespace: 'mobilePagination',
	touches: {
		start_time: null,
		start: {},
		start_relative: {},
		delta: {}
	},
	fb: {
		start: {
			scroll: 0,
			container_offset: {}
		},
		slide_index: 1,
		current: {
			scroll: 0
		}
	},
	onTouchEnd: function(e) {
		if(this.ignoreTouch) {
			this.ignoreTouch = false;
			return true;
		}
		this.$slider.removeClass(this.options.touchingClass);
		var now = new Date();
		var start_time = this.touches.start_time.getTime();
		var duration = now.getTime() - start_time;

		// Detect a swipe
		if(duration < this.options.swipeTimeThreshold && Math.abs(this.touches.delta.x) > this.options.swipeThreshold) {
			var slide_direction = (this.touches.delta.x < 0 ? 1 : -1);
			var new_index = (slide_direction === -1 ? this.fb.slide_index - 1 : this.fb.slide_index + 1);

			if(new_index === 0) this.gotoBanner(1);
			else if(new_index === this.bannerCount+1) this.gotoBanner(this.bannerCount);
			else this.gotoBanner(new_index);
		}
		// Normal drag
		else {
			var container_width = this.$container.width();
			var total_width = this.$slider.width();
			var half_slide_width = (container_width * 0.5);
			var percentage = parseInt((((this.fb.current.scroll * -1) + half_slide_width) / total_width) * 100);
			var slide_index = Math.ceil(percentage/((container_width / total_width) * 100));

			if(slide_index > this.bannerCount) slide_index = this.bannerCount;
			else if(slide_index < 1) slide_index = 1;
			this.gotoBanner(slide_index);
		}
	},
	onTouchMove: function(e) {
		if(this.ignoreTouch) return true;
		var touch = e.originalEvent.touches[0];
		this.touches.delta = {
			x: touch.clientX - this.touches.start.x,
			y: touch.clientY - this.touches.start.y
		};
		// User is trying to scroll vertically
		if(Math.abs(this.touches.delta.x) < Math.abs(this.touches.delta.y)) {
			return true;
		}
		e.preventDefault();

		var scroll_to = this.fb.start.scroll + this.touches.delta.x;

		if(this.options.easingFunction) {
			var container_width = this.$container.width();
			var max_elastic_pull = container_width * this.options.maxEasingPercentage;
			// The user is trying to pull the first or last banner
			if(this.fb.slide_index === this.bannerCount && this.touches.delta.x < 0) {
				scroll_to = this.fb.start.scroll - this.options.easingFunction(this.touches.delta.x * -1,0,max_elastic_pull,container_width);
			}
			else if(this.fb.slide_index === 1 && this.touches.delta.x > 0) {
				scroll_to = this.fb.start.scroll + this.options.easingFunction(this.touches.delta.x,0,max_elastic_pull,container_width);
			}
		}
		this.scrollBanners(scroll_to);
	},
	onTouchStart: function(e) {
		if(!this.options.isMobile()) {
			this.ignoreTouch = true;
			return true;
		}
		this.$slider.addClass(this.options.touchingClass);
		var touch = e.originalEvent.touches[0];
		this.touches.start = {
			x: touch.clientX,
			y: touch.clientY
		};
		this.fb.start.container_offset = this.$container.offset();
		this.fb.start.scroll = this.fb.current.scroll;
		this.touches.start_relative = {
			x: touch.clientX - this.fb.start.container_offset.left + this.fb.start.scroll,
			y: touch.clientY - this.fb.start.container_offset.top
		}
		this.touches.start_time = new Date();
	},
	onResize: function() {
		if(this.options.isMobile()) {
			this.gotoBanner(this.fb.slide_index);
		}
		else {
			this.$slider.css('-webkit-transform','');
			this.$slider.css('transform','');
		}
	},
	getProp: function(what) {
		var prop = this[what];
		if(typeof prop === 'function') {
			prop = $.proxy(prop,this);
		}
		return prop;
	},
	_create: function() {
		this.$container = $(this.element);
		this.$slider = this.$container.find(this.options.sliderSelector);
		this.bannerCount = this.$slider.children().length;
		this.id = Math.random() * 10000;
		var that = this;

		this.$container
		.on('touchstart.' + this.namespace,this.getProp('onTouchStart'))
		.on('touchmove.' + this.namespace,this.getProp('onTouchMove'))
		.on('touchend.' + this.namespace + ' touchcancel.' + this.namespace,this.getProp('onTouchEnd'));
		this.$window.on('resize.' + this.namespace + this.id + ' orientationchange.' + this.namespace + this.id,this.getProp('onResize'));
	},
	_destroy: function() {
		this.$window.off('resize.' + this.namespace + this.id + ' orientationchange.' + this.namespace + this.id);
		this.$container.off('.' + this.namespace);
	},
	gotoBanner: function(new_index) {
		this.fb.slide_index = new_index;
		if(this.options.onChange) {
			this.options.onChange.call(this.$container,new_index);
		}
		if(this.options.isMobile()) {
			this.scrollBanners($.proxy(this.options.bannerWidth,this)(this.fb.slide_index) * -1);
		}
		else {
			this.$slider.css('-webkit-transform','');
			this.$slider.css('transform','');
		}
	},
	scrollBanners: function(offset) {
		this.$slider.css('-webkit-transform','translate(' + offset + 'px,0)');
		this.$slider.css('transform','translate(' + offset + 'px,0)');
		this.fb.current.scroll = offset;
	}
});<|endoftext|>


<commit_before>import moment from 'moment'
import fetch from 'node-fetch'
import qs from 'qs'
import { getTeam, getUser } from './db'

const atUser = async (teamid, username) => {
  let { token } = await getTeam(teamid)
  let body = qs.stringify({ token })
  let headers = { 'Content-Type': 'application/json; charset=utf-8' }
  let res = await fetch('https://slack.com/api/users.list?' + body, headers )
  body = await res.json()
  if (body.ok == false)
    console.log('Error: ' + body.error)
  else {
    let user
    body.members.forEach((member) => {
      if (!user && member.name == username)
        user = member.id
    })
    if (user) {
      return user
    }
  }
}

export default async (ctx, next, kitsu) => {
  let query = ctx.request.body.text
  console.log('user: ' + query)
  let extended = false
  if (query.indexOf('extended ') == 0) {
    query = query.substring(9)
    extended = true
  }
  if (query.indexOf('ex ') == 0) {
    query = query.substring(3)
    extended = true
  }
  let user
  if (query.indexOf('@') == 0) {
    query = query.substring(1)
    let { team_id } = ctx.request.body
    let id = await atUser(team_id, query)
    if (id) {
      let u = await getUser(team_id, id)
      if (u) {
        try {
          user = await kitsu.getUser(u.kitsuid)
        }
        catch (error) {
          ctx.status = 404
        }
      }
      else ctx.body = 'User has not logged in.'
    }
    else ctx.body = 'No such Slack user.'
  }
  else try {
    user = await kitsu.searchUsers(encodeURI(query))
  }
  catch (error) {
    ctx.status = 404
    return
  }
  if (user) {
    console.log(user.name)
    let text = ''
    let fields = []
    let title_link = process.env.KITSU_HOST + '/users/' +  user.name
    let fallback = user.name + ' - ' + title_link

    if (user.about) {
      text = user.about
      fallback += `\nAbout: ${user.about}`
    }

    if (extended) {
      let { gender, birthday, createdAt } = user

      if (user.waifuOrHusbando) {
        fields.push({
          title: ':wedding: ' + user.waifuOrHusbando,
          value: user.waifu.name,
          short: true
        })
        fallback += `\n${user.waifuOrHusbando}: ${user.waifu.name}`
      }

      if (gender && gender != 'secret') {
        gender = gender.charAt(0).toUpperCase() + gender.slice(1)
        fields.push({
          title: ':man-woman-girl-boy: Gender',
          value: gender,
          short: true
        })
        fallback += `\nGender: ${gender}`
      }

      if (user.location) {
        fields.push({
          title: ':round_pushpin: Location',
          value: user.location,
          short: true
        })
        fallback += `\nLocation: ${user.location}`
      }

      if (birthday) {
        let date = moment(birthday.substring(birthday.indexOf('-') + 1), '[YYYY-]MM[-]DD')
        birthday = `${date.format('MMMM Do')} (${date.fromNow()})`
        fields.push({
          title: ':birthday: Birthday',
          value: birthday,
          short: true
        })
        fallback += `\nBirthday: ${birthday}`
      }

      if (createdAt) {
        let date = moment(createdAt, 'YYYY[-]MM[-]DD')
        createdAt = `${date.format('MMMM Do YYYY')} (${date.fromNow()})`
        fields.push({
          title: ':spiral_calendar_pad: Join Date',
          value: createdAt,
          short: true
        })
        fallback += `\nJoin Date: ${createdAt}`
      }

      fields.push({
        title: ':busts_in_silhouette: Followers',
        value: user.followersCount,
        short: true
      })
      fallback += `\nFollowers: ${user.followersCount}`

      fields.push({
        title: ':sleuth_or_spy: Following',
        value: user.followingCount,
        short: true
      })
      fallback += `\nFollowing: ${user.followingCount}`
    }

    let body = {
      response_type: 'in_channel',
      link_names: true,
      attachments: [{
        color: '#F65440',
        mrkdwn_in: ['text'],
        callback_id: user.id,
        title: user.name,
        title_link,
        text,
        thumb_url: user.avatar ? user.avatar.medium : null,
        fields,
        fallback,
        footer: 'Kitsu API',
        footer_icon: 'https://kitsu-slack.herokuapp.com/icon.png',
        ts: moment().unix(),
        actions: [{
          name: 'user',
          text: 'Follow/Unfollow',
          type: 'button'
        }]
      }]
    }

    ctx.status = 200
    ctx.body = body
  }
}
<commit_msg>Fix searchUsers call<commit_after>import moment from 'moment'
import fetch from 'node-fetch'
import qs from 'qs'
import { getTeam, getUser } from './db'

const atUser = async (teamid, username) => {
  let { token } = await getTeam(teamid)
  let body = qs.stringify({ token })
  let headers = { 'Content-Type': 'application/json; charset=utf-8' }
  let res = await fetch('https://slack.com/api/users.list?' + body, headers )
  body = await res.json()
  if (body.ok == false)
    console.log('Error: ' + body.error)
  else {
    let user
    body.members.forEach((member) => {
      if (!user && member.name == username)
        user = member.id
    })
    if (user) {
      return user
    }
  }
}

export default async (ctx, next, kitsu) => {
  let query = ctx.request.body.text
  console.log('user: ' + query)
  let extended = false
  if (query.indexOf('extended ') == 0) {
    query = query.substring(9)
    extended = true
  }
  if (query.indexOf('ex ') == 0) {
    query = query.substring(3)
    extended = true
  }
  let user
  if (query.indexOf('@') == 0) {
    query = query.substring(1)
    let { team_id } = ctx.request.body
    let id = await atUser(team_id, query)
    if (id) {
      let u = await getUser(team_id, id)
      if (u) {
        try {
          user = await kitsu.getUser(u.kitsuid)
        }
        catch (error) {
          ctx.status = 404
        }
      }
      else ctx.body = 'User has not logged in.'
    }
    else ctx.body = 'No such Slack user.'
  }
  else try {
    user = await kitsu.searchUsers(encodeURI(query), extended)
  }
  catch (error) {
    ctx.status = 404
    return
  }
  if (user) {
    console.log(user.name)
    let text = ''
    let fields = []
    let title_link = process.env.KITSU_HOST + '/users/' +  user.name
    let fallback = user.name + ' - ' + title_link

    if (user.about) {
      text = user.about
      fallback += `\nAbout: ${user.about}`
    }

    if (extended) {
      let { gender, birthday, createdAt } = user

      if (user.waifuOrHusbando) {
        fields.push({
          title: ':wedding: ' + user.waifuOrHusbando,
          value: user.waifu.name,
          short: true
        })
        fallback += `\n${user.waifuOrHusbando}: ${user.waifu.name}`
      }

      if (gender && gender != 'secret') {
        gender = gender.charAt(0).toUpperCase() + gender.slice(1)
        fields.push({
          title: ':man-woman-girl-boy: Gender',
          value: gender,
          short: true
        })
        fallback += `\nGender: ${gender}`
      }

      if (user.location) {
        fields.push({
          title: ':round_pushpin: Location',
          value: user.location,
          short: true
        })
        fallback += `\nLocation: ${user.location}`
      }

      if (birthday) {
        let date = moment(birthday.substring(birthday.indexOf('-') + 1), '[YYYY-]MM[-]DD')
        birthday = `${date.format('MMMM Do')} (${date.fromNow()})`
        fields.push({
          title: ':birthday: Birthday',
          value: birthday,
          short: true
        })
        fallback += `\nBirthday: ${birthday}`
      }

      if (createdAt) {
        let date = moment(createdAt, 'YYYY[-]MM[-]DD')
        createdAt = `${date.format('MMMM Do YYYY')} (${date.fromNow()})`
        fields.push({
          title: ':spiral_calendar_pad: Join Date',
          value: createdAt,
          short: true
        })
        fallback += `\nJoin Date: ${createdAt}`
      }

      fields.push({
        title: ':busts_in_silhouette: Followers',
        value: user.followersCount,
        short: true
      })
      fallback += `\nFollowers: ${user.followersCount}`

      fields.push({
        title: ':sleuth_or_spy: Following',
        value: user.followingCount,
        short: true
      })
      fallback += `\nFollowing: ${user.followingCount}`
    }

    let body = {
      response_type: 'in_channel',
      link_names: true,
      attachments: [{
        color: '#F65440',
        mrkdwn_in: ['text'],
        callback_id: user.id,
        title: user.name,
        title_link,
        text,
        thumb_url: user.avatar ? user.avatar.medium : null,
        fields,
        fallback,
        footer: 'Kitsu API',
        footer_icon: 'https://kitsu-slack.herokuapp.com/icon.png',
        ts: moment().unix(),
        actions: [{
          name: 'user',
          text: 'Follow/Unfollow',
          type: 'button'
        }]
      }]
    }

    ctx.status = 200
    ctx.body = body
  }
}
<|endoftext|>


<commit_before>import React, {Component} from 'react';

class Converter extends Component {
    getRequest() {

    }

    render() {
        return (

Number Converter

              Number:
              <input type="text"></input>

              Base:
              <input type="text"></input>

              New Base:
              <input type="text"></input>

            <button onClick={this.getRequest}>Convert</button>

        );
      }
}

export default Converter;<commit_msg>Event Handling<commit_after>import React, {Component} from 'react';

class Converter extends Component {
    constructor(props) {
        super(props);
        this.state = {isClicked: true};
        this.getRequest = this.getRequest.bind(this);
    }

    getRequest() {
        console.log(this.state.isClicked);
        this.setState(prevState => ({
            isClicked: !prevState.isClicked
        }));
    }

    render() {
        return (

Number Converter

              Number:
              <input type="text"></input>

              Base:
              <input type="text"></input>

              New Base:
              <input type="text"></input>

            <button onClick={this.getRequest}>Convert</button>

        );
      }
}

export default Converter;<|endoftext|>


<commit_before>(function (global) {
	/**
	 * console shim
	 */
	var objToString = Object.prototype.toString,
		console = global.console = {
			log: function () {
				sendRequest('log', {
					message: Array.prototype.slice.call(arguments).map(function (it) {
						return it && objToString.call(it) == '[object Object]' ? JSON.stringify(it) : it;
					}).join(' ')
				});
			}
		},
		requests = {},
		handles = {};

	function log(type) {
		type = '[' + type.toUpperCase() + ']';
		console.log.apply(null, arguments);
	}

	function processResponse(data) {
		var tmp = data.primitiveValue;
		return tmp !== void 0 ? tmp : (tmp = data.handle) ? handles[tmp] || (handles[tmp] = new Handle(tmp)) : data;
	}

	// WARNING: Do NOT use console.log() inside this function!
	function sendRequest(type, data, callback) {
		callback || (callback = processResponse);
		var token = '' + Math.round(Math.random() * 1e9).toString(16),
			tmp;
		requests[token] = callback;
		global.external.notify(JSON.stringify({
			type: type,
			token: token,
			data: data
		}));
		tmp = requests[token];
		delete requests[token];
		if (tmp instanceof Error) {
			tmp.toString().split(/\r\n|\n/).forEach(function (s) { log('error', s); });
			throw tmp;
		}
		return tmp;
	}

	function valueify(v, obj) {
		obj || (obj = {});
		if (v) {
			v instanceof Handle ? (obj.valueHnd = v._hnd) : (obj.valuePrimitive = v);
		}
		return obj;
	}

	/**
	 * Native object handle
	 */
	function Handle(hnd) {
		this._hnd = hnd
		this._listeners = {};
	}

	Handle.prototype = Object.create({
		addEventListener: function (name, callback) {
			var listeners = this._listeners[name];
			if (!listeners) {
				listeners = this._listeners[name] = [];
				sendRequest('reflection', {
					action: 'addEventListener',
					handle: this._hnd,
					name: name
				});
			}
			listeners.push(callback);
		},

		destroy: function () {
			for (var evt in this._listeners) {
				for (var i = 0, cbs = this._listeners[evt], len = cbs.length; i < len; i++) {
					this.removeEventListener(evt, cbs[i]);
				}
			}
			sendRequest('reflection', {
				action: 'destroy',
				handle: this._hnd
			});
			delete handles[this._hnd];
		},

		invoke: function (method, args) {
			return sendRequest('reflection', {
				action: 'invokeMethod',
				handle: this._hnd,
				method: method,
				args: Array.isArray(args) ? args.map(function (a, i) {
						return i % 2 == 0 ? a : valueify(a);
					}) : []
			});
		},

		property: function (name, value) {
			if (name && objToString.call(name) == '[object Object]') {
				for (var i in name) {
					name[i] = valueify(name[i]);
				}
			}

			return sendRequest('reflection', valueify(value, {
				action: 'property',
				handle: this._hnd,
				name: name
			}), function (data) {
				var obj = data.value;
				if (obj && objToString.call(obj) == '[object Object]') {
					for (var i in obj) {
						obj[i] = processResponse(obj[i]);
					}
					return obj;
				}
				return processResponse(data);
			});
		},

		removeEventListener: function (name, callback) {
			var idx,
				listeners = this._listeners[name];
			if (listeners && ~(idx = listeners.indexOf(callback))) {
				listeners.splice(idx, 1);
				listeners.length || sendRequest('reflection', {
					action: 'removeEventListener',
					handle: this._hnd,
					name: name
				});
			}
		}
	});

	// init default handles
	handles.app = new Handle('app');
	handles.browser = new Handle('browser');
	handles.root = new Handle('root');

	/**
	 * tiwp8 - Titanium Windows Phone 8 namespace
	 */
	global.tiwp8 = {
		createInstance: function (className, args) {
			return sendRequest('reflection', {
				action: 'createInstance',
				className: className,
				args: Array.isArray(args) ? args.map(function (a, i) {
						return i % 2 == 0 ? a : valueify(a);
					}) : []
			});
		},

		fireEvent: function (data) {
			var src = data.source = handles[data._hnd],
				listeners = src._listeners[data.type],
				i = 0,
				len = listeners ? listeners.length : 0;
			data.sender = new Handle(data.sender);
			data.eventArgs = new Handle(data.eventArgs);
			for (; i < len; i++) {
				listeners[i](data);
			}
		},

		getEnum: function (name, value) {
			return sendRequest('reflection', {
				action: 'getEnum',
				name: name,
				value: value
			});
		},

		getFile: function (file, isBinary) {
			return sendRequest('file', {
				file: file,
				isBinary: isBinary
			});
		},

		getHandles: function () {
			return handles;
		},

		getPhoneApplicationPage: function () {
			return handles.app;
		},

		getRootGrid: function () {
			return handles.root;
		},

		getWebBrowser: function () {
			return handles.browser;
		},

		handleResponse: function (data) {
			var err = data.error,
				token = data.token;
			try {
				if (err) {
					throw new Error(err);
				}
				token && requests[token] && (requests[token] = requests[token](data));
			} catch (ex) {
				token && (requests[token] = ex);
			}
		},

		invokeStatic: function (className, method, args) {
			return sendRequest('reflection', {
				action: 'invokeStatic',
				className: className,
				method: method,
				args: Array.isArray(args) ? args.map(function (a, i) {
						return i % 2 == 0 ? a : valueify(a);
					}) : []
			});
		},

		sendRequest: sendRequest
	};

	/**
	 * XMLHttpRequest shim
	 */
	var open = XMLHttpRequest.prototype.open;
	XMLHttpRequest.prototype.open = function (method, url) {
		url = 'http://localhost:9999/fetch/' + escape(btoa(url));
		open.apply(this, arguments);
	};
}(window));<commit_msg>[TIMOB-16523] Fixed bugs in the event system.<commit_after>(function (global) {
	/**
	 * console shim
	 */
	var objToString = Object.prototype.toString,
		console = global.console = {
			log: function () {
				sendRequest('log', {
					message: Array.prototype.slice.call(arguments).map(function (it) {
						return it === void 0 ? 'undefined' : it === null ? 'null' : Array.isArray(it) ? JSON.stringify(it.map(function (f) {
							return typeof f == 'function' ? f.toString() : f;
						})) : objToString.call(it) == '[object Object]' ? JSON.stringify(it) : it;
					}).join(' ')
				});
			}
		},
		requests = {},
		handles = {};

	function processResponse(data) {
		var tmp = data.primitiveValue;
		return tmp !== void 0 ? tmp : (tmp = data.handle) ? handles[tmp] || (handles[tmp] = new Handle(tmp)) : data;
	}

	// WARNING: Do NOT use console.log() inside this function when type == 'log'!
	function sendRequest(type, data, callback) {
		callback || (callback = processResponse);
		var token = '' + Math.round(Math.random() * 1e9).toString(16),
			tmp;
		requests[token] = callback;
		global.external.notify(JSON.stringify({
			type: type,
			token: token,
			data: data
		}));
		tmp = requests[token];
		delete requests[token];
		if (tmp instanceof Error && type != 'log') {
			tmp.toString().split(/\r\n|\n/).forEach(function (s) { console.log('[ERROR] ', s); });
			throw tmp;
		}
		return tmp;
	}

	function valueify(v, obj) {
		obj || (obj = {});
		if (v) {
			v instanceof Handle ? (obj.valueHnd = v._hnd) : (obj.valuePrimitive = v);
		}
		return obj;
	}

	/**
	 * Native object handle
	 */
	function Handle(hnd) {
		this._hnd = hnd
		this._listeners = {};
	}

	Handle.prototype = Object.create({
		addEventListener: function (name, callback) {
			var listeners = this._listeners[name] || (this._listeners[name] = []);
			if (!listeners.length) {
				sendRequest('reflection', {
					action: 'addEventListener',
					handle: this._hnd,
					name: name
				});
			}
			listeners.push(callback);
		},

		destroy: function () {
			for (var evt in this._listeners) {
				for (var i = 0, cbs = this._listeners[evt], len = cbs.length; i < len; i++) {
					this.removeEventListener(evt, cbs[i]);
				}
			}
			sendRequest('reflection', {
				action: 'destroy',
				handle: this._hnd
			});
			delete handles[this._hnd];
		},

		invoke: function (method, args) {
			return sendRequest('reflection', {
				action: 'invokeMethod',
				handle: this._hnd,
				method: method,
				args: Array.isArray(args) ? args.map(function (a, i) {
						return i % 2 == 0 ? a : valueify(a);
					}) : []
			});
		},

		property: function (name, value) {
			if (name && objToString.call(name) == '[object Object]') {
				for (var i in name) {
					name[i] = valueify(name[i]);
				}
			}

			return sendRequest('reflection', valueify(value, {
				action: 'property',
				handle: this._hnd,
				name: name
			}), function (data) {
				var obj = data.value;
				if (obj && objToString.call(obj) == '[object Object]') {
					for (var i in obj) {
						obj[i] = processResponse(obj[i]);
					}
					return obj;
				}
				return processResponse(data);
			});
		},

		removeEventListener: function (name, callback) {
			var idx,
				listeners = this._listeners[name];
			if (listeners && ~(idx = listeners.indexOf(callback))) {
				listeners.splice(idx, 1);
				listeners.length || sendRequest('reflection', {
					action: 'removeEventListener',
					handle: this._hnd,
					name: name
				});
			}
		}
	});

	// init default handles
	handles.app = new Handle('app');
	handles.browser = new Handle('browser');
	handles.root = new Handle('root');

	/**
	 * tiwp8 - Titanium Windows Phone 8 namespace
	 */
	global.tiwp8 = {
		createInstance: function (className, args) {
			return sendRequest('reflection', {
				action: 'createInstance',
				className: className,
				args: Array.isArray(args) ? args.map(function (a, i) {
						return i % 2 == 0 ? a : valueify(a);
					}) : []
			});
		},

		fireEvent: function (data) {
			var src = data.source = handles[data._hnd],
				listeners = src._listeners[data.type],
				i = 0,
				len = listeners ? listeners.length : 0;
			data.sender = new Handle(data.sender);
			data.eventArgs = new Handle(data.eventArgs);
			for (; i < len; i++) {
				listeners[i](data);
			}
		},

		getEnum: function (name, value) {
			return sendRequest('reflection', {
				action: 'getEnum',
				name: name,
				value: value
			});
		},

		getFile: function (file, isBinary) {
			return sendRequest('file', {
				file: file,
				isBinary: isBinary
			});
		},

		getHandles: function () {
			return handles;
		},

		getPhoneApplicationPage: function () {
			return handles.app;
		},

		getRootGrid: function () {
			return handles.root;
		},

		getWebBrowser: function () {
			return handles.browser;
		},

		handleResponse: function (data) {
			var err = data.error,
				token = data.token;
			try {
				if (err) {
					throw new Error(err);
				}
				token && requests[token] && (requests[token] = requests[token](data));
			} catch (ex) {
				token && (requests[token] = ex);
			}
		},

		invokeStatic: function (className, method, args) {
			return sendRequest('reflection', {
				action: 'invokeStatic',
				className: className,
				method: method,
				args: Array.isArray(args) ? args.map(function (a, i) {
						return i % 2 == 0 ? a : valueify(a);
					}) : []
			});
		},

		sendRequest: sendRequest
	};

	/**
	 * XMLHttpRequest shim
	 */
	var open = XMLHttpRequest.prototype.open;
	XMLHttpRequest.prototype.open = function (method, url) {
		url = 'http://localhost:9999/fetch/' + escape(btoa(url));
		open.apply(this, arguments);
	};
}(window));<|endoftext|>