<commit_before>"use strict";

var logger = require('winston');
var pluralize = require('pluralize');

class Model {

	// Standard constructor
	constructor(useDefaults) {

		if (!this.constructor.connection) {
			return this._newNoConnectionPromise();
		} else {
			this.connection = this.constructor.connection;
		}

		// Properties stores the actual data for the schema
		this.properties = {};

		var schema = this.constructor.schema;

		// Initialize the various properties
		Object.keys(schema).forEach((key) => {

			if (useDefaults) {
				// Insert any defaults if necessary
				var defaultValue = schema[key].defaultValue;

				// If a function is provided as a default, call the function
				if (defaultValue) {
					if (typeof defaultValue === "function") {
						this.properties[key] = defaultValue();
					} else {
						this.properties[key] = defaultValue;
					}
				}
			}

			// Create accessors for the properties on the main class
			if (this.key !== undefined) {
				logger.warn(`${key} is already defined in model ${this.constructor.name}. Be sure to access it through ${this.constructor.name}.properties.${key}.`);
			} else {
				Object.defineProperty(this, key, {
					get: () => this.properties[key],
					set: (newValue) => { this.properties[key] = newValue; }
				});
			}
		});
	}

	/**
	 * Find a particular record by id, if an id is specified
	 * @param id	a unique id for the object
	 * @return a Promise
	 */
	static findById(id) {
		if (!this.connection) return this._newNoConnectionPromise();

		var query = this.connection.select().from(this.tableName).where({ id: id });

		if (!this.connection.production) this._logQuery(query);

		return query;
	}

	/**
	 * Find all records in a specific table
	 * @return a Query object
	 */
	static findAll() {
		if (!this.connection) return this._newNoConnectionPromise();

		// TODO: Implement findAll
	}

	/**
	 * Creation class methods
	 */

	/**
	 * Create a new record in the database.
	 * @param properties	a JS object of properties for the object
	 * @return an Operation object
	 */
	static create(properties) {
		if (!this.connection) return this._newNoConnectionPromise();

		// TODO: implement create
	}

	/**
	 * If a record exists in the database, update it.
	 * If the record does not exist, create a new one.
	 * @param properties	a JS object of properties for the object
	 * @return an Operation object
	 */
	static createOrUpdate(properties) {
		if (!this.connection) return this._newNoConnectionPromise();

		// TODO: implement createOrUpdate
	}

	/**
	 * Creation instance methods
	 */

	/**
	 * Create a new record in the database.
	 * @return an Operation object
	 */
	create() {
		// TODO: implement create
	}

	/**
	 * If a record exists in the database, update it.
	 * If the record does not exist, create a new one.
	 * @return an Operation object
	 */
	createOrUpdate() {
		// TODO: implement createOrUpdate
	}

	/**
	 * Update methods
	 */

	/**
	 * Push any updates made to the object to the database
	 * @return an Operation object
	 */
	update() {
		// TODO: implement update
	}

	/**
	 * Delete an object from the database
	 * @return an Operation object
	 */
	delete() {
		// TODO: implement delete
	}

	/**
	 * Utility methods
	 */

	/**
	 * Get the name that should represent this model in the database
	 * @return the name of the table as a string
	 */
	static get tableName() {
		// Lazy-load the table name
		delete this.tableName;

		if (typeof this.options.tableName === "string") {
			return this.tableName = this.options.tableName;
		}

		return this.tableName = pluralize(this.name).toLowerCase();
	}

	/**
	 * Create a Promise that immediately provides an error for no
	 * available connection
	 */
	static _newNoConnectionPromise() {
		return new Promise(
			(resolve, reject) => {
				var err = new Error("No connection available");
				err.type = "estelle.no-connection";
				logger.error("Model objects must have Model.connection defined.");
				reject(err);
			}
		);
	}

	/**
	 * Writes a query to the log
	 */
	static _logQuery(query) {
		logger.info(query.toString());
	}
}

/**
 * A set of global options for the model.
 * Should NOT be modified at runtime
 */
Model.options = {
	// If true, the rows will only be marked deleted instead of actually removed
	safeDelete:	true,

	// Automatically add timestamps for update and creation times
	timestamp: true,

	// The name of the table in the database
	// If not set, the name will be automatically generated
	tableName: undefined,
};

/**
 * The schema for the data model
 * Represented as a JS object where the property name is the key,
 * and the value is the type from DataTypes
 *
 * Alternatively, the value can be an object with the following options:
 * dataType: the type from DataTypes
 * defaultValue: the default value of the field
 * validator: a special validation function for this field (returns false if bad)
 */
Model.schema = {};

module.exports = Model;<commit_msg>Added support for validation<commit_after>"use strict";

var logger = require('winston');
var pluralize = require('pluralize');

class Model {

	// Standard constructor
	constructor(useDefaults) {

		if (!this.constructor.connection) {
			return this._newNoConnectionPromise();
		} else {
			this.connection = this.constructor.connection;
		}

		// On first model init, add all required keys to an option
		var schema = this.constructor.schema;

		if (this.constructor.required === undefined) {
			var required = new Set();
			schema.forEach((value, key) => {
				if (value.required === true || value.primaryKey === true) {
					required.add(key);
				}
			});

			this.constructor.required = required;
		}

		// Properties stores the actual data for the schema
		this.properties = new Map();

		// Initialize the various properties
		schema.forEach((value, key) => {

			if (useDefaults) {
				// Insert any defaults if necessary
				var defaultValue = schema.get(key).defaultValue;

				// If a function is provided as a default, call the function
				if (defaultValue) {
					if (typeof defaultValue === "function") {
						this.properties.set(key, defaultValue());
					} else {
						this.properties.set(key, defaultValue);
					}
				}
			}

			// Create accessors for the properties on the main class
			if (this[key] !== undefined) {
				logger.warn(`${key} is already defined in model ${this.constructor.name}. Be sure to access it through ${this.constructor.name}.properties.${key}.`);
			} else {
				Object.defineProperty(this, key, {
					get: () => this.properties[key],
					set: (newValue) => { this.properties[key] = newValue; }
				});
			}
		});
	}

	/**
	 * Find a particular record by id, if an id is specified
	 * @param id	a unique id for the object
	 * @return a Promise
	 */
	static findById(id) {
		if (!this.connection) return this._newNoConnectionPromise();

		var query = this.connection.select().from(this.tableName).where({ id: id });

		if (!this.connection.production) this._logQuery(query);

		return query;
	}

	/**
	 * Find all records in a specific table
	 * @return a Query object
	 */
	static findAll() {
		if (!this.connection) return this._newNoConnectionPromise();

		var query = this.connection.select().from(this.tableName);

		if (!this.connection.production) this._logQuery(query);

		return query;
	}

	/**
	 * Creation class methods
	 */

	/**
	 * Create a new record in the database.
	 * @param properties	a JS object of properties for the object
	 * @return an Operation object
	 */
	static create(properties) {
		if (!this.connection) return this._newNoConnectionPromise();

		// TODO: implement create
	}

	/**
	 * If a record exists in the database, update it.
	 * If the record does not exist, create a new one.
	 * @param properties	a JS object of properties for the object
	 * @return an Operation object
	 */
	static createOrUpdate(properties) {
		if (!this.connection) return this._newNoConnectionPromise();

		// TODO: implement createOrUpdate
	}

	/**
	 * Static Utility methods
	 */

	/**
	 * Get the name that should represent this model in the database
	 * @return the name of the table as a string
	 */
	static get tableName() {
		// Lazy-load the table name
		delete this.tableName;

		if (typeof this.options.tableName === "string") {
			return this.tableName = this.options.tableName;
		}

		return this.tableName = pluralize(this.name).toLowerCase();
	}

	/**
	 * Create a Promise that immediately provides an error for no
	 * available connection
	 */
	static _newNoConnectionPromise() {
		return new Promise(
			(resolve, reject) => {
				var err = new Error("No connection available");
				err.type = "estelle.no-connection";
				logger.error("Model objects must have Model.connection defined.");
				reject(err);
			}
		);
	}

	/**
	 * Writes a query to the log
	 */
	static _logQuery(query) {
		logger.info(query.toString());
	}

	/**
	 * Instance methods
	 */

	/**
	 * Creation instance methods
	 */

	/**
	 * Create a new record in the database.
	 * @return an Operation object
	 */
	create() {
		// TODO: implement create
	}

	/**
	 * If a record exists in the database, update it.
	 * If the record does not exist, create a new one.
	 * @return an Operation object
	 */
	createOrUpdate() {
		// TODO: implement createOrUpdate
	}

	/**
	 * Update methods
	 */

	/**
	 * Push any updates made to the object to the database
	 * @return an Operation object
	 */
	update() {
		// TODO: implement update
	}

	/**
	 * Delete an object from the database
	 * @return an Operation object
	 */
	delete() {
		// TODO: implement delete
	}

	/**
	 * Instance Utilties
	 */

