<commit_before>module.exports = {
  root: true,

  parser: 'babel-eslint',

  extends: [
    'airbnb-base',
    'plugin:promise/recommended',
    'plugin:jest/recommended',
    'plugin:unicorn/recommended',
    'prettier',
  ],

  plugins: ['promise', 'jest', 'unicorn'],

  parserOptions: {
    sourceType: 'script',
  },

  env: {
    jest: true,
  },

  overrides: [
    {
      files: ['*.{ts,tsx}'],
      parser: '@typescript-eslint/parser',
      parserOptions: {
        ecmaVersion: 2018,
        sourceType: 'module',
        warnOnUnsupportedTypeScriptVersion: true,
      },
      extends: ['plugin:@typescript-eslint/recommended'],
      plugins: ['@typescript-eslint'],
    },
  ],

  rules: {
    strict: 0,
    'no-var': 2,
    'no-shadow': 0,
    'no-param-reassign': 0,
    'arrow-parens': ['error', 'as-needed'],
    'class-methods-use-this': 0,
    'unicorn/import-index': 'off',
    'unicorn/filename-case': 'off',
    'unicorn/prefer-includes': 'off',
    'unicorn/prefer-node-remove': 'off',
    'unicorn/prevent-abbreviations': 'off',
    'import/no-extraneous-dependencies': 0,
    'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
    'no-underscore-dangle': 0,
    'promise/avoid-new': 0,
    'prefer-destructuring': [
      'error',
      {
        object: true,
        array: false,
      },
    ],
    'unicorn/prefer-node-append': 0,
  },
};
<commit_msg>feat: make @typescript-eslint parser optional<commit_after>const resolve = require('resolve');
const path = require('path');
const fs = require('fs');

const overrides = [];

// Lint tsx only if typescript is installed
try {
  resolve.sync('typescript', {
    basedir: path.resolve(fs.realpathSync(process.cwd()), 'node_modules'),
  });

  overrides.push({
    files: ['*.{ts,tsx}'],
    parser: '@typescript-eslint/parser',
    parserOptions: {
      ecmaVersion: 2018,
      sourceType: 'module',
      warnOnUnsupportedTypeScriptVersion: true,
    },
    extends: ['plugin:@typescript-eslint/recommended'],
    plugins: ['@typescript-eslint'],
  });
} catch (error) {
  if (error.code !== 'MODULE_NOT_FOUND') {
    throw error;
  }
}

module.exports = {
  root: true,

  parser: 'babel-eslint',

  extends: [
    'airbnb-base',
    'plugin:promise/recommended',
    'plugin:jest/recommended',
    'plugin:unicorn/recommended',
    'prettier',
  ],

  plugins: ['promise', 'jest', 'unicorn'],

  parserOptions: {
    sourceType: 'script',
  },

  env: {
    jest: true,
  },

  overrides,

  rules: {
    strict: 0,
    'no-var': 2,
    'no-shadow': 0,
    'no-param-reassign': 0,
    'arrow-parens': ['error', 'as-needed'],
    'class-methods-use-this': 0,
    'unicorn/import-index': 'off',
    'unicorn/filename-case': 'off',
    'unicorn/prefer-includes': 'off',
    'unicorn/prefer-node-remove': 'off',
    'unicorn/prevent-abbreviations': 'off',
    'import/no-extraneous-dependencies': 0,
    'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
    'no-underscore-dangle': 0,
    'promise/avoid-new': 0,
    'prefer-destructuring': [
      'error',
      {
        object: true,
        array: false,
      },
    ],
    'unicorn/prefer-node-append': 0,
  },
};
<|endoftext|>


<commit_before>function findValue (parent, dotNot) {

    if (!dotNot) return undefined;

    var splits = dotNot.split(".");
    var value;

    for (var i = 0; i < splits.length; i++) {
        value = parent[splits[i]];
        if (value === undefined) return undefined;
        if (typeof value === "object") parent = value;
    }

    return value;
}

function findFunction (parent, dotNot) {

    var func = findValue(parent, dotNot);

    if (typeof func !== "function") {
        return undefined;
    }

    return func;
}

var Bind = module.exports = function (bind, dataContext) {

    var self = this;

    var context = $(this.dom);
    if (bind.context) {
        context = $(bind.context, context);
    }
    var target = context;
    if (bind.target) {
        target = $(bind.target, context);
    }

    dataContext = dataContext || {};

    function computeStringOrSourceDataValue(dataType, dataContext) {
        var value = "";
        if (typeof dataType === "string") {
            value = dataType;
        } else {
            value = computeDataValue(dataType, dataContext);
        }
        return value;
    }

    function computeDataValue(dataType, dataContext) {

        var dataSource = undefined;

        // if the source is $ the value the data context will be considered the value
        if (dataType.source === "$") {
            dataSource = dataContext.toString();
        } else {
            dataSource = findValue(dataContext, dataType.source);
        }

        if (dataSource === undefined || dataSource === null) {
            if (typeof dataType["default"] === "string") {
                value = dataType["default"];
            } else {
                value = "?" + dataType.source + "?";
            }
        } else if (typeof dataSource === "object") {
            var locale = M.getLocale();
            value = dataSource[locale] || "Missing value for '" + locale + "' language";
        } else {
            value = dataSource;
        }

        var filterFunction = findFunction(self, dataType.filter) || findFunction(window, dataType.filter);
        if (typeof filterFunction === "function") {
            value = filterFunction(self, dataContext, dataType.source, value);
        }

        return value;
    };

    var domManipulators = {

        // add/modify attribute
        /* Examples:
         *  "binds": [
         *      {
         *          "attr": [
         *              {
         *                  "name": "the_attribute name",
         *                  "value": "a_string_value"
         *              },
         *              {
         *                  "name": "the_attribute name",
         *                  "value": {
         *                      "source": "the_field_name_from_a_source"
         *                  }
         *              },
         *              ...
         *          ]
         *      }
         *  ]
         */
        attr: function(target, context, attrTypes, dataContext) {
            if (!attrTypes || !attrTypes.length) {
                return;
            }
            for (var i = 0; i < attrTypes.length; ++i) {
                var value = computeStringOrSourceDataValue(attrTypes[i].value, dataContext);
                target.attr(attrTypes[i].name, value);
            }
        },

        // add class
        /* Examples:
         *  "binds": [
         *      {
         *          "addClass": [
         *              "class_1",
         *              "class_2",
         *              ...
         *          ]
         *      }
         *  ]
         */
        addClass: function(target, context, classes, dataContext) {
            if (!classes || !classes.length) {
                return;
            }
            for (var i = 0; i < classes.length; ++i) {
                target.addClass(classes[i]);
            }
        },

        // remove class
        /* Examples:
         *  "binds": [
         *      {
         *          "removeClass": [
         *              "class_1",
         *              "class_2",
         *              ...
         *          ]
         *      }
         *  ]
         */
        removeClass: function(target, context, classes, dataContext) {
            if (!classes || !classes.length) {
                return;
            }
            for (var i = 0; i < classes.length; ++i) {
                target.removeClass(classes[i]);
            }
        },

        // innerHTML
        /* Examples:
         *  "binds": [
         *      {
         *          "html": "a_string_value"
         *      },
         *
         *      {
         *          "html": {
         *              "source": "the_field_name_from_a_source"
         *          }
         *      }
         *  ]
         */
        html: function(target, context, dataType, dataContext) {
            var value = computeStringOrSourceDataValue(dataType, dataContext);
            if (value === undefined || value === null) {
                value = '';
            } else {
                value = value.toString();
            }
            target.html(value);
        },

        // repeat the target for each item in array source
        /*
         *   "binds": [
         *       {
         *           "repeat": {
         *               "source": "the_array_name_from_a_source",
         *               "preFilter": "handler_name",
         *               "postFilter": "handler_name",
         *               "binds": [
         *                   ...
         *               ]
         *           }
         *       }
         *   ]
         */
        repeat: function(target, context, bindTemplate, dataContext) {

            if (!target.length) {
                console.warn("Empty bind 'repeat' target");
                return;
            }

            if (typeof dataContext !== "object" || !dataContext) {
                console.warn("A bind 'repeat' can only be used with an object data context");
                return;
            }

            var sourceArray = dataContext[bindTemplate.source] || [];

            if (Object.prototype.toString.call(sourceArray) !== "[object Array]" ) {
                console.warn("A bind 'repeat' did not find an array in the source field of the data context");
                return;
            }

            var template = target.clone();
            var container = target.parent();

            // run the pre-filtering handler
            var filterFunction = findFunction(self, bindTemplate.preFilter) || findFunction(window, bindTemplate.prefilter);
            if (filterFunction) {
                sourceArray = filterFunction(self, dataContext, bindTemplate.source, sourceArray, container);
            }

            // run the binds for each item
            for (var i = 0; i < sourceArray.length; ++i) {

                var newDom = template.clone();

                if (!bindTemplate.binds || !bindTemplate.binds.length) {
                    continue;
                }

                for (var j = 0; j < bindTemplate.binds.length; ++j) {
                    var bind = bindTemplate.binds[j];
                    bind.context = newDom;
                    Bind.call(self, bind, sourceArray[i]);
                }

                container.append(newDom);
            }

            // run the post-filtering handler
            filterFunction = findFunction(self, bindTemplate.postFilter) || findFunction(window, bindTemplate.postFilter);
            if (filterFunction) {
                sourceArray = filterFunction(self, dataContext, bindTemplate.source, sourceArray, container);
            }

            target.remove();
        }
    }

    for (var key in bind) {
        if (!bind.hasOwnProperty(key)) continue;

        if (domManipulators[key]) {
            domManipulators[key](target, context, bind[key], dataContext);
        }
    }

    if (bind.on) {
        for (var i = 0; i < bind.on.length; ++i) {
            var curOn = bind.on[i];
            if (curOn.handler || curOn.emit) {
                (function (curOn) {
                    var t = target;
                    var s = null;

                    // of the delegated option is set, this bind will work for future DOM insertions
                    if (curOn.delegated) {
                        t = context;
                        s = target.selector;
                    }

                    t.on(curOn.name, s,function(event) {
                        event.stopPropagation();

                        var name = curOn.handler;
                        var args = [];

                        if (typeof name === "object") {
                            args = name.args || [];
                            name = name.name;
                        }

                        // if the noEvent option is set, the DOM event will not be passed to the called handler or emitted event
                        if (!curOn.noEvent) {
                            args.push(event);
                        }
                        args.push(dataContext);

                        if (typeof name === "function") {
                            name.apply(self, args);
                            return false;
                        }

                        var handler = findFunction(self, name) || findFunction(window, name);

                        if (typeof handler === "function") {
                            handler.apply(self, args);
                        }

                        if (curOn.emit) {
                            self.emit(curOn.emit, dataContext);
                        }

                        return false;
                    });
                })(curOn);
            }
        }
    }

    for (var key in bind.listen) {
        if (!bind.listen.hasOwnProperty(key)) continue;

        var curListen = bind.listen[key];
        self.on(curListen.name, curListen.miid, self[curListen.handler]);
    }
};

