<commit_before>/*
 *  FSTransport.js
 *
 *  David Janes
 *  IOTDB.org
 *  2015-03-07
 *
 *  Copyright [2013-2015] [David P. Janes]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

"use strict";

var iotdb = require('iotdb');
var _ = iotdb._;
var bunyan = iotdb.bunyan;

var fs = require('fs');
var path = require('path');
var mkdirp = require('mkdirp');
var watch = require('watch');

var util = require('util');
var url = require('url');

var logger = bunyan.createLogger({
    name: 'iotdb-transport-fs',
    module: 'FSTransport',
});

/* --- forward definitions --- */
var _encode;
var _decode;
var _unpack;
var _pack;

/* --- constructor --- */

/**
 *  File System based Transport
 *

 *  See {iotdb.transporter.Transport#Transport} for documentation.
 */
var FSTransport = function (initd) {
    var self = this;

    self.initd = _.defaults(
        initd, {
            channel: iotdb.transporter.channel,
            unchannel: iotdb.transporter.unchannel,
            encode: _encode,
            decode: _decode,
            pack: _pack,
            unpack: _unpack,
        },
        iotdb.keystore().get("/transports/FSTransport/initd"), {
            prefix: path.join(process.cwd(), ".iotdb", "fs"),
            flat_band: null,
        }
    );

    /* for consistency but not used */
    self.native = {};

    /* ignore errors - they will occur later anyway */
    mkdirp.sync(self.initd.prefix, function (error) {});
};

FSTransport.prototype = new iotdb.transporter.Transport();

/* --- methods --- */

/**
 *  See {iotdb.transporter.Transport#list} for documentation.
 */
FSTransport.prototype.list = function (paramd, callback) {
    var self = this;

    if (arguments.length === 1) {
        paramd = {};
        callback = arguments[0];
    }

    self._validate_list(paramd, callback);

    fs.readdir(self.initd.prefix, function (error, names) {
        if (error) {
            return;
        }

        var _pop = function () {
            if (names.length === 0) {
                callback({
                    end: true,
                });
                return;
            }

            var name = names.pop();
            var folder = path.join(self.initd.prefix, name);

            var result = self.initd.unchannel(self.initd, folder);
            if (result) {
                if (callback({
                        id: result[0],
                    })) {
                    names = [];
                }

                _pop();
            }
        };

        _pop();
    });
};

/**
 *  See {iotdb.transporter.Transport#added} for documentation.
 *

 *  NOT FINISHED
 */
FSTransport.prototype.added = function (paramd, callback) {
    var self = this;

    if (arguments.length === 1) {
        paramd = {};
        callback = arguments[0];
    }

    self._validate_added(paramd, callback);
};

/**
 *  See {iotdb.transporter.Transport#about} for documentation.
 */
FSTransport.prototype.about = function (paramd, callback) {
    var self = this;

    self._validate_about(paramd, callback);

    if (self.initd.flat_band) {
        self._about_flat(paramd, callback);
    } else {
        self._about_normal(paramd, callback);
    }
};

/**
 *  Flat files - read and if it exists return [ id, flat_band ]
 */
FSTransport.prototype._about_flat = function (paramd, callback) {
    var self = this;
    var channel = self.initd.channel(self.initd, paramd.id);

    fs.readFile(channel, {
        encoding: 'utf8'
    }, function (error, doc) {
        if (error) {
            return callback({
                id: paramd.id,
                bands: null,
                error: error,
            });
        }

        return callback({
            id: paramd.id,
            bands: [self.initd.flat_band, ],
        });
    });
};

/**
 */
FSTransport.prototype._about_normal = function (paramd, callback) {
    var self = this;
    var channel = self.initd.channel(self.initd, paramd.id);
    var bands = [];

    fs.readdir(channel, function (error, names) {
        if (error) {
            return;
        }

        var _pop = function () {
            if (names.length === 0) {
                callback({
                    id: paramd.id,
                    bands: bands,
                });
                return;
            }

            var name = names.pop();
            var folder = path.join(channel, name);
            var result = self.initd.unchannel(self.initd, folder);
            if (!result) {
                _pop();
                return;
            }

            fs.readFile(folder, {
                encoding: 'utf8'
            }, function (error, doc) {
                if (!error) {
                    bands.push(name);
                }

                _pop();
            });
        };

        _pop();
    });
};

/**
 *  See {iotdb.transporter.Transport#get} for documentation.
 */
FSTransport.prototype.get = function (paramd, callback) {
    var self = this;

    self._validate_get(paramd, callback);

    var channel = self.initd.channel(self.initd, paramd.id, paramd.band);

    /* undefined for "don't know"; null for "doesn't exist" */
    fs.readFile(channel, {
        encoding: 'utf8'
    }, function (error, doc) {
        if (error) {
            callback({
                id: paramd.id,
                band: paramd.band,
                value: null,
                error: error,
            });
            return;
        }

        try {
            callback({
                id: paramd.id,
                band: paramd.band,
                value: self.initd.unpack(JSON.parse(doc), paramd.id, paramd.band),
            });
        } catch (x) {
            logger.error({
                method: "get",
                cause: "see stack trace",
                stack: x.stack,
            }, "exception in callback");
        }
    });
};

/**
 *  See {iotdb.transporter.Transport#update} for documentation.
 */
FSTransport.prototype.update = function (paramd, callback) {
    var self = this;

    self._validate_update(paramd, callback);

    var channel = self.initd.channel(self.initd, paramd.id, paramd.band);
    var d = self.initd.pack(paramd.value, paramd.id, paramd.band);

    mkdirp(path.dirname(channel), function (error) {
        if (error) {
            if (callback) {
                callback({
                    error: error
                });
            }
            return;
        }

        fs.writeFileSync(channel, JSON.stringify(d, null, 2));

        if (callback) {
            callback(null);
        }
    });
};

/**
 *  See {iotdb.transporter.Transport#updated} for documentation.
 */
FSTransport.prototype.updated = function (paramd, callback) {
    var self = this;

    if (arguments.length === 1) {
        paramd = {};
        callback = arguments[0];
    }

    self._validate_updated(paramd, callback);

    var last_time = 0;
    var last_id = null;
    var last_band = null;

    var _doit = function (f) {
        var result = self.initd.unchannel(self.initd, f);
        if (!result) {
            return;
        }

        var this_id = result[0];
        var this_band = result[1];

        if (paramd.id && (this_id !== paramd.id)) {
            return;
        }

        if (paramd.band && (this_band !== paramd.band)) {
            return;
        }

        /* debounce, sigh */
        var now = (new Date()).getTime();
        if ((this_id === last_id) && (this_band === last_band) && ((now - last_time) < 50)) {
            return;
        }

        last_id = this_id;
        last_band = this_band;
        last_time = now;

        callback({
            id: this_id,
            band: this_band,
            value: undefined,
        });
    };

    watch.createMonitor(self.initd.prefix, function (monitor) {
        monitor.on("created", function (f, stat) {
            _doit(f);
        });
        monitor.on("changed", function (f, curr, prev) {
            _doit(f);
        });
        monitor.on("removed", function (f, stat) {
            _doit(f);
        });
    });
};

/**
 *  See {iotdb.transporter.Transport#remove} for documentation.
 */
FSTransport.prototype.remove = function (paramd, callback) {
    var self = this;

    self._validate_remove(paramd, callback);

    var channel = self.initd.channel(self.initd, paramd.id);

    fs.readdir(channel, function (error, names) {
        if (error) {
            return;
        }

        var _pop = function () {
            if (names.length === 0) {
                fs.rmdir(channel, function (error) {});
            }

            var name = names.pop();
            var folder = path.join(channel, name);

            fs.unlink(folder, function (error) {
                _pop();
            });
        };

        _pop();
    });
};

/* --- internals --- */