	/**
	 * Validates the current instance based on the parent schema
	 * @param err	An empty error object for storing possible errors
	 * @return boolean - false if the schema is invalid, true if the schema is valid
	 */
	validate(err) {
		var model = this.constructor;
		var schema = model.schema;
		var prop = this.properties;

		for (let [key, value] of prop) {

			var type = schema.get(key);

			// Check if the key is in the schema
			if (!type) {
				err.type = "estelle.validation.unrecognizedKey";
				err.message = `${key} is not in the schema for ${model.name}.`;
				return false;
			}

			// Check that the key returns a supported type
			var supportedTypes;
			if (type.supportedTypes) {
				supportedTypes = type.supportedTypes;
			} else if (type.dataType) {
				supportedTypes = type.dataType.supportedTypes;
			}

			if (supportedTypes) {
				if (!supportedTypes.has(typeof value)) {
					err.type = "estelle.validation.unacceptedType";
					err.message = `${typeof value} is not an accepted type for ${key} (type: ${type.name}) in ${model.name}.`;
					return false;
				}
			}

			// Check in with the validation function
			var validate = type.validator || type.dataType.validator;
			if (typeof validate !== 'function') {
				err.type = "estelle.validation.noValidator";
				err.message = `${key} in ${model.name} does not have a valid validation function.`;
				return false;
			}

			if (!validate(value)) {
				err.type = "estelle.validation.validationFailed";
				err.message = `${value} is not a valid value for ${model.name}.${key}.`;
				return false;
			}
		}

		// Check to see if any required values are missing
		for (let item of model.required) {
			if (!prop.has(item)) {
				err.type = "estelle.validation.missingRequired";
				err.message = `${item} is required in ${model.name}.`;
				return false;
			}
		}

		// If we reach this point, then validation passed
		return true;
	}
}

/**
 * A set of global options for the model.
 * Should NOT be modified at runtime
 */
Model.options = {
	// If true, the rows will only be marked deleted instead of actually removed
	safeDelete:	true,

	// Automatically add timestamps for update and creation times
	timestamp: true,

	// The name of the table in the database
	// If not set, the name will be automatically generated
	tableName: undefined,
};

/**
 * The schema for the data model
 * Represented as a JS Map where the property name is the key,
 * and the value is the type from DataTypes
 *
 * Alternatively, the value can be an object with the following options:
 * dataType: the type from DataTypes
 * defaultValue: the default value of the field
 * validator: a special validation function for this field (returns false if bad)
 * required: whether or not this is necessary
 * primaryKey: true if this is the primaryKey
 */
Model.schema = new Map();

module.exports = Model;<|endoftext|>


<commit_before>roll(message, args) {
  return this.getRandomInt(6);
}

getRandomInt(max) {
  return Math.floor(Math.random() * max + 1);
}

module.exports = {
  'name': 'roll',
  'description': 'Roll a six-sided dice',
  'callback': roll
};
<commit_msg>Update dice command<commit_after>const roll = (message, args) => {
  return this.getRandomInt(6);
}

const getRandomInt = (max) => {
  return Math.floor(Math.random() * max + 1);
}

module.exports = {
  'name': 'roll',
  'description': 'Roll a six-sided dice',
  'callback': roll
};
<|endoftext|>


<commit_before>/**
 * Created by lz on 15/10/13.
 */
!function (factory) {
    if (typeof define === "function") {
        define("prefix", factory);
    } else {
        factory();
    }
}(function () {
    var toolDiv = document.createElement("div"),
        CURRENT_PREFIX = function () {
            if (navigator.userAgent.indexOf("MSIE") >= 0) {
                return "-ms-";
            } else if (navigator.userAgent.indexOf("Firefox") >= 0) {
                return "-moz-";
            } else if (navigator.userAgent.indexOf("Opera") >= 0) {
                return "-o-";
            } else if (navigator.userAgent.indexOf("Mozilla") >= 0) {
                return "-webkit-";
            }
        }();

    function getPrefixURL() {
        var links = document.getElementsByTagName("link"),
            prefixLinks = [],
            i,
            l;

        for (i = 0, l = links.length; i < l; i++) {
            if (links[i].getAttribute("rel") === "stylesheet/prefix") {
                prefixLinks.push(links[i].href);
            }
        }

        return prefixLinks;
    }

    function getPrefixFile(callback) {
        var urls = getPrefixURL(),
            files = [],
            i,
            l;

        for (i = 0, l = urls.length; i < l; i++) {
            (function (index) {
                doXHR(urls[i], function (data) {
                    if (data) {
                        data = doPrefix(data);
                        files.push(data);

                        checkAllDone();
                    }
                });
            })(i)
        }

        function checkAllDone() {
            if (files.length === urls.length) {
                callback(files);
            }
        }
    }

    function getXMLHttpRequest() {
        if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject)) {
            return new XMLHttpRequest();
        } else {
            try {
                return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                console.log("browser doesn't support AJAX.");
                return null;
            }
        }
    }

    function doXHR(url, callback, errback) {
        var xhr = getXMLHttpRequest();

        if (typeof(xhr.overrideMimeType) === 'function') {
            xhr.overrideMimeType('text/css');
        }

        xhr.open('GET', url, true);
        xhr.setRequestHeader('Accept', 'text/css; q=0.9, */*; q=0.5');
        xhr.send(null);

        function handleResponse(xhr, callback, errback) {
            if (xhr.status >= 200 && xhr.status < 300) {
                callback(xhr.responseText,
                    xhr.getResponseHeader("Last-Modified"));
            } else if (typeof(errback) === 'function') {
                errback(xhr.status, url);
            }
        }

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                handleResponse(xhr, callback, errback);
            }
        };
    }

    function doPrefix(data) {
        var blockPattern = new RegExp("{(.*?)}", "g"),
            pattern = new RegExp("([^;]*?):(.*?)(;|$)", "g"),
            temp = {},
            result;

        data = data
            .replace(/\s|\/\*.*\*\//g, "")
            .replace(blockPattern, function (all, block) {
                block = block.replace(pattern, function (all, prop, value) {
                    if (!isCSSSupport(prop, value)) {
                        return "";
                    } else {
                        return prop + ":" + value + ";";
                    }
                });
                return "{" + block + "}";
            });

        return data;
    }

    function isCSSSupport(prop, value) {
        var support;

        value = typeof value === "undefined" ? "inherit" : value;

        if ("CSS" in window && "supports" in window.CSS) {
            return window.CSS.supports(prop, value);
        }

        if ("supportsCSS" in window) {
            return window.supportsCSS(prop, value);
        }

        support = prop in toolDiv.style;

        toolDiv.style.cssText = prop + ":" + value;

        return support && toolDiv.style[prop] !== "";
    }

    function insertIntoDOM(files) {
        var i, l, style,
            box = document.createElement("div");

        for (i = 0, l = files.length; i < l; i++) {
            style = document.createElement("style");

            style.innerHTML = files[i];
            box.appendChild(style);
        }

        box.id = "prefixStyleBox";
        document.body.appendChild(box);
    }

    getPrefixFile(function (files) {
        //console.log(files)
        insertIntoDOM(files)
    });
});<commit_msg>use replacement function instead<commit_after>/**
 * Created by lz on 15/10/13.
 */
!function (factory) {
    if (typeof define === "function") {
        define("prefix", factory);
    } else {
        factory();
    }
}(function () {
    var toolDiv = document.createElement("div"),
        CURRENT_PREFIX = function () {
            if (navigator.userAgent.indexOf("MSIE") >= 0) {
                return "-ms-";
            } else if (navigator.userAgent.indexOf("Firefox") >= 0) {
                return "-moz-";
            } else if (navigator.userAgent.indexOf("Opera") >= 0) {
                return "-o-";
            } else if (navigator.userAgent.indexOf("Mozilla") >= 0) {
                return "-webkit-";
            }
        }();

    function getPrefixLinks() {
        var links = document.getElementsByTagName("link"),
            prefixLinks = [],
            i,
            l;

        for (i = 0, l = links.length; i < l; i++) {
            if (links[i].getAttribute("rel") === "stylesheet/prefix") {
                prefixLinks.push(links[i]);
            }
        }

        return prefixLinks;
    }

    function getPrefixPair(callback) {
        var result = {key: getPrefixLinks(), value: []},
            i,
            l;

        for (i = 0, l = result.key.length; i < l; i++) {
            (function (index) {
                doXHR(result.key[index].href, function (data) {
                    if (data) {
                        result.value[index] = doPrefix(data);

                        checkAllDone(result);
                    }
                });
            })(i)
        }

        function checkAllDone(result) {
            var len = 0,
                i = 0,
                l = result.key.length;

            for(; i < l; i++){
                if(typeof result.value[i] !== "undefined"){
                    len++;
                }
            }

            if(len == l){
                callback(result);
            }
        }
    }

    function getXMLHttpRequest() {
        if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject)) {
            return new XMLHttpRequest();
        } else {
            try {
                return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                console.log("browser doesn't support AJAX.");
                return null;
            }
        }
    }

    function doXHR(url, callback, errback) {
        var xhr = getXMLHttpRequest();

        if (typeof(xhr.overrideMimeType) === 'function') {
            xhr.overrideMimeType('text/css');
        }

        xhr.open('GET', url, true);
        xhr.setRequestHeader('Accept', 'text/css; q=0.9, */*; q=0.5');
        xhr.send(null);

        function handleResponse(xhr, callback, errback) {
            if (xhr.status >= 200 && xhr.status < 300) {
                callback(xhr.responseText,
                    xhr.getResponseHeader("Last-Modified"));
            } else if (typeof(errback) === 'function') {
                errback(xhr.status, url);
            }
        }

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                handleResponse(xhr, callback, errback);
            }
        };
    }

    function doPrefix(data) {
        var blockPattern = new RegExp("{(.*?)}", "g"),
            pattern = new RegExp("([^;]*?):(.*?)(;|$)", "g"),
            temp = {},
            result;

        data = data
            .replace(/\s|\/\*.*\*\//g, "")
            .replace(blockPattern, function (all, block) {
                block = block.replace(pattern, function (all, prop, value) {
                    if (!isCSSSupport(prop, value)) {
                        return "";
                    } else {
                        return prop + ":" + value + ";";
                    }
                });
                return "{" + block + "}";
            });

        return data;
    }

    function isCSSSupport(prop, value) {
        var support;

        value = typeof value === "undefined" ? "inherit" : value;

        if ("CSS" in window && "supports" in window.CSS) {
            return window.CSS.supports(prop, value);
        }

        if ("supportsCSS" in window) {
            return window.supportsCSS(prop, value);
        }

        support = prop in toolDiv.style;

        toolDiv.style.cssText = prop + ":" + value;

        return support && toolDiv.style[prop] !== "";
    }

    function insertIntoDOM(pair) {
        var i, l, style,
            box = document.createElement("div");

        //todo change the function to replacement
        for (i = 0, l = pair.key.length; i < l; i++) {
            style = document.createElement("style");

            style.innerHTML = files[i];
            box.appendChild(style);
        }

        box.id = "prefixStyleBox";
        document.body.appendChild(box);
    }

    getPrefixPair(function (pair) {
        insertIntoDOM(pair);
    });
});<|endoftext|>