<commit_msg>Added prop dom manipulator. Fixed #2.<commit_after>function findValue (parent, dotNot) {

    if (!dotNot) return undefined;

    var splits = dotNot.split(".");
    var value;

    for (var i = 0; i < splits.length; i++) {
        value = parent[splits[i]];
        if (value === undefined) return undefined;
        if (typeof value === "object") parent = value;
    }

    return value;
}

function findFunction (parent, dotNot) {

    var func = findValue(parent, dotNot);

    if (typeof func !== "function") {
        return undefined;
    }

    return func;
}

var Bind = module.exports = function (bind, dataContext) {

    var self = this;

    var context = $(this.dom);
    if (bind.context) {
        context = $(bind.context, context);
    }
    var target = context;
    if (bind.target) {
        target = $(bind.target, context);
    }

    dataContext = dataContext || {};

    function computeStringOrSourceDataValue(dataType, dataContext) {
        var value = "";
        if (typeof dataType === "string") {
            value = dataType;
        } else {
            value = computeDataValue(dataType, dataContext);
        }
        return value;
    }

    function computeDataValue(dataType, dataContext) {

        var dataSource = undefined;

        // if the source is $ the value the data context will be considered the value
        if (dataType.source === "$") {
            dataSource = dataContext.toString();
        } else {
            dataSource = findValue(dataContext, dataType.source);
        }

        if (dataSource === undefined || dataSource === null) {
            if (typeof dataType["default"] === "string") {
                value = dataType["default"];
            } else {
                value = "?" + dataType.source + "?";
            }
        } else if (typeof dataSource === "object") {
            var locale = M.getLocale();
            value = dataSource[locale] || "Missing value for '" + locale + "' language";
        } else {
            value = dataSource;
        }

        var filterFunction = findFunction(self, dataType.filter) || findFunction(window, dataType.filter);
        if (typeof filterFunction === "function") {
            value = filterFunction(self, dataContext, dataType.source, value);
        }

        return value;
    };

    var domManipulators = {

        // add/modify attribute
        /* Examples:
         *  "binds": [
         *      {
         *          "attr": [
         *              {
         *                  "name": "the_attribute name",
         *                  "value": "a_string_value"
         *              },
         *              {
         *                  "name": "the_attribute name",
         *                  "value": {
         *                      "source": "the_field_value_from_a_source"
         *                  }
         *              },
         *              ...
         *          ]
         *      }
         *  ]
         */
        attr: function(target, context, attrTypes, dataContext) {
            if (!attrTypes || !attrTypes.length) {
                return;
            }
            for (var i = 0; i < attrTypes.length; ++i) {
                var value = computeStringOrSourceDataValue(attrTypes[i].value, dataContext);
                target.attr(attrTypes[i].name, value);
            }
        },

        // add/modify properties
        /* Examples:
         *  "binds": [
         *      {
         *          "prop": [
         *              {
         *                  "name": "prop name",
         *                  "value": "a_string_value"
         *              },
         *              {
         *                  "name": "prop name",
         *                  "value": {
         *                      "source": "the_prop_value_from_a_source"
         *                  }
         *              },
         *              ...
         *          ]
         *      }
         *  ]
         */
        prop: function(target, context, propTypes, dataContext) {
            if (!propTypes || !propTypes.length) {
                return;
            }
            for (var i = 0; i < prop.length; ++i) {
                var value = computeStringOrSourceDataValue(propTypes[i].value, dataContext);
                target.prop(propTypes[i].name, value);
            }
        },

        // add class
        /* Examples:
         *  "binds": [
         *      {
         *          "addClass": [
         *              "class_1",
         *              "class_2",
         *              ...
         *          ]
         *      }
         *  ]
         */
        addClass: function(target, context, classes, dataContext) {
            if (!classes || !classes.length) {
                return;
            }
            for (var i = 0; i < classes.length; ++i) {
                target.addClass(classes[i]);
            }
        },

        // remove class
        /* Examples:
         *  "binds": [
         *      {
         *          "removeClass": [
         *              "class_1",
         *              "class_2",
         *              ...
         *          ]
         *      }
         *  ]
         */
        removeClass: function(target, context, classes, dataContext) {
            if (!classes || !classes.length) {
                return;
            }
            for (var i = 0; i < classes.length; ++i) {
                target.removeClass(classes[i]);
            }
        },

        // innerHTML
        /* Examples:
         *  "binds": [
         *      {
         *          "html": "a_string_value"
         *      },
         *
         *      {
         *          "html": {
         *              "source": "the_field_name_from_a_source"
         *          }
         *      }
         *  ]
         */
        html: function(target, context, dataType, dataContext) {
            var value = computeStringOrSourceDataValue(dataType, dataContext);
            if (value === undefined || value === null) {
                value = '';
            } else {
                value = value.toString();
            }
            target.html(value);
        },

        // repeat the target for each item in array source
        /*
         *   "binds": [
         *       {
         *           "repeat": {
         *               "source": "the_array_name_from_a_source",
         *               "preFilter": "handler_name",
         *               "postFilter": "handler_name",
         *               "binds": [
         *                   ...
         *               ]
         *           }
         *       }
         *   ]
         */
        repeat: function(target, context, bindTemplate, dataContext) {

            if (!target.length) {
                console.warn("Empty bind 'repeat' target");
                return;
            }

            if (typeof dataContext !== "object" || !dataContext) {
                console.warn("A bind 'repeat' can only be used with an object data context");
                return;
            }

            var sourceArray = dataContext[bindTemplate.source] || [];

            if (Object.prototype.toString.call(sourceArray) !== "[object Array]" ) {
                console.warn("A bind 'repeat' did not find an array in the source field of the data context");
                return;
            }

            var template = target.clone();
            var container = target.parent();

            // run the pre-filtering handler
            var filterFunction = findFunction(self, bindTemplate.preFilter) || findFunction(window, bindTemplate.prefilter);
            if (filterFunction) {
                sourceArray = filterFunction(self, dataContext, bindTemplate.source, sourceArray, container);
            }

            // run the binds for each item
            for (var i = 0; i < sourceArray.length; ++i) {

                var newDom = template.clone();

                if (!bindTemplate.binds || !bindTemplate.binds.length) {
                    continue;
                }

                for (var j = 0; j < bindTemplate.binds.length; ++j) {
                    var bind = bindTemplate.binds[j];
                    bind.context = newDom;
                    Bind.call(self, bind, sourceArray[i]);
                }

                container.append(newDom);
            }

            // run the post-filtering handler
            filterFunction = findFunction(self, bindTemplate.postFilter) || findFunction(window, bindTemplate.postFilter);
            if (filterFunction) {
                sourceArray = filterFunction(self, dataContext, bindTemplate.source, sourceArray, container);
            }

            target.remove();
        }
    }

    for (var key in bind) {
        if (!bind.hasOwnProperty(key)) continue;

        if (domManipulators[key]) {
            domManipulators[key](target, context, bind[key], dataContext);
        }
    }

    if (bind.on) {
        for (var i = 0; i < bind.on.length; ++i) {
            var curOn = bind.on[i];
            if (curOn.handler || curOn.emit) {
                (function (curOn) {
                    var t = target;
                    var s = null;

                    // of the delegated option is set, this bind will work for future DOM insertions
                    if (curOn.delegated) {
                        t = context;
                        s = target.selector;
                    }

                    t.on(curOn.name, s,function(event) {
                        event.stopPropagation();

                        var name = curOn.handler;
                        var args = [];

                        if (typeof name === "object") {
                            args = name.args || [];
                            name = name.name;
                        }

                        // if the noEvent option is set, the DOM event will not be passed to the called handler or emitted event
                        if (!curOn.noEvent) {
                            args.push(event);
                        }
                        args.push(dataContext);

                        if (typeof name === "function") {
                            name.apply(self, args);
                            return false;
                        }

                        var handler = findFunction(self, name) || findFunction(window, name);

                        if (typeof handler === "function") {
                            handler.apply(self, args);
                        }

                        if (curOn.emit) {
                            self.emit(curOn.emit, dataContext);
                        }

                        return false;
                    });
                })(curOn);
            }
        }
    }

    for (var key in bind.listen) {
        if (!bind.listen.hasOwnProperty(key)) continue;

        var curListen = bind.listen[key];
        self.on(curListen.name, curListen.miid, self[curListen.handler]);
    }
};<|endoftext|>


<commit_before>'use strict';