var safe_rex = /[\/$%#.\]\[]/g;
if (/^win/.test(process.platform)) {
    safe_rex = /[:\/$%#.\]\[]/g;
}

var _encode = function (s) {
    return s.replace(safe_rex, function (c) {
        return '%' + c.charCodeAt(0).toString(16);
    });
};

var _decode = function (s) {
    return decodeURIComponent(s);
};

var _unpack = function (d, id, band) {
    return _.d.transform(d, {
        pre: _.ld_compact,
        key: _decode,
    });
};

var _pack = function (d, id, band) {
    return _.d.transform(d, {
        pre: _.ld_compact,
        key: _encode,
    });
};

/**
 *  API
 */
exports.FSTransport = FSTransport;
<commit_msg>updates for working with app, avoid loops<commit_after>/*
 *  FSTransport.js
 *
 *  David Janes
 *  IOTDB.org
 *  2015-03-07
 *
 *  Copyright [2013-2015] [David P. Janes]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

"use strict";

var iotdb = require('iotdb');
var _ = iotdb._;
var bunyan = iotdb.bunyan;

var fs = require('fs');
var path = require('path');
var mkdirp = require('mkdirp');
var watch = require('watch');

var util = require('util');
var url = require('url');

var logger = bunyan.createLogger({
    name: 'iotdb-transport-fs',
    module: 'FSTransport',
});

/* --- forward definitions --- */
var _encode;
var _decode;
var _unpack;
var _pack;

/* --- constructor --- */

/**
 *  File System based Transport
 *

 *  See {iotdb.transporter.Transport#Transport} for documentation.
 */
var FSTransport = function (initd) {
    var self = this;

    self.initd = _.defaults(
        initd, {
            channel: iotdb.transporter.channel,
            unchannel: iotdb.transporter.unchannel,
            encode: _encode,
            decode: _decode,
            pack: _pack,
            unpack: _unpack,
        },
        iotdb.keystore().get("/transports/FSTransport/initd"), {
            prefix: path.join(process.cwd(), ".iotdb", "fs"),
            flat_band: null,
        }
    );

    /* for consistency but not used */
    self.native = {};

    /* ignore errors - they will occur later anyway */
    mkdirp.sync(self.initd.prefix, function (error) {});
};

FSTransport.prototype = new iotdb.transporter.Transport();

/* --- methods --- */

/**
 *  See {iotdb.transporter.Transport#list} for documentation.
 */
FSTransport.prototype.list = function (paramd, callback) {
    var self = this;

    if (arguments.length === 1) {
        paramd = {};
        callback = arguments[0];
    }

    self._validate_list(paramd, callback);

    fs.readdir(self.initd.prefix, function (error, names) {
        if (error) {
            return;
        }

        var _pop = function () {
            if (names.length === 0) {
                callback({
                    end: true,
                });
                return;
            }

            var name = names.pop();
            var folder = path.join(self.initd.prefix, name);

            var result = self.initd.unchannel(self.initd, folder);
            if (result) {
                if (callback({
                        id: result[0],
                    })) {
                    names = [];
                }

                _pop();
            }
        };

        _pop();
    });
};

/**
 *  See {iotdb.transporter.Transport#added} for documentation.
 *

 *  NOT FINISHED
 */
FSTransport.prototype.added = function (paramd, callback) {
    var self = this;

    if (arguments.length === 1) {
        paramd = {};
        callback = arguments[0];
    }

    self._validate_added(paramd, callback);
};

/**
 *  See {iotdb.transporter.Transport#about} for documentation.
 */
FSTransport.prototype.about = function (paramd, callback) {
    var self = this;

    self._validate_about(paramd, callback);

    if (self.initd.flat_band) {
        self._about_flat(paramd, callback);
    } else {
        self._about_normal(paramd, callback);
    }
};

/**
 *  Flat files - read and if it exists return [ id, flat_band ]
 */
FSTransport.prototype._about_flat = function (paramd, callback) {
    var self = this;
    var channel = self.initd.channel(self.initd, paramd.id);

    fs.readFile(channel, {
        encoding: 'utf8'
    }, function (error, doc) {
        if (error) {
            return callback({
                id: paramd.id,
                bands: null,
                error: error,
            });
        }

        return callback({
            id: paramd.id,
            bands: [self.initd.flat_band, ],
        });
    });
};

/**
 */
FSTransport.prototype._about_normal = function (paramd, callback) {
    var self = this;
    var channel = self.initd.channel(self.initd, paramd.id);
    var bands = [];

    fs.readdir(channel, function (error, names) {
        if (error) {
            return;
        }

        var _pop = function () {
            if (names.length === 0) {
                callback({
                    id: paramd.id,
                    bands: bands,
                });
                return;
            }

            var name = names.pop();
            var folder = path.join(channel, name);
            var result = self.initd.unchannel(self.initd, folder);
            if (!result) {
                _pop();
                return;
            }

            fs.readFile(folder, {
                encoding: 'utf8'
            }, function (error, doc) {
                if (!error) {
                    bands.push(name);
                }

                _pop();
            });
        };

        _pop();
    });
};

/**
 *  See {iotdb.transporter.Transport#get} for documentation.
 */
FSTransport.prototype.get = function (paramd, callback) {
    var self = this;

    self._validate_get(paramd, callback);

    var channel = self.initd.channel(self.initd, paramd.id, paramd.band);

    /* undefined for "don't know"; null for "doesn't exist" */
    fs.readFile(channel, {
        encoding: 'utf8'
    }, function (error, doc) {
        if (error) {
            callback({
                id: paramd.id,
                band: paramd.band,
                value: null,
                error: error,
            });
            return;
        }

        try {
            callback({
                id: paramd.id,
                band: paramd.band,
                value: self.initd.unpack(JSON.parse(doc), paramd.id, paramd.band),
            });
        } catch (x) {
            logger.error({
                method: "get",
                cause: "see stack trace",
                stack: x.stack,
            }, "exception in callback");
        }
    });
};

/**
 *  See {iotdb.transporter.Transport#update} for documentation.
 */
FSTransport.prototype.update = function (paramd, callback) {
    var self = this;

    self._validate_update(paramd, callback);

    var channel = self.initd.channel(self.initd, paramd.id, paramd.band);
    var d = self.initd.pack(paramd.value, paramd.id, paramd.band);

    mkdirp(path.dirname(channel), function (error) {
        if (error) {
            if (callback) {
                callback({
                    error: error
                });
            }
            return;
        }

        fs.writeFileSync(channel, JSON.stringify(d, null, 2));

        if (callback) {
            callback(null);
        }
    });
};

/**
 *  See {iotdb.transporter.Transport#updated} for documentation.
 */
FSTransport.prototype.updated = function (paramd, callback) {
    var self = this;

    if (arguments.length === 1) {
        paramd = {};
        callback = arguments[0];
    }

    self._validate_updated(paramd, callback);

    var last_time = 0;
    var last_id = null;
    var last_band = null;

    var _doit = function (f) {
        var result = self.initd.unchannel(self.initd, f);
        if (!result) {
            return;
        }

        var this_id = result[0];
        var this_band = result[1];

        if (paramd.id && (this_id !== paramd.id)) {
            return;
        }

        if (paramd.band && (this_band !== paramd.band)) {
            return;
        }

        /* debounce, sigh */
        var now = (new Date()).getTime();
        if ((this_id === last_id) && (this_band === last_band) && ((now - last_time) < 50)) {
            return;
        }

        last_id = this_id;
        last_band = this_band;
        last_time = now;

        callback({
            id: this_id,
            band: this_band,
            value: undefined,
        });
    };

    watch.createMonitor(self.initd.prefix, function (monitor) {
        monitor.on("created", function (f, stat) {
            _doit(f);
        });
        monitor.on("changed", function (f, curr, prev) {
            _doit(f);
        });
        monitor.on("removed", function (f, stat) {
            _doit(f);
        });
    });
};

/**
 *  See {iotdb.transporter.Transport#remove} for documentation.
 */
FSTransport.prototype.remove = function (paramd, callback) {
    var self = this;

    self._validate_remove(paramd, callback);

    var channel = self.initd.channel(self.initd, paramd.id);

    fs.readdir(channel, function (error, names) {
        if (error) {
            return;
        }

        var _pop = function () {
            if (names.length === 0) {
                fs.rmdir(channel, function (error) {});
            }

            var name = names.pop();
            var folder = path.join(channel, name);

            fs.unlink(folder, function (error) {
                _pop();
            });
        };

        _pop();
    });
};

/* --- internals --- */

var safe_rex = /[\/$%#\]\[]/g;
if (/^win/.test(process.platform)) {
    safe_rex = /[:\/$%#\]\[]/g;
}

var _encode = function (s) {
    return s.replace(safe_rex, function (c) {
        return '%' + c.charCodeAt(0).toString(16);
    });
};

var _decode = function (s) {
    return decodeURIComponent(s);
};

var _unpack = function (d, id, band) {
    return _.d.transform(d, {
        pre: _.ld_compact,
        key: _decode,
    });
};

var _pack = function (d, id, band) {
    return _.d.transform(d, {
        pre: _.ld_compact,
        key: _encode,
    });
};

/**
 *  API
 */
exports.FSTransport = FSTransport;
<|endoftext|>


<commit_before>var Snipe = Class.extend({
    /**
     * Init method
     * @param options (Object) - Options for the method.
     *  Eg.
     *  options: {
     *      //Maximum number of results to display
     *      maxResults: 5,
     *
     *      refresh: function(value) {
     *          //Method to handle fetching new data
     *          //The value param is the value of the input field
     *      },
     *
     *      onRefreshed: function(resultsList) {
     *          //Method called after refresh operation
     *      },
     *
     *      select: function(winid, tabid) {
     *          //Method to handle what happens when an item is selected
     *      },
     *
     *      onDestroyed: function() {
     *          //Method to handle what happens when snipe is destroyed
     *      }
     *
     *      onSettingsChanged: function(settings) {
     *          //Method to handle what happens when snipe's settings are updated
     *      }
     *  }
     */
    init: function(options) {
        var self = this,

            element = document.createElement('div'),
            wrapper = document.createElement('div'),
            form = document.createElement('form'),
            settingsBtn = document.createElement('a'),
            field = document.createElement('input'),
            resultsList = new Snipe.Results(document.createElement('ul'), {
                select: onTabSelected,
                maxResults: options.maxResults
            }),
            settings = new Snipe.Settings(document.createElement('form'), {
                change: onSettingsChanged,
                submit: onSettings
            }),

            timer;

        self.element = element;

// PRIVATE METHODS ____________________________________________________________

        function create() {
            addClass(element, 'snipe');
            addClass(wrapper, 'wrapper');
            addClass(form, 'input');
            addClass(settingsBtn, 'settingsBtn');

            element.appendChild(wrapper);

            wrapper.appendChild(form);
            wrapper.appendChild(settings.element);

            form.appendChild(settingsBtn);
            form.appendChild(field);
            form.appendChild(resultsList.element);

            document.body.insertBefore(element, document.body.firstChild);
        }

        function addEvents() {
            element.addEventListener('webkitTransitionEnd', onTransitionEnd, false);
            field.addEventListener('keyup', onKeyUp, false);
            field.addEventListener('keydown', onKeyDown, false);
            form.addEventListener('submit', onFormSubmit, false);

            //Bring up the settings window
            settingsBtn.addEventListener('click', onSettings, false);

            //Hide Snipe when the window loses focus
            window.addEventListener('blur', onWindowBlur);

            //Hide snipe when clicking outside the snipe window
            window.addEventListener('click', onWindowClick);
        }

        function removeEvents() {
            element.removeEventListener('webkitTransitionEnd', onTransitionEnd);
            field.removeEventListener('keyup', onKeyUp);
            field.removeEventListener('keydown', onKeyDown);
            form.removeEventListener('submit', onFormSubmit);
            settingsBtn.removeEventListener('click', onSettings)

            window.removeEventListener('blur', onWindowBlur);
            window.removeEventListener('click', onWindowClick);
        }

        function destroy() {
            resultsList.destroy();
            element.parentNode.removeChild(element);
            field.value = '';

            removeEvents();

            removeClass(element, 'settings');

            if (options.onDestroyed) {
                options.onDestroyed();
            }
        }

// EVENT HANDLERS _____________________________________________________________

        function onTransitionEnd(e) {
            switch (e.propertyName) {
                case 'opacity':
                    if (hasClass(element, 'in')) {
                        var yScroll = window.scrollY;
                        field.focus();
                        window.scrollTo(window.scrollX, yScroll);
                    }
                    else {
                        destroy();
                    }
                break;
            }
        }

        function onTabSelected(winid, tabid) {
            self.hide();
            if (options.select) {
                options.select.apply(null, [winid, tabid]);
            }
        }

        function onSettingsChanged(settings) {
            if (options.onSettingsChanged) {
                options.onSettingsChanged.apply(null, [settings]);
            }
        }

        function onKeyDown(e) {
            //Up Arrow or Ctrl + P to go up
            if ((e.keyCode == KEY_UP) || (e.ctrlKey && KEYMAP[e.keyCode].name == 'P')) {
                var curIndex = resultsList.curIndex,
                    items = resultsList.element.querySelectorAll('li'),
                    length = items.length || 0,
                    prev = curIndex - 1 < 0 ? length - 1 : curIndex - 1;

                resultsList.selectResult(items[prev]);
                e.preventDefault();
            }

            //Down Arrow or Ctrl + N to go down
            else if (e.keyCode == KEY_DOWN || (e.ctrlKey && KEYMAP[e.keyCode].name == 'N')) {
                var curIndex = resultsList.curIndex,
                    items = resultsList.element.querySelectorAll('li'),
                    length = items.length || 0,
                    next = curIndex + 1 >= length ? 0 : curIndex + 1;

                resultsList.selectResult(items[next]);
                e.preventDefault();
            }

            //Esc closes
            else if (e.keyCode == KEY_ESC) {
                snipe.hide();
            }
        }

        function onKeyUp(e) {
            switch (e.keyCode) {
                //Do nothing
                case KEY_SHIFT:
                case KEY_CTRL:
                case KEY_ALT:
                case KEY_CAPS:
                case KEY_ESC:
                case KEY_END:
                case KEY_HOME:
                case KEY_LEFT:
                case KEY_UP:
                case KEY_RIGHT:
                case KEY_DOWN:
                case KEY_META:
                break;

                //Get results
                default:
                    if (!e.ctrlKey) {
                        clearTimeout(timer);
                        timer = setTimeout(function () {
                            if (!field || (!field.value && field.value != '')) {return false;}
                            options.refresh.apply(null, [field.value]);
                        }, 100);
                    }
            }
        }

        function onFormSubmit(e) {
            resultsList.activateResult();
            e.preventDefault();
        }

        function onSettings(e) {
            if (hasClass(element, 'settings')) {
                removeClass(element, 'settings');
            }
            else {
                addClass(element, 'settings');
            }

            if (e && e.preventDefault) {
                e.preventDefault();
            }
        }

        function onWindowBlur(e) {
            self.hide();
        }

        function onWindowClick(e) {
            if (!hasAncestor(e.target, element) || e.target == element) {
                self.hide();
            }
        }

// PRIVILEGED METHODS _________________________________________________________

        self.show = function() {
            create();
            addEvents();

            setTimeout(function() {
                addClass(element, 'in');
                field.focus();
            }, 10);
        };

        self.hide = function() {
            self.refresh();
            removeClass(element, 'in');
        };

        self.toggle = function() {
            if (hasClass(element, 'in')) {
                self.hide();
            }
            else {
                self.show();
            }
        }

        self.refresh = function(data) {
            if (!element) {return false;}
            resultsList.refresh(data);

            if (options.onRefreshed) {
                options.onRefreshed(element.clientHeight);
            }
        };

        self.updateSettings = function(newSettings) {
            settings.set(newSettings);
        };

        self.matchesShortcut = function(e) {
            if (!settings || !settings.get()) {
                return false;
            }

            var mods = settings.get().shortcut.modifiers,
                key = settings.get().shortcut.key;

            function matchesMods() {
                for (var i = 0, length = mods.length, modKey, matches = true; i < length; i++) {
                    modKey = mods[i].modifier;
                    if (!e[modKey]) {
                        return false;
                    }
                }

                return true;
            }

            if ( matchesMods() && e.keyCode == key.id) {
                return true;
            }

            return false;
        };

// CONSTRUCTOR ________________________________________________________________

        //Sucks to do UA detection, but Chrome won't support webkitBackfaceVisibility
        //until version 11, and this is the easiest way to detect that (no real feature-
        //detection for that CSS property).
        if (BrowserDetect.browser == 'Chrome' && BrowserDetect.version < 11) {
            addClass(element, 'anim2d');
        }
    }
});<commit_msg>Not asking for new results if alt key and meta key are down.<commit_after>var Snipe = Class.extend({
    /**
     * Init method
     * @param options (Object) - Options for the method.
     *  Eg.
     *  options: {
     *      //Maximum number of results to display
     *      maxResults: 5,
     *
     *      refresh: function(value) {
     *          //Method to handle fetching new data
     *          //The value param is the value of the input field
     *      },
     *
     *      onRefreshed: function(resultsList) {
     *          //Method called after refresh operation
     *      },
     *
     *      select: function(winid, tabid) {
     *          //Method to handle what happens when an item is selected
     *      },
     *
     *      onDestroyed: function() {
     *          //Method to handle what happens when snipe is destroyed
     *      }
     *
     *      onSettingsChanged: function(settings) {
     *          //Method to handle what happens when snipe's settings are updated
     *      }
     *  }
     */
    init: function(options) {
        var self = this,

            element = document.createElement('div'),
            wrapper = document.createElement('div'),
            form = document.createElement('form'),
            settingsBtn = document.createElement('a'),
            field = document.createElement('input'),
            resultsList = new Snipe.Results(document.createElement('ul'), {
                select: onTabSelected,
                maxResults: options.maxResults
            }),
            settings = new Snipe.Settings(document.createElement('form'), {
                change: onSettingsChanged,
                submit: onSettings
            }),

            timer;

        self.element = element;

// PRIVATE METHODS ____________________________________________________________

        function create() {
            addClass(element, 'snipe');
            addClass(wrapper, 'wrapper');
            addClass(form, 'input');
            addClass(settingsBtn, 'settingsBtn');

            element.appendChild(wrapper);

            wrapper.appendChild(form);
            wrapper.appendChild(settings.element);

            form.appendChild(settingsBtn);
            form.appendChild(field);
            form.appendChild(resultsList.element);

            document.body.insertBefore(element, document.body.firstChild);
        }

        function addEvents() {
            element.addEventListener('webkitTransitionEnd', onTransitionEnd, false);
            field.addEventListener('keyup', onKeyUp, false);
            field.addEventListener('keydown', onKeyDown, false);
            form.addEventListener('submit', onFormSubmit, false);

            //Bring up the settings window
            settingsBtn.addEventListener('click', onSettings, false);

            //Hide Snipe when the window loses focus
            window.addEventListener('blur', onWindowBlur);

            //Hide snipe when clicking outside the snipe window
            window.addEventListener('click', onWindowClick);
        }

        function removeEvents() {
            element.removeEventListener('webkitTransitionEnd', onTransitionEnd);
            field.removeEventListener('keyup', onKeyUp);
            field.removeEventListener('keydown', onKeyDown);
            form.removeEventListener('submit', onFormSubmit);
            settingsBtn.removeEventListener('click', onSettings)

            window.removeEventListener('blur', onWindowBlur);
            window.removeEventListener('click', onWindowClick);
        }

        function destroy() {
            resultsList.destroy();
            element.parentNode.removeChild(element);
            field.value = '';

            removeEvents();

            removeClass(element, 'settings');

            if (options.onDestroyed) {
                options.onDestroyed();
            }
        }

// EVENT HANDLERS _____________________________________________________________

        function onTransitionEnd(e) {
            switch (e.propertyName) {
                case 'opacity':
                    if (hasClass(element, 'in')) {
                        var yScroll = window.scrollY;
                        field.focus();
                        window.scrollTo(window.scrollX, yScroll);
                    }
                    else {
                        destroy();
                    }
                break;
            }
        }

        function onTabSelected(winid, tabid) {
            self.hide();
            if (options.select) {
                options.select.apply(null, [winid, tabid]);
            }
        }

        function onSettingsChanged(settings) {
            if (options.onSettingsChanged) {
                options.onSettingsChanged.apply(null, [settings]);
            }
        }

        function onKeyDown(e) {
            //Up Arrow or Ctrl + P to go up
            if ((e.keyCode == KEY_UP) || (e.ctrlKey && KEYMAP[e.keyCode].name == 'P')) {
                var curIndex = resultsList.curIndex,
                    items = resultsList.element.querySelectorAll('li'),
                    length = items.length || 0,
                    prev = curIndex - 1 < 0 ? length - 1 : curIndex - 1;

                resultsList.selectResult(items[prev]);
                e.preventDefault();
            }

            //Down Arrow or Ctrl + N to go down
            else if (e.keyCode == KEY_DOWN || (e.ctrlKey && KEYMAP[e.keyCode].name == 'N')) {
                var curIndex = resultsList.curIndex,
                    items = resultsList.element.querySelectorAll('li'),
                    length = items.length || 0,
                    next = curIndex + 1 >= length ? 0 : curIndex + 1;

                resultsList.selectResult(items[next]);
                e.preventDefault();
            }

            //Esc closes
            else if (e.keyCode == KEY_ESC) {
                snipe.hide();
            }
        }

        function onKeyUp(e) {
            switch (e.keyCode) {
                //Do nothing
                case KEY_SHIFT:
                case KEY_CTRL:
                case KEY_ALT:
                case KEY_CAPS:
                case KEY_ESC:
                case KEY_END:
                case KEY_HOME:
                case KEY_LEFT:
                case KEY_UP:
                case KEY_RIGHT:
                case KEY_DOWN:
                case KEY_META:
                break;

                //Get results
                default:
                    if (!e.ctrlKey && !e.metaKey && !e.altKey) {
                        clearTimeout(timer);
                        timer = setTimeout(function () {
                            if (!field || (!field.value && field.value != '')) {return false;}
                            options.refresh.apply(null, [field.value]);
                        }, 100);
                    }
            }
        }

        function onFormSubmit(e) {
            resultsList.activateResult();
            e.preventDefault();
        }

        function onSettings(e) {
            if (hasClass(element, 'settings')) {
                removeClass(element, 'settings');
            }
            else {
                addClass(element, 'settings');
            }

            if (e && e.preventDefault) {
                e.preventDefault();
            }
        }

        function onWindowBlur(e) {
            self.hide();
        }

        function onWindowClick(e) {
            if (!hasAncestor(e.target, element) || e.target == element) {
                self.hide();
            }
        }

// PRIVILEGED METHODS _________________________________________________________

        self.show = function() {
            create();
            addEvents();

            setTimeout(function() {
                addClass(element, 'in');
                field.focus();
            }, 10);
        };

        self.hide = function() {
            self.refresh();
            removeClass(element, 'in');
        };

        self.toggle = function() {
            if (hasClass(element, 'in')) {
                self.hide();
            }
            else {
                self.show();
            }
        }

        self.refresh = function(data) {
            if (!element) {return false;}
            resultsList.refresh(data);

            if (options.onRefreshed) {
                options.onRefreshed(element.clientHeight);
            }
        };

        self.updateSettings = function(newSettings) {
            settings.set(newSettings);
        };

        self.matchesShortcut = function(e) {
            if (!settings || !settings.get()) {
                return false;
            }

            var mods = settings.get().shortcut.modifiers,
                key = settings.get().shortcut.key;

            function matchesMods() {
                for (var i = 0, length = mods.length, modKey, matches = true; i < length; i++) {
                    modKey = mods[i].modifier;
                    if (!e[modKey]) {
                        return false;
                    }
                }

                return true;
            }

            if ( matchesMods() && e.keyCode == key.id) {
                return true;
            }

            return false;
        };

// CONSTRUCTOR ________________________________________________________________

        //Sucks to do UA detection, but Chrome won't support webkitBackfaceVisibility
        //until version 11, and this is the easiest way to detect that (no real feature-
        //detection for that CSS property).
        if (BrowserDetect.browser == 'Chrome' && BrowserDetect.version < 11) {
            addClass(element, 'anim2d');
        }
    }
});<|endoftext|>


<commit_before>alert('Hi');<commit_msg>@bamdad  - One Sound<commit_after>var context = new webkitAudioContext();

oscillator = context.createOscillator(); // Oscillator defaults to sine wave
oscillator.connect(context.destination);
oscillator.noteOn(0);<|endoftext|>


<commit_before>exports.run = async (bot, msg, args) => {
  if (!args.length) {
    throw new Error('You must provide some text to convert!')
  }

  const emojis = bot.utils.buildEmojisArray(args.join(' '), {
    guild: msg.guild,
    preserve: true
  })

  if (!emojis.length) {
    throw new Error('Unable to parse text into emojis!')
  }

  return msg.edit(emojis.join(' '))
}

exports.info = {
  name: 'fanceh',
  usage: 'fanceh <text|emoji|both>',
  description: 'Renders text in big emoji letters',
  aliases: ['fancy', 'letters']
}
<commit_msg>Updated fanceh.js<commit_after>exports.run = async (bot, msg, args) => {
  if (!args.length) {
    throw new Error('You must provide some text to convert!')
  }

  const emojis = bot.utils.buildEmojisArray(args.join(' '), {
    guild: msg.guild,
    preserve: true,
    external: msg.guild ? msg.channel.permissionsFor(msg.guild.me).has('USE_EXTERNAL_EMOJIS') : true
  })

  if (!emojis.length) {
    throw new Error('Unable to parse text into emojis!')
  }

  return msg.edit(emojis.join(' '))
}

exports.info = {
  name: 'fanceh',
  usage: 'fanceh <text|emoji|both>',
  description: 'Renders text in big emoji letters',
  aliases: ['fancy', 'letters']
}
<|endoftext|>


<commit_before>"use strict";

import url from 'url';
import path from 'path';
import gm from 'gm';
import Promise from 'promise';
import {log,error} from './utils';

function headers(contentType) {
  let extraHeaders = arguments.length > 1 ? arguments[1] : {};
  return Object.assign({
    'Date': dateHeaderValue(new Date()),
    'Content-Type': contentType
  }, extraHeaders);
}

function dateHeaderValue(dt) {
  return dt.toUTCString();
}

function handleFailedImageResponse(imageResponse, res) {
  let h = headers(imageResponse.headers['content-type'], {'Cache-Control': 'no-cache'});
  res.writeHead(imageResponse.statusCode, h);
  imageResponse.on('error', function(err) {
    error('handleFailedImageResponse imageResponse stream error: %o', err);
    try { imageResponse.close(); } catch(e) {}
    res.end();
  });
  imageResponse.pipe(res);
}

function failResponse(res, message) {
  res.writeHead(500, headers('text/plain', {'Cache-Control': 'no-cache'}));
  res.end(message);
}

class Processor {
  constructor(route, imageSource, options, processFunc) {
    this.route = route;
    this.imageSource = imageSource;
    this.processFunc = processFunc;

    if ('cacheExpiration' in options) {
      this.cacheExpiration = options.cacheExpiration;
    } else {
      this.cacheExpiration = null;
    }
    if ('socketTimeout' in options) {
      this.socketTimeout = options.socketTimeout;
    } else {
      this.socketTimeout = null;
    }
    if ('gifFirstFrame' in options) {
      this.gifFirstFrame = options.gifFirstFrame;
    } else {
      this.gifFirstFrame = false;
    }
  }

  process(context, res) {
    context.params = this.route.extractParameters(context.request);
    log('params: %o', context.params);
    return this._getImage(context, res).
      then( (image) => this.processImage(image, context, res) ).
      then( (image) => this._streamImage(image, context, res) ).
      then(function() {
        if (context._cleanupFunctions) {
          for (let i = 0, len = context._cleanupFunctions.length; i < len; i++) {
            let func = context._cleanupFunctions[0];
            log('performing cleanup: %o', func);
            try {
              func();
            } catch (err) {
              error('error in cleanup function: %o', err);
            }
          }
        }
      });
  }

  processImage(image, context, res) {
    return this._executeProcessFunction(image, context).
      catch(function(err) {
        error("error in process function: %o", err);
        failResponse(res, err.message);
        return Promise.reject(err);
      });
  }

  _getImage(context, res) {
    let gifFirstFrame = this.gifFirstFrame;
    return this._requestImage(context).
      then(function(imageResponse) {
        if (imageResponse.statusCode != 200) {
          handleFailedImageResponse(imageResponse, res);
          return Promise.reject(new Error("Unexpected HTTP response code: " + imageResponse.statusCode));
        } else {
          context.imageContentType = imageResponse.headers['content-type'];
          context.imageLastModified = imageResponse.headers['last-modified'];
          log("received image: %s", context.imageContentType);
          let filename = path.basename(context.imageUrl);
          if (gifFirstFrame && filename.match(/\.gif$/)) {
            log('processing first frame of gif: %s', filename);
            filename = filename + '[0]';
          }
          return gm(imageResponse, filename);
        }
      }, function(err) {
        error("error fetching image: %o", err);
        failResponse(res, err.message);
        return Promise.reject(err);
      });
  }

  _requestImage(context) {
    log('requesting image...');
    let proc = this;
    let socketTimeout = this.socketTimeout;
    return new Promise(function(resolve, reject) {
      proc.imageSource.getImage(context, function(imageResponse) {
        resolve(imageResponse);
      }).on('error', function(err) {
        reject(err);
      }).on('socket', function(socket) {
        if (socketTimeout) {
          socket.setTimeout(socketTimeout);
        }
      });
    });
  }

  _executeProcessFunction(image, context) {
    let promise = null;
    try {
      log('executing process image function...');
      let result = this.processFunc(image, context);
      if (result == null || typeof result == 'undefined') {
        promise = Promise.reject(new Error('Expecting promise or image as result of process function'));
      } else if (('constructor' in result) && result.constructor == Promise) {
        promise = result;
      } else {
        promise = Promise.resolve(result);
      }
    } catch(err) {
      promise = Promise.reject(err);
    }
    return promise;
  }

  _streamImage(image, context, res) {
    log('streaming processed image...');
    let proc = this;
    return this._createImageStream(image, context).
      then(function(stream) {
        return proc._pipeStreamToResponse(stream, context, res);
      }, function(err) {
        error("error processing image: %o", err);
        failResponse(res, err.message);
        return Promise.reject(err);
      });
  }

  _createImageStream(image, context) {
    return new Promise(function(resolve, reject) {
      image.stream(function(err, stdout, stderr) {
        if (err) {
          reject(err);
        } else {
          resolve(stdout);
        }
      });
    });
  }

  _pipeStreamToResponse(stream, context, res) {
    log('sending transformed image...');
    let cacheExpiration = this.cacheExpiration;
    let h = headers(context.imageContentType, {'Last-Modified': context.imageLastModified});
    if (cacheExpiration) {
      h['Expires'] = dateHeaderValue(new Date(new Date().getTime() + (cacheExpiration*1000)));
      h['Cache-Control'] = "public, max-age=" + cacheExpiration;
    }
    res.writeHead(200, h);
    return this._pipeStream(stream, res).
      catch(function(err) {
        error('error streaming image to response: %o', err);
        failResponse(res, err.message);
        res.end();
        return Promise.reject(err);
      });
  }

  _pipeStream(a,b) {
    return new Promise(function(resolve, reject) {
      let streamError = false;
      a.on('finish', function() {
          if (!streamError) { resolve(); }
        }).
        on('error', function(err) {
          streamError = true;
          reject(err);
          try { a.close(); } catch(e) {}
        });
      a.pipe(b);
    });
  }
}

module.exports = Processor;
<commit_msg>Logging end of cleanup call<commit_after>"use strict";

import url from 'url';
import path from 'path';
import gm from 'gm';
import Promise from 'promise';
import {log,error} from './utils';

function headers(contentType) {
  let extraHeaders = arguments.length > 1 ? arguments[1] : {};
  return Object.assign({
    'Date': dateHeaderValue(new Date()),
    'Content-Type': contentType
  }, extraHeaders);
}

function dateHeaderValue(dt) {
  return dt.toUTCString();
}

function handleFailedImageResponse(imageResponse, res) {
  let h = headers(imageResponse.headers['content-type'], {'Cache-Control': 'no-cache'});
  res.writeHead(imageResponse.statusCode, h);
  imageResponse.on('error', function(err) {
    error('handleFailedImageResponse imageResponse stream error: %o', err);
    try { imageResponse.close(); } catch(e) {}
    res.end();
  });
  imageResponse.pipe(res);
}

function failResponse(res, message) {
  res.writeHead(500, headers('text/plain', {'Cache-Control': 'no-cache'}));
  res.end(message);
}

class Processor {
  constructor(route, imageSource, options, processFunc) {
    this.route = route;
    this.imageSource = imageSource;
    this.processFunc = processFunc;

    if ('cacheExpiration' in options) {
      this.cacheExpiration = options.cacheExpiration;
    } else {
      this.cacheExpiration = null;
    }
    if ('socketTimeout' in options) {
      this.socketTimeout = options.socketTimeout;
    } else {
      this.socketTimeout = null;
    }
    if ('gifFirstFrame' in options) {
      this.gifFirstFrame = options.gifFirstFrame;
    } else {
      this.gifFirstFrame = false;
    }
  }

  process(context, res) {
    context.params = this.route.extractParameters(context.request);
    log('params: %o', context.params);
    return this._getImage(context, res).
      then( (image) => this.processImage(image, context, res) ).
      then( (image) => this._streamImage(image, context, res) ).
      then( () => this._cleanup(context) );
  }

  processImage(image, context, res) {
    return this._executeProcessFunction(image, context).
      catch(function(err) {
        error("error in process function: %o", err);
        failResponse(res, err.message);
        return Promise.reject(err);
      });
  }

  _getImage(context, res) {
    let gifFirstFrame = this.gifFirstFrame;
    return this._requestImage(context).
      then(function(imageResponse) {
        if (imageResponse.statusCode != 200) {
          handleFailedImageResponse(imageResponse, res);
          return Promise.reject(new Error("Unexpected HTTP response code: " + imageResponse.statusCode));
        } else {
          context.imageContentType = imageResponse.headers['content-type'];
          context.imageLastModified = imageResponse.headers['last-modified'];
          log("received image: %s", context.imageContentType);
          let filename = path.basename(context.imageUrl);
          if (gifFirstFrame && filename.match(/\.gif$/)) {
            log('processing first frame of gif: %s', filename);
            filename = filename + '[0]';
          }
          return gm(imageResponse, filename);
        }
      }, function(err) {
        error("error fetching image: %o", err);
        failResponse(res, err.message);
        return Promise.reject(err);
      });
  }

  _requestImage(context) {
    log('requesting image...');
    let proc = this;
    let socketTimeout = this.socketTimeout;
    return new Promise(function(resolve, reject) {
      proc.imageSource.getImage(context, function(imageResponse) {
        resolve(imageResponse);
      }).on('error', function(err) {
        reject(err);
      }).on('socket', function(socket) {
        if (socketTimeout) {
          socket.setTimeout(socketTimeout);
        }
      });
    });
  }

  _executeProcessFunction(image, context) {
    let promise = null;
    try {
      log('executing process image function...');
      let result = this.processFunc(image, context);
      if (result == null || typeof result == 'undefined') {
        promise = Promise.reject(new Error('Expecting promise or image as result of process function'));
      } else if (('constructor' in result) && result.constructor == Promise) {
        promise = result;
      } else {
        promise = Promise.resolve(result);
      }
    } catch(err) {
      promise = Promise.reject(err);
    }
    return promise;
  }

  _streamImage(image, context, res) {
    log('streaming processed image...');
    let proc = this;
    return this._createImageStream(image, context).
      then(function(stream) {
        return proc._pipeStreamToResponse(stream, context, res);
      }, function(err) {
        error("error processing image: %o", err);
        failResponse(res, err.message);
        return Promise.reject(err);
      });
  }

  _createImageStream(image, context) {
    return new Promise(function(resolve, reject) {
      image.stream(function(err, stdout, stderr) {
        if (err) {
          reject(err);
        } else {
          resolve(stdout);
        }
      });
    });
  }

  _pipeStreamToResponse(stream, context, res) {
    log('sending transformed image...');
    let cacheExpiration = this.cacheExpiration;
    let h = headers(context.imageContentType, {'Last-Modified': context.imageLastModified});
    if (cacheExpiration) {
      h['Expires'] = dateHeaderValue(new Date(new Date().getTime() + (cacheExpiration*1000)));
      h['Cache-Control'] = "public, max-age=" + cacheExpiration;
    }
    res.writeHead(200, h);
    return this._pipeStream(stream, res).
      catch(function(err) {
        error('error streaming image to response: %o', err);
        failResponse(res, err.message);
        res.end();
        return Promise.reject(err);
      });
  }

  _pipeStream(a,b) {
    return new Promise(function(resolve, reject) {
      let streamError = false;
      a.on('finish', function() {
          if (!streamError) { resolve(); }
        }).
        on('error', function(err) {
          streamError = true;
          reject(err);
          try { a.close(); } catch(e) {}
        });
      a.pipe(b);
    });
  }

  _cleanup(context) {
    if (context._cleanupFunctions) {
      for (let i = 0, len = context._cleanupFunctions.length; i < len; i++) {
        let func = context._cleanupFunctions[0];
        log('performing cleanup: %o', func);
        try {
          func();
          log('cleanup completed');
        } catch (err) {
          error('error in cleanup function: %o', err);
        }
      }
    }
  }

}

module.exports = Processor;
<|endoftext|>


<commit_before>const MSS = require("./../../functions/");
const meta = require("./meta.json");

const filter = () => { return true; }

const emoji = {
	1: "\u0031\u20e3",
	2: "\u0032\u20e3",
	3: "\u0033\u20e3",
	4: "\u0034\u20e3",
	5: "\u0035\u20e3",
	6: "\u0036\u20e3",
	7: "\u0037\u20e3",
	8: "\u0038\u20e3",
	9: "\u0039\u20e3",
	0: "\u0030\u20e3"
}

module.exports = function yt(message) {
	let input = message.content.replace (/\n/g, "").split(" ");

	input.shift();
	input.shift();
	let items = input.join(" ");
	let vote = items.split(";");

	if(vote.length < 1) {
		return message.channel.send("Too few options!");
	} else if (vote.length > 9) {
		return message.channel.send("Too many options!");
	}

	let reply = meta[message.data.lang] && meta[message.data.lang].message_vote || "message_vote";

	vote.forEach((item, iterator) => {
		reply += `\n${emoji[iterator + 1]} ${item}`
	});

	message.channel.send(reply)
		.then((message) => {
			vote.forEach((item, iterator) => {
				setTimeout(() => {
					message.react(emoji[iterator + 1]);
				}, 1000 * iterator);
			});

			message.awaitReactions(filter, {time: 5000, errors: ['time']})
				.catch((collected) => {
					collected.forEach((messageReaction)=>{
						messageReaction.users.forEach((user)=>{
							console.log(user.id);
						});
					});
				});
		});
}
<commit_msg>log voters<commit_after>const MSS = require("./../../functions/");
const meta = require("./meta.json");

const filter = () => { return true; }

const emoji = {
	1: "\u0031\u20e3",
	2: "\u0032\u20e3",
	3: "\u0033\u20e3",
	4: "\u0034\u20e3",
	5: "\u0035\u20e3",
	6: "\u0036\u20e3",
	7: "\u0037\u20e3",
	8: "\u0038\u20e3",
	9: "\u0039\u20e3",
	0: "\u0030\u20e3"
}

module.exports = function yt(message) {
	let input = message.content.replace (/\n/g, "").split(" ");

	input.shift();
	input.shift();
	let items = input.join(" ");
	let vote = items.split(";");

	if(vote.length < 1) {
		return message.channel.send("Too few options!");
	} else if (vote.length > 9) {
		return message.channel.send("Too many options!");
	}

	let reply = meta[message.data.lang] && meta[message.data.lang].message_vote || "message_vote";

	vote.forEach((item, iterator) => {
		reply += `\n${emoji[iterator + 1]} ${item}`
	});

	message.channel.send(reply)
		.then((message) => {
			vote.forEach((item, iterator) => {
				setTimeout(() => {
					message.react(emoji[iterator + 1]);
				}, 1000 * iterator);
			});

			message.awaitReactions(filter, {time: 10000, errors: ['time']})
				.catch((collected) => {

					let voters = [];

					//Get all voters
					collected.forEach((messageReaction)=>{
						messageReaction.users.forEach((user)=>{
							voters.push(user.id);
						});
					});

					//Get all unique voters
					voters = [...new Set(voters)];

					//Log voters
					console.log(voters);
				});
		});
}
<|endoftext|>


<commit_before>// dimensions of the SVG viewport
var w = 600;
var h = 400;
var r = 3;

// TODO change domain and range according to some configuration

// scale for the second Chern number
var c2 = d3.scale.linear()
  .domain([-20, 80])
  .range([0, w]);

// scale for the first Chern number
var c12 = d3.scale.linear()
  .domain([-30, 60])
  .range([h, 0]);

// axis for the second Chern number
var c2Axis = d3.svg.axis()
  .scale(c2);

// axis for the first Chern number
var c12Axis = d3.svg.axis()
  .scale(c12)
  .orient("left");

// scale for the Kodaira dimension
var kodaira = d3.scale.ordinal()
  .domain([-1, 0, 1, 2])
  .range(["kodaira-infty", "kodaira-0", "kodaira-1", "kodaira-2"]);

// all the pairs (c_2,c_1^2) corresponding to a minimal projective surface
var points = []

// projective plane
points.push([3, 9, -1]);

// minimal surfaces of Kodaira dimension 0
points.push([0, 0, 0]); // abelian and hyperelliptic surfaces
points.push([12, 0, 0]); // Enriques surfaces
points.push([24, 0, 0]); // K3 surfaces

for (var i2 = c2.domain()[0]; i2 < c2.domain()[1]; i2++) {
  for (var i12 = c12.domain()[0]; i12 < c12.domain()[1]; i12++) {
    // ruled surfaces
    var positivity = (i2 <= 4) && (i12 <= 8);
    var congruence = (i2 % 4 == 0) && (i12 % 8 == 0) && (i12 == i2 * 2);
    if (congruence && positivity)
      points.push([i2, i12, -1]);

    // minimal surface of Kodaira dimension 1
    var congruence = ((i12 + i2) % 12 == 0);
    var positivity = (i12 == 0) && (i2 >= 0);
    if (congruence && positivity)
      points.push([i2, i12, 1]);

    // minimal surface of general type
    var congruence = ((i12 + i2) % 12 == 0);
    var positivity = (i12 >= 0) && (i2 >= 0);
    var BMY = (i12 <= (3 * i2));
    var noether = ((5 * i12 - i2 + 36) >= 0);

    if (congruence && positivity && BMY && noether)
      points.push([i2, i12, 2]);
  }
}

var svg = d3.select("body")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

// all the minimal nodes
svg.selectAll("circle")
  .data(points)
  .enter()
  .append("circle")
  .attr("cx", function(d) { return c2(d[0]); })
  .attr("cy", function(d) { return c12(d[1]); })
  .attr("r", function(d) { return r; })
  .attr("class", function(d) { return kodaira(d[2]); })

// horizontal axis
svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0," + c12(0) + ")")
  .call(c2Axis);

// vertical axis
svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(" + c2(0) + ",0)")
  .call(c12Axis);

// assign click event to points
d3.selectAll("circle").on("click", clickedPoint);

function clickedPoint(point) {
  // only act when the clicked node is active (i.e. has the correct Kodaira dimension)
  if (!d3.select(this).classed("inactive")) {
    // make all nodes inactive
    d3.selectAll("circle").classed("active", false);

    // make this node active
    d3.select(this).classed("active", true);

    // remove candidates
    clearCandidates();

    // reset the Hodge diamond
    setInactive();

    // add the coordinates to the legend in the fieldset
    $("fieldset#candidates legend").html("Candidates
for $\\mathrm{c}_2=" + point[0] + "$, $\\mathrm{c}_1^2=" + point[1] + "$");
    MathJax.Hub.Queue(["Typeset", MathJax.Hub]);

    // look for surfaces with the correct invariants
    for (var i = 0; i < surfaces.length; i++) {
      if (surfaces[i].c2 == point[0] && surfaces[i].c12 == point[1] && surfaces[i].kodaira == point[2])
        addCandidateSurface(surfaces[i]);
    }

    // check whether we have found surfaces, otherwise display a message
    if ($("fieldset#candidates ol li").length == 0)
      $("fieldset#candidates").prepend("
No surfaces known with these invariants, sorry.");
  }
}
<commit_msg>General type cannot have c_2 = c_1^2 = 0<commit_after>// dimensions of the SVG viewport
var w = 600;
var h = 400;
var r = 3;

// TODO change domain and range according to some configuration

// scale for the second Chern number
var c2 = d3.scale.linear()
  .domain([-20, 80])
  .range([0, w]);

// scale for the first Chern number
var c12 = d3.scale.linear()
  .domain([-30, 60])
  .range([h, 0]);

// axis for the second Chern number
var c2Axis = d3.svg.axis()
  .scale(c2);

// axis for the first Chern number
var c12Axis = d3.svg.axis()
  .scale(c12)
  .orient("left");

// scale for the Kodaira dimension
var kodaira = d3.scale.ordinal()
  .domain([-1, 0, 1, 2])
  .range(["kodaira-infty", "kodaira-0", "kodaira-1", "kodaira-2"]);

// all the pairs (c_2,c_1^2) corresponding to a minimal projective surface
var points = []

// projective plane
points.push([3, 9, -1]);

// minimal surfaces of Kodaira dimension 0
points.push([0, 0, 0]); // abelian and hyperelliptic surfaces
points.push([12, 0, 0]); // Enriques surfaces
points.push([24, 0, 0]); // K3 surfaces

for (var i2 = c2.domain()[0]; i2 < c2.domain()[1]; i2++) {
  for (var i12 = c12.domain()[0]; i12 < c12.domain()[1]; i12++) {
    // ruled surfaces
    var positivity = (i2 <= 4) && (i12 <= 8);
    var congruence = (i2 % 4 == 0) && (i12 % 8 == 0) && (i12 == i2 * 2);
    if (congruence && positivity)
      points.push([i2, i12, -1]);

    // minimal surface of Kodaira dimension 1
    var congruence = ((i12 + i2) % 12 == 0);
    var positivity = (i12 == 0) && (i2 >= 0);
    if (congruence && positivity)
      points.push([i2, i12, 1]);

    // minimal surface of general type
    var congruence = ((i12 + i2) % 12 == 0);
    var positivity = (i12 >= 0) && (i2 >= 0) && ((i12 > 0) || (i2 > 0));
    var BMY = (i12 <= (3 * i2));
    var noether = ((5 * i12 - i2 + 36) >= 0);

    if (congruence && positivity && BMY && noether)
      points.push([i2, i12, 2]);
  }
}

var svg = d3.select("body")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

// all the minimal nodes
svg.selectAll("circle")
  .data(points)
  .enter()
  .append("circle")
  .attr("cx", function(d) { return c2(d[0]); })
  .attr("cy", function(d) { return c12(d[1]); })
  .attr("r", function(d) { return r; })
  .attr("class", function(d) { return kodaira(d[2]); })

// horizontal axis
svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0," + c12(0) + ")")
  .call(c2Axis);

// vertical axis
svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(" + c2(0) + ",0)")
  .call(c12Axis);

// assign click event to points
d3.selectAll("circle").on("click", clickedPoint);

function clickedPoint(point) {
  // only act when the clicked node is active (i.e. has the correct Kodaira dimension)
  if (!d3.select(this).classed("inactive")) {
    // make all nodes inactive
    d3.selectAll("circle").classed("active", false);

    // make this node active
    d3.select(this).classed("active", true);

    // remove candidates
    clearCandidates();

    // reset the Hodge diamond
    setInactive();

    // add the coordinates to the legend in the fieldset
    $("fieldset#candidates legend").html("Candidates
for $\\mathrm{c}_2=" + point[0] + "$, $\\mathrm{c}_1^2=" + point[1] + "$");
    MathJax.Hub.Queue(["Typeset", MathJax.Hub]);

    // look for surfaces with the correct invariants
    for (var i = 0; i < surfaces.length; i++) {
      if (surfaces[i].c2 == point[0] && surfaces[i].c12 == point[1] && surfaces[i].kodaira == point[2])
        addCandidateSurface(surfaces[i]);
    }

    // check whether we have found surfaces, otherwise display a message
    if ($("fieldset#candidates ol li").length == 0)
      $("fieldset#candidates").prepend("
No surfaces known with these invariants, sorry.");
  }
}
<|endoftext|>


<commit_before>import Vue from 'vue';
import InfiniteLoading from '../../../src/components/InfiniteLoading';

function isShow(elm) {
  const styles = getComputedStyle(elm);

  return styles.getPropertyValue('display') !== 'none';
}

describe('InfiniteLoading.vue', () => {
  let vm;
  const initConf = {
    data() {
      return {
        list: [],
        distance: 50,
        isLoadedAll: false,
        isDivScroll: true,
        isCustomSpinner: false,
        listContainerHeight: 200,
        listItemHeight: 20,
      };
    },
    render(createElement) {
      return createElement(
        'div',
        {
          style: {
            height: `${this.listContainerHeight}px`,
            overflow: this.isDivScroll ? 'auto' : 'visible',
          },
        },
        [
          createElement('ul', {
            style: {
              margin: 0,
              padding: 0,
            },
          }, this.list.map((item) => createElement('li', {
            style: {
              height: `${this.listItemHeight}px`,
            },
          }, item))),
          this.isLoadedAll ? undefined : createElement(InfiniteLoading,
            {
              props: {
                distance: this.distance,
                onInfinite: this.onInfinite,
              },
              ref: 'infiniteLoading',
            },
            [
              this.isCustomSpinner ? createElement('span',
                {
                  slot: 'spinner',
                },
                [
                  createElement('i', {
                    attrs: {
                      class: 'custom-spinner',
                    },
                  }),
                ]
              ) : undefined,
            ]
          ),
        ]
      );
    },
  };

  // create new Vue instance for every test case
  beforeEach(() => {
    const container = document.createElement('div');
    container.setAttribute('id', 'app');
    document.body.appendChild(container);

    vm = new Vue(initConf);
  });

  afterEach(() => {
    /**
     * because of call the $destroy method of parent cannot trigger
     * destroy event for child component in Vue.js 2.0.0-rc6
     */
    vm.$refs.infiniteLoading && vm.$refs.infiniteLoading.$destroy();
    vm.$destroy(true);
    /**
     * because of pass true as the argument for destroy method cannot
     * remove element from DOM in Vue.js 2.0.0-rc6
     */
    vm.$el && vm.$el.remove();
  });

  it('should render a basic template', (done) => {
    vm.isDivScroll = false;
    setTimeout(() => {
      vm.$mount('#app');
      expect(vm.$el.querySelector('.loading-default')).to.be.ok;
      done();
    }, 1);
  });

  it('should execute callback and display a spinner immediately after initialize', (done) => {
    vm.onInfinite = function test() {
      Vue.nextTick(() => {
        expect(isShow(vm.$el.querySelector('.loading-default'))).to.be.true;
        done();
      });
    };

    vm.$mount('#app');
  });

  it('should not to execute callback if the previous loading has not be completed', (done) => {
    vm.onInfinite = function test() {
      const len = this.list.length + 1;
      for (let i = len; i < len + 20; i++) {
        this.list.push(i);
      }

      Vue.nextTick(() => {
        if (this.list.length === 20) {
          vm.$el.addEventListener('scroll', () => {
            expect(this.list).to.have.lengthOf(20);
            done();
          });

          // trigger scroll event manually
          vm.$el.scrollTop = vm.$el.scrollHeight;
        }
      });
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should be destroyed completely by v-if', (done) => {
    vm.onInfinite = function test() {
      this.isLoadedAll = true;
      Vue.nextTick(() => {
        expect(vm.$el.querySelector('.loading-default')).to.not.be.ok;
        done();
      });
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should display no results prompt', (done) => {
    vm.onInfinite = function test() {
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
      Vue.nextTick(() => {
        expect(isShow(vm.$el.querySelectorAll('.infinite-status-prompt')[0])).to.be.true;
        done();
      });
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should display no more data prompt', (done) => {
    vm.onInfinite = function test() {
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
      // test for whether trigger again after complete
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
      Vue.nextTick(() => {
        expect(isShow(vm.$el.querySelectorAll('.infinite-status-prompt')[1])).to.be.true;
        done();
      });
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should load results to fill up the container', (done) => {
    const expectedCount = Math.floor(vm.listContainerHeight / vm.listItemHeight);
    let i = 0;
    let timer;

    vm.onInfinite = function test() {
      setTimeout(() => {
        this.list.push(++i);
        this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
        clearTimeout(timer);
        timer = setTimeout(() => {
          if (i >= expectedCount) {
            done();
          } else {
            done(new Error('List not be fill up!'));
          }
        }, 100);
      }, 1);
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should reset component and call onInfinite again', (done) => {
    let callCount = 0;
    vm.onInfinite = function test() {
      if (!callCount++) {
        this.$refs.infiniteLoading.$emit('$InfiniteLoading:reset');
      } else {
        done();
      }
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should display the custom spinner if customize it with slot', () => {
    vm.isCustomSpinner = true;
    delete vm.distance;
    vm.$mount('#app');

    expect(vm.$el.querySelector('.custom-spinner')).to.be.ok;
  });
});
<commit_msg>Add unit test for the top direction load function<commit_after>import Vue from 'vue';
import InfiniteLoading from '../../../src/components/InfiniteLoading';

function isShow(elm) {
  const styles = getComputedStyle(elm);

  return styles.getPropertyValue('display') !== 'none';
}

describe('InfiniteLoading.vue', () => {
  let vm;
  const initConf = {
    data() {
      return {
        list: [],
        distance: 50,
        isLoadedAll: false,
        isDivScroll: true,
        isCustomSpinner: false,
        listContainerHeight: 200,
        listItemHeight: 20,
        direction: 'bottom',
      };
    },
    render(createElement) {
      return createElement(
        'div',
        {
          style: {
            height: `${this.listContainerHeight}px`,
            overflow: this.isDivScroll ? 'auto' : 'visible',
          },
        },
        [
          createElement('ul', {
            style: {
              margin: 0,
              padding: 0,
            },
          }, this.list.map((item) => createElement('li', {
            style: {
              height: `${this.listItemHeight}px`,
            },
          }, item))),
          this.isLoadedAll ? undefined : createElement(InfiniteLoading,
            {
              props: {
                distance: this.distance,
                onInfinite: this.onInfinite,
                direction: this.direction,
              },
              ref: 'infiniteLoading',
            },
            [
              this.isCustomSpinner ? createElement('span',
                {
                  slot: 'spinner',
                },
                [
                  createElement('i', {
                    attrs: {
                      class: 'custom-spinner',
                    },
                  }),
                ]
              ) : undefined,
            ]
          ),
        ]
      );
    },
  };

  // create new Vue instance for every test case
  beforeEach(() => {
    const container = document.createElement('div');
    container.setAttribute('id', 'app');
    document.body.appendChild(container);

    vm = new Vue(initConf);
  });

  afterEach(() => {
    /**
     * because of call the $destroy method of parent cannot trigger
     * destroy event for child component in Vue.js 2.0.0-rc6
     */
    vm.$refs.infiniteLoading && vm.$refs.infiniteLoading.$destroy();
    vm.$destroy(true);
    /**
     * because of pass true as the argument for destroy method cannot
     * remove element from DOM in Vue.js 2.0.0-rc6
     */
    vm.$el && vm.$el.remove();
  });

  it('should render a basic template', (done) => {
    vm.isDivScroll = false;
    setTimeout(() => {
      vm.$mount('#app');
      expect(vm.$el.querySelector('.loading-default')).to.be.ok;
      done();
    }, 1);
  });

  it('should execute callback and display a spinner immediately after initialize', (done) => {
    vm.onInfinite = function test() {
      Vue.nextTick(() => {
        expect(isShow(vm.$el.querySelector('.loading-default'))).to.be.true;
        done();
      });
    };

    vm.$mount('#app');
  });

  it('should not to execute callback if the previous loading has not be completed', (done) => {
    vm.onInfinite = function test() {
      const len = this.list.length + 1;
      for (let i = len; i < len + 20; i++) {
        this.list.push(i);
      }

      Vue.nextTick(() => {
        if (this.list.length === 20) {
          vm.$el.addEventListener('scroll', () => {
            expect(this.list).to.have.lengthOf(20);
            done();
          });

          // trigger scroll event manually
          vm.$el.scrollTop = vm.$el.scrollHeight;
        }
      });
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should be destroyed completely by v-if', (done) => {
    vm.onInfinite = function test() {
      this.isLoadedAll = true;
      Vue.nextTick(() => {
        expect(vm.$el.querySelector('.loading-default')).to.not.be.ok;
        done();
      });
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should display no results prompt', (done) => {
    vm.onInfinite = function test() {
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
      Vue.nextTick(() => {
        expect(isShow(vm.$el.querySelectorAll('.infinite-status-prompt')[0])).to.be.true;
        done();
      });
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should display no more data prompt', (done) => {
    vm.onInfinite = function test() {
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:complete');
      // test for whether trigger again after complete
      this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
      Vue.nextTick(() => {
        expect(isShow(vm.$el.querySelectorAll('.infinite-status-prompt')[1])).to.be.true;
        done();
      });
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should load results to fill up the container', (done) => {
    const expectedCount = Math.floor(vm.listContainerHeight / vm.listItemHeight);
    let i = 0;
    let timer;

    vm.onInfinite = function test() {
      setTimeout(() => {
        this.list.push(++i);
        this.$refs.infiniteLoading.$emit('$InfiniteLoading:loaded');
        clearTimeout(timer);
        timer = setTimeout(() => {
          if (i >= expectedCount) {
            done();
          } else {
            done(new Error('List not be fill up!'));
          }
        }, 100);
      }, 1);
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should reset component and call onInfinite again', (done) => {
    let callCount = 0;
    vm.onInfinite = function test() {
      if (!callCount++) {
        this.$refs.infiniteLoading.$emit('$InfiniteLoading:reset');
      } else {
        done();
      }
    }.bind(vm);

    vm.$mount('#app');
  });

  it('should display the custom spinner if customize it with slot', () => {
    vm.isCustomSpinner = true;
    delete vm.distance;
    vm.$mount('#app');

    expect(vm.$el.querySelector('.custom-spinner')).to.be.ok;
  });

  it('should load data when scroll top (direction attribute)', (done) => {
    vm.direction = 'top';
    vm.onInfinite = function test() {
      Vue.nextTick(() => {
        expect(isShow(vm.$el.querySelector('.loading-default'))).to.be.true;
        done();
      });
    };

    vm.$mount('#app');
  });
});
<|endoftext|>


<commit_before>var Timer = function(cpu, memory) {
    this.cpu    = cpu;
    this.memory = memory;

    this.DIV  = 0xFF04;
    this.TIMA = 0xFF05;
    this.TMA  = 0xFF06;
    this.TAC  = 0xFF07;

    this.mainTime  = 0;
    this.divTime   = 0;
};

Timer.prototype.tick = function(clockElapsed) {
    this.updateDiv(clockElapsed);
    this.updateTimer(clockElapsed);
};

Timer.prototype.updateTimer = function(clockElapsed) {
    if (!(this.memory[0xFF07]&0x4)) {
        return;
    }
    this.mainTime += clockElapsed;

    var threshold = 64;
    switch (this.memory[this.TAC]&3) {
        case 0: threshold=64; break; // 4KHz
        case 1: threshold=1;  break; // 256KHz
        case 2: threshold=4;  break; // 64KHz
        case 3: threshold=16; break; // 16KHz
    }
    threshold *= 16;

    if (this.mainTime >= threshold) {
        this.mainTime -= threshold;

        this.memory[this.TIMA]++;
        if (this.memory[this.TIMA] > 0xFF) {
            this.memory.wb(this.TIMA, this.memory[this.TMA]);
            this.cpu.requestInterrupt(this.cpu.INTERRUPTS.TIMER);
        }
    }
};

Timer.prototype.updateDiv = function(clockElapsed) {
    var divThreshold = 256; // DIV is 16KHz
    if (this.divTime > divThreshold) {
        this.divTime -= divThreshold;
        var div = this.memory[this.DIV];
        this.memory.wb(this.DIV, (div++)&0xFF);
    }
};
<commit_msg>fix timer<commit_after>var Timer = function(cpu, memory) {
    this.cpu    = cpu;
    this.memory = memory;

    this.DIV  = 0xFF04;
    this.TIMA = 0xFF05;
    this.TMA  = 0xFF06;
    this.TAC  = 0xFF07;

    this.mainTime  = 0;
    this.divTime   = 0;
};

Timer.prototype.tick = function(clockElapsed) {
    this.updateDiv(clockElapsed);
    this.updateTimer(clockElapsed);
};

Timer.prototype.updateTimer = function(clockElapsed) {
    if (!(this.memory[this.TAC]&0x4)) {
        return;
    }
    this.mainTime += clockElapsed;

    var threshold = 64;
    switch (this.memory[this.TAC]&3) {
        case 0: threshold=64; break; // 4KHz
        case 1: threshold=1;  break; // 256KHz
        case 2: threshold=4;  break; // 64KHz
        case 3: threshold=16; break; // 16KHz
    }
    threshold *= 16;

    while (this.mainTime >= threshold) {
        this.mainTime -= threshold;

        this.memory[this.TIMA]++;
        if (this.memory[this.TIMA] > 0xFF) {
            this.memory.wb(this.TIMA, this.memory[this.TMA]);
            this.cpu.requestInterrupt(this.cpu.INTERRUPTS.TIMER);
        }
    }
};

Timer.prototype.updateDiv = function(clockElapsed) {
    var divThreshold = 256; // DIV is 16KHz
    if (this.divTime > divThreshold) {
        this.divTime -= divThreshold;
        var div = this.memory[this.DIV] + 1;
        this.memory.wb(this.DIV, div&0xFF);
    }
};
<|endoftext|>


<commit_before>var e = module.exports = {}
var bu = require('./../util.js')
var exec = require('child_process').exec;
var fs = require('fs')

var bot
e.init = (Tbot) => {
    bot = Tbot
}

e.requireCtx = require

e.isCommand = true;
e.hidden = true
e.usage = 'lines';
e.info = 'Gets the number of lines the bot is made of';
e.category = bu.CommandType.GENERAL;

e.execute = (msg, words, text) => {
    var fileArray = fs.readdirSync(path.join(__dirname, '..'));
    var files = []
    for (var i = 0; i < fileArray.length; i++) {
        if (fileArray[i].endsWith('.js')) {
            files.push(path.join(__dirname, '..', fileArray[i]))
        }
    }
    fileArray = fs.readdirSync(path.join(__dirname));
    for (var i = 0; i < fileArray.length; i++) {
        if (fileArray[i].endsWith('.js')) {
            files.push(path.join(__dirname, fileArray[i]))
        }
    }
    var lineCount = 0
    function onComplete(lines) {
        bu.sendMessageToDiscord(msg.channel.id, 'I am made of ' + lines + ' lines.')
    }
    var count = files.length
    for (var i = 0; i < files.length; i++) {
        exec(`wc -l ${files[i]}`, (err, res) => {
            console.log(res)
            lines += parseInt(res.split(' ')[0])
            count--;
            if (count == 0) {
                onComplete(lines)
            }
        })
    }
}<commit_msg>forgot path -_-<commit_after>var e = module.exports = {}
var bu = require('./../util.js')
var exec = require('child_process').exec;
var fs = require('fs')
var path = require('path')
var bot
e.init = (Tbot) => {
    bot = Tbot
}

e.requireCtx = require

e.isCommand = true;
e.hidden = true
e.usage = 'lines';
e.info = 'Gets the number of lines the bot is made of';
e.category = bu.CommandType.GENERAL;

e.execute = (msg, words, text) => {
    var fileArray = fs.readdirSync(path.join(__dirname, '..'));
    var files = []
    for (var i = 0; i < fileArray.length; i++) {
        if (fileArray[i].endsWith('.js')) {
            files.push(path.join(__dirname, '..', fileArray[i]))
        }
    }
    fileArray = fs.readdirSync(path.join(__dirname));
    for (var i = 0; i < fileArray.length; i++) {
        if (fileArray[i].endsWith('.js')) {
            files.push(path.join(__dirname, fileArray[i]))
        }
    }
    var lineCount = 0
    function onComplete(lines) {
        bu.sendMessageToDiscord(msg.channel.id, 'I am made of ' + lines + ' lines.')
    }
    var count = files.length
    for (var i = 0; i < files.length; i++) {
        exec(`wc -l ${files[i]}`, (err, res) => {
            console.log(res)
            lines += parseInt(res.split(' ')[0])
            count--;
            if (count == 0) {
                onComplete(lines)
            }
        })
    }
}<|endoftext|>