<commit_before>'use strict'

const { Command } = require('discord.js-commando');
const config = require('config.json')('./config.json');
const { MessageEmbed } = require('discord.js');

module.exports = class SuggestCommand extends Command {
    constructor(client) {
        super(client, {
            name: 'suggest',
            aliases: ['addsuggestion', 'suggestion'],
            group: 'util',
            memberName: 'suggest',
            description: 'Suggest a new feature for the bot!',
            examples: ['suggest "Add a suggest command." "It would be nice to have an easy way of suggesting bot features!"'],
            args: [
                {
                    key: 'title',
                    prompt: 'What is the title of your suggestion?',
                    type: 'string'
                },
                {
                    key: 'description',
                    prompt: 'What is the description of your suggestion?',
                    type: 'string'
                }
            ]
        });
    }

    run(msg, { title, description }) {
        if (!config.hasOwnProperty('suggestions'))
            return msg.say(`Sorry ${msg.author}, suggestions aren't configured correctly on this host of the bot. Please contact ${msg.client.owners.map(e => e.tag).join(' or ')}`);
        else if (!(config.suggestions.hasOwnProperty('guild') && config.suggestions.hasOwnProperty('channel')))
            return msg.say(`Sorry ${msg.author}, suggestions aren't configured correctly on this host of the bot. Please contact ${msg.client.owners.map(e => e.tag).join(' or ')}`);

        let settings = msg.client.settings;

        let fbid = settings.get('feedbackid', 1);
        settings.set('feedbackid', fbid + 1);

        msg.client.guilds.find('id', config.suggestions.guild)
        .channels.find('id', config.updates.channel).send(new MessageEmbed()
        .setColor(config.embedColor)
        .addField('Title', title)
        .addField('Description', description)
        .setAuthor(`Feedback #${fbid}`, msg.client.user.avatarURL())
        .setFooter(`Posted by ${msg.author.tag}`, msg.author.avatarURL())
        .setTimestamp());

        return msg.say(`Added suggestion with title \`\`\`${title}\`\`\` and description \`\`\`${description}\`\`\``);
    }
};
<commit_msg>Fix suggestions<commit_after>'use strict'

const { Command } = require('discord.js-commando');
const config = require('config.json')('./config.json');
const { MessageEmbed } = require('discord.js');

module.exports = class SuggestCommand extends Command {
    constructor(client) {
        super(client, {
            name: 'suggest',
            aliases: ['addsuggestion', 'suggestion'],
            group: 'util',
            memberName: 'suggest',
            description: 'Suggest a new feature for the bot!',
            examples: ['suggest "Add a suggest command." "It would be nice to have an easy way of suggesting bot features!"'],
            args: [
                {
                    key: 'title',
                    prompt: 'What is the title of your suggestion?',
                    type: 'string'
                },
                {
                    key: 'description',
                    prompt: 'What is the description of your suggestion?',
                    type: 'string'
                }
            ]
        });
    }

    run(msg, { title, description }) {
        if (!config.hasOwnProperty('updates'))
            return msg.say(`Sorry ${msg.author}, suggestions aren't configured correctly on this host of the bot. Please contact ${msg.client.owners.map(e => e.tag).join(' or ')}`);
        else if (!(config.updates.hasOwnProperty('guild') && config.updates.hasOwnProperty('channel')))
            return msg.say(`Sorry ${msg.author}, suggestions aren't configured correctly on this host of the bot. Please contact ${msg.client.owners.map(e => e.tag).join(' or ')}`);

        let settings = msg.client.settings;

        let fbid = settings.get('feedbackid', 1);
        settings.set('feedbackid', fbid + 1);

        msg.client.guilds.find('id', config.suggestions.guild)
        .channels.find('id', config.updates.channel).send(new MessageEmbed()
        .setColor(config.embedColor)
        .addField('Title', title)
        .addField('Description', description)
        .setAuthor(`Feedback #${fbid}`, msg.client.user.avatarURL())
        .setFooter(`Posted by ${msg.author.tag}`, msg.author.avatarURL())
        .setTimestamp());

        return msg.say(`Added suggestion with title \`\`\`${title}\`\`\` and description \`\`\`${description}\`\`\``);
    }
};
<|endoftext|>


<commit_before>var exposeMethods = require('./mr-rpc-methods')
var debug = require('debug')('moonridge:server')
var _ = require('lodash')
var mongoose = require('mongoose')

/**
 * @param {String} name
 * @param {Schema} schema NOTE: don't use these properties on your schemas: '$$hashKey', '__id', '__v', those names are
 * reserved for angular and Mongoose
 * @param {Object} opts
 * @param {Boolean} opts.readOnly will expose only find and sub/pub methods
 * @param {Object} [opts.permissions] should look something like:
                                 permissions: {
                                  C: 1,
                                  R: 0,
                                  U: 5,
                                  D: 5
                                }
 * @param {Object} opts.statics will extend the mongoose schema.statics so that you can call this function on your model
 * @param {Function} opts.schemaInit gives you opportunity to use schema before mongoose model is instantiated
 * @param {Function} opts.onExistence similar to subscribing to create event, but with an added benefit that this gets called for preexisting documents in the DB on startup
 * @returns {Object}
 */
module.exports = function moonridgeModel (name, schema, opts) {
  opts = opts || {}

  _.assign(schema, {owner: {type: mongoose.Schema.Types.ObjectId, ref: 'user'}})   // users own all other entities
  // mongoose schema
  var mgSchema = new mongoose.Schema(schema)

  if (opts.statics) {
    _.extend(mgSchema.statics, opts.statics)
  }

  if (opts.schemaInit) {
    debug('running schemaInit for ' + name)
    opts.schemaInit(mgSchema)
  }

  var paths = mgSchema.paths
  var pathPermissions = {}
  for (var prop in paths) {
    if (paths[prop].options) {
      var perm = paths[prop].options.permissions // looks like {R: 10, W: 20}
      if (perm !== undefined) {
        pathPermissions[prop] = perm
      }
    }
  }
  mgSchema.pathPermissions = pathPermissions // prepared object for handling access control

  var newDocs = []
  mgSchema.pre('save', function (next) {
    if (this.isNew) {
      newDocs.push(this._id)
    }
    next()
  })

  // Hook `save` post method called after creation/update
  mgSchema.post('save', function postSave (doc) {
    var indexInNewDocs = newDocs.indexOf(doc._id)
    if (indexInNewDocs !== -1) {
      newDocs.splice(indexInNewDocs, 1)
      mgSchema.emit('create', doc)
      if (opts.onExistence) {
        opts.onExistence.call(model, doc)
      }
    } else {
      mgSchema.emit('update', doc)
    }
    return true
  })

  mgSchema.post('remove', function postRemove (doc) {
    mgSchema.emit('remove', doc)
  })

  var model = mongoose.model(name, mgSchema)
  if (opts.onExistence) {
    model.find().exec((err, docs) => {
      if (err) {
        throw err
      }
      docs.forEach(opts.onExistence)
    })
  }
  var exposeCallback = exposeMethods(model, mgSchema, opts)

  // these two methods are possible to use and your LQ will refresh accordingly,
  // it is not possible with their originals
  var originalFindByIdAndUpdate = model.findByIdAndUpdate
  var originalFindByIdAndRemove = model.findByIdAndRemove

  _.assign(model, {
    findByIdAndUpdate: function () {
      var args = arguments
      return originalFindByIdAndUpdate.apply(model, args).then(function (result) {
        mgSchema.emit('update', args[0])
        return result
      })
    },
    findByIdAndRemove: function () {
      var args = arguments
      return originalFindByIdAndRemove.apply(model, args).then(function (result) {
        mgSchema.emit('remove', args[0])
        return result
      })
    },
    schemaInit: opts.schemaInit,
    moonridgeSchema: schema,
    _exposeCallback: exposeCallback
  })

  return model
}
<commit_msg>added model.initPromise for models with onExistence<commit_after>var exposeMethods = require('./mr-rpc-methods')
var debug = require('debug')('moonridge:server')
var _ = require('lodash')
var mongoose = require('mongoose')