var _            = require('lodash'),
    db           = require('larvitdb'),
    log          = require('winston'),
    async        = require('async'),
    events       = require('events'),
    slugify      = require('larvitslugify'),
    dbmigration  = require('larvitdbmigration')({'tableName': 'blog_db_version', 'migrationScriptsPath': __dirname + '/dbmigration'}),
    eventEmitter = new events.EventEmitter(),
    dbChecked    = false;

// Handle database migrations
dbmigration(function(err) {
	if (err) {
		log.error('larvitblog: createTablesIfNotExists() - Database error: ' + err.message);
		return;
	}

	dbChecked = true;
	eventEmitter.emit('checked');
});

/**
 * Get blog entries
 *
 * @param obj options - { // All options are optional!
 *                        'langs': ['sv', 'en'],
 *                        'slugs': ['blu', 'bla'],
 *                        'publishedAfter': dateObj,
 *                        'publishedBefore': dateObj,
 *                        'tags': ['dks', 'ccc'],
 *                        'ids': [32,4],
 *                        'limit': 10,
 *                        'offset': 20
 *                      }
 * @param func cb - callback(err, entries)
 */
function getEntries(options, cb) {
	var tmpEntries = {},
	    dbFields   = [],
	    entries    = [],
	    sql,
	    i;

	if (typeof options === 'function') {
		cb      = options;
		options = {};
	}

	log.debug('larvitblog: getEntries() - Called with options: "' + JSON.stringify(options) + '"');

	// Make sure options that should be arrays actually are arrays
	// This will simplify our lives in the SQL builder below
	if (options.langs !== undefined && ! (options.langs instanceof Array))
		options.langs = [options.langs];

	if (options.ids !== undefined && ! (options.ids instanceof Array))
		options.ids = [options.ids];

	if (options.slugs !== undefined && ! (options.slugs instanceof Array))
		options.slugs = [options.slugs];

	if (options.tags !== undefined && ! (options.tags instanceof Array))
		options.tags = [options.tags];

	// Make sure there is an invalid ID in the id list if it is empty
	// Since the most logical thing to do is replying with an empty set
	if (options.ids instanceof Array && options.ids.length === 0)
		options.ids.push(- 1);

	if (options.limit === undefined)
		options.limit = 10;

	// Make sure the database tables exists before going further!
	if ( ! dbChecked) {
		log.debug('larvitblog: getEntries() - Database not checked, rerunning this method when event have been emitted.');
		eventEmitter.on('checked', function() {
			log.debug('larvitblog: getEntries() - Database check event received, rerunning getEntries().');
			getEntries(options, cb);
		});

		return;
	}

	sql  = 'SELECT ed.*, e.id, e.created, e.published, GROUP_CONCAT(t.content) AS tags, GROUP_CONCAT(i.uri) AS images\n';
	sql += 'FROM blog_entries e\n';
	sql += '	LEFT JOIN blog_entriesData       ed ON ed.entryId = e.id\n';
	sql += '	LEFT JOIN blog_entriesDataTags   t  ON t.entryId  = e.id AND t.lang = ed.lang\n';
	sql += '	LEFT JOIN blog_entriesDataImages i  ON i.entryId  = e.id\n';
	sql += 'WHERE 1 + 1\n';

	// Only get post contents with selected languages
	if (options.langs !== undefined) {
		sql += '	AND ed.lang IN (';

		i = 0;
		while (options.langs[i] !== undefined) {
			sql += '?,';
			dbFields.push(options.langs[i]);

			i ++;
		}

		sql = sql.substring(0, sql.length - 1) + ')\n';
	}

	// Only get posts with the current slugs
	if (options.slugs !== undefined) {
		sql += '	AND e.id IN (SELECT entryId FROM blog_entriesData WHERE slug IN (';

		i = 0;
		while (options.slugs[i] !== undefined) {
			sql += '?,';
			dbFields.push(options.slugs[i]);

			i ++;
		}

		sql = sql.substring(0, sql.length - 1) + '))\n';
	}

	// Only get post contents with selected tags
	if (options.tags !== undefined) {
		sql += '	AND e.id IN (SELECT entryId FROM blog_entriesDataTags WHERE content IN (';

		i = 0;
		while (options.tags[i] !== undefined) {
			sql += '?,';
			dbFields.push(options.tags[i]);

			i ++;
		}

		sql = sql.substring(0, sql.length - 1) + '))\n';
	}

	// Only get posts with given ids
	if (options.ids !== undefined) {
		sql += '	AND e.id IN (';

		i = 0;
		while (options.ids[i] !== undefined) {
			sql += '?,';
			dbFields.push(options.ids[i]);

			i ++;
		}

		sql = sql.substring(0, sql.length - 1) + ')\n';
	}

	// Only get posts published after a certain date
	if (options.publishedAfter) {
		sql += '	AND e.published > ?\n';
		dbFields.push(new Date(options.publishedAfter));
	}

	// Only get posts published before a certain date
	if (options.publishedBefore) {
		sql += '	AND e.published < ?\n';
		dbFields.push(new Date(options.publishedBefore));
	}

	sql += 'GROUP BY e.id, ed.lang\n';
	sql += 'ORDER BY e.published DESC, ed.lang, i.imgNr\n';
	sql += 'LIMIT ' + parseInt(options.limit) + '\n';

	if (options.offset !== undefined)
		sql += ' OFFSET ' + parseInt(options.offset);

	db.query(sql, dbFields, function(err, rows) {
		var entryId,
		    i;

		if (err) {
			cb(err);
			return;
		}

		i = 0;
		while (rows[i] !== undefined) {
			if (tmpEntries[rows[i].id] === undefined) {
				tmpEntries[rows[i].id] = {
					'id': rows[i].id,
					'created': rows[i].created,
					'published': rows[i].published,
					'langs': {}
				};
			}

			tmpEntries[rows[i].id].langs[rows[i].lang] = {
				'header':  rows[i].header,
				'summary': rows[i].summary,
				'body':    rows[i].body,
				'slug':    rows[i].slug,
				'tags':    rows[i].tags,
				'images':  rows[i].images
			};

			i ++;
		}

		for (entryId in tmpEntries) {
			entries.push(tmpEntries[entryId]);
		}

		// Make sure sorting is right
		entries.sort(function(a, b) {
			if (a.published > b.published)
				return - 1;
			if (a.published < b.published)
				return 1;
			return 0;
		});

		cb(null, entries);
	});
};

function getTags(cb) {
	var sql = 'SELECT COUNT(entryId) AS posts, lang, content FROM blog_entriesDataTags GROUP BY lang, content ORDER BY lang, COUNT(entryId) DESC;';

	db.query(sql, function(err, rows) {
		var tags = {'langs': {}},
		    i;

		if (err) {
			cb(err);
			return;
		}

		i = 0;
		while (rows[i] !== undefined) {
			if (tags.langs[rows[i].lang] === undefined)
				tags.langs[rows[i].lang] = [];

			tags.langs[rows[i].lang].push({
				'posts': rows[i].posts,
				'content': rows[i].content
			});

			i ++;
		}

		cb(null, tags);
	});
}

function rmEntry(id, cb) {
	var tasks = [];

	// Make sure the database tables exists before going further!
	if ( ! dbChecked) {
		log.debug('larvitblog: rmEntry() - Database not checked, rerunning this method when event have been emitted.');
		eventEmitter.on('checked', function() {
			log.debug('larvitblog: rmEntry() - Database check event received, rerunning rmEntry().');
			exports.rmEntry(id, cb);
		});

		return;
	}

	tasks.push(function(cb) {
		db.query('DELETE FROM blog_entriesDataTags WHERE entryId = ?', [id], cb);
	});

	tasks.push(function(cb) {
		db.query('DELETE FROM blog_entriesDataImages WHERE entryId = ?', [id], cb);
	});

	tasks.push(function(cb) {
		db.query('DELETE FROM blog_entriesData WHERE entryId = ?', [id], cb);
	});

	tasks.push(function(cb) {
		db.query('DELETE FROM blog_entries WHERE id = ?', [id], cb);
	});

	async.series(tasks, cb);
}

/**
 * Save an entry
 *
 * @param obj data - { // All options are optional!
 *                     'id': 1323,
 *                     'published': dateObj,
 *                     'langs': {
 *                       'en': {
 *                         'header': 'foo',
 *                         'slug': 'bar',
 *                         'summary': 'lots of foo and bars'
 *                         'body': 'even more foos and bars'
 *                         'tags': 'comma,separated,string'
 *                       },
 *                       'sv' ...
 *                     }
 *                   }
 * @param func cb(err, entry) - the entry will be a row from getEntries()
 */