/**
 * @param {String} name
 * @param {Schema} schema NOTE: don't use these properties on your schemas: '$$hashKey', '__id', '__v', those names are
 * reserved for angular and Mongoose
 * @param {Object} opts
 * @param {Boolean} opts.readOnly will expose only find and sub/pub methods
 * @param {Object} [opts.permissions] should look something like:
                                 permissions: {
                                  C: 1,
                                  R: 0,
                                  U: 5,
                                  D: 5
                                }
 * @param {Object} opts.statics will extend the mongoose schema.statics so that you can call this function on your model
 * @param {Function} opts.schemaInit gives you opportunity to use schema before mongoose model is instantiated
 * @param {Function} opts.onExistence similar to subscribing to create event, but with an added benefit that this gets called for preexisting documents in the DB on startup
 * @returns {Object}
 */
module.exports = function moonridgeModel (name, schema, opts) {
  opts = opts || {}

  _.assign(schema, {owner: {type: mongoose.Schema.Types.ObjectId, ref: 'user'}})   // users own all other entities
  // mongoose schema
  var mgSchema = new mongoose.Schema(schema)

  if (opts.statics) {
    _.extend(mgSchema.statics, opts.statics)
  }

  if (opts.schemaInit) {
    debug('running schemaInit for ' + name)
    opts.schemaInit(mgSchema)
  }

  var paths = mgSchema.paths
  var pathPermissions = {}
  for (var prop in paths) {
    if (paths[prop].options) {
      var perm = paths[prop].options.permissions // looks like {R: 10, W: 20}
      if (perm !== undefined) {
        pathPermissions[prop] = perm
      }
    }
  }
  mgSchema.pathPermissions = pathPermissions // prepared object for handling access control

  var newDocs = []
  mgSchema.pre('save', function (next) {
    if (this.isNew) {
      newDocs.push(this._id)
    }
    next()
  })

  // Hook `save` post method called after creation/update
  mgSchema.post('save', function postSave (doc) {
    var indexInNewDocs = newDocs.indexOf(doc._id)
    if (indexInNewDocs !== -1) {
      newDocs.splice(indexInNewDocs, 1)
      mgSchema.emit('create', doc)
      if (opts.onExistence) {
        opts.onExistence.call(model, doc)
      }
    } else {
      mgSchema.emit('update', doc)
    }
    return true
  })

  mgSchema.post('remove', function postRemove (doc) {
    mgSchema.emit('remove', doc)
  })

  var model = mongoose.model(name, mgSchema)
  if (opts.onExistence) {
    model.initPromise = new Promise(function (resolve, reject) {
      model.find().exec((err, docs) => {
        if (err) {
          reject(err)
          throw err
        }
        docs.forEach(opts.onExistence)
        resolve(docs)
      })
    })
  }
  var exposeCallback = exposeMethods(model, mgSchema, opts)

  // these two methods are possible to use and your LQ will refresh accordingly,
  // it is not possible with their originals
  var originalFindByIdAndUpdate = model.findByIdAndUpdate
  var originalFindByIdAndRemove = model.findByIdAndRemove

  _.assign(model, {
    findByIdAndUpdate: function () {
      var args = arguments
      return originalFindByIdAndUpdate.apply(model, args).then(function (result) {
        mgSchema.emit('update', args[0])
        return result
      })
    },
    findByIdAndRemove: function () {
      var args = arguments
      return originalFindByIdAndRemove.apply(model, args).then(function (result) {
        mgSchema.emit('remove', args[0])
        return result
      })
    },
    schemaInit: opts.schemaInit,
    moonridgeSchema: schema,
    _exposeCallback: exposeCallback
  })

  return model
}
<|endoftext|>


<commit_before>// This is the script that I wrote and ran on http://en.wikipedia.org/wiki/List_of_DNS_record_types via the chrome console

var records = [];
$('table:first tbody tr').each(function(i, tr) {
   var kids = $(tr).children().toArray();
  records.push({
    type: $('div', kids[0]).attr('id'),
    decimal_value: parseInt($(kids[1]).text()),
    rfc: $(kids[2]).text(),
    description: $(kids[3]).text(),
    func: $(kids[4]).text(),

  });
});
JSON.stringify(records);
<commit_msg>Update scrape_wikipedia_page.js<commit_after>// This is the script that I wrote and ran on http://en.wikipedia.org/wiki/List_of_DNS_record_types via the chrome console

var records = [];
$('table:first tbody tr').each(function(i, tr) {
   var kids = $(tr).children().toArray();
  records.push({
    type: $.trim($(kids[0]).text()),
    decimal_value: parseInt($(kids[1]).text()),
    rfc: $(kids[2]).text(),
    description: $(kids[3]).text(),
    func: $(kids[4]).text(),

  });
});
JSON.stringify(records);
<|endoftext|>


<commit_before>/*global System*/
import { string, obj } from "lively.lang";
import { Rectangle, Color, pt } from "lively.graphics";
import { Morph } from "../index.js";
import { Selection } from "./selection.js";
import DocumentRenderer from "./rendering.js";

export class Text extends Morph {

  static makeLabel(string, props) {
    return new Text({
      textString: string,
      fontFamily: "Helvetica Neue, Arial",
      fontColor: Color.black,
      fontSize: 11,
      readOnly: true,
      ...props
    });
  }

  constructor(props) {
    var fontMetric;
    if (props.fontMetric) {
      fontMetric = props.fontMetric
      props = obj.dissoc(props, ["fontMetric"]);
    }
    super({
      readOnly: false,
      clipMode: "hidden",
      textString: "",
      fixedWidth: false, fixedHeight: false,
      padding: 0,
      draggable: false,
      _selection: { start: 0, end: 0 },
      fontFamily: "Sans-Serif",
      fontSize: 12,
      ...props
    });
    this.renderer = new DocumentRenderer(fontMetric || this.env.fontMetric);
    this.fit();
    this._needsFit = false;
  }

  get isText() { return true }

  onChange(change) {
    super.onChange(change);
    if (change.prop === "textString"
     || change.prop === "fontFamily"
     || change.prop === "fontSize"
     || change.prop === "fixedWidth"
     || change.prop === "fixedHeight")
       this.renderer && (this.renderer.layoutComputed = false);
  }

  get textString() { return this.getProperty("textString") }
  set textString(value) {
    let oldText = this.textString;
    oldText && this.deleteText(0, oldText.length);
    this.insertText(0, value);
  }

  get readOnly() { return this.getProperty("readOnly"); }
  set readOnly(value) {
    this.nativeCursor = value ? "default" : "auto";
    this.addValueChange("readOnly", value);
  }

  rejectsInput() { return this.readOnly || !this.isFocused() }

  get fixedWidth() { return this.getProperty("fixedWidth") }
  set fixedWidth(value) {
    this.addValueChange("fixedWidth", value);
    this._needsFit = true;
  }

  get fixedHeight() { return this.getProperty("fixedHeight") }
  set fixedHeight(value) {
    this.addValueChange("fixedHeight", value);
    this._needsFit = true;
  }

  get padding() { return this.getProperty("padding") }
  set padding(value) {
    this.addValueChange("padding", typeof value === "number" ? Rectangle.inset(value) : value);
    this._needsFit = true;
  }

  get fontFamily() { return this.getProperty("fontFamily") }
  set fontFamily(value) {
    this.addValueChange("fontFamily", value);
    this._needsFit = true;
  }

  get fontSize() { return this.getProperty("fontSize") }
  set fontSize(value) {
    this.addValueChange("fontSize", value);
    this._needsFit = true;
  }

  get fontColor() { return this.getProperty("fontColor") }
  set fontColor(value) { this.addValueChange("fontColor", value); }

  get placeholder() { return this.getProperty("placeholder") }
  set placeholder(value) {
    this.addValueChange("placeholder", value);
    this._needsFit = true;
  }

  get _selection() { return this.getProperty("_selection") }
  set _selection(value) { this.addValueChange("_selection", value); }

  get selection() { return new Selection(this) }

  get clipMode()  { return this.getProperty("clipMode"); }
  set clipMode(value)  {
    this.addValueChange("clipMode", value);
    this.fixedWidth = this.fixedHeight = this.isClip();
  }

  insertText(pos, str) {
    var str = String(str),
        oldText = this.textString,
        newText = oldText ? oldText.substr(0, pos) + str + oldText.substr(pos) : str;
    this._needsFit = true;

    this.addValueChange(
      "textString", newText,
      {action: "insert", pos: pos, str: str});
  }

  deleteText(start, end) {
    var oldText = this.textString,
        newText = oldText.substr(0, start) + oldText.substr(end);
    this._needsFit = true;

    this.addValueChange(
      "textString", newText,
      {action: "delete", start: start, end: end});
  }

  selectionOrLineString() {
    var sel = this.selection;
    if (sel.text) return sel.text;
    var line = string.lineIndexComputer(this.textString)(sel.start),
        [start, end] = string.lineNumberToIndexesComputer(this.textString)(line);
    return this.textString.slice(start, end).trim();
  }

  aboutToRender(renderer) {
    super.aboutToRender(renderer);
    this.fitIfNeeded();
  }

  render(renderer) {
    return this.renderer.renderMorph(renderer, this);
  }

  fit() {
    let {fixedWidth, fixedHeight} = this;
    if ((fixedHeight && fixedWidth) || !this.renderer/*not init'ed yet*/) return;
    let textBounds = this.renderer.textBounds(this);
    if (!fixedHeight && !fixedWidth) this.extent = textBounds.extent();
    else if (!fixedHeight) this.height = textBounds.height;
    else if (!fixedWidth) this.width = textBounds.width;
  }