function saveEntry(data, cb) {
	var tasks = [],
	    lang;

	if (typeof data === 'function') {
		cb   = data;
		data = {};
	}

	log.verbose('larvitblog: saveEntry() - Running with data. "' + JSON.stringify(data) + '"');

	// Make sure the database tables exists before going further!
	if ( ! dbChecked) {
		log.debug('larvitblog: saveEntry() - Database not checked, rerunning this method when event have been emitted.');
		eventEmitter.on('checked', function() {
			log.debug('larvitblog: saveEntry() - Database check event received, rerunning saveEntry().');
			exports.saveEntry(data, cb);
		});

		return;
	}

	// Create a new post id is not set
	if (data.id === undefined) {
		tasks.push(function(cb) {
			var sql      = 'INSERT INTO blog_entries (created',
				  dbFields = [];

			if (data.published)
				sql += ', published';

			sql += ') VALUES(NOW()';

			if (data.published) {
				sql += ',?';
				dbFields.push(data.published);
			}

			sql += ');';

			db.query(sql, dbFields, function(err, result) {
				if (err) {
					cb(err);
					return;
				}

				log.debug('larvitblog: saveEntry() - New blog entry created with id: "' + result.insertId + '"');
				data.id = result.insertId;
				cb();
			});
		});
	} else {
		// Erase previous data
		tasks.push(function(cb) {
			db.query('DELETE FROM blog_entriesData WHERE entryId = ?', [parseInt(data.id)], cb);
		});

		// Set published
		if (data.published !== undefined) {
			tasks.push(function(cb) {
				var sql      = 'UPDATE blog_entries SET published = ? WHERE id = ?',
				    dbFields = [data.published, data.id];

				db.query(sql, dbFields, cb);
			});
		}
	}

	// We need to declare this outside the loop because of async operations
	function addEntryData(lang, header, summary, body, slug) {
		tasks.push(function(cb) {
			var sql      = 'INSERT INTO blog_entriesData (entryId, lang, header, summary, body, slug) VALUES(?,?,?,?,?,?);',
			    dbFields = [data.id, lang, header, summary, body, slug];

			db.query(sql, dbFields, cb);
		});
	}

	function addTagData(lang, content) {
		tasks.push(function(cb) {
			var sql      = 'INSERT INTO blog_entriesDataTags (entryId, lang, content) VALUES(?,?,?);',
			    dbFields = [data.id, lang, content];

			db.query(sql, dbFields, cb);
		});
	}

	// Add content data
	if (data.langs) {
		tasks.push(function(cb) {
			db.query('DELETE FROM blog_entriesDataTags WHERE entryId = ?', [data.id], cb);
		});

		for (lang in data.langs) {
			if (data.langs[lang].slug)
				data.langs[lang].slug = slugify(data.langs[lang].slug, {'save': '/'});

			if (data.langs[lang].header || data.langs[lang].body || data.langs[lang].summary) {
				addEntryData(lang, data.langs[lang].header, data.langs[lang].summary, data.langs[lang].body, data.langs[lang].slug);

				if (data.langs[lang].tags) {
					_.each(data.langs[lang].tags.split(','), function(tagContent) {
						addTagData(lang, _.trim(tagContent));
					});
				}
			}
		}
	}

	async.series(tasks, function(err) {
		if (err) {
			cb(err);
			return;
		}

		// Re-read this entry from the database to be sure to get the right deal!
		getEntries({'ids': data.id}, function(err, entries) {
			if (err) {
				cb(err);
				return;
			}

			cb(null, entries[0]);
		});
	});
};

exports.getEntries = getEntries;
exports.getTags    = getTags;
exports.rmEntry    = rmEntry;
exports.saveEntry  = saveEntry;<commit_msg>Fixed duplicate issue in SQL<commit_after>'use strict';

var _            = require('lodash'),
    db           = require('larvitdb'),
    log          = require('winston'),
    async        = require('async'),
    events       = require('events'),
    slugify      = require('larvitslugify'),
    dbmigration  = require('larvitdbmigration')({'tableName': 'blog_db_version', 'migrationScriptsPath': __dirname + '/dbmigration'}),
    eventEmitter = new events.EventEmitter(),
    dbChecked    = false;

// Handle database migrations
dbmigration(function(err) {
	if (err) {
		log.error('larvitblog: createTablesIfNotExists() - Database error: ' + err.message);
		return;
	}

	dbChecked = true;
	eventEmitter.emit('checked');
});

/**
 * Get blog entries
 *
 * @param obj options - { // All options are optional!
 *                        'langs': ['sv', 'en'],
 *                        'slugs': ['blu', 'bla'],
 *                        'publishedAfter': dateObj,
 *                        'publishedBefore': dateObj,
 *                        'tags': ['dks', 'ccc'],
 *                        'ids': [32,4],
 *                        'limit': 10,
 *                        'offset': 20
 *                      }
 * @param func cb - callback(err, entries)
 */
function getEntries(options, cb) {
	var tmpEntries = {},
	    dbFields   = [],
	    entries    = [],
	    sql,
	    i;

	if (typeof options === 'function') {
		cb      = options;
		options = {};
	}

	log.debug('larvitblog: getEntries() - Called with options: "' + JSON.stringify(options) + '"');

	// Make sure options that should be arrays actually are arrays
	// This will simplify our lives in the SQL builder below
	if (options.langs !== undefined && ! (options.langs instanceof Array))
		options.langs = [options.langs];

	if (options.ids !== undefined && ! (options.ids instanceof Array))
		options.ids = [options.ids];

	if (options.slugs !== undefined && ! (options.slugs instanceof Array))
		options.slugs = [options.slugs];

	if (options.tags !== undefined && ! (options.tags instanceof Array))
		options.tags = [options.tags];

	// Make sure there is an invalid ID in the id list if it is empty
	// Since the most logical thing to do is replying with an empty set
	if (options.ids instanceof Array && options.ids.length === 0)
		options.ids.push(- 1);

	if (options.limit === undefined)
		options.limit = 10;

	// Make sure the database tables exists before going further!
	if ( ! dbChecked) {
		log.debug('larvitblog: getEntries() - Database not checked, rerunning this method when event have been emitted.');
		eventEmitter.on('checked', function() {
			log.debug('larvitblog: getEntries() - Database check event received, rerunning getEntries().');
			getEntries(options, cb);
		});

		return;
	}

	sql  = 'SELECT ed.*, e.id, e.created, e.published, GROUP_CONCAT(DISTINCT t.content) AS tags, GROUP_CONCAT(DISTINCT i.uri) AS images\n';
	sql += 'FROM blog_entries e\n';
	sql += '	LEFT JOIN blog_entriesData       ed ON ed.entryId = e.id\n';
	sql += '	LEFT JOIN blog_entriesDataTags   t  ON t.entryId  = e.id AND t.lang = ed.lang\n';
	sql += '	LEFT JOIN blog_entriesDataImages i  ON i.entryId  = e.id\n';
	sql += 'WHERE 1 + 1\n';

	// Only get post contents with selected languages
	if (options.langs !== undefined) {
		sql += '	AND ed.lang IN (';

		i = 0;
		while (options.langs[i] !== undefined) {
			sql += '?,';
			dbFields.push(options.langs[i]);

			i ++;
		}

		sql = sql.substring(0, sql.length - 1) + ')\n';
	}

	// Only get posts with the current slugs
	if (options.slugs !== undefined) {
		sql += '	AND e.id IN (SELECT entryId FROM blog_entriesData WHERE slug IN (';

		i = 0;
		while (options.slugs[i] !== undefined) {
			sql += '?,';
			dbFields.push(options.slugs[i]);

			i ++;
		}

		sql = sql.substring(0, sql.length - 1) + '))\n';
	}

	// Only get post contents with selected tags
	if (options.tags !== undefined) {
		sql += '	AND e.id IN (SELECT entryId FROM blog_entriesDataTags WHERE content IN (';

		i = 0;
		while (options.tags[i] !== undefined) {
			sql += '?,';
			dbFields.push(options.tags[i]);

			i ++;
		}

		sql = sql.substring(0, sql.length - 1) + '))\n';
	}

	// Only get posts with given ids
	if (options.ids !== undefined) {
		sql += '	AND e.id IN (';

		i = 0;
		while (options.ids[i] !== undefined) {
			sql += '?,';
			dbFields.push(options.ids[i]);

			i ++;
		}

		sql = sql.substring(0, sql.length - 1) + ')\n';
	}

	// Only get posts published after a certain date
	if (options.publishedAfter) {
		sql += '	AND e.published > ?\n';
		dbFields.push(new Date(options.publishedAfter));
	}

	// Only get posts published before a certain date
	if (options.publishedBefore) {
		sql += '	AND e.published < ?\n';
		dbFields.push(new Date(options.publishedBefore));
	}

	sql += 'GROUP BY e.id, ed.lang\n';
	sql += 'ORDER BY e.published DESC, ed.lang, i.imgNr\n';
	sql += 'LIMIT ' + parseInt(options.limit) + '\n';

	if (options.offset !== undefined)
		sql += ' OFFSET ' + parseInt(options.offset);

	db.query(sql, dbFields, function(err, rows) {
		var entryId,
		    i;

		if (err) {
			cb(err);
			return;
		}

		i = 0;
		while (rows[i] !== undefined) {
			if (tmpEntries[rows[i].id] === undefined) {
				tmpEntries[rows[i].id] = {
					'id': rows[i].id,
					'created': rows[i].created,
					'published': rows[i].published,
					'langs': {}
				};
			}

			tmpEntries[rows[i].id].langs[rows[i].lang] = {
				'header':  rows[i].header,
				'summary': rows[i].summary,
				'body':    rows[i].body,
				'slug':    rows[i].slug,
				'tags':    rows[i].tags,
				'images':  rows[i].images
			};

			i ++;
		}

		for (entryId in tmpEntries) {
			entries.push(tmpEntries[entryId]);
		}

		// Make sure sorting is right
		entries.sort(function(a, b) {
			if (a.published > b.published)
				return - 1;
			if (a.published < b.published)
				return 1;
			return 0;
		});

		cb(null, entries);
	});
};

function getTags(cb) {
	var sql = 'SELECT COUNT(entryId) AS posts, lang, content FROM blog_entriesDataTags GROUP BY lang, content ORDER BY lang, COUNT(entryId) DESC;';

	db.query(sql, function(err, rows) {
		var tags = {'langs': {}},
		    i;

		if (err) {
			cb(err);
			return;
		}

		i = 0;
		while (rows[i] !== undefined) {
			if (tags.langs[rows[i].lang] === undefined)
				tags.langs[rows[i].lang] = [];

			tags.langs[rows[i].lang].push({
				'posts': rows[i].posts,
				'content': rows[i].content
			});

			i ++;
		}

		cb(null, tags);
	});
}