  fitIfNeeded() {
    if (this._needsFit) { this.fit(); this._needsFit = false; }
  }

  indexFromPoint(point) {
    var pos = this.renderer.textPositionFor(this, point),
        lines = this.textString.split("\n"),
        index = 0;
    for (var i = 0; i < Math.min(pos.row, lines.length); i++) index += lines[i].length;
    index += pos.column;
    return index;
  }

  pointFromIndex(index) {
    return this.renderer.pixelPositionForIndex(this, index);
  }

  paddingAndScrollOffset() {
    return this.padding.topLeft().subPt(this.scroll);
  }

  addPaddingAndScroll(point) {
    return point.addPt(this.paddingAndScrollOffset());
  }

  removePaddingAndScroll(point) {
    return point.subPt(this.paddingAndScrollOffset());
  }

  scrollToSelection() {
    var {scroll, selection, padding} = this,
        paddedBounds = this.innerBounds().insetByRect(padding),
        selPt = this.addPaddingAndScroll(this.pointFromIndex(selection.start));
    if (!paddedBounds.containsPoint(selPt)) {
      this.scroll = scroll.addPt(selPt.subPt(paddedBounds.bottomRight()));
    }
  }

  onMouseDown(evt) {
    this.onMouseMove(evt);
  }

  onMouseMove(evt) {
    var {clickedOnMorph, clickedOnPosition} = evt.state;
    if (clickedOnMorph !== this) return;

    var {selection} = this,
        {start: curStart, end: curEnd} = selection,
        start = this.indexFromPoint(this.localize(clickedOnPosition)),
        end = this.indexFromPoint(this.localize(evt.position))
        // start = this.indexFromPoint(this.removePaddingAndScroll(this.localize(clickedOnPosition))),
        // end = this.indexFromPoint(this.removePaddingAndScroll(this.localize(evt.position)))

    if (start > end)
      [start, end] = [end, start];
    if (end !== curEnd || start !== curStart)
      selection.range = {start: start, end: end};
  }

  onKeyUp(evt) {
    switch (evt.keyString()) {
      case 'Command-D': case 'Command-P': evt.stop(); break;
    }
  }

  onKeyDown(evt) {
    var keyString = evt.keyString(),
        key = evt.domEvt.key,
        sel = this.selection;

    switch (keyString) {
      case 'Command-C': case 'Command-X': case 'Command-V':
        break; // handled by onCut()/onPaste()

      case 'Command-A':
        evt.stop();
        sel.range = { start: 0, end: this.textString.length };
        break;

      case 'Command-D':
        evt.stop();
        (async () => {
          var result = await lively.vm.runEval(this.selectionOrLineString(), {System, targetModule: "lively://test-text/1"});
          this.world()[result.isError ? "logError" : "setStatusMessage"](result.value);
        })();
        break;

      case 'Command-P':
        evt.stop();
        (async () => {
          var result = await lively.vm.runEval(this.selectionOrLineString(), {System, targetModule: "lively://test-text/1"});
          this.textString = this.textString.slice(0, sel.end) + result.value + this.textString.slice(sel.end);
        })();
        break;

      case 'Command-S':
        evt.stop();
        this.doSave();
        break;

      case 'Backspace':
        if (this.rejectsInput()) break;
        evt.stop();
        sel.isCollapsed && sel.start && sel.start--;
        sel.text = "";
        sel.collapse();
        break;

      case 'Del': // forward-delete
        if (this.rejectsInput()) break;
        evt.stop();
        sel.isCollapsed && sel.end++;
        sel.text = "";
        sel.collapse();
        break;

      case 'Left': case 'Right':
        evt.stop();
        sel.start += (keyString === 'Right' ? 1 : (sel.start > 0 ? -1 : 0));
        sel.collapse();
        break;

      case 'Up': case 'Down':
        evt.stop();
        var text = this.textString,
            line = string.lineIndexComputer(text)(sel.start),
            otherLine = line + (keyString === "Down" ? 1 : -1),
            rangeComp = string.lineNumberToIndexesComputer(text),
            [lineStart, lineEnd] = rangeComp(line),
            otherLineRange = rangeComp(otherLine),
            [otherLineStart, otherLineEnd] = otherLineRange || [lineStart, lineEnd];
        sel.start = Math.min(otherLineStart + (sel.start - lineStart), otherLineEnd-1);
        sel.collapse();
        break;

      default:
        if (this.rejectsInput()) break;
        evt.stop();
        switch (key) {
          case 'Enter':
            sel.text = "\n"; break;
          case 'Space':
            sel.text = " "; break;
          case 'Tab':
            sel.text = "\t"; break;
          default:
            if (key.length === 1) sel.text = key;
            else return; // ignored key
        }
        sel.collapse(sel.start + 1);
    }

    this.scrollToSelection();
  }

  doSave() { /*...*/ }

  onCut(evt) {
    if (this.rejectsInput()) return;
    this.onCopy(evt);
    var sel = this.selection;
    sel.text = "";
    sel.collapse();
  }

  onCopy(evt) {
    if (!this.isFocused()) return;
    evt.stop();
    evt.domEvt.clipboardData.setData("text", this.selection.text);
  }

  onPaste(evt) {
    if (this.rejectsInput()) return;
    evt.stop();
    var sel = this.selection;
    sel.text = evt.domEvt.clipboardData.getData("text");
    sel.collapse(sel.end);
  }

  onFocus(evt) {
    this.makeDirty();
  }

  onBlur(evt) { this.makeDirty(); }

  // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  // debugging
  inspect() {
    var inspected = `<${this.name}>`,
        {range: {start,end}, text} = this.selection
    inspected += `\n  selection: ${start} -> ${end} ${text}`
    inspected += "\n  " + this.renderer.lines.map(({height, width, text}, i) => {
      return `[${i}] ${width.toFixed(0)}x${height.toFixed(0)} ${obj.inspect(text)}`
    }).join("\n  ");
    return inspected += `\n</${this.name}>`
  }

}
<commit_msg>text: fix Text.indexFromPoint()<commit_after>/*global System*/
import { string, obj } from "lively.lang";
import { Rectangle, Color, pt } from "lively.graphics";
import { Morph } from "../index.js";
import { Selection } from "./selection.js";
import DocumentRenderer from "./rendering.js";

export class Text extends Morph {

  static makeLabel(string, props) {
    return new Text({
      textString: string,
      fontFamily: "Helvetica Neue, Arial",
      fontColor: Color.black,
      fontSize: 11,
      readOnly: true,
      ...props
    });
  }

  constructor(props) {
    var fontMetric;
    if (props.fontMetric) {
      fontMetric = props.fontMetric
      props = obj.dissoc(props, ["fontMetric"]);
    }
    super({
      readOnly: false,
      clipMode: "hidden",
      textString: "",
      fixedWidth: false, fixedHeight: false,
      padding: 0,
      draggable: false,
      _selection: { start: 0, end: 0 },
      fontFamily: "Sans-Serif",
      fontSize: 12,
      ...props
    });
    this.renderer = new DocumentRenderer(fontMetric || this.env.fontMetric);
    this.fit();
    this._needsFit = false;
  }

  get isText() { return true }

  onChange(change) {
    super.onChange(change);
    if (change.prop === "textString"
     || change.prop === "fontFamily"
     || change.prop === "fontSize"
     || change.prop === "fixedWidth"
     || change.prop === "fixedHeight")
       this.renderer && (this.renderer.layoutComputed = false);
  }

  get textString() { return this.getProperty("textString") }
  set textString(value) {
    let oldText = this.textString;
    oldText && this.deleteText(0, oldText.length);
    this.insertText(0, value);
  }

  get readOnly() { return this.getProperty("readOnly"); }
  set readOnly(value) {
    this.nativeCursor = value ? "default" : "auto";
    this.addValueChange("readOnly", value);
  }

  rejectsInput() { return this.readOnly || !this.isFocused() }

  get fixedWidth() { return this.getProperty("fixedWidth") }
  set fixedWidth(value) {
    this.addValueChange("fixedWidth", value);
    this._needsFit = true;
  }

  get fixedHeight() { return this.getProperty("fixedHeight") }
  set fixedHeight(value) {
    this.addValueChange("fixedHeight", value);
    this._needsFit = true;
  }

  get padding() { return this.getProperty("padding") }
  set padding(value) {
    this.addValueChange("padding", typeof value === "number" ? Rectangle.inset(value) : value);
    this._needsFit = true;
  }

  get fontFamily() { return this.getProperty("fontFamily") }
  set fontFamily(value) {
    this.addValueChange("fontFamily", value);
    this._needsFit = true;
  }

  get fontSize() { return this.getProperty("fontSize") }
  set fontSize(value) {
    this.addValueChange("fontSize", value);
    this._needsFit = true;
  }

  get fontColor() { return this.getProperty("fontColor") }
  set fontColor(value) { this.addValueChange("fontColor", value); }

  get placeholder() { return this.getProperty("placeholder") }
  set placeholder(value) {
    this.addValueChange("placeholder", value);
    this._needsFit = true;
  }

  get _selection() { return this.getProperty("_selection") }
  set _selection(value) { this.addValueChange("_selection", value); }

  get selection() { return new Selection(this) }

  get clipMode()  { return this.getProperty("clipMode"); }
  set clipMode(value)  {
    this.addValueChange("clipMode", value);
    this.fixedWidth = this.fixedHeight = this.isClip();
  }

  insertText(pos, str) {
    var str = String(str),
        oldText = this.textString,
        newText = oldText ? oldText.substr(0, pos) + str + oldText.substr(pos) : str;
    this._needsFit = true;

    this.addValueChange(
      "textString", newText,
      {action: "insert", pos: pos, str: str});
  }

  deleteText(start, end) {
    var oldText = this.textString,
        newText = oldText.substr(0, start) + oldText.substr(end);
    this._needsFit = true;

    this.addValueChange(
      "textString", newText,
      {action: "delete", start: start, end: end});
  }

  selectionOrLineString() {
    var sel = this.selection;
    if (sel.text) return sel.text;
    var line = string.lineIndexComputer(this.textString)(sel.start),
        [start, end] = string.lineNumberToIndexesComputer(this.textString)(line);
    return this.textString.slice(start, end).trim();
  }

  aboutToRender(renderer) {
    super.aboutToRender(renderer);
    this.fitIfNeeded();
  }

  render(renderer) {
    return this.renderer.renderMorph(renderer, this);
  }

  fit() {
    let {fixedWidth, fixedHeight} = this;
    if ((fixedHeight && fixedWidth) || !this.renderer/*not init'ed yet*/) return;
    let textBounds = this.renderer.textBounds(this);
    if (!fixedHeight && !fixedWidth) this.extent = textBounds.extent();
    else if (!fixedHeight) this.height = textBounds.height;
    else if (!fixedWidth) this.width = textBounds.width;
  }

  fitIfNeeded() {
    if (this._needsFit) { this.fit(); this._needsFit = false; }
  }

  indexFromPoint(point) {
    return this.renderer.textIndexFor(this, point);
  }

  pointFromIndex(index) {
    return this.renderer.pixelPositionForIndex(this, index);
  }

  paddingAndScrollOffset() {
    return this.padding.topLeft().subPt(this.scroll);
  }

  addPaddingAndScroll(point) {
    return point.addPt(this.paddingAndScrollOffset());
  }

  removePaddingAndScroll(point) {
    return point.subPt(this.paddingAndScrollOffset());
  }

  scrollToSelection() {
    var {scroll, selection, padding} = this,
        paddedBounds = this.innerBounds().insetByRect(padding),
        selPt = this.addPaddingAndScroll(this.pointFromIndex(selection.start));
    if (!paddedBounds.containsPoint(selPt)) {
      this.scroll = scroll.addPt(selPt.subPt(paddedBounds.bottomRight()));
    }
  }

  onMouseDown(evt) {
    this.onMouseMove(evt);
  }

  onMouseMove(evt) {
    var {clickedOnMorph, clickedOnPosition} = evt.state;
    if (clickedOnMorph !== this) return;

    var {selection} = this,
        {start: curStart, end: curEnd} = selection,
        start = this.indexFromPoint(this.localize(clickedOnPosition)),
        end = this.indexFromPoint(this.localize(evt.position))
        // start = this.indexFromPoint(this.removePaddingAndScroll(this.localize(clickedOnPosition))),
        // end = this.indexFromPoint(this.removePaddingAndScroll(this.localize(evt.position)))

    if (start > end)
      [start, end] = [end, start];
    if (end !== curEnd || start !== curStart)
      selection.range = {start: start, end: end};
  }

  onKeyUp(evt) {
    switch (evt.keyString()) {
      case 'Command-D': case 'Command-P': evt.stop(); break;
    }
  }

  onKeyDown(evt) {
    var keyString = evt.keyString(),
        key = evt.domEvt.key,
        sel = this.selection;

    switch (keyString) {
      case 'Command-C': case 'Command-X': case 'Command-V':
        break; // handled by onCut()/onPaste()

      case 'Command-A':
        evt.stop();
        sel.range = { start: 0, end: this.textString.length };
        break;

      case 'Command-D':
        evt.stop();
        (async () => {
          var result = await lively.vm.runEval(this.selectionOrLineString(), {System, targetModule: "lively://test-text/1"});
          this.world()[result.isError ? "logError" : "setStatusMessage"](result.value);
        })();
        break;

      case 'Command-P':
        evt.stop();
        (async () => {
          var result = await lively.vm.runEval(this.selectionOrLineString(), {System, targetModule: "lively://test-text/1"});
          this.textString = this.textString.slice(0, sel.end) + result.value + this.textString.slice(sel.end);
        })();
        break;

      case 'Command-S':
        evt.stop();
        this.doSave();
        break;

      case 'Backspace':
        if (this.rejectsInput()) break;
        evt.stop();
        sel.isCollapsed && sel.start && sel.start--;
        sel.text = "";
        sel.collapse();
        break;

      case 'Del': // forward-delete
        if (this.rejectsInput()) break;
        evt.stop();
        sel.isCollapsed && sel.end++;
        sel.text = "";
        sel.collapse();
        break;

      case 'Left': case 'Right':
        evt.stop();
        sel.start += (keyString === 'Right' ? 1 : (sel.start > 0 ? -1 : 0));
        sel.collapse();
        break;

      case 'Up': case 'Down':
        evt.stop();
        var text = this.textString,
            line = string.lineIndexComputer(text)(sel.start),
            otherLine = line + (keyString === "Down" ? 1 : -1),
            rangeComp = string.lineNumberToIndexesComputer(text),
            [lineStart, lineEnd] = rangeComp(line),
            otherLineRange = rangeComp(otherLine),
            [otherLineStart, otherLineEnd] = otherLineRange || [lineStart, lineEnd];
        sel.start = Math.min(otherLineStart + (sel.start - lineStart), otherLineEnd-1);
        sel.collapse();
        break;

      default:
        if (this.rejectsInput()) break;
        evt.stop();
        switch (key) {
          case 'Enter':
            sel.text = "\n"; break;
          case 'Space':
            sel.text = " "; break;
          case 'Tab':
            sel.text = "\t"; break;
          default:
            if (key.length === 1) sel.text = key;
            else return; // ignored key
        }
        sel.collapse(sel.start + 1);
    }

    this.scrollToSelection();
  }

  doSave() { /*...*/ }

  onCut(evt) {
    if (this.rejectsInput()) return;
    this.onCopy(evt);
    var sel = this.selection;
    sel.text = "";
    sel.collapse();
  }

  onCopy(evt) {
    if (!this.isFocused()) return;
    evt.stop();
    evt.domEvt.clipboardData.setData("text", this.selection.text);
  }

  onPaste(evt) {
    if (this.rejectsInput()) return;
    evt.stop();
    var sel = this.selection;
    sel.text = evt.domEvt.clipboardData.getData("text");
    sel.collapse(sel.end);
  }

  onFocus(evt) {
    this.makeDirty();
  }

  onBlur(evt) { this.makeDirty(); }

  // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  // debugging
  inspect() {
    var inspected = `<${this.name}>`,
        {range: {start,end}, text} = this.selection
    inspected += `\n  selection: ${start} -> ${end} ${text}`
    inspected += "\n  " + this.renderer.lines.map(({height, width, text}, i) => {
      return `[${i}] ${width.toFixed(0)}x${height.toFixed(0)} ${obj.inspect(text)}`
    }).join("\n  ");
    return inspected += `\n</${this.name}>`
  }

}
<|endoftext|>