function rmEntry(id, cb) {
	var tasks = [];

	// Make sure the database tables exists before going further!
	if ( ! dbChecked) {
		log.debug('larvitblog: rmEntry() - Database not checked, rerunning this method when event have been emitted.');
		eventEmitter.on('checked', function() {
			log.debug('larvitblog: rmEntry() - Database check event received, rerunning rmEntry().');
			exports.rmEntry(id, cb);
		});

		return;
	}

	tasks.push(function(cb) {
		db.query('DELETE FROM blog_entriesDataTags WHERE entryId = ?', [id], cb);
	});

	tasks.push(function(cb) {
		db.query('DELETE FROM blog_entriesDataImages WHERE entryId = ?', [id], cb);
	});

	tasks.push(function(cb) {
		db.query('DELETE FROM blog_entriesData WHERE entryId = ?', [id], cb);
	});

	tasks.push(function(cb) {
		db.query('DELETE FROM blog_entries WHERE id = ?', [id], cb);
	});

	async.series(tasks, cb);
}

/**
 * Save an entry
 *
 * @param obj data - { // All options are optional!
 *                     'id': 1323,
 *                     'published': dateObj,
 *                     'langs': {
 *                       'en': {
 *                         'header': 'foo',
 *                         'slug': 'bar',
 *                         'summary': 'lots of foo and bars'
 *                         'body': 'even more foos and bars'
 *                         'tags': 'comma,separated,string'
 *                       },
 *                       'sv' ...
 *                     }
 *                   }
 * @param func cb(err, entry) - the entry will be a row from getEntries()
 */
function saveEntry(data, cb) {
	var tasks = [],
	    lang;

	if (typeof data === 'function') {
		cb   = data;
		data = {};
	}

	log.verbose('larvitblog: saveEntry() - Running with data. "' + JSON.stringify(data) + '"');

	// Make sure the database tables exists before going further!
	if ( ! dbChecked) {
		log.debug('larvitblog: saveEntry() - Database not checked, rerunning this method when event have been emitted.');
		eventEmitter.on('checked', function() {
			log.debug('larvitblog: saveEntry() - Database check event received, rerunning saveEntry().');
			exports.saveEntry(data, cb);
		});

		return;
	}

	// Create a new post id is not set
	if (data.id === undefined) {
		tasks.push(function(cb) {
			var sql      = 'INSERT INTO blog_entries (created',
				  dbFields = [];

			if (data.published)
				sql += ', published';

			sql += ') VALUES(NOW()';

			if (data.published) {
				sql += ',?';
				dbFields.push(data.published);
			}

			sql += ');';

			db.query(sql, dbFields, function(err, result) {
				if (err) {
					cb(err);
					return;
				}

				log.debug('larvitblog: saveEntry() - New blog entry created with id: "' + result.insertId + '"');
				data.id = result.insertId;
				cb();
			});
		});
	} else {
		// Erase previous data
		tasks.push(function(cb) {
			db.query('DELETE FROM blog_entriesData WHERE entryId = ?', [parseInt(data.id)], cb);
		});

		// Set published
		if (data.published !== undefined) {
			tasks.push(function(cb) {
				var sql      = 'UPDATE blog_entries SET published = ? WHERE id = ?',
				    dbFields = [data.published, data.id];

				db.query(sql, dbFields, cb);
			});
		}
	}

	// We need to declare this outside the loop because of async operations
	function addEntryData(lang, header, summary, body, slug) {
		tasks.push(function(cb) {
			var sql      = 'INSERT INTO blog_entriesData (entryId, lang, header, summary, body, slug) VALUES(?,?,?,?,?,?);',
			    dbFields = [data.id, lang, header, summary, body, slug];

			db.query(sql, dbFields, cb);
		});
	}

	function addTagData(lang, content) {
		tasks.push(function(cb) {
			var sql      = 'INSERT INTO blog_entriesDataTags (entryId, lang, content) VALUES(?,?,?);',
			    dbFields = [data.id, lang, content];

			db.query(sql, dbFields, cb);
		});
	}

	// Add content data
	if (data.langs) {
		tasks.push(function(cb) {
			db.query('DELETE FROM blog_entriesDataTags WHERE entryId = ?', [data.id], cb);
		});

		for (lang in data.langs) {
			if (data.langs[lang].slug)
				data.langs[lang].slug = slugify(data.langs[lang].slug, {'save': '/'});

			if (data.langs[lang].header || data.langs[lang].body || data.langs[lang].summary) {
				addEntryData(lang, data.langs[lang].header, data.langs[lang].summary, data.langs[lang].body, data.langs[lang].slug);

				if (data.langs[lang].tags) {
					_.each(data.langs[lang].tags.split(','), function(tagContent) {
						addTagData(lang, _.trim(tagContent));
					});
				}
			}
		}
	}

	async.series(tasks, function(err) {
		if (err) {
			cb(err);
			return;
		}

		// Re-read this entry from the database to be sure to get the right deal!
		getEntries({'ids': data.id}, function(err, entries) {
			if (err) {
				cb(err);
				return;
			}

			cb(null, entries[0]);
		});
	});
};

exports.getEntries = getEntries;
exports.getTags    = getTags;
exports.rmEntry    = rmEntry;
exports.saveEntry  = saveEntry;<|endoftext|>


<commit_before>appName.define("buzz", ["foo", "bar"], function(){

	function okThen(who) {
        return "Ok then, " + who;
    }

    return {
        okThen: okThen
    };

});<commit_msg>Edited indentation and added use strict.<commit_after>'use strict';

appName.define("buzz", ["foo", "bar"], function(){

  function okThen(who) {
    return "Ok then, " + who;
  };

  return {
    okThen: okThen
  };

});<|endoftext|>


<commit_before>/* global $, Util, connection, nickname:true, getVideoSize, getVideoPosition, showToolbar, processReplacements */
/**
 * Chat related user interface.
 */