<commit_before>!function(){

  // This object gets globalalized/exported
  var promiz = {

    // promise factory
    defer: function(){
      return new promise()
    },

    // calls a function and resolved as a promise
    /*fcall: function() {
      var def = new promise()
      var args = Array.apply([], arguments)
      var fn = args.shift()
      try {
        var val = fn.apply(null, args)
        def.resolve(val)
      } catch(e) {
        def.reject(e)
      }

      return def
    },

    // calls a node-style function (eg. expects callback as function(err, callback))
    nfcall: function() {
      var def = new promise()
      var args = Array.apply([], arguments)
      var fn = args.shift()
      try {

        // Add our custom promise callback to the end of the arguments
        args.push(function(err, val){
          if(err) {
            return def.reject(err)
          }
          return def.resolve(val)
        })
        fn.apply(null, args)
      } catch (e) {
        def.reject(e)
      }

      return def
    }*/
  }

  // This is the promise object itself
  function promise(fn, er){
    this.promise = this
    this.state = 'pending'
    this.val = null
    this.next = []
    this.prev = null
    this.fn = fn || null
    this.er = er || null

    this.resolve = function(val) {
      if(this.state !== 'pending') return
      if(this.prev && this.prev.state === 'pending') return this.prev.resolve(val)
      this.val = val
      this.state = 'resolving'

      process.nextTick(function() {
        this.fire()
      }.bind(this))
    }

    this.reject = function(val) {
      if(this.state !== 'pending') return
      if(this.prev && this.prev.state === 'pending') return this.prev.reject(val)
      this.val = val
      this.state = 'rejecting'

      process.nextTick(function() {
        this.fire()
      }.bind(this))
    }

    this.then = function(fn, er) {
      var p = new promise(fn, er)
      this.next.push(p)
      p.prev = this
      if(this.state === 'resolved' || this.state === 'rejected') {
        if(this.state === 'resolved' && this.next) {
            p.resolve(this.val)
        }
        if(this.state === 'rejected' && this.next) {
            p.reject(this.val)
        }
      }
      return p
    }

    this.fail = function(er) {
      return this.then(null, er)
    }

    this.finish = function(type, val) {
      this.state = type
      this.val = val || this.val

      if(this.state === 'resolved' && this.next) {
        this.next.map(function(p){
          p.resolve(this.val)
        }.bind(this))
      }

      if(this.state === 'rejected' && this.next) {
        this.next.map(function(p){
          p.reject(this.val)
        }.bind(this))
      }
    }

    this.chain = function(promise, ref) {
      var self = this

      if(promise === this) {
        return this.finish('rejected', new TypeError())
      }

      // it's not a thenable, resolve/reject with it's value
      if(typeof promise !== 'object' || typeof ref !== 'function') {
        if(this.state === 'resolving')
          return this.finish('resolved', promise)
        return this.finish('rejected', promise)
      }

      try {
        ref.call(promise, function resolved(val) {
          self.finish('resolved', val)
        }, function(val) {
          self.finish('rejected', val)
        })
      } catch(e) {
        this.finish('rejected', e)
      }

    }

    this.fire = function() {
      var self = this
      // check if it's a thenable
      var promise = this.val
      if(promise === this) {
        return this.finish('rejected', new TypeError())
      }

      var ref;
      try {
        ref = promise && promise.then
      } catch(e) {
        this.val = e
        this.state = 'rejecting'
        return this.fire()
      }

      // it's a thenable chain it
      if(typeof promise === 'object' && typeof ref === 'function') {
        try {
          var cnt=0
          ref.call(promise, function(val) {
            if(cnt++!== 0) return
            self.val = val
            self.state = 'resolving'
            self.fire()
          }, function(val) {
            if(cnt++!== 0) return
            self.val = val
            self.state = 'rejecting'
            self.fire()
          })
        } catch(e) {
          this.state = 'rejecting'
          this.val = e
          this.fire()
        }
        return
      }

      if(this.state === 'resolving' && typeof this.fn === 'function' ) {
        try {
          this.val = this.fn.call(undefined, this.val)
        } catch(e) {
          return this.finish('rejected', e)
        }
      }

      if (this.state === 'rejecting' && typeof this.er === 'function') {
        try {
          this.val = this.er.call(undefined, this.val)
          this.state = 'resolving'
        } catch(e) {
          return this.finish('rejected', e)
        }
      }

      return this.chain(this.val, ref)
    }

    // State transitions from pending to either resolved or rejected
    /*this.state = 'p'

    // Our current value
    this.val = val || undefined

    // This is a pointer to the next promise
    this.next = null

    // this is a pointer to the previous promise
    this.previous = null

    // functions to call
    this.successFn = null
    this.failFn = null

    // Resolved the promise to a value. Only affects the first time it is called
    this.resolve = function(val) {
      this.resolve = function(){}

      if(this.previous) {
        return this.previous.resolve(val)
      }
      this.val = val
      process.nextTick(function() {
        this.state = 'r'
        this.fire()
        this.next = this.q
      }.bind(this))
      this.fire()

      this.q = new promise()
      this.q.previous = this

      return this.q
    }

    // Rejects the promise with a value. Only affects the first time it is called
    this.reject = function(val) {
      this.reject = function() {}
      if(this.previous) {
        return this.previous.reject(val)
      }
      this.val = val
      process.nextTick(function() {
        this.state = 'f'
        this.fire()
        this.next = this.q
      }.bind(this))
      this.fire()

      this.q = new promise()
      this.q.previous = this
      return this.q
    }

    // The heart of the promise, adding a defered call to our call stack
    this.then = function(fn, er) {
      this.successFn = fn
      this.failFn = er
      this.next = new promise()
      this.next.previous = this

      if(this.state !== 'p') {
        process.nextTick(function() {
          this.fire()
        }.bind(this))
      }

      return this.next
    }

    this.fire = function() {
      var res = this.val
      try {
        if(this.state === 's' && this.successFn) {
          res = this.successFn(this.val)
        }

        if(this.state === 'f' && this.failFn) {
          res = this.failFn(this.val)
        }
      } catch(e) {
        if(this.state === 's' && this.failFn) {
          try {
            res = this.failFn(e)
          } catch(e) {
            res = e
          }
        } else {
          res = e
        }
      }
      if(res && res.then) {
        res.then(function(val) {
          if(this.next) {
            this.next.state = 'r'
            this.next.val = val
            this.next.fire()
          }
        }.bind(this), function(val) {
          if(this.failFn) {
            var res = val
            try {
              res = this.failFn(val)
              this.state = 's'
            } catch(e) {
              this.state = 'f'
              res = e
            }
            val = res
          }
          if(this.next) {
            this.next.state = 'f'
            this.next.val = val
            this.next.fire()
          }
        }.bind(this))
      } else if (this.next) {
        this.next.state = 's'
        this.next.val = res
        this.next.fire()
      }
    }

    this.fail = function(fn) {
      return this.then(null, fn)
    }
    */
    /*
    // If there is an unhandled error, throw it
    // End the promise chain by returning null
    this.done = function(){
      this.failing = true
      if (this.state !== 'pending') {
        this.fire()
      }
      return null
    }

    // Catch any errors up to this point
    this.fail = function (fn) {
      return this.then(null, fn)
    }

    // Allow for node-style callback returning
    this.nodeify = function (cb) {

      // Process asyncronously, so if the function fails the error gets thrown
      function tick(fn){
        if(typeof process !== 'undefined' && process.nextTick) {
          process.nextTick(fn)
        } else {
          setTimeout(fn, 0)
        }
      }

      if(cb) {
        this.then(function(val){
          tick(function(){
            cb(null, val)
          })

          return val
        }, function(err){
          tick(function(){
            cb(err)
          })
        })
      }

      // still returns a promise to allow `dual` functions (callback + promise)
      return this
    }

    // Apply a list value over the next function
    this.spread = function (fn, er) {
      return this.all().then(function(list){
        return fn ? fn.apply(null, list) :  null
      }, er)
    }

    // Resolves an array of promises before continuing
    this.all = function () {
      var self = this

      // create a new deferred, to be resolved when we finish
      var def = new defer()

      // Add a special function to the stack, which takes in the list of promise objects
      this.stack.push([function(list){
        list = list ? (list instanceof Array ? list : [list]) : []
        if (list.length === 0){
          return list
        }

        // We count up resolved and match it to the length of the list of promises
        // This lets us know when we've finished
        var cnt = 0
        var len = list.length

        function checkDone(){
          if(cnt !== len) {
            return
          }
          def.resolve(list)
        }

        // iterate over the list, resolving each value
        var ind = len

        while(ind--) {

          // Create varaible scope
          (function(){
            var i = ind
            var val = list[i]
            if(val && val.then &&
               typeof val.then === 'function' &&
               typeof val === 'object'){
            val.then(function(res){
              list[i] = res
              cnt++
              checkDone()
            }, function(err){
              def.reject(err)
            })
          } else {
            list[i] = val
            cnt++
            checkDone()
          }
          })()
        }

        return null
      }, null])

      if (this.state !== 'pending') {
        this.fire()
      }

      return def
    }

    // This is our main execution thread
    // Here is where we consume the stack of promises
    this.fire = function (val) {
      var self = this
      this.val = typeof val !== 'undefined' ? val : this.val

      // Iterate through the stack
      while(this.stack.length && this.state !== 'pending') {
        // Get the next stack item
        var entry = this.stack.shift()
        var fn = this.state === 'rejected' ? entry[1] : entry[0]

        if(fn) {
          try {
            this.val = fn(this.val)

            // If the value returned is a promise, resolve it
            if(this.val &&
               typeof this.val.then === 'function' &&
               typeof this.val === 'object') {
              var prevState = this.state

              // Halt stack execution until the promise resolves
              this.state = 'pending'

              // resolving
              this.val.then(function(v){

                // success callback
                self.resolve(v)
              }, function(err){

                // error callback

                // re-run the stack item if it has an error callback
                // but only if we weren't already in a rejected state
                if(prevState !== 'rejected' && entry[1]) {
                  self.stack.unshift(entry)
                }

                self.reject(err)
              })

            } else {
              //this.state = 'resolved'
            }
          } catch (e) {

            // the function call failed, lets reject ourselves
            // and re-run the stack item in case it can handle an error case
            // but only if we didn't just do that (eg. the error function of on the stack threw)
            this.val = e
            if(this.state !== 'rejected' && entry[1]) {
              this.stack.unshift(entry)
            }

            this.state = 'rejected'
          }
        }
      }

      // If the `failing` flag has been set, and we have exausted the stack, and we have an error
      // Throw the error
      if(this.failing && this.stack.length === 0 && this.state === 'rejected') {
        throw this.val
      }

    }
*/

  }

  // Export our library object, either for node.js or as a globally scoped variable
  if(typeof module !== 'undefined' && module.exports) {
    module.exports = promiz
  } else {
    this.Promiz = promiz
  }
}()
<commit_msg>optimized core for size<commit_after>(function () {

  // self is the promise object itself
  /**
   * @constructor
   */
  function promise(fn, er) {
    // states
    // 0: pending
    // 1: resoling
    // 2: rejecting
    // 3: resolved
    // 4: rejected
    var self = this

    self.promise = self
    var state = 'pending',
      val = null,
      prev = null,
      fn = fn || null,
      er = er || null,
      next = [];

    self.resolve = function (v) {
      if (state === 'pending') {
        if (prev && prev.state === 'pending') return prev.resolve(v)
        val = v
        state = 'resolving'

        setImmediate(function () {
          fire()
        })
      }
    }

    self.reject = function (v) {
      if (state === 'pending') {
        if (prev && prev.state === 'pending') return prev.reject(v)
        val = v
        state = 'rejecting'

        setImmediate(function () {
          fire()
        })
      }
    }

    self.then = function (fn, er) {
      var p = new promise(fn, er)
      next.push(p)
      p.prev = self
      if (state === 'resolved') {
        p.resolve(val)
      }
      if (state === 'rejected') {
        p.reject(val)
      }
      return p
    }

    self.fail = function (er) {
      return self.then(null, er)
    }

    var finish = function (type) {
      state = type

      if (state === 'resolved') {
        next.map(function (p) {
          p.resolve(val)
        })
      }

      if (state === 'rejected') {
        next.map(function (p) {
          p.reject(val)
        })
      }
    }

    // ref : reference to 'then' function
    // cb, ec, cn : successCallback, failureCallback, notThennableCallback
    var thennable = function (ref, cb, ec, cn) {
      if (typeof val === 'object' && typeof ref === 'function') {
        try {

          // cnt protects against abuse calls from spec checker
          var cnt = 0
          ref.call(val, function x(v) {
            if (cnt++ !== 0) return
            val = v
            cb()
          }, function (v) {
            if (cnt++ !== 0) return
            val = v
            ec()
          })
        } catch (e) {
          val = e
          ec()
        }
      } else {
        cn()
      }
    }

    var fire = function () {

      // check if it's a thenable
      var ref;
      try {
        ref = val && val.then
      } catch (e) {
        val = e
        state = 'rejecting'
        return fire()
      }

      thennable(ref, function () {
        state = 'resolving'
        fire()
      }, function () {
        state = 'rejecting'
        fire()
      }, function () {
        if (state === 'resolving' && typeof fn === 'function') {
          try {
            val = fn(val)
          } catch (e) {
            val = e
            return finish('rejected')
          }
        }

        if (state === 'rejecting' && typeof er === 'function') {
          try {
            val = er(val)
            state = 'resolving'
          } catch (e) {
            val = e
            return finish('rejected')
          }
        }

        if (val === self) {
          val = TypeError()
          return finish('rejected')
        }

        thennable(ref, function () {
          finish('resolved')
        }, function () {
          finish('rejected')
        }, function () {
          state === 'resolving' ? finish('resolved') : finish('rejected')
        })

      })
    }

    // State transitions from pending to either resolved or rejected
    /*self.state = 'p'

    // Our current value
    self.val = val || undefined

    // self is a pointer to the next promise
    self.next = null

    // self is a pointer to the previous promise
    self.previous = null

    // functions to call
    self.successFn = null
    self.failFn = null

    // Resolved the promise to a value. Only affects the first time it is called
    self.resolve = function(val) {
      self.resolve = function(){}

      if(self.previous) {
        return self.previous.resolve(val)
      }
      self.val = val
      process.nextTick(function() {
        self.state = 'r'
        fire()
        self.next = self.q
      }.bind(self))
      fire()

      self.q = new promise()
      self.q.previous = self

      return self.q
    }

    // Rejects the promise with a value. Only affects the first time it is called
    self.reject = function(val) {
      self.reject = function() {}
      if(self.previous) {
        return self.previous.reject(val)
      }
      self.val = val
      process.nextTick(function() {
        self.state = 'f'
        fire()
        self.next = self.q
      }.bind(self))
      fire()

      self.q = new promise()
      self.q.previous = self
      return self.q
    }

    // The heart of the promise, adding a defered call to our call stack
    self.then = function(fn, er) {
      self.successFn = fn
      self.failFn = er
      self.next = new promise()
      self.next.previous = self

      if(self.state !== 'p') {
        process.nextTick(function() {
          fire()
        }.bind(self))
      }

      return self.next
    }

    fire = function() {
      var res = self.val
      try {
        if(self.state === 's' && self.successFn) {
          res = self.successFn(self.val)
        }

        if(self.state === 'f' && self.failFn) {
          res = self.failFn(self.val)
        }
      } catch(e) {
        if(self.state === 's' && self.failFn) {
          try {
            res = self.failFn(e)
          } catch(e) {
            res = e
          }
        } else {
          res = e
        }
      }
      if(res && res.then) {
        res.then(function(val) {
          if(self.next) {
            self.next.state = 'r'
            self.next.val = val
            self.next.fire()
          }
        }.bind(self), function(val) {
          if(self.failFn) {
            var res = val
            try {
              res = self.failFn(val)
              self.state = 's'
            } catch(e) {
              self.state = 'f'
              res = e
            }
            val = res
          }
          if(self.next) {
            self.next.state = 'f'
            self.next.val = val
            self.next.fire()
          }
        }.bind(self))
      } else if (self.next) {
        self.next.state = 's'
        self.next.val = res
        self.next.fire()
      }
    }

    self.fail = function(fn) {
      return self.then(null, fn)
    }
    */
    /*
    // If there is an unhandled error, throw it
    // End the promise chain by returning null
    self.done = function(){
      self.failing = true
      if (self.state !== 'pending') {
        fire()
      }
      return null
    }

    // Catch any errors up to self point
    self.fail = function (fn) {
      return self.then(null, fn)
    }

    // Allow for node-style callback returning
    self.nodeify = function (cb) {

      // Process asyncronously, so if the function fails the error gets thrown
      function tick(fn){
        if(typeof process !== 'undefined' && process.nextTick) {
          process.nextTick(fn)
        } else {
          setTimeout(fn, 0)
        }
      }

      if(cb) {
        self.then(function(val){
          tick(function(){
            cb(null, val)
          })

          return val
        }, function(err){
          tick(function(){
            cb(err)
          })
        })
      }

      // still returns a promise to allow `dual` functions (callback + promise)
      return self
    }

    // Apply a list value over the next function
    self.spread = function (fn, er) {
      return self.all().then(function(list){
        return fn ? fn.apply(null, list) :  null
      }, er)
    }

    // Resolves an array of promises before continuing
    self.all = function () {
      var self = self

      // create a new deferred, to be resolved when we finish
      var def = new defer()

      // Add a special function to the stack, which takes in the list of promise objects
      self.stack.push([function(list){
        list = list ? (list instanceof Array ? list : [list]) : []
        if (list.length === 0){
          return list
        }

        // We count up resolved and match it to the length of the list of promises
        // self lets us know when we've finished
        var cnt = 0
        var len = list.length

        function checkDone(){
          if(cnt !== len) {
            return
          }
          def.resolve(list)
        }

        // iterate over the list, resolving each value
        var ind = len

        while(ind--) {

          // Create varaible scope
          (function(){
            var i = ind
            var val = list[i]
            if(val && val.then &&
               typeof val.then === 'function' &&
               typeof val === 'object'){
            val.then(function(res){
              list[i] = res
              cnt++
              checkDone()
            }, function(err){
              def.reject(err)
            })
          } else {
            list[i] = val
            cnt++
            checkDone()
          }
          })()
        }

        return null
      }, null])

      if (self.state !== 'pending') {
        fire()
      }

      return def
    }

    // self is our main execution thread
    // Here is where we consume the stack of promises
    fire = function (val) {
      var self = self
      self.val = typeof val !== 'undefined' ? val : self.val

      // Iterate through the stack
      while(self.stack.length && self.state !== 'pending') {
        // Get the next stack item
        var entry = self.stack.shift()
        var fn = self.state === 'rejected' ? entry[1] : entry[0]

        if(fn) {
          try {
            self.val = fn(self.val)

            // If the value returned is a promise, resolve it
            if(self.val &&
               typeof self.val.then === 'function' &&
               typeof self.val === 'object') {
              var prevState = self.state

              // Halt stack execution until the promise resolves
              self.state = 'pending'

              // resolving
              self.val.then(function(v){

                // success callback
                self.resolve(v)
              }, function(err){

                // error callback

                // re-run the stack item if it has an error callback
                // but only if we weren't already in a rejected state
                if(prevState !== 'rejected' && entry[1]) {
                  self.stack.unshift(entry)
                }

                self.reject(err)
              })

            } else {
              //self.state = 'resolved'
            }
          } catch (e) {

            // the function call failed, lets reject ourselves
            // and re-run the stack item in case it can handle an error case
            // but only if we didn't just do that (eg. the error function of on the stack threw)
            self.val = e
            if(self.state !== 'rejected' && entry[1]) {
              self.stack.unshift(entry)
            }

            self.state = 'rejected'
          }
        }
      }

      // If the `failing` flag has been set, and we have exausted the stack, and we have an error
      // Throw the error
      if(self.failing && self.stack.length === 0 && self.state === 'rejected') {
        throw self.val
      }

    }
*/

  }

  // self object gets globalalized/exported
  var promiz = {

    // promise factory
    defer: function () {
      return new promise(null, null)
    }

    // calls a function and resolved as a promise
    /*fcall: function() {
      var def = new promise()
      var args = Array.apply([], arguments)
      var fn = args.shift()
      try {
        var val = fn.apply(null, args)
        def.resolve(val)
      } catch(e) {
        def.reject(e)
      }

      return def
    },

    // calls a node-style function (eg. expects callback as function(err, callback))
    nfcall: function() {
      var def = new promise()
      var args = Array.apply([], arguments)
      var fn = args.shift()
      try {

        // Add our custom promise callback to the end of the arguments
        args.push(function(err, val){
          if(err) {
            return def.reject(err)
          }
          return def.resolve(val)
        })
        fn.apply(null, args)
      } catch (e) {
        def.reject(e)
      }

      return def
    }*/
  }
  // Export our library object, either for node.js or as a globally scoped variable
  if (typeof module !== 'undefined') {
    module.exports = promiz
  } else {
    self.Promiz = promiz
  }
})()<|endoftext|>