var Chat = (function (my) {
    var notificationInterval = false;
    var unreadMessages = 0;

    /**
     * Initializes chat related interface.
     */
    my.init = function () {
        var storedDisplayName = window.localStorage.displayname;
        if (storedDisplayName) {
            nickname = storedDisplayName;

            Chat.setChatConversationMode(true);
        }

        $('#nickinput').keydown(function (event) {
            if (event.keyCode === 13) {
                event.preventDefault();
                var val = Util.escapeHtml(this.value);
                this.value = '';
                if (!nickname) {
                    nickname = val;
                    window.localStorage.displayname = nickname;

                    connection.emuc.addDisplayNameToPresence(nickname);
                    connection.emuc.sendPresence();

                    Chat.setChatConversationMode(true);

                    return;
                }
            }
        });

        $('#usermsg').keydown(function (event) {
            if (event.keyCode === 13) {
                event.preventDefault();
                var value = this.value;
                $('#usermsg').val('').trigger('autosize.resize');
                this.focus();
                var command = new CommandsProcessor(value);
                if(command.isCommand())
                {
                    command.processCommand();
                }
                else
                {
                    var message = Util.escapeHtml(value);
                    connection.emuc.sendMessage(message, nickname);
                }
            }
        });

        var onTextAreaResize = function () {
            resizeChatConversation();
            Chat.scrollChatToBottom();
        };
        $('#usermsg').autosize({callback: onTextAreaResize});

        $("#chatspace").bind("shown",
            function () {
                unreadMessages = 0;
                setVisualNotification(false);
            });

        addSmileys();
    };

    /**
     * Appends the given message to the chat conversation.
     */
    my.updateChatConversation = function (from, displayName, message) {
        var divClassName = '';

        if (connection.emuc.myroomjid === from) {
            divClassName = "localuser";
        }
        else {
            divClassName = "remoteuser";

            if (!Chat.isVisible()) {
                unreadMessages++;
                Util.playSoundNotification('chatNotification');
                setVisualNotification(true);
            }
        }

        //replace links and smileys
        var escMessage = Util.escapeHtml(message);
        var escDisplayName = Util.escapeHtml(displayName);
        message = processReplacements(escMessage);

        var messageContainer =
            '
'+
                '' +
                '
' + escDisplayName + '
' +
                '
' + getCurrentTime() + '
' +
                '
' + message + '
' +
            '
';

        $('#chatconversation').append(messageContainer);
        $('#chatconversation').animate(
                { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
    };

    /**
     * Appends error message to the conversation
     * @param errorMessage the received error message.
     * @param originalText the original message.
     */
    my.chatAddError = function(errorMessage, originalText)
    {
        errorMessage = Util.escapeHtml(errorMessage);
        originalText = Util.escapeHtml(originalText);

        $('#chatconversation').append('
Error: '
            + 'Your message' + (originalText? (' \"'+ originalText + '\"') : "")
            + ' was not sent.' + (errorMessage? (' Reason: ' + errorMessage) : '')
            +  '
');
        $('#chatconversation').animate(
            { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
    };

    /**
     * Sets the subject to the UI
     * @param subject the subject
     */
    my.chatSetSubject = function(subject)
    {
        if(subject)
            subject = subject.trim();
        $('#subject').html(linkify(Util.escapeHtml(subject)));
        if(subject == "")
        {
            $("#subject").css({display: "none"});
        }
        else
        {
            $("#subject").css({display: "block"});
        }
    };

    /**
     * Sets the chat conversation mode.
     */
    my.setChatConversationMode = function (isConversationMode) {
        if (isConversationMode) {
            $('#nickname').css({visibility: 'hidden'});
            $('#chatconversation').css({visibility: 'visible'});
            $('#usermsg').css({visibility: 'visible'});
            $('#smileysarea').css({visibility: 'visible'});
            $('#usermsg').focus();
        }
    };

    /**
     * Resizes the chat area.
     */
    my.resizeChat = function () {
        var chatSize = PanelToggler.getPanelSize();

        $('#chatspace').width(chatSize[0]);
        $('#chatspace').height(chatSize[1]);

        resizeChatConversation();
    };

    /**
     * Indicates if the chat is currently visible.
     */
    my.isVisible = function () {
        return $('#chatspace').is(":visible");
    };
    /**
     * Shows and hides the window with the smileys
     */
    my.toggleSmileys = function() {
        var smileys = $('#smileysContainer');
        if(!smileys.is(':visible')) {
            smileys.show("slide", { direction: "down", duration: 300});
        } else {
            smileys.hide("slide", { direction: "down", duration: 300});
        }
        $('#usermsg').focus();
    };

    /**
     * Scrolls chat to the bottom.
     */
    my.scrollChatToBottom = function() {
        setTimeout(function () {
            $('#chatconversation').scrollTop(
                $('#chatconversation')[0].scrollHeight);
        }, 5);
    };

    /**
     * Adds the smileys container to the chat
     */
    function addSmileys() {
        var smileysContainer = document.createElement('div');
        smileysContainer.id = 'smileysContainer';
        function addClickFunction(smiley, number) {
            smiley.onclick = function addSmileyToMessage() {
                var usermsg = $('#usermsg');
                var message = usermsg.val();
                message += smileys['smiley' + number];
                usermsg.val(message);
                usermsg.get(0).setSelectionRange(message.length, message.length);
                Chat.toggleSmileys();
                usermsg.focus();
            };
        }
        for(var i = 1; i <= 21; i++) {
            var smileyContainer = document.createElement('div');
            smileyContainer.id = 'smiley' + i;
            smileyContainer.className = 'smileyContainer';
            var smiley = document.createElement('img');
            smiley.src = 'images/smileys/smiley' + i + '.svg';
            smiley.className =  'smiley';
            addClickFunction(smiley, i);
            smileyContainer.appendChild(smiley);
            smileysContainer.appendChild(smileyContainer);
        }

        $("#chatspace").append(smileysContainer);
    }

    /**
     * Resizes the chat conversation.
     */
    function resizeChatConversation() {
        var msgareaHeight = $('#usermsg').outerHeight();
        var chatspace = $('#chatspace');
        var width = chatspace.width();
        var chat = $('#chatconversation');
        var smileys = $('#smileysarea');

        smileys.height(msgareaHeight);
        $("#smileys").css('bottom', (msgareaHeight - 26) / 2);
        $('#smileysContainer').css('bottom', msgareaHeight);
        chat.width(width - 10);
        chat.height(window.innerHeight - 15 - msgareaHeight);
    }

    /**
     * Shows/hides a visual notification, indicating that a message has arrived.
     */
    function setVisualNotification(show) {
        var unreadMsgElement = document.getElementById('unreadMessages');
        var unreadMsgBottomElement = document.getElementById('bottomUnreadMessages');

        var glower = $('#chatButton');
        var bottomGlower = $('#chatBottomButton');

        if (unreadMessages) {
            unreadMsgElement.innerHTML = unreadMessages.toString();
            unreadMsgBottomElement.innerHTML = unreadMessages.toString();

            ToolbarToggler.dockToolbar(true);

            var chatButtonElement
                = document.getElementById('chatButton').parentNode;
            var leftIndent = (Util.getTextWidth(chatButtonElement) -
                Util.getTextWidth(unreadMsgElement)) / 2;
            var topIndent = (Util.getTextHeight(chatButtonElement) -
                Util.getTextHeight(unreadMsgElement)) / 2 - 3;

            unreadMsgElement.setAttribute(
                'style',
                    'top:' + topIndent +
                    '; left:' + leftIndent + ';');

            var chatBottomButtonElement
                = document.getElementById('chatBottomButton').parentNode;
            var bottomLeftIndent = (Util.getTextWidth(chatBottomButtonElement) -
                Util.getTextWidth(unreadMsgBottomElement)) / 2;
            var bottomTopIndent = (Util.getTextHeight(chatBottomButtonElement) -
                Util.getTextHeight(unreadMsgBottomElement)) / 2 - 2;

            unreadMsgBottomElement.setAttribute(
                'style',
                    'top:' + bottomTopIndent +
                    '; left:' + bottomLeftIndent + ';');

            if (!glower.hasClass('icon-chat-simple')) {
                glower.removeClass('icon-chat');
                glower.addClass('icon-chat-simple');
            }
        }
        else {
            unreadMsgElement.innerHTML = '';
            unreadMsgBottomElement.innerHTML = '';
            glower.removeClass('icon-chat-simple');
            glower.addClass('icon-chat');
        }

        if (show && !notificationInterval) {
            notificationInterval = window.setInterval(function () {
                glower.toggleClass('active');
                bottomGlower.toggleClass('active glowing');
            }, 800);
        }
        else if (!show && notificationInterval) {
            window.clearInterval(notificationInterval);
            notificationInterval = false;
            glower.removeClass('active');
            bottomGlower.removeClass('glowing');
            bottomGlower.addClass('active');
        }
    }

    /**
     * Returns the current time in the format it is shown to the user
     * @returns {string}
     */
    function getCurrentTime() {
        var now     = new Date();
        var hour    = now.getHours();
        var minute  = now.getMinutes();
        var second  = now.getSeconds();
        if(hour.toString().length === 1) {
            hour = '0'+hour;
        }
        if(minute.toString().length === 1) {
            minute = '0'+minute;
        }
        if(second.toString().length === 1) {
            second = '0'+second;
        }
        return hour+':'+minute+':'+second;
    }

    return my;
}(Chat || {}));
<commit_msg>Fixes chat messages<commit_after>/* global $, Util, connection, nickname:true, getVideoSize, getVideoPosition, showToolbar, processReplacements */
/**
 * Chat related user interface.
 */
var Chat = (function (my) {
    var notificationInterval = false;
    var unreadMessages = 0;

    /**
     * Initializes chat related interface.
     */
    my.init = function () {
        var storedDisplayName = window.localStorage.displayname;
        if (storedDisplayName) {
            nickname = storedDisplayName;

            Chat.setChatConversationMode(true);
        }

        $('#nickinput').keydown(function (event) {
            if (event.keyCode === 13) {
                event.preventDefault();
                var val = Util.escapeHtml(this.value);
                this.value = '';
                if (!nickname) {
                    nickname = val;
                    window.localStorage.displayname = nickname;

                    connection.emuc.addDisplayNameToPresence(nickname);
                    connection.emuc.sendPresence();

                    Chat.setChatConversationMode(true);

                    return;
                }
            }
        });

        $('#usermsg').keydown(function (event) {
            if (event.keyCode === 13) {
                event.preventDefault();
                var value = this.value;
                $('#usermsg').val('').trigger('autosize.resize');
                this.focus();
                var command = new CommandsProcessor(value);
                if(command.isCommand())
                {
                    command.processCommand();
                }
                else
                {
                    var message = Util.escapeHtml(value);
                    connection.emuc.sendMessage(message, nickname);
                }
            }
        });

        var onTextAreaResize = function () {
            resizeChatConversation();
            Chat.scrollChatToBottom();
        };
        $('#usermsg').autosize({callback: onTextAreaResize});

        $("#chatspace").bind("shown",
            function () {
                unreadMessages = 0;
                setVisualNotification(false);
            });

        addSmileys();
    };

    /**
     * Appends the given message to the chat conversation.
     */
    my.updateChatConversation = function (from, displayName, message) {
        var divClassName = '';

        if (connection.emuc.myroomjid === from) {
            divClassName = "localuser";
        }
        else {
            divClassName = "remoteuser";

            if (!Chat.isVisible()) {
                unreadMessages++;
                Util.playSoundNotification('chatNotification');
                setVisualNotification(true);
            }
        }

        //replace links and smileys
        var escMessage = message.replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '
'); //Strophe already escapes special symbols on sending, so we escape here only tags to avoid double &
        var escDisplayName = Util.escapeHtml(displayName);
        message = processReplacements(escMessage);

        var messageContainer =
            '
'+
                '' +
                '
' + escDisplayName + '
' +
                '
' + getCurrentTime() + '
' +
                '
' + message + '
' +
            '
';

        $('#chatconversation').append(messageContainer);
        $('#chatconversation').animate(
                { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
    };

    /**
     * Appends error message to the conversation
     * @param errorMessage the received error message.
     * @param originalText the original message.
     */
    my.chatAddError = function(errorMessage, originalText)
    {
        errorMessage = Util.escapeHtml(errorMessage);
        originalText = Util.escapeHtml(originalText);

        $('#chatconversation').append('
Error: '
            + 'Your message' + (originalText? (' \"'+ originalText + '\"') : "")
            + ' was not sent.' + (errorMessage? (' Reason: ' + errorMessage) : '')
            +  '
');
        $('#chatconversation').animate(
            { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
    };

    /**
     * Sets the subject to the UI
     * @param subject the subject
     */
    my.chatSetSubject = function(subject)
    {
        if(subject)
            subject = subject.trim();
        $('#subject').html(linkify(Util.escapeHtml(subject)));
        if(subject == "")
        {
            $("#subject").css({display: "none"});
        }
        else
        {
            $("#subject").css({display: "block"});
        }
    };

    /**
     * Sets the chat conversation mode.
     */
    my.setChatConversationMode = function (isConversationMode) {
        if (isConversationMode) {
            $('#nickname').css({visibility: 'hidden'});
            $('#chatconversation').css({visibility: 'visible'});
            $('#usermsg').css({visibility: 'visible'});
            $('#smileysarea').css({visibility: 'visible'});
            $('#usermsg').focus();
        }
    };

    /**
     * Resizes the chat area.
     */
    my.resizeChat = function () {
        var chatSize = PanelToggler.getPanelSize();

        $('#chatspace').width(chatSize[0]);
        $('#chatspace').height(chatSize[1]);

        resizeChatConversation();
    };

    /**
     * Indicates if the chat is currently visible.
     */
    my.isVisible = function () {
        return $('#chatspace').is(":visible");
    };
    /**
     * Shows and hides the window with the smileys
     */
    my.toggleSmileys = function() {
        var smileys = $('#smileysContainer');
        if(!smileys.is(':visible')) {
            smileys.show("slide", { direction: "down", duration: 300});
        } else {
            smileys.hide("slide", { direction: "down", duration: 300});
        }
        $('#usermsg').focus();
    };

    /**
     * Scrolls chat to the bottom.
     */
    my.scrollChatToBottom = function() {
        setTimeout(function () {
            $('#chatconversation').scrollTop(
                $('#chatconversation')[0].scrollHeight);
        }, 5);
    };

    /**
     * Adds the smileys container to the chat
     */
    function addSmileys() {
        var smileysContainer = document.createElement('div');
        smileysContainer.id = 'smileysContainer';
        function addClickFunction(smiley, number) {
            smiley.onclick = function addSmileyToMessage() {
                var usermsg = $('#usermsg');
                var message = usermsg.val();
                message += smileys['smiley' + number];
                usermsg.val(message);
                usermsg.get(0).setSelectionRange(message.length, message.length);
                Chat.toggleSmileys();
                usermsg.focus();
            };
        }
        for(var i = 1; i <= 21; i++) {
            var smileyContainer = document.createElement('div');
            smileyContainer.id = 'smiley' + i;
            smileyContainer.className = 'smileyContainer';
            var smiley = document.createElement('img');
            smiley.src = 'images/smileys/smiley' + i + '.svg';
            smiley.className =  'smiley';
            addClickFunction(smiley, i);
            smileyContainer.appendChild(smiley);
            smileysContainer.appendChild(smileyContainer);
        }

        $("#chatspace").append(smileysContainer);
    }

    /**
     * Resizes the chat conversation.
     */
    function resizeChatConversation() {
        var msgareaHeight = $('#usermsg').outerHeight();
        var chatspace = $('#chatspace');
        var width = chatspace.width();
        var chat = $('#chatconversation');
        var smileys = $('#smileysarea');

        smileys.height(msgareaHeight);
        $("#smileys").css('bottom', (msgareaHeight - 26) / 2);
        $('#smileysContainer').css('bottom', msgareaHeight);
        chat.width(width - 10);
        chat.height(window.innerHeight - 15 - msgareaHeight);
    }

    /**
     * Shows/hides a visual notification, indicating that a message has arrived.
     */
    function setVisualNotification(show) {
        var unreadMsgElement = document.getElementById('unreadMessages');
        var unreadMsgBottomElement = document.getElementById('bottomUnreadMessages');

        var glower = $('#chatButton');
        var bottomGlower = $('#chatBottomButton');

        if (unreadMessages) {
            unreadMsgElement.innerHTML = unreadMessages.toString();
            unreadMsgBottomElement.innerHTML = unreadMessages.toString();

            ToolbarToggler.dockToolbar(true);

            var chatButtonElement
                = document.getElementById('chatButton').parentNode;
            var leftIndent = (Util.getTextWidth(chatButtonElement) -
                Util.getTextWidth(unreadMsgElement)) / 2;
            var topIndent = (Util.getTextHeight(chatButtonElement) -
                Util.getTextHeight(unreadMsgElement)) / 2 - 3;

            unreadMsgElement.setAttribute(
                'style',
                    'top:' + topIndent +
                    '; left:' + leftIndent + ';');

            var chatBottomButtonElement
                = document.getElementById('chatBottomButton').parentNode;
            var bottomLeftIndent = (Util.getTextWidth(chatBottomButtonElement) -
                Util.getTextWidth(unreadMsgBottomElement)) / 2;
            var bottomTopIndent = (Util.getTextHeight(chatBottomButtonElement) -
                Util.getTextHeight(unreadMsgBottomElement)) / 2 - 2;

            unreadMsgBottomElement.setAttribute(
                'style',
                    'top:' + bottomTopIndent +
                    '; left:' + bottomLeftIndent + ';');

            if (!glower.hasClass('icon-chat-simple')) {
                glower.removeClass('icon-chat');
                glower.addClass('icon-chat-simple');
            }
        }
        else {
            unreadMsgElement.innerHTML = '';
            unreadMsgBottomElement.innerHTML = '';
            glower.removeClass('icon-chat-simple');
            glower.addClass('icon-chat');
        }

        if (show && !notificationInterval) {
            notificationInterval = window.setInterval(function () {
                glower.toggleClass('active');
                bottomGlower.toggleClass('active glowing');
            }, 800);
        }
        else if (!show && notificationInterval) {
            window.clearInterval(notificationInterval);
            notificationInterval = false;
            glower.removeClass('active');
            bottomGlower.removeClass('glowing');
            bottomGlower.addClass('active');
        }
    }

    /**
     * Returns the current time in the format it is shown to the user
     * @returns {string}
     */
    function getCurrentTime() {
        var now     = new Date();
        var hour    = now.getHours();
        var minute  = now.getMinutes();
        var second  = now.getSeconds();
        if(hour.toString().length === 1) {
            hour = '0'+hour;
        }
        if(minute.toString().length === 1) {
            minute = '0'+minute;
        }
        if(second.toString().length === 1) {
            second = '0'+second;
        }
        return hour+':'+minute+':'+second;
    }

    return my;
}(Chat || {}));
<|endoftext|>


<commit_before>var net          = require('net'),
    EventEmitter = require('events').EventEmitter,
    carry        = require('carrier').carry;

module.exports = function (conn_opts, opts, continuation) {

  var self = new EventEmitter();

  var timeout = opts && opts.timeout || 5;

  var async_id = 0,
      async_cb = {};

  var alive = false;

  var session = net.connect(conn_opts, function () {

    /* Init asynchronous session. */

    session.write('nIDSESSION\n');
    alive = true;

    /* Call the continuation, if given. */

    if (typeof continuation === 'function') {
      continuation.call(self);
    }

  });

  /* Register callbacks for line-based reading and
     end, close, error. */

  carry(session, function (line) {
    var match = line.match(/^([0-9]+): (.+)/);
    if (match !== null && typeof async_cb[match[1]] === 'function') {
      setTimeout(function () { async_cb[match[1]](match[2]); }, 0);
    }
  });

  session.on('close', function (had_error) {
    alive = false;
    self.emit('close', had_error);
  });

  session.on('error', function (err) {
    self.emit('error', err);
  });

  /* Functions for low-level handling of the session. */

  var _raw = function (cmd, extra, cb) {
    var line = 'n' + cmd.toUpperCase() + (extra ? ' ' + extra : '') + '\n';
    async_cb[++async_id] = cb;
    session.write(line);
  };

  var _end = function () {
    session.end('nEND\n');
  };

  /* Ping the session regularly to keep it alive. */

  var ping = function () {
    if (alive) {
      _raw('ping', null, function (pong) {
        self.emit('pong', pong);
      });
      setTimeout(ping, timeout * 1000 / 2);
    }
  };

  ping();

  /* Define frontend methods. */

  self.alive = function () {
    return alive;
  };

  self.version = function (cb) {
    _raw('version', null, cb);
  };

  self.scan = function (path, cb) {
    _raw('scan', path, cb);
  };

  return self;

};
<commit_msg>Fire connect event.<commit_after>var net          = require('net'),
    EventEmitter = require('events').EventEmitter,
    carry        = require('carrier').carry;

module.exports = function (conn_opts, opts, continuation) {

  var self = new EventEmitter();

  var timeout = opts && opts.timeout || 5;

  var async_id = 0,
      async_cb = {};

  var alive = false;

  var session = net.connect(conn_opts, function () {

    /* Init asynchronous session. */

    session.write('nIDSESSION\n');
    alive = true;

    /* Call the continuation, if given. */

    if (typeof continuation === 'function') {
      continuation.call(self);
    }

    self.emit('connect');

  });

  /* Register callbacks for line-based reading and
     end, close, error. */

  carry(session, function (line) {
    var match = line.match(/^([0-9]+): (.+)/);
    if (match !== null && typeof async_cb[match[1]] === 'function') {
      setTimeout(function () { async_cb[match[1]](match[2]); }, 0);
    }
  });

  session.on('close', function (had_error) {
    alive = false;
    self.emit('close', had_error);
  });

  session.on('error', function (err) {
    self.emit('error', err);
  });

  /* Functions for low-level handling of the session. */

  var _raw = function (cmd, extra, cb) {
    var line = 'n' + cmd.toUpperCase() + (extra ? ' ' + extra : '') + '\n';
    async_cb[++async_id] = cb;
    session.write(line);
  };

  var _end = function () {
    session.end('nEND\n');
  };

  /* Ping the session regularly to keep it alive. */

  var ping = function () {
    if (alive) {
      _raw('ping', null, function (pong) {
        self.emit('pong', pong);
      });
      setTimeout(ping, timeout * 1000 / 2);
    }
  };

  ping();

  /* Define frontend methods. */

  self.alive = function () {
    return alive;
  };

  self.version = function (cb) {
    _raw('version', null, cb);
  };

  self.scan = function (path, cb) {
    _raw('scan', path, cb);
  };

  return self;

};
<|endoftext|>


<commit_before>'use strict';
hljs.initHighlightingOnLoad();
console.log($);
$(function () {
	'use strict';
	function equal(a, b) {
		for(var i = 0; i < a.length; i++) {
			if(a[i] != b[i]) {
				return false;
			}
		}
		return true;
	}
	var header = $("h1");
  console.log(header);
	var delay = 1000;
	var keys = new Uint8Array(11);
	var desiredKeys = new Uint8Array([65, 66, 39, 37, 39, 37, 40, 40, 38, 38]);
	var usedKeys = 0;
	$("html").keydown(function (event) {
		keys.set(keys.subarray(0, 10), 1);
		keys[0] = event.keyCode;
		if (equal(desiredKeys, keys)) {
			var width = document.body.getElementsByClassName("konami")[0].width;
			$(".konami").slideDown(400, function () {
				var self = this;
				var delay = 500 + Math.random() * 1000;
				var offset = Math.random() * window.innerHeight - width / 2;
				function to(x) {
					$(self).animate({
						left: x,
						top: window.scrollY + offset
					}, {
						easing: "linear",
						complete: x == 0 ? right : left,
						duration: delay
					});
				}
				function right() {
					to(window.innerWidth - width - 10);
				}
				function left() {
					to(0);
				}
				right();
			});
		}
	});
	$(".konami").hide();
  	var colorCycle = ["red", "green", "blue"];
  	var colorIndex = 0;
	function easeHeader() {
      	if(colorIndex + 1 >= colorCycle.length)
          colorIndex = 0;
		header.animate({
			color: colorCycle[colorIndex++]
		}, { duration: delay, complete: easeHeader });
	}
	easeHeader();
	$("#tabs").tabs();
	$("#click").click(function () {
		$("#click p").slideToggle();
	});
	$("#dblclick").dblclick(function () {
		$("#dblclick p").slideToggle();
	});
	$("#hover").hover(function () {
		$("#hover p").slideToggle();
	});
	$("#mousedown").mousedown(function () {
		$("#mousedown p").slideToggle();
	});
	$("#mouseup").mouseup(function () {
		$("#mouseup p").slideToggle();
	});
	$("#hide").click(function () {
		$("#hide p").hide();
	});
	$("#animate").click(function () {
		$("#animate p").animate({
			fontSize: '2em'
		});
	});
	$("#slide").click(function () {
		$("#slide p").slideToggle();
	});
});
<commit_msg>Updated code.js<commit_after>'use strict';
hljs.initHighlightingOnLoad();
console.log($);
$(function () {
	'use strict';
	function equal(a, b) {
		for(var i = 0; i < a.length; i++) {
			if(a[i] != b[i]) {
				return false;
			}
		}
		return true;
	}
	var header = $("h1");
	var delay = 1000;
	var keys = new Uint8Array(11);
	var desiredKeys = new Uint8Array([65, 66, 39, 37, 39, 37, 40, 40, 38, 38]);
	var usedKeys = 0;
	$("html").keydown(function (event) {
		keys.set(keys.subarray(0, 10), 1);
		keys[0] = event.keyCode;
		if (equal(desiredKeys, keys)) {
			var width = document.body.getElementsByClassName("konami")[0].width;
			$(".konami").slideDown(400, function () {
				var self = this;
				var delay = 500 + Math.random() * 1000;
				var offset = Math.random() * window.innerHeight - width / 2;
				function to(x) {
					$(self).animate({
						left: x,
						top: window.scrollY + offset
					}, {
						easing: "linear",
						complete: x == 0 ? right : left,
						duration: delay
					});
				}
				function right() {
					to(window.innerWidth - width - 10);
				}
				function left() {
					to(0);
				}
				right();
			});
		}
	});
	$(".konami").hide();
  	var colorCycle = ["red", "green", "blue"];
  	var colorIndex = 0;
	function easeHeader() {
      	if(colorIndex + 1 >= colorCycle.length)
          colorIndex = 0;
		header.animate({
			color: colorCycle[colorIndex++]
		}, { duration: delay, complete: easeHeader });
	}
	easeHeader();
	$("#tabs").tabs();
	$("#click").click(function () {
		$("#click p").slideToggle();
	});
	$("#dblclick").dblclick(function () {
		$("#dblclick p").slideToggle();
	});
	$("#hover").hover(function () {
		$("#hover p").slideToggle();
	});
	$("#mousedown").mousedown(function () {
		$("#mousedown p").slideToggle();
	});
	$("#mouseup").mouseup(function () {
		$("#mouseup p").slideToggle();
	});
	$("#hide").click(function () {
		$("#hide p").hide();
	});
	$("#animate").click(function () {
		$("#animate p").animate({
			fontSize: '2em'
		});
	});
	$("#slide").click(function () {
		$("#slide p").slideToggle();
	});
});
<|endoftext|>


<commit_before>// lifted from node core, https://github.com/nodejs/node/blob/88307974e60346bc98c4e9f70a2b6918ccb6844f/src/node.js
// needed to instrument timers

exports.NativeModule = NativeModule
exports.globalTimeouts = globalTimeouts

var ContextifyScript = process.binding('contextify').ContextifyScript;
function runInThisContext(code, options) {
  var script = new ContextifyScript(code, options);
  return script.runInThisContext();
}

function globalTimeouts () {
  const timers = NativeModule.require('timers');
  global.clearImmediate = timers.clearImmediate;
  global.clearInterval = timers.clearInterval;
  global.clearTimeout = timers.clearTimeout;
  global.setImmediate = timers.setImmediate;
  global.setInterval = timers.setInterval;
  global.setTimeout = timers.setTimeout;
};

function NativeModule(id) {
  this.filename = id + '.js';
  this.id = id;
  this.exports = {};
  this.loaded = false;
}

NativeModule._source = process.binding('natives');
NativeModule._cache = {};

NativeModule.require = function(id) {
  if (id == 'native_module') {
    return NativeModule;
  }

  var cached = NativeModule.getCached(id);
  if (cached) {
    return cached.exports;
  }

  if (!NativeModule.exists(id)) {
    throw new Error('No such native module ' + id);
  }

  process.moduleLoadList.push('NativeModule ' + id);

  var nativeModule = new NativeModule(id);

  nativeModule.cache();
  nativeModule.compile();

  return nativeModule.exports;
};

NativeModule.getCached = function(id) {
  return NativeModule._cache[id];
};

NativeModule.exists = function(id) {
  return NativeModule._source.hasOwnProperty(id);
};

const EXPOSE_INTERNALS = process.execArgv.some(function(arg) {
  return arg.match(/^--expose[-_]internals$/);
});

if (EXPOSE_INTERNALS) {
  NativeModule.nonInternalExists = NativeModule.exists;

  NativeModule.isInternal = function(id) {
    return false;
  };
} else {
  NativeModule.nonInternalExists = function(id) {
    return NativeModule.exists(id) && !NativeModule.isInternal(id);
  };

  NativeModule.isInternal = function(id) {
    return id.startsWith('internal/');
  };
}

NativeModule.getSource = function(id) {
  return NativeModule._source[id];
};

NativeModule.wrap = function(script) {
  return NativeModule.wrapper[0] + script + NativeModule.wrapper[1];
};

NativeModule.wrapper = [
  '(function (exports, require, module, __filename, __dirname) { ',
  '\n});'
];

NativeModule.prototype.compile = function() {
  var source = NativeModule.getSource(this.id);
  source = NativeModule.wrap(source);

  var fn = runInThisContext(source, {
    filename: this.filename,
    lineOffset: 0,
    displayErrors: true
  });
  fn(this.exports, NativeModule.require, this, this.filename);

  this.loaded = true;
};

NativeModule.prototype.cache = function() {
  NativeModule._cache[this.id] = this;
};
<commit_msg>only recompile timers<commit_after>// lifted from node core, https://github.com/nodejs/node/blob/88307974e60346bc98c4e9f70a2b6918ccb6844f/src/node.js
// needed to instrument timers

exports.NativeModule = NativeModule
exports.globalTimeouts = globalTimeouts

var ContextifyScript = process.binding('contextify').ContextifyScript;
function runInThisContext(code, options) {
  var script = new ContextifyScript(code, options);
  return script.runInThisContext();
}

function globalTimeouts () {
  const timers = NativeModule.require('timers');
  global.clearImmediate = timers.clearImmediate;
  global.clearInterval = timers.clearInterval;
  global.clearTimeout = timers.clearTimeout;
  global.setImmediate = timers.setImmediate;
  global.setInterval = timers.setInterval;
  global.setTimeout = timers.setTimeout;
};

function NativeModule(id) {
  this.filename = id + '.js';
  this.id = id;
  this.exports = {};
  this.loaded = false;
}

NativeModule._source = process.binding('natives');
NativeModule._cache = {};

NativeModule.require = function(id) {
  if (id == 'native_module') {
    return NativeModule;
  }

  var cached = NativeModule.getCached(id);
  if (cached) {
    return cached.exports;
  }

  if (!NativeModule.exists(id)) {
    throw new Error('No such native module ' + id);
  }

  process.moduleLoadList.push('NativeModule ' + id);

  var nativeModule = new NativeModule(id);

  nativeModule.cache();
  nativeModule.compile();

  return nativeModule.exports;
};

NativeModule.getCached = function(id) {
  return NativeModule._cache[id];
};

NativeModule.exists = function(id) {
  return NativeModule._source.hasOwnProperty(id);
};

const EXPOSE_INTERNALS = process.execArgv.some(function(arg) {
  return arg.match(/^--expose[-_]internals$/);
});

if (EXPOSE_INTERNALS) {
  NativeModule.nonInternalExists = NativeModule.exists;

  NativeModule.isInternal = function(id) {
    return false;
  };
} else {
  NativeModule.nonInternalExists = function(id) {
    return NativeModule.exists(id) && !NativeModule.isInternal(id);
  };

  NativeModule.isInternal = function(id) {
    return id.startsWith('internal/');
  };
}

NativeModule.getSource = function(id) {
  return NativeModule._source[id];
};

NativeModule.wrap = function(script) {
  return NativeModule.wrapper[0] + script + NativeModule.wrapper[1];
};

NativeModule.wrapper = [
  '(function (exports, require, module, __filename, __dirname) { ',
  '\n});'
];

NativeModule.prototype.compile = function() {
  var source = NativeModule.getSource(this.id);
  source = NativeModule.wrap(source);

  var fn = runInThisContext(source, {
    filename: this.filename,
    lineOffset: 0,
    displayErrors: true
  });
  fn(this.exports, require, this, this.filename);

  this.loaded = true;
};

NativeModule.prototype.cache = function() {
  NativeModule._cache[this.id] = this;
};
<|endoftext|>