<commit_before>module.exports = function (db, options) {
  return wrap(db, new Version(options))
}
module.exports.Version = Version

var wrap = require("level-onion")
var fix = require("level-fix-range")
var concat = require("concat-stream")

var VersionFilter = require("./streams").VersionFilter
var StripKeys = require("./streams").StripKeys
var VersionTransform = require("./streams").VersionTransform

var u = require("./util")
var makeKey = u.makeKey
var unmakeKey = u.unmakeKey
var wrapCb = u.wrapCb
var encode = u.encode
var decode = u.decode

/**
 * @param  {Object} options  Wrapping options
 *                           - gcMaxVersions [no default] When doing GC it will only keep gcMaxVersions for each key
 *                           - gcMaxAge [no default] When doing GC only keep versions where (most_recent_timestamp) - gcMaxAge > version
 *                           - gcFreqMs [60000] How often the GC runs to apply GC rules.
 *                           - defaultVersion [Date.now] A function to provide the default version if none is specified.
 *                           - delimiter [\xff] The internal delimiter to use.
 */

function Version(options) {
  this.type = "version"
  this.unique = true
  options = options || {}

  // TODO GC stuffs.
  var gcOptions = {}
  if (options.gcMaxVersions) gcOptions.gcMaxVersions = +options.gcMaxVersions
  if (options.gcMaxAge) gcOptions.gcMaxAge = +options.gcMaxAge
  if (options.gcFreqMs) gcOptions.gcFreqMs = +options.gcFreqMs

  if (!options.defaultVersion) options.defaultVersion = Date.now
  if (typeof options.defaultVersion != "function") throw new Error("defaultVersion generator must be a function.")

  this.delimiter = (options.delimiter != null) ? options.delimiter : "\xff"
  this.defaultVersion = options.defaultVersion
}

Version.prototype.install = function (db, parent) {

  var self = this
  var sep = this.delimiter
  /* -- put -- */
  db.put = function (key, value, version, options, cb) {
    // put(key, value [,version] [,options] [,cb])

    // (k, v, cb)
    if (!cb && typeof version == "function") {
      cb = version
      version = undefined
    }
    // (k, v, o[, cb])
    if (!options && typeof version == "object") {
      options = version
      version = undefined
    }

    // (k, v[, o] [,cb])
    // (k, v, vr [,o] [,cb]
    if (version === undefined) version = self.defaultVersion()

    // parent is (expected to be) put(key, value [,options] [,cb])
    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }
    return parent.put(makeKey(sep, key, version), value, options, wrapCb(version, cb))
  }

  /* -- get -- */
  db.get = function (key, version, options, cb) {
    // get(key [,version] [,options] [,cb])

    // (k, cb)
    if (!cb && typeof version == "function") {
      cb = version
      version = undefined
    }
    // (k, o [,cb])
    if (!options && typeof version == "object") {
      options = version
      version = undefined
    }

    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }

    if (version === undefined) {
      return db.getLast(key, options, cb)
    }

    return parent.get(makeKey(sep, key, version), options, wrapCb(version, cb))
  }

  function getEnd(reverse, key, options, cb) {
    // TODO options???

    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }
    if (!cb) throw new Error("Get with no callback?")

    function collect(records) {
      if (!records || !records.length) return cb(new Error("Did not find a record %s", key))
      var r = records[0]
      return cb(null, r.value, r.version)
    }

    db.createVersionStream(key, {limit: 1, reverse: reverse})
      .pipe(concat(collect))
  }

  db.getLast = function (key, options, cb) {
    return getEnd(false, key, options, cb)
  }

  db.getFirst = function (key, options, cb) {
    return getEnd(true, key, options, cb)
  }

  /* -- del -- */
  db.del = function (key, version, options, cb) {
    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }
    return parent.del(makeKey(sep, key, version), options, wrapCb(version, cb))
  }

  /* -- batch -- */

  // TODO This is incomplete as it doesn't allow the per-command
  // options override that you get with chained batch syntax.
  function Batch() {
    this.ops = []
  }
  Batch.prototype.put = function (key, value, version, options) {
    // TODO ignoring options...
    this.ops.push({type: "put", key: key, value: value, version: version})
    return this
  }
  Batch.prototype.del = function (key, version, options) {
    // TODO ignoring options...
    this.ops.push({type: "del", key: key, version: version})
    return this
  }
  Batch.prototype.clear = function () {
    this.ops = []
    return this
  }
  Batch.prototype.write = function (cb) {
    db.batch(this.ops, cb)
  }

  db.batch = function (arr, options, cb) {
    if (!arguments.length) return new Batch()
    var transformed = arr.map(function (e) {
      var version = (e.version != null) ? e.version : self.defaultVersion()
      e.key = makeKey(sep, e.key, version)
      return e
    })
    parent.batch(transformed, options, cb)
  }

  /* -- STREAMS -- */

  /* -- createReadStream -- */
  db.createReadStream = function (options) {
    // additional options:
    //   minVersion -- Only include versions >= minVersion
    //   maxVersion -- Only include version <= maxVersion
    //   versionLimit -- Only return versionLimit records per key
    options = options || {}
    if (options.max != null) options.max = options.max + sep + sep
    if (options.end != null) options.end = options.end + sep + sep

    var removeKeys = ! options.keys
    options.keys = true
    options.delimiter = sep

    var filter = new VersionFilter(options)
    parent.createReadStream(fix(options))
      .pipe(filter)

    if (removeKeys) {
      var stripKeys = new StripKeys()
      filter.pipe(stripKeys)
      return stripKeys
    }

    return filter
  }

  db.readStream = db.createReadStream

  /* -- createKeyStream -- */
  db.createKeyStream = function (options) {
    options = options || {}
    options.keys = true
    options.values = false

    return db.createReadStream(options)
  }

  db.keyStream = db.createKeyStream

  /* -- createValueStream -- */
  db.createValueStream = function (options) {
    options = options || {}
    options.keys = false
    options.values = true

    return db.createReadStream(options)
  }

  db.valueStream = db.createValueStream

  /* -- createVersionStream -- */
  db.createVersionStream = function (key, options) {
    if (key == null) throw new Error("Key required for createVersionStream")
    options = options || {}
    options.delimiter = sep

    var filter = new VersionFilter(options)

    // Ignore start/min end/max
    options.start = options.min = options.end = options.max = undefined

    options.start = (options.minVersion != null)
                  ? makeKey(sep, key, options.minVersion)
                  : key + sep + sep

    options.end = (options.maxVersion != null)
                ? makeKey(sep, key, options.maxVersion)
                : key + sep

    parent.createReadStream(fix(options))
      .pipe(filter)

    return filter
  }

  db.versionStream = db.createVersionStream

  /* -- createWriteStream -- */
  db.createWriteStream = function (options) {
    options = options || {}
    options.delimiter = sep
    var transform = new VersionTransform(self.defaultVersion, options)

    var ws = parent.createWriteStream(options)
    transform.pipe(ws)

    return transform
  }
  db.writeStream = db.createWriteStream
}
<commit_msg>Better variable argument handling<commit_after>module.exports = function (db, options) {
  return wrap(db, new Version(options))
}
module.exports.Version = Version

var wrap = require("level-onion")
var fix = require("level-fix-range")
var concat = require("concat-stream")

var VersionFilter = require("./streams").VersionFilter
var StripKeys = require("./streams").StripKeys
var VersionTransform = require("./streams").VersionTransform

var u = require("./util")
var makeKey = u.makeKey
var unmakeKey = u.unmakeKey
var wrapCb = u.wrapCb
var encode = u.encode
var decode = u.decode

/**
 * @param  {Object} options  Wrapping options
 *                           - gcMaxVersions [no default] When doing GC it will only keep gcMaxVersions for each key
 *                           - gcMaxAge [no default] When doing GC only keep versions where (most_recent_timestamp) - gcMaxAge > version
 *                           - gcFreqMs [60000] How often the GC runs to apply GC rules.
 *                           - defaultVersion [Date.now] A function to provide the default version if none is specified.
 *                           - delimiter [\xff] The internal delimiter to use.
 */

function Version(options) {
  this.type = "version"
  this.unique = true
  options = options || {}

  // TODO GC stuffs.
  var gcOptions = {}
  if (options.gcMaxVersions) gcOptions.gcMaxVersions = +options.gcMaxVersions
  if (options.gcMaxAge) gcOptions.gcMaxAge = +options.gcMaxAge
  if (options.gcFreqMs) gcOptions.gcFreqMs = +options.gcFreqMs

  if (!options.defaultVersion) options.defaultVersion = Date.now
  if (typeof options.defaultVersion != "function") throw new Error("defaultVersion generator must be a function.")

  this.delimiter = (options.delimiter != null) ? options.delimiter : "\xff"
  this.defaultVersion = options.defaultVersion
}

Version.prototype.install = function (db, parent) {

  var self = this
  var sep = this.delimiter

  /* -- put -- */
  db.put = function (key, value, version, options, cb) {
    // put(key, value [,version] [,options] [,cb])

    // (k, v, [,vr/o], cb)
    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }
    // (k, v, o[, cb])
    if (!options && typeof version == "object") {
      options = version
      version = undefined
    }

    // (k, v, cb)
    if (typeof version == "function") {
      cb = version
      version = undefined
    }

    // (k, v[, o] [,cb])
    // (k, v, vr [,o] [,cb]
    if (version === undefined) version = self.defaultVersion()

    // parent is (expected to be) put(key, value [,options] [,cb])
    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }
    return parent.put(makeKey(sep, key, version), value, options, wrapCb(version, cb))
  }

  /* -- get -- */
  db.get = function (key, version, options, cb) {
    // get(key [,version] [,options] [,cb])

    // (k, cb)
    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }
    // (k, o [,cb])
    if (!options && typeof version == "object") {
      options = version
      version = undefined
    }

    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }

    // (k, cb)
    if (typeof version == "function") {
      cb = version
      version = undefined
    }

    if (version === undefined) {
      return db.getLast(key, options, cb)
    }

    return parent.get(makeKey(sep, key, version), options, wrapCb(version, cb))
  }

  function getEnd(reverse, key, options, cb) {
    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }
    if (!cb) throw new Error("Get with no callback?")

    function collect(records) {
      if (!records || !records.length) return cb(new Error("Did not find a record %s", key))
      var r = records[0]
      // TODO other options?
      if (options && options.valueEncoding == "json") r.value = JSON.parse(r.value)
      return cb(null, r.value, r.version)
    }

    db.createVersionStream(key, {limit: 1, reverse: reverse})
      .pipe(concat(collect))
  }

  db.getLast = function (key, options, cb) {
    return getEnd(false, key, options, cb)
  }

  db.getFirst = function (key, options, cb) {
    return getEnd(true, key, options, cb)
  }

  /* -- del -- */
  db.del = function (key, version, options, cb) {
    if (!cb && typeof options == "function") {
      cb = options
      options = undefined
    }
    return parent.del(makeKey(sep, key, version), options, wrapCb(version, cb))
  }

  /* -- batch -- */

  // TODO This is incomplete as it doesn't allow the per-command
  // options override that you get with chained batch syntax.
  function Batch() {
    this.ops = []
  }
  Batch.prototype.put = function (key, value, version, options) {
    // TODO ignoring options...
    this.ops.push({type: "put", key: key, value: value, version: version})
    return this
  }
  Batch.prototype.del = function (key, version, options) {
    // TODO ignoring options...
    this.ops.push({type: "del", key: key, version: version})
    return this
  }
  Batch.prototype.clear = function () {
    this.ops = []
    return this
  }
  Batch.prototype.write = function (cb) {
    db.batch(this.ops, cb)
  }

  db.batch = function (arr, options, cb) {
    if (!arguments.length) return new Batch()
    var transformed = arr.map(function (e) {
      var version = (e.version != null) ? e.version : self.defaultVersion()
      e.key = makeKey(sep, e.key, version)
      return e
    })
    parent.batch(transformed, options, cb)
  }

  /* -- STREAMS -- */

  /* -- createReadStream -- */
  db.createReadStream = function (options) {
    // additional options:
    //   minVersion -- Only include versions >= minVersion
    //   maxVersion -- Only include version <= maxVersion
    //   versionLimit -- Only return versionLimit records per key
    options = options || {}
    if (options.max != null) options.max = options.max + sep + sep
    if (options.end != null) options.end = options.end + sep + sep

    var removeKeys = ! options.keys
    options.keys = true
    options.delimiter = sep

    var filter = new VersionFilter(options)
    parent.createReadStream(fix(options))
      .pipe(filter)

    if (removeKeys) {
      var stripKeys = new StripKeys()
      filter.pipe(stripKeys)
      return stripKeys
    }

    return filter
  }

  db.readStream = db.createReadStream

  /* -- createKeyStream -- */
  db.createKeyStream = function (options) {
    options = options || {}
    options.keys = true
    options.values = false

    return db.createReadStream(options)
  }

  db.keyStream = db.createKeyStream

  /* -- createValueStream -- */
  db.createValueStream = function (options) {
    options = options || {}
    options.keys = false
    options.values = true

    return db.createReadStream(options)
  }

  db.valueStream = db.createValueStream

  /* -- createVersionStream -- */
  db.createVersionStream = function (key, options) {
    if (key == null) throw new Error("Key required for createVersionStream")
    options = options || {}
    options.delimiter = sep

    var filter = new VersionFilter(options)

    // Ignore start/min end/max
    options.start = options.min = options.end = options.max = undefined

    options.start = (options.minVersion != null)
                  ? makeKey(sep, key, options.minVersion)
                  : key + sep + sep

    options.end = (options.maxVersion != null)
                ? makeKey(sep, key, options.maxVersion)
                : key + sep

    parent.createReadStream(fix(options))
      .pipe(filter)

    return filter
  }

  db.versionStream = db.createVersionStream

  /* -- createWriteStream -- */
  db.createWriteStream = function (options) {
    options = options || {}
    options.delimiter = sep
    var transform = new VersionTransform(self.defaultVersion, options)

    var ws = parent.createWriteStream(options)
    transform.pipe(ws)

    return transform
  }
  db.writeStream = db.createWriteStream
}
<|endoftext|>


<commit_before>const FORM_CHAIN_LOOKUP_SELECTOR = '#ext-etheraddresslookup-chain_lookup_form';
const FORM_CHAIN_LOOKUP_INPUT_SELECTOR = '#ext-etheraddresslookup-addr_or_tx';
const FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR = '#ext-etheraddresslookup-chain_lookup_output';
const FORM_CHAIN_LOOKUP_DETAILS_SELECTOR = '#ext-etheraddresslookup-chain_lookup_details';

class ChainLookup
{
    constructor()
    {
        chrome.runtime.sendMessage({ func: "rpc_provider" }, (objResponse) => {
            this.web3 = new Web3(new Web3.providers.HttpProvider(objResponse.resp));
            this.setupFormSubmitHandler();
        });
    }

    setupFormSubmitHandler()
    {
        if(document.querySelector(FORM_CHAIN_LOOKUP_SELECTOR)) {

            this.getRpcDetails();
            // setInterval(async function() {
            //     await this.getRpcDetails();
            // }.bind(this), 10000);

            document.querySelector(FORM_CHAIN_LOOKUP_SELECTOR).addEventListener('submit', async (event) => {
                event.preventDefault();

                const strInput = document.querySelector(FORM_CHAIN_LOOKUP_INPUT_SELECTOR).value;
                await this.resolve(strInput);
            });
        }
    }

    async getRpcDetails()
    {

        if(document.querySelector(FORM_CHAIN_LOOKUP_DETAILS_SELECTOR)) {
            let intBlockNumber = await this.web3.eth.blockNumber;

            this.intBlockNumber = intBlockNumber;

            document.querySelector(FORM_CHAIN_LOOKUP_DETAILS_SELECTOR).innerHTML = `
                Latest Block Number: ${intBlockNumber.toLocaleString("en-US")}

            `

            chrome.runtime.sendMessage({ func: "rpc_details" }, (objResponse) => {
                let objDetails = JSON.parse(objResponse.resp);

                document.querySelector(FORM_CHAIN_LOOKUP_DETAILS_SELECTOR).innerHTML += `
                    Network: ${objDetails.name} (${objDetails.type})
                `;
            });
        }
    }

    async resolve(strInput)
    {
        strInput = strInput.trim();
        document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = ``;
        let strInputType = this.getInputType(strInput);

        switch(strInputType.toUpperCase()) {
            default:
            case 'ADDRESS':
                await this.doAddressLookup(strInput);
                break;
            case 'TX':
                this.doTxLookup(strInput);
                break;
            case 'UNKNOWN':
                document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = `
                    Invalid input. Either an Ethereum address or transaction hash.
                `;
            break;
        }
    }

    getInputType(strInput)
    {
        /**
         * Determines if we are inptting an address or transaction hash
         */

        strInput = strInput.startsWith("0x") ? strInput : `0x${strInput}`

        switch(strInput.length) {
            case 42 : //Address
                return "ADDRESS";
            case 66 : //TX HASH
                return "TX";
            default :
                return "UNKNOWN";
        }
    }

    async doAddressLookup(strInput)
    {
        let strAddressBlockie = blockies.create({
            seed: strInput.toLowerCase(),
            size: 8,
            scale: 16
        }).toDataURL();

        let objAddressDetails = {
            "eth": 0,
            "tx": 0,
            "contract": false
        };

        objAddressDetails.eth = this.web3.fromWei(
            this.web3.eth.getBalance(strInput).toString(10), "ether"
        ).toLocaleString("en-US", {maximumSignificantDigits: 5});

        objAddressDetails.tx = parseInt(this.web3.eth.getTransactionCount(strInput)).toLocaleString();
        objAddressDetails.contract = this.web3.eth.getCode(strInput) === "0x" ? "Normal (EOA)": "Contract";

        document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = `
                Address:

                        ${strInput}

ETH: ${objAddressDetails.eth}

Transactions out: ${objAddressDetails.tx}

Type: ${objAddressDetails.contract}

            `;

        let objLabels = new Labels();
        let objLabelledAddress = await objLabels.getLabelForAddress(strInput);
        if(typeof objLabelledAddress !== "undefined") {
            const { color, label } = objLabelledAddress;
            if(label.length) {
                document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML += `
                    ${objLabels.getTemplate(label, color)}
                `;
            }
        }
    }

    async doTxLookup(strInput)
    {
        let objTransaction = await this.web3.eth.getTransaction(strInput);

        if(objTransaction === null) {
            document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = `
                Unknown transaction (it might still be pending, waiting to be mined by the network)
            `;
            return;
        }

        let objTransactionReceipt = await this.web3.eth.getTransactionReceipt(strInput);

        let strAddressFromBlockie = blockies.create({
            seed: objTransaction.from.toLowerCase(),
            size: 8,
            scale: 16
        }).toDataURL();

        let strToAddress = objTransaction.to !== null ? objTransaction.to : objTransactionReceipt.contractAddress;
        let strAddressToBlockie = blockies.create({
            seed: strToAddress.toLowerCase(),
            size: 8,
            scale: 16
        }).toDataURL();

        let objTxDetails = {
            "eth": this.web3.fromWei(objTransaction.value).toLocaleString("en-US", {maximumSignificantDigits: 4}),
            "eth_full": this.web3.fromWei(objTransaction.value).toLocaleString("en-US", {maximumSignificantDigits: 18}),
            "gas": {
                "limit": objTransaction.gas.toLocaleString("en-US"),
                "price": this.web3.fromWei(objTransaction.gasPrice.toString()).toLocaleString("en-US"),
                "used": objTransactionReceipt.gasUsed,
                "used_percent": (objTransactionReceipt.gasUsed / objTransaction.gas)*100
            },
            "block": {
                "number": objTransaction.blockNumber.toLocaleString("en-US"),
                "ago": (this.intBlockNumber - objTransaction.blockNumber).toLocaleString("en-US"),
            },
            "nonce": objTransaction.nonce.toLocaleString("en-US"),
            "input": objTransaction.v
        }

        let objLabels = new Labels();
        let objLabelledAddress;
        let strLabel;
        let objLabelledAddresses = {
            "to": ChainLookup.getShortAddress(objTransaction.from),
            "from": ChainLookup.getShortAddress(strToAddress)
        }

        objLabelledAddress = await objLabels.getLabelForAddress(objTransaction.from);
        if(typeof objLabelledAddress !== "undefined") {
            strLabel = `${objLabelledAddress.label} (${ChainLookup.getShortAddress(strToAddress)})`;
            objLabelledAddresses.from = objLabels.getTemplate(strLabel, objLabelledAddress.color);
        }

        objLabelledAddress = await objLabels.getLabelForAddress(strToAddress);
        if(typeof objLabelledAddress !== "undefined") {
            strLabel = `${objLabelledAddress.label} (${ChainLookup.getShortAddress(strToAddress)})`;
            objLabelledAddresses.to = objLabels.getTemplate(strLabel, objLabelledAddress.color);
        }

        document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = `
                Transaction:

                        ${objTransactionReceipt.contractAddress !== null
                            ? `<strong>This transaction created a contract</strong><br />`
                            : ``
                        }

                            ${objLabelledAddresses.from}

                        →
                        ${objTxDetails.eth} ETH
                        →

                            ${objLabelledAddresses.to}

Gas Limit: ${objTxDetails.gas.limit} (${Math.ceil(objTxDetails.gas.used_percent)}% consumed)

Transaction Fee: Ξ${objTxDetails.gas.used * objTxDetails.gas.price}

Block: ${objTxDetails.block.number} (${objTxDetails.block.ago <= 1000000 ? objTxDetails.block.ago + " blocks ago" : "millions of blocks ago"})

            `;
    }

    static getShortAddress(strAddress)
    {
        return `${strAddress.slice(0, 4)}...${strAddress.slice(strAddress.length-4, strAddress.length)}`
    }
} <commit_msg>Removed commas for int comparison<commit_after>const FORM_CHAIN_LOOKUP_SELECTOR = '#ext-etheraddresslookup-chain_lookup_form';
const FORM_CHAIN_LOOKUP_INPUT_SELECTOR = '#ext-etheraddresslookup-addr_or_tx';
const FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR = '#ext-etheraddresslookup-chain_lookup_output';
const FORM_CHAIN_LOOKUP_DETAILS_SELECTOR = '#ext-etheraddresslookup-chain_lookup_details';

class ChainLookup
{
    constructor()
    {
        chrome.runtime.sendMessage({ func: "rpc_provider" }, (objResponse) => {
            this.web3 = new Web3(new Web3.providers.HttpProvider(objResponse.resp));
            this.setupFormSubmitHandler();
        });
    }

    setupFormSubmitHandler()
    {
        if(document.querySelector(FORM_CHAIN_LOOKUP_SELECTOR)) {

            this.getRpcDetails();
            // setInterval(async function() {
            //     await this.getRpcDetails();
            // }.bind(this), 10000);

            document.querySelector(FORM_CHAIN_LOOKUP_SELECTOR).addEventListener('submit', async (event) => {
                event.preventDefault();

                const strInput = document.querySelector(FORM_CHAIN_LOOKUP_INPUT_SELECTOR).value;
                await this.resolve(strInput);
            });
        }
    }

    async getRpcDetails()
    {

        if(document.querySelector(FORM_CHAIN_LOOKUP_DETAILS_SELECTOR)) {
            let intBlockNumber = await this.web3.eth.blockNumber;

            this.intBlockNumber = intBlockNumber;

            document.querySelector(FORM_CHAIN_LOOKUP_DETAILS_SELECTOR).innerHTML = `
                Latest Block Number: ${intBlockNumber.toLocaleString("en-US")}

            `

            chrome.runtime.sendMessage({ func: "rpc_details" }, (objResponse) => {
                let objDetails = JSON.parse(objResponse.resp);

                document.querySelector(FORM_CHAIN_LOOKUP_DETAILS_SELECTOR).innerHTML += `
                    Network: ${objDetails.name} (${objDetails.type})
                `;
            });
        }
    }

    async resolve(strInput)
    {
        strInput = strInput.trim();
        document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = ``;
        let strInputType = this.getInputType(strInput);

        switch(strInputType.toUpperCase()) {
            default:
            case 'ADDRESS':
                await this.doAddressLookup(strInput);
                break;
            case 'TX':
                this.doTxLookup(strInput);
                break;
            case 'UNKNOWN':
                document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = `
                    Invalid input. Either an Ethereum address or transaction hash.
                `;
            break;
        }
    }

    getInputType(strInput)
    {
        /**
         * Determines if we are inptting an address or transaction hash
         */

        strInput = strInput.startsWith("0x") ? strInput : `0x${strInput}`

        switch(strInput.length) {
            case 42 : //Address
                return "ADDRESS";
            case 66 : //TX HASH
                return "TX";
            default :
                return "UNKNOWN";
        }
    }

    async doAddressLookup(strInput)
    {
        let strAddressBlockie = blockies.create({
            seed: strInput.toLowerCase(),
            size: 8,
            scale: 16
        }).toDataURL();

        let objAddressDetails = {
            "eth": 0,
            "tx": 0,
            "contract": false
        };

        objAddressDetails.eth = this.web3.fromWei(
            this.web3.eth.getBalance(strInput).toString(10), "ether"
        ).toLocaleString("en-US", {maximumSignificantDigits: 5});

        objAddressDetails.tx = parseInt(this.web3.eth.getTransactionCount(strInput)).toLocaleString();
        objAddressDetails.contract = this.web3.eth.getCode(strInput) === "0x" ? "Normal (EOA)": "Contract";

        document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = `
                Address:

                        ${strInput}

ETH: ${objAddressDetails.eth}

Transactions out: ${objAddressDetails.tx}

Type: ${objAddressDetails.contract}

            `;

        let objLabels = new Labels();
        let objLabelledAddress = await objLabels.getLabelForAddress(strInput);
        if(typeof objLabelledAddress !== "undefined") {
            const { color, label } = objLabelledAddress;
            if(label.length) {
                document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML += `
                    ${objLabels.getTemplate(label, color)}
                `;
            }
        }
    }

    async doTxLookup(strInput)
    {
        let objTransaction = await this.web3.eth.getTransaction(strInput);

        if(objTransaction === null) {
            document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = `
                Unknown transaction (it might still be pending, waiting to be mined by the network)
            `;
            return;
        }

        let objTransactionReceipt = await this.web3.eth.getTransactionReceipt(strInput);

        let strAddressFromBlockie = blockies.create({
            seed: objTransaction.from.toLowerCase(),
            size: 8,
            scale: 16
        }).toDataURL();

        let strToAddress = objTransaction.to !== null ? objTransaction.to : objTransactionReceipt.contractAddress;
        let strAddressToBlockie = blockies.create({
            seed: strToAddress.toLowerCase(),
            size: 8,
            scale: 16
        }).toDataURL();

        let objTxDetails = {
            "eth": this.web3.fromWei(objTransaction.value).toLocaleString("en-US", {maximumSignificantDigits: 4}),
            "eth_full": this.web3.fromWei(objTransaction.value).toLocaleString("en-US", {maximumSignificantDigits: 18}),
            "gas": {
                "limit": objTransaction.gas.toLocaleString("en-US"),
                "price": this.web3.fromWei(objTransaction.gasPrice.toString()).toLocaleString("en-US"),
                "used": objTransactionReceipt.gasUsed,
                "used_percent": (objTransactionReceipt.gasUsed / objTransaction.gas)*100
            },
            "block": {
                "number": objTransaction.blockNumber.toLocaleString("en-US"),
                "ago": (this.intBlockNumber - objTransaction.blockNumber).toLocaleString("en-US"),
            },
            "nonce": objTransaction.nonce.toLocaleString("en-US"),
            "input": objTransaction.v
        }

        let objLabels = new Labels();
        let objLabelledAddress;
        let strLabel;
        let objLabelledAddresses = {
            "to": ChainLookup.getShortAddress(objTransaction.from),
            "from": ChainLookup.getShortAddress(strToAddress)
        }

        objLabelledAddress = await objLabels.getLabelForAddress(objTransaction.from);
        if(typeof objLabelledAddress !== "undefined") {
            strLabel = `${objLabelledAddress.label} (${ChainLookup.getShortAddress(strToAddress)})`;
            objLabelledAddresses.from = objLabels.getTemplate(strLabel, objLabelledAddress.color);
        }

        objLabelledAddress = await objLabels.getLabelForAddress(strToAddress);
        if(typeof objLabelledAddress !== "undefined") {
            strLabel = `${objLabelledAddress.label} (${ChainLookup.getShortAddress(strToAddress)})`;
            objLabelledAddresses.to = objLabels.getTemplate(strLabel, objLabelledAddress.color);
        }

        document.querySelector(FORM_CHAIN_LOOKUP_OUTPUT_SELECTOR).innerHTML = `
                Transaction:

                        ${objTransactionReceipt.contractAddress !== null
                            ? `<strong>This transaction created a contract</strong><br />`
                            : ``
                        }

                            ${objLabelledAddresses.from}

                        →
                        ${objTxDetails.eth} ETH
                        →

                            ${objLabelledAddresses.to}

Gas Limit: ${objTxDetails.gas.limit} (${Math.ceil(objTxDetails.gas.used_percent)}% consumed)

Transaction Fee: Ξ${objTxDetails.gas.used * objTxDetails.gas.price}

Block: ${objTxDetails.block.number} (${objTxDetails.block.ago.replace(",", "") <= 1000000 ? objTxDetails.block.ago + " blocks ago" : "millions of blocks ago"})

            `;
    }

    static getShortAddress(strAddress)
    {
        return `${strAddress.slice(0, 4)}...${strAddress.slice(strAddress.length-4, strAddress.length)}`
    }
} <|endoftext|>


<commit_before>#! /usr/bin/env node

/*
 * Module dependencies.
 */
var program = require('commander');
var chalk = require('chalk');

// Googleit's version
// Only change this in release branch
program.version('1.1.6');

// Check system is running on macOS or not => Show error message and retrun false
function checkEnvironment(callback) {
  var exec = require('child_process').exec;
  var cmd = 'uname -s';
  exec(cmd, function(error, stdout, stderr) {
    if (!stdout.includes('Darwin')) {
      var errorMessage = 'googleit only supports macOS. Using other OS may causing error.';
      console.error(chalk.red(errorMessage));
      result = false;
      callback(result);
      process.exit(1);
    } else {
      result = true;
      callback(result);
    }
  })
}

// Callback for checkEnvironment
var checkEnvironmentIsTrue = function(param) {
  if (param === true) {
    argumentsExist(typeof wordValue);
  }
}

// Error message when no any argument
function argumentsExist(wordValue) {
  if (wordValue === 'undefined') {
    var errorMessage = '\n    Please enter search terms. "googleit <terms>"\n'
    console.error(chalk.red(errorMessage));
    process.exit(1);
  }
}

// ReplaceAll function(replaceThisWord, replacement)
// Use in multiple terms search
String.prototype.replaceAll = function(search, replacement) {
  var target = this;
  return target.split(search).join(replacement);
};

// CheckEnvironment before check argumentsExistence
checkEnvironment(checkEnvironmentIsTrue);

// Example command usages in --help
program.on('--help', function() {
  console.log('  Examples:');
  console.log('');
  console.log('    $ googleit weather-tomorrow');
  console.log('    $ googleit -i cat');
  console.log('    $ googleit -b harry-potter');
  console.log('');
});

program
  .arguments('<word>')
  .option('-i, --image', 'Search Image on Google')
  .option('-n, --news', 'Search News on Google')
  .option('-v, --video', 'Search Video on Google')
  .option('-p, --patent', 'Search Patent on Google')
  .option('-b, --book', 'Search Book on Google')

  .action(function(word) {

    wordValue = word;
    word = word.replaceAll('-', '%20');

    var exec = require('child_process').exec;
    var cmd = 'open https://google.com/#q=' + word;
    var base = "open \'https://google.com/search?q="
    if (program.image) {
      cmd = base + word + "&tbm=isch\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else if (program.news) {
      cmd = base + word + "&tbm=nws\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else if (program.video) {
      cmd = base + word + "&tbm=vid\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else if (program.patent) {
      cmd = base + word + "&tbm=pts\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else if (program.book) {
      cmd = base + word + "&tbm=bks\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else {
      exec(cmd, function(error, stdout, stderr) {});
    }
  })
  .parse(process.argv);
<commit_msg>Add margin to unsupported system<commit_after>#! /usr/bin/env node

/*
 * Module dependencies.
 */
var program = require('commander');
var chalk = require('chalk');

// Googleit's version
// Only change this in release branch
program.version('1.1.6');

// Check system is running on macOS or not => Show error message and retrun false
function checkEnvironment(callback) {
  var exec = require('child_process').exec;
  var cmd = 'uname -s';
  exec(cmd, function(error, stdout, stderr) {
    if (!stdout.includes('Darwin')) {
      var errorMessage = '\n    googleit only supports macOS. Using other OS may causing error.\n';
      console.error(chalk.red(errorMessage));
      result = false;
      callback(result);
      process.exit(1);
    } else {
      result = true;
      callback(result);
    }
  })
}

// Callback for checkEnvironment
var checkEnvironmentIsTrue = function(param) {
  if (param === true) {
    argumentsExist(typeof wordValue);
  }
}

// Error message when no any argument
function argumentsExist(wordValue) {
  if (wordValue === 'undefined') {
    var errorMessage = '\n    Please enter search terms. "googleit <terms>"\n'
    console.error(chalk.red(errorMessage));
    process.exit(1);
  }
}

// ReplaceAll function(replaceThisWord, replacement)
// Use in multiple terms search
String.prototype.replaceAll = function(search, replacement) {
  var target = this;
  return target.split(search).join(replacement);
};

// CheckEnvironment before check argumentsExistence
checkEnvironment(checkEnvironmentIsTrue);

// Example command usages in --help
program.on('--help', function() {
  console.log('  Examples:');
  console.log('');
  console.log('    $ googleit weather-tomorrow');
  console.log('    $ googleit -i cat');
  console.log('    $ googleit -b harry-potter');
  console.log('');
});

program
  .arguments('<word>')
  .option('-i, --image', 'Search Image on Google')
  .option('-n, --news', 'Search News on Google')
  .option('-v, --video', 'Search Video on Google')
  .option('-p, --patent', 'Search Patent on Google')
  .option('-b, --book', 'Search Book on Google')

  .action(function(word) {

    wordValue = word;
    word = word.replaceAll('-', '%20');

    var exec = require('child_process').exec;
    var cmd = 'open https://google.com/#q=' + word;
    var base = "open \'https://google.com/search?q="
    if (program.image) {
      cmd = base + word + "&tbm=isch\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else if (program.news) {
      cmd = base + word + "&tbm=nws\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else if (program.video) {
      cmd = base + word + "&tbm=vid\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else if (program.patent) {
      cmd = base + word + "&tbm=pts\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else if (program.book) {
      cmd = base + word + "&tbm=bks\'";
      exec(cmd, function(error, stdout, stderr) {});
    } else {
      exec(cmd, function(error, stdout, stderr) {});
    }
  })
  .parse(process.argv);
<|endoftext|>


<commit_before>/**
 * Springle Chat
 *
 * @author Saurabh aka JSX <saurabh@rebugged.com>
 * @copyright
 * @license GNU AFFERO GENERAL PUBLIC LICENSE v3
 */

$(document).ready(function () {
    'use strict';
    var socket;
    var protocol_identifier = 'chat';
    var nickname = 'Guest-' + Math.floor(Math.random() * 100);
    var chatroom = 'public';
    var myId;
    var nicklist;
    var is_typing_indicator;
    var window_has_focus = true;
    var actual_window_title = document.title;
    var flash_title_timer;
    var enable_ssl = true;

    if (enable_ssl === false) {
        var server_url = 'ws://sky.rebugged.com:8804/';
    } else {
        var server_url = 'wss://sky.rebugged.com:8805/';
    }

    var msg_bubble_colors = [
        '#FFFFFF',
        '#E2EBC0',
        '#F3F1DC',
        '#F6E1E1',
        '#EDF9FC',
        '#EBF3EC',
        '#F4EAF1',
        '#FCF1F8',
        '#FBFAEF',
        '#EFF2FC'
    ];

    if (!is_websocket_supported()) {
        $('#chat-nickname-form').html('Your browser doesnt support '
                                 + 'websockets :(
Please use an updated version '
                                 + 'of a modern browser, such as Firefox '
                                 + 'or Google Chrome.');
    }

    $('#nickname-submit').click(function () {
        handshake_with_server();
    });

    $('#nickname, #chatroom').keypress(function (e) {
        if (e.which === 13) {
            handshake_with_server();
        }
    });

    $('#send-btn').click(function () {
        send_msg_box_content();
    });

    $('#msg-box').keypress(function (e) {
        if (e.which === 13 && !e.shiftKey) {
            send_msg_box_content();
            e.preventDefault();
        } else {
            send_user_typing_activity_alert();
        }
    });

    $('#clear-log-link').click(function () {
        var clear = confirm('Clear chat log?');
        if (clear) {
            clear_chat_log();
        }
    });

    $(window).focus(function() {
        window_has_focus = true;
        clearInterval(flash_title_timer);
        document.title = actual_window_title;
    });

    $(window).blur(function() {
        window_has_focus = false;
    });

    function handshake_with_server() {
        nickname = $('#nickname').val() !== '' ? $('#nickname').val() : nickname;
        nickname = strip_html_tags(nickname);
        chatroom = $('#chatroom').val() !== '' ? $('#chatroom').val() : chatroom;
        chatroom = strip_html_tags(chatroom);
        show_timer();
        open_connection();

        $('#chat-nickname-form').fadeOut(function () {
            if (myId === undefined) { // if connection not already established
                $('#loading-message').fadeIn();
            }
        });
    }

    function open_connection() {
        socket = new WebSocket(server_url, protocol_identifier);
        socket.addEventListener("open", connection_established);
    }

    function connection_established(event) {
        introduce(nickname);
        socket.addEventListener('message', function (event) {
            console.log(event.data)
            message_received(event.data);
        });
    }

    function introduce(nickname) {
        var intro = {
            type: 'intro',
            nickname: nickname,
            chatroom: chatroom
        }

        socket.send(JSON.stringify(intro));
    }

    function message_received(message) {
        var message;

        message = JSON.parse(message);

        if (message.type === 'welcome') {
            myId = message.userId;

            $('#chat-container').fadeIn();
            $('#loading-message').hide();
            $('#welcome-message-user-name').html(nickname);
        } else if (message.type === 'message' && parseInt(message.sender) !== parseInt(myId)) {
            add_new_msg_to_log(message);
            blink_window_title('~ New Message ~');
        } else if (message.type === 'nicklist') {
            var chatter_list_html = '';
            nicklist = message.nicklist;
            for(var i in nicklist) {
                chatter_list_html += '
' + nicklist[i] + '
';
            }

            chatter_list_html = '
' + chatter_list_html + '
';

            $('#chatter-list').html(chatter_list_html);
        } else if (message.type === 'activity_typing' && parseInt(message.sender) !== parseInt(myId)) {
            var activity_msg = message.name + ' is typing..';
            $('#is-typig-status').html(activity_msg).fadeIn();
            clearTimeout(is_typing_indicator);

            is_typing_indicator = setTimeout(function () {
                $('#is-typig-status').fadeOut();
            }, 2000);
        }

    }

    function send_msg_box_content() {
        var message = $('#msg-box').val();
        if (message != '') {
            send_message(message);
            $('#msg-box').val('');
        }
    }

    function send_message(message) {
        var message_to_send = {
            type: 'message',
            nickname: nickname,
            message: message,
            sender: myId,
            chatroom: chatroom
        };

        var msg_data_str = JSON.stringify(message_to_send);

        socket.send(msg_data_str);
        add_new_msg_to_log(message_to_send);
    }

    function add_new_msg_to_log(message) {
        var msg_string;
        var bubble_bg_color = msg_bubble_colors[message.sender % msg_bubble_colors.length];

        // Lets replace \n characters with html line break before rendering to the user
        var msg_text = strip_html_tags(message.message).split('\n').join('
');

        msg_string  = '
';
        msg_string += '
' + strip_html_tags(message.nickname) + '
';
        msg_string += '
';
        msg_string += '        ';
        msg_string +=              msg_text;
        msg_string +=  '       ';
        msg_string += '
';
        msg_string += '
';

        $('#message-log-area').append(msg_string);

        $("#message-log-area").animate({
            scrollTop: $("#message-log-area")[0].scrollHeight
        }, 1000);

        $('#message-log-area .talk-bubble-set:last').fadeIn();
    }

    function is_websocket_supported() {
        if ('WebSocket' in window) {
            return true;
        }
        return false;
    }

    function show_timer() {
        var time_start = 5;
        var time_string;
        var tick = window.setInterval(function () {
            if (time_start-- > 0) {
                time_string = time_start + ' seconds';
            } else {
                time_string = '..ahem ahem, a little more..';
            }

            $('#loading-timer').html(time_string);
        }, 1000);
    }

    function strip_html_tags(text) {
        var temp_element = document.createElement('div');
        temp_element.innerHTML = text.replace(/(<([^>]+)>)/ig, '');
        return temp_element.textContent || temp_element.innerText || '--empty--';
    }

    function send_user_typing_activity_alert() {
        var message_to_send = {
            type: 'activity_typing',
            name: nickname,
            chatroom: chatroom
        };

        var msg_data_str = JSON.stringify(message_to_send);
        socket.send(msg_data_str);
    }

    function clear_chat_log() {
        $('#message-log-area').html('

');
    }

    function blink_window_title(msg_to_blink) {
        if (!window_has_focus) {
            play_notification_sound();

            clearInterval(flash_title_timer);

                flash_title_timer = setInterval(function () {
                    if (document.title === actual_window_title) {
                        document.title = msg_to_blink;
                    } else {
                        document.title = actual_window_title;
                    }
                }, 1000);
            }
    }

    function play_notification_sound() {
        document.getElementById('chat-notification-sound').play();
    }
});
<commit_msg>Removed a forgotten console.log() from chat_client<commit_after>/**
 * Springle Chat
 *
 * @author Saurabh aka JSX <saurabh@rebugged.com>
 * @copyright
 * @license GNU AFFERO GENERAL PUBLIC LICENSE v3
 */

$(document).ready(function () {
    'use strict';
    var socket;
    var protocol_identifier = 'chat';
    var nickname = 'Guest-' + Math.floor(Math.random() * 100);
    var chatroom = 'public';
    var myId;
    var nicklist;
    var is_typing_indicator;
    var window_has_focus = true;
    var actual_window_title = document.title;
    var flash_title_timer;
    var enable_ssl = true;

    if (enable_ssl === false) {
        var server_url = 'ws://sky.rebugged.com:8804/';
    } else {
        var server_url = 'wss://sky.rebugged.com:8805/';
    }

    var msg_bubble_colors = [
        '#FFFFFF',
        '#E2EBC0',
        '#F3F1DC',
        '#F6E1E1',
        '#EDF9FC',
        '#EBF3EC',
        '#F4EAF1',
        '#FCF1F8',
        '#FBFAEF',
        '#EFF2FC'
    ];

    if (!is_websocket_supported()) {
        $('#chat-nickname-form').html('Your browser doesnt support '
                                 + 'websockets :(
Please use an updated version '
                                 + 'of a modern browser, such as Firefox '
                                 + 'or Google Chrome.');
    }

    $('#nickname-submit').click(function () {
        handshake_with_server();
    });

    $('#nickname, #chatroom').keypress(function (e) {
        if (e.which === 13) {
            handshake_with_server();
        }
    });

    $('#send-btn').click(function () {
        send_msg_box_content();
    });

    $('#msg-box').keypress(function (e) {
        if (e.which === 13 && !e.shiftKey) {
            send_msg_box_content();
            e.preventDefault();
        } else {
            send_user_typing_activity_alert();
        }
    });

    $('#clear-log-link').click(function () {
        var clear = confirm('Clear chat log?');
        if (clear) {
            clear_chat_log();
        }
    });

    $(window).focus(function() {
        window_has_focus = true;
        clearInterval(flash_title_timer);
        document.title = actual_window_title;
    });

    $(window).blur(function() {
        window_has_focus = false;
    });

    function handshake_with_server() {
        nickname = $('#nickname').val() !== '' ? $('#nickname').val() : nickname;
        nickname = strip_html_tags(nickname);
        chatroom = $('#chatroom').val() !== '' ? $('#chatroom').val() : chatroom;
        chatroom = strip_html_tags(chatroom);
        show_timer();
        open_connection();

        $('#chat-nickname-form').fadeOut(function () {
            if (myId === undefined) { // if connection not already established
                $('#loading-message').fadeIn();
            }
        });
    }

    function open_connection() {
        socket = new WebSocket(server_url, protocol_identifier);
        socket.addEventListener("open", connection_established);
    }

    function connection_established(event) {
        introduce(nickname);
        socket.addEventListener('message', function (event) {
            message_received(event.data);
        });
    }

    function introduce(nickname) {
        var intro = {
            type: 'intro',
            nickname: nickname,
            chatroom: chatroom
        }

        socket.send(JSON.stringify(intro));
    }

    function message_received(message) {
        var message;

        message = JSON.parse(message);

        if (message.type === 'welcome') {
            myId = message.userId;

            $('#chat-container').fadeIn();
            $('#loading-message').hide();
            $('#welcome-message-user-name').html(nickname);
        } else if (message.type === 'message' && parseInt(message.sender) !== parseInt(myId)) {
            add_new_msg_to_log(message);
            blink_window_title('~ New Message ~');
        } else if (message.type === 'nicklist') {
            var chatter_list_html = '';
            nicklist = message.nicklist;
            for(var i in nicklist) {
                chatter_list_html += '
' + nicklist[i] + '
';
            }

            chatter_list_html = '
' + chatter_list_html + '
';

            $('#chatter-list').html(chatter_list_html);
        } else if (message.type === 'activity_typing' && parseInt(message.sender) !== parseInt(myId)) {
            var activity_msg = message.name + ' is typing..';
            $('#is-typig-status').html(activity_msg).fadeIn();
            clearTimeout(is_typing_indicator);

            is_typing_indicator = setTimeout(function () {
                $('#is-typig-status').fadeOut();
            }, 2000);
        }

    }

    function send_msg_box_content() {
        var message = $('#msg-box').val();
        if (message != '') {
            send_message(message);
            $('#msg-box').val('');
        }
    }

    function send_message(message) {
        var message_to_send = {
            type: 'message',
            nickname: nickname,
            message: message,
            sender: myId,
            chatroom: chatroom
        };

        var msg_data_str = JSON.stringify(message_to_send);

        socket.send(msg_data_str);
        add_new_msg_to_log(message_to_send);
    }

    function add_new_msg_to_log(message) {
        var msg_string;
        var bubble_bg_color = msg_bubble_colors[message.sender % msg_bubble_colors.length];

        // Lets replace \n characters with html line break before rendering to the user
        var msg_text = strip_html_tags(message.message).split('\n').join('
');

        msg_string  = '
';
        msg_string += '
' + strip_html_tags(message.nickname) + '
';
        msg_string += '
';
        msg_string += '        ';
        msg_string +=              msg_text;
        msg_string +=  '       ';
        msg_string += '
';
        msg_string += '
';

        $('#message-log-area').append(msg_string);

        $("#message-log-area").animate({
            scrollTop: $("#message-log-area")[0].scrollHeight
        }, 1000);

        $('#message-log-area .talk-bubble-set:last').fadeIn();
    }

    function is_websocket_supported() {
        if ('WebSocket' in window) {
            return true;
        }
        return false;
    }

    function show_timer() {
        var time_start = 5;
        var time_string;
        var tick = window.setInterval(function () {
            if (time_start-- > 0) {
                time_string = time_start + ' seconds';
            } else {
                time_string = '..ahem ahem, a little more..';
            }

            $('#loading-timer').html(time_string);
        }, 1000);
    }

    function strip_html_tags(text) {
        var temp_element = document.createElement('div');
        temp_element.innerHTML = text.replace(/(<([^>]+)>)/ig, '');
        return temp_element.textContent || temp_element.innerText || '--empty--';
    }

    function send_user_typing_activity_alert() {
        var message_to_send = {
            type: 'activity_typing',
            name: nickname,
            chatroom: chatroom
        };

        var msg_data_str = JSON.stringify(message_to_send);
        socket.send(msg_data_str);
    }

    function clear_chat_log() {
        $('#message-log-area').html('

');
    }

    function blink_window_title(msg_to_blink) {
        if (!window_has_focus) {
            play_notification_sound();

            clearInterval(flash_title_timer);

                flash_title_timer = setInterval(function () {
                    if (document.title === actual_window_title) {
                        document.title = msg_to_blink;
                    } else {
                        document.title = actual_window_title;
                    }
                }, 1000);
            }
    }

    function play_notification_sound() {
        document.getElementById('chat-notification-sound').play();
    }
});
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter,
  url = require('url'),
  util = require('util'),
  http = require('http'),
  https = require('https'),
  appManager = require('./lib/appManager.js'),
  mongooseManager = require('./lib/mongooseManager.js'),
  redisManager = require('./lib/redisManager.js');

/**
 * @ngdoc function
 * @name MWC
 * @constructor
 * @param {object} config - config object
 */
function MWC(config) {

  EventEmitter.call(this);
  if (typeof config === 'object') {
  if(process.env.redisUrl && !config.redis){
//Using redis configuration from enviromental value
    config.redis=process.env.redisUrl;
  }
  if(process.env.mongoUrl && !config.mongoUrl){
//Using mongo configuration from enviromental value
    config.mongoUrl=process.env.mongoUrl;
  }
  }
  this.validateConfig(config);
  this.config = config;
  this._extendCoreFunctions = [];
  this._additionalModels = [];
  this._extendAppFunctions = [];
  this._additionalStrategies = [];
  this._extendMiddlewaresFunctions = [];
  this._extendRoutesFunctions = [];
  this._listeners = {};

  return this;
}

util.inherits(MWC, EventEmitter);

MWC.prototype.validateConfig = function(config) {
  // General check
  if (typeof config !== 'object') {
    throw new Error('Config is not an object!');
  }
  if (!(config.hostUrl && url.parse(config.hostUrl)['hostname'])) {
    throw new Error('Config.hostUrl have to be valid hostname - for example, http://example.org/ with http(s) on start and "/" at end!!!');
  }
  if (!(config.secret && config.secret.length>9)) {
    throw new Error('Config.secret is not set or is to short!');
  }

  mongooseManager.validateConfig(config.mongoUrl);
  redisManager.validateConfig(config.redis);

  return true;
};

//extending application
MWC.prototype.extendCore = function (fieldName,value) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    if (typeof fieldName === 'string') {
      this._extendCoreFunctions.push({'field':fieldName,'value':value});
      return this;
    } else {
      throw new Error('MWC.extendCore requires argument of fieldName, value');
    }
  }
};

MWC.prototype.extendModel = function (modelName, modelFunction) {
  if (modelName === 'Users') {
    throw new Error('Error extending model, "Users" is reserved name');
  } else {
    if (typeof modelName === 'string' && typeof modelFunction === 'function') {
      this._additionalModels.push({'name': modelName, 'initFunction': modelFunction});
      return this;
    } else {
      throw new Error('MWC.extendModel requires arguments of string of "modelName" and function(core){...}');
    }
  }
};

MWC.prototype.extendApp = function (environment, settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var environmentToUse = null;
    if (typeof settingsFunction === 'undefined') {
      settingsFunction = environment;
      environment = null;
    }
    if (typeof environment === 'string') {
      environmentToUse = [];
      environmentToUse.push(environment);
    }
    if (environment instanceof Array) {
      environmentToUse = environment;
      for (var i = 0; i < environment.length;i++){
        if(typeof environment[i] !== 'string'){
          throw new Error('#MWC.extendApp requires environment name to be a string!');
        }
      }
    }
    if (typeof settingsFunction === 'function') {
      if (environmentToUse) {
        for (var i = 0; i < environmentToUse.length; i++) {
          this._extendAppFunctions.push({
            'environment': environmentToUse[i],
            'settingsFunction': settingsFunction
          });
        }
      } else {
        this._extendAppFunctions.push({
          'settingsFunction': settingsFunction
        });
      }
    } else {
      throw new Error('Wrong arguments for extendApp(arrayOrStringOfEnvironments,settingsFunction)');
    }
    return this;
  }
};

MWC.prototype.extendStrategies = function(strategyObject){
  if(typeof strategyObject !== 'object') throw new Error('mwc.extendStrategies requires strategyObject to be an object');
  if(typeof strategyObject.strategy !== 'function') throw new Error('mwc.extendStrategies requires strategyObject.strategy to be a proper function!');
  if(typeof strategyObject.routes !== 'function') throw new Error('mwc.extendStrategies requires strategyObject.routes to be a proper function!');

  this._additionalStrategies.push(strategyObject);
  return this;
};

MWC.prototype.extendMiddleware = function (environment, path, settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var environmentToUse = null,
      pathToUse = '/',
      settingsFunctionToUse = null;

    if (typeof environment === 'function' && typeof path === 'undefined' && typeof settingsFunction === 'undefined') {
      settingsFunctionToUse = environment;
    }

    if (typeof environment === 'string' || environment instanceof Array) {

      if (typeof environment === 'string') {
        environmentToUse = [];
        environmentToUse.push(environment);
      }
      if (environment instanceof Array) {
        environmentToUse = environment;
        for (var i = 0; i < environment.length;i++){
          if(typeof environment[i] !== 'string'){
            throw new Error('#MWC.extendMiddleware requires environment name to be a string!');
          }
        }
      }
      if (typeof path === 'string') {
        if(/^\//.test(path)){
          pathToUse = path;
          if (typeof settingsFunction === 'function') {
            settingsFunctionToUse = settingsFunction;
          }
        } else {
          throw new Error('#MWC.extendMiddleware path to be a middleware valid path, that starts from "/"!');
        }
      } else {
        if (typeof path === 'function') {
          settingsFunctionToUse = path;
        }
      }
    }

    if (settingsFunctionToUse) {
      if (environmentToUse) {
        for (var i = 0; i < environmentToUse.length; i++) {
          this._extendMiddlewaresFunctions.push({
            'environment': environmentToUse[i],
            'path': pathToUse,
            'SettingsFunction': settingsFunctionToUse
          });
        }
      } else {
        //we set middleware for all environments
        this._extendMiddlewaresFunctions.push({
          'path': pathToUse,
          'SettingsFunction': settingsFunctionToUse
        });
      }
    } else {
      throw new Error('Wrong arguments for function MWC.extendMiddleware(environmentArrayOrStrings, [path], settingsFunction(core){...})');
    }
    return this;
  }
};

MWC.prototype.extendRoutes = function (settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    if (typeof settingsFunction === 'function') {
      this._extendRoutesFunctions.push(settingsFunction);
      return this;
    } else {
      throw new Error('Wrong argument for MWC.extendAppRoutes(function(core){...});');
    }
  }
};
//todo - refactor
MWC.prototype.usePlugin = function (pluginObjectOrName) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var pluginToBeInstalled = {};
    if (typeof pluginObjectOrName === 'string') {
      pluginToBeInstalled = require('' + pluginObjectOrName);
    } else {
      pluginToBeInstalled = pluginObjectOrName;
    }

    if (pluginToBeInstalled.extendCore) {
      this.extendCore(pluginToBeInstalled.extendCore);
    }
    if (pluginToBeInstalled.extendModel && typeof pluginToBeInstalled.extendModel === 'object') {
      for (var x in pluginToBeInstalled.extendModel) {
        this.extendModel(x, pluginObjectOrName.extendModel[x]);
      }
    }
    if(pluginToBeInstalled.setAppParameters && typeof pluginToBeInstalled.extendApp === 'undefined'){
      console.log('Plugin is outdated! Use extendApp instead of setAppParameters with same syntax!');
      pluginToBeInstalled.extendApp=pluginToBeInstalled.setAppParameters;
    }
    if (pluginToBeInstalled.extendApp) {
      this.extendApp(pluginToBeInstalled.extendApp);
    }
    if(pluginToBeInstalled.setAppMiddlewares && typeof pluginToBeInstalled.extendMiddleware === 'undefined'){
      console.log('Plugin is outdated! Use extendMiddleware instead of setAppMiddlewares with same syntax!');
      pluginToBeInstalled.extendMiddleware=pluginToBeInstalled.setAppMiddlewares;
    }
    if (pluginToBeInstalled.extendMiddleware) {
      this.extendMiddleware(pluginToBeInstalled.extendMiddleware);
    }
    if(pluginToBeInstalled.extendAppRoutes && typeof pluginToBeInstalled.extendRoutes === 'undefined'){
      console.log('Plugin is outdated! Use extendMiddleware instead of setAppMiddlewares with same syntax!');
      pluginToBeInstalled.extendRoutes=pluginToBeInstalled.extendAppRoutes;
    }
    if (pluginToBeInstalled.extendRoutes) {
      this.extendRoutes(pluginToBeInstalled.extendRoutes);
    }
    return this;
  }
};

MWC.prototype.extendListeners = function (eventName, eventHandlerFunction) {
  if (typeof eventName === "string" && typeof eventHandlerFunction === "function") {
    if (typeof this._listeners[eventName] === "undefined") {
      this._listeners[eventName] = eventHandlerFunction;
      return this;
    } else {
      throw new Error('Unable set listener for event ' + eventName + '! Event name is occupied!');
    }
  } else {
    throw new Error('#MWC.extendListeners(eventName,eventHandlerFunction) have wrong arguments!');
  }
};

MWC.prototype.ready = function () {
  var thisMWC = this;//because we sometimes issue closures with thisMWC
  thisMWC.prepared = true;

  //injecting redis
  thisMWC.redisClient = redisManager.create(thisMWC.config.redis);

  // initializing MongoDB and Core Models
  thisMWC.mongoose = mongooseManager.create(thisMWC.config.mongoUrl);
  thisMWC.mongoose.setConnectEvent(thisMWC);
  thisMWC.model = mongooseManager.initModels(thisMWC);

  //doing extendCore
  //extending core by extendCore
  thisMWC._extendCoreFunctions.map(function (settingsFunction) {
    if(typeof thisMWC[settingsFunction.field] === "undefined"){
      thisMWC[settingsFunction.field]=settingsFunction.value;
    } else {
      throw new Error('We try to overwrite kernel field with name of '+settingsFunction.field+'!');
    }
  });

  //loading custom models //todo - maybe redo
  thisMWC._additionalModels.map(function (customModel) {
    thisMWC.model[customModel.name] = customModel.initFunction(thisMWC.mongoose, thisMWC.config);
  });

  //initialize expressJS application
  thisMWC.app = appManager.create(thisMWC);
  appManager.extendApp(thisMWC);

  // set shutdown procedure
  process.on('SIGINT', thisMWC.shutdown);

  for(var eventName in thisMWC._listeners){
    thisMWC.on(eventName, thisMWC._listeners[eventName]);
  }

  return thisMWC;
};

MWC.prototype.listen = function (httpOrHttpsOrPort) {

  if (!this.prepared) {
    this.ready();
  }

  if (httpOrHttpsOrPort) {
    if (typeof httpOrHttpsOrPort === 'number' && httpOrHttpsOrPort > 0) {
      this.app.listen(httpOrHttpsOrPort);
      return;
    }

    if (httpOrHttpsOrPort instanceof http || httpOrHttpsOrPort instanceof https) {
      httpOrHttpsOrPort.createServer(this.app).listen(this.app.get('port'));
      return;
    }
    throw new Error('Function MWC.listen(httpOrHttpsOrPort) accepts objects of null, http, https or port\'s number as argument!');
  } else {
    this.app.listen(this.app.get('port'));//listening to default port
  }
};

MWC.prototype.setAppParameters = function(environment, settingsFunction){
  console.log('setAppParameters is outdated, use extendApp  with the same syntax');
  this.extendApp(environment, settingsFunction);
  return this;
};

MWC.prototype.setAppMiddlewares = function(environment, path, settingsFunction){
  console.log('setAppMiddlewares is outdated, use extendMiddleware with the same syntax');
  this.extendMiddleware(environment, path, settingsFunction);
  return this;
};

MWC.prototype.extendAppRoutes = function(settingsFunction){
  console.log('extendAppRoutes is outdated, use extendRoutes with the same syntax');
  this.extendRoutes(settingsFunction);
  return this;
};

MWC.prototype.shutdown = function () {

  console.log('MWC IS GOING TO SHUT DOWN....');
  if(this.mongoose.connection){
    this.mongoose.connection.close();
  }
  this.redisClient.end();
  // calling .shutdown allows your process to exit normally
  toobusy.shutdown();
  process.exit();

};

MWC.prototype.injectEmit = function(object) {
  var thisMWC = this;
  object.emitMWC = function (eventName, eventContent) {
    thisMWC.emit(eventName, eventContent);
  };
};

/**
 * @ngdoc function
 * @name mwc.createRedisClient
 * @description
 * Create new redis client
 *
 * Use this function with great caution! Because usually redis-database-as-a-service providers have
 * strict connection limit!!! and every one redis client created like this consumes one connection!
 * Usually, MWC needs only one redis client connection
 * BTW, redis is NOT MySQL - we can't increase speed with connection pooling!
 * @returns {RedisClient} redis client
 */
MWC.prototype.createRedisClient = function() {
  return redisManager.create(this.config.redis);
};

/**
 * @ngdoc function
 * @name mwcKernel.create
 * @description
 * Create MWC object instance (factory)
 * @param {object} config - config object
 */
MWC.create = function(config) {
  return new MWC(config);
};

module.exports = exports = MWC.create;
<commit_msg>[fix] compatibility for extendMiddlewares -> extendMiddleware<commit_after>var EventEmitter = require('events').EventEmitter,
  url = require('url'),
  util = require('util'),
  http = require('http'),
  https = require('https'),
  appManager = require('./lib/appManager.js'),
  mongooseManager = require('./lib/mongooseManager.js'),
  redisManager = require('./lib/redisManager.js');

/**
 * @ngdoc function
 * @name MWC
 * @constructor
 * @param {object} config - config object
 */
function MWC(config) {

  EventEmitter.call(this);
  if (typeof config === 'object') {
  if(process.env.redisUrl && !config.redis){
//Using redis configuration from enviromental value
    config.redis=process.env.redisUrl;
  }
  if(process.env.mongoUrl && !config.mongoUrl){
//Using mongo configuration from enviromental value
    config.mongoUrl=process.env.mongoUrl;
  }
  }
  this.validateConfig(config);
  this.config = config;
  this._extendCoreFunctions = [];
  this._additionalModels = [];
  this._extendAppFunctions = [];
  this._additionalStrategies = [];
  this._extendMiddlewaresFunctions = [];
  this._extendRoutesFunctions = [];
  this._listeners = {};

  return this;
}

util.inherits(MWC, EventEmitter);

MWC.prototype.validateConfig = function(config) {
  // General check
  if (typeof config !== 'object') {
    throw new Error('Config is not an object!');
  }
  if (!(config.hostUrl && url.parse(config.hostUrl)['hostname'])) {
    throw new Error('Config.hostUrl have to be valid hostname - for example, http://example.org/ with http(s) on start and "/" at end!!!');
  }
  if (!(config.secret && config.secret.length>9)) {
    throw new Error('Config.secret is not set or is to short!');
  }

  mongooseManager.validateConfig(config.mongoUrl);
  redisManager.validateConfig(config.redis);

  return true;
};

//extending application
MWC.prototype.extendCore = function (fieldName,value) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    if (typeof fieldName === 'string') {
      this._extendCoreFunctions.push({'field':fieldName,'value':value});
      return this;
    } else {
      throw new Error('MWC.extendCore requires argument of fieldName, value');
    }
  }
};

MWC.prototype.extendModel = function (modelName, modelFunction) {
  if (modelName === 'Users') {
    throw new Error('Error extending model, "Users" is reserved name');
  } else {
    if (typeof modelName === 'string' && typeof modelFunction === 'function') {
      this._additionalModels.push({'name': modelName, 'initFunction': modelFunction});
      return this;
    } else {
      throw new Error('MWC.extendModel requires arguments of string of "modelName" and function(core){...}');
    }
  }
};

MWC.prototype.extendApp = function (environment, settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var environmentToUse = null;
    if (typeof settingsFunction === 'undefined') {
      settingsFunction = environment;
      environment = null;
    }
    if (typeof environment === 'string') {
      environmentToUse = [];
      environmentToUse.push(environment);
    }
    if (environment instanceof Array) {
      environmentToUse = environment;
      for (var i = 0; i < environment.length;i++){
        if(typeof environment[i] !== 'string'){
          throw new Error('#MWC.extendApp requires environment name to be a string!');
        }
      }
    }
    if (typeof settingsFunction === 'function') {
      if (environmentToUse) {
        for (var i = 0; i < environmentToUse.length; i++) {
          this._extendAppFunctions.push({
            'environment': environmentToUse[i],
            'settingsFunction': settingsFunction
          });
        }
      } else {
        this._extendAppFunctions.push({
          'settingsFunction': settingsFunction
        });
      }
    } else {
      throw new Error('Wrong arguments for extendApp(arrayOrStringOfEnvironments,settingsFunction)');
    }
    return this;
  }
};

MWC.prototype.extendStrategies = function(strategyObject){
  if(typeof strategyObject !== 'object') throw new Error('mwc.extendStrategies requires strategyObject to be an object');
  if(typeof strategyObject.strategy !== 'function') throw new Error('mwc.extendStrategies requires strategyObject.strategy to be a proper function!');
  if(typeof strategyObject.routes !== 'function') throw new Error('mwc.extendStrategies requires strategyObject.routes to be a proper function!');
  this._additionalStrategies.push(strategyObject);
  return this;
};

MWC.prototype.extendMiddleware = function (environment, path, settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var environmentToUse = null,
      pathToUse = '/',
      settingsFunctionToUse = null;

    if (typeof environment === 'function' && typeof path === 'undefined' && typeof settingsFunction === 'undefined') {
      settingsFunctionToUse = environment;
    }

    if (typeof environment === 'string' || environment instanceof Array) {

      if (typeof environment === 'string') {
        environmentToUse = [];
        environmentToUse.push(environment);
      }
      if (environment instanceof Array) {
        environmentToUse = environment;
        for (var i = 0; i < environment.length;i++){
          if(typeof environment[i] !== 'string'){
            throw new Error('#MWC.extendMiddleware requires environment name to be a string!');
          }
        }
      }
      if (typeof path === 'string') {
        if(/^\//.test(path)){
          pathToUse = path;
          if (typeof settingsFunction === 'function') {
            settingsFunctionToUse = settingsFunction;
          }
        } else {
          throw new Error('#MWC.extendMiddleware path to be a middleware valid path, that starts from "/"!');
        }
      } else {
        if (typeof path === 'function') {
          settingsFunctionToUse = path;
        }
      }
    }

    if (settingsFunctionToUse) {
      if (environmentToUse) {
        for (var i = 0; i < environmentToUse.length; i++) {
          this._extendMiddlewaresFunctions.push({
            'environment': environmentToUse[i],
            'path': pathToUse,
            'SettingsFunction': settingsFunctionToUse
          });
        }
      } else {
        //we set middleware for all environments
        this._extendMiddlewaresFunctions.push({
          'path': pathToUse,
          'SettingsFunction': settingsFunctionToUse
        });
      }
    } else {
      throw new Error('Wrong arguments for function MWC.extendMiddleware(environmentArrayOrStrings, [path], settingsFunction(core){...})');
    }
    return this;
  }
};

MWC.prototype.extendRoutes = function (settingsFunction) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    if (typeof settingsFunction === 'function') {
      this._extendRoutesFunctions.push(settingsFunction);
      return this;
    } else {
      throw new Error('Wrong argument for MWC.extendAppRoutes(function(core){...});');
    }
  }
};
//todo - refactor
MWC.prototype.usePlugin = function (pluginObjectOrName) {
  if (this.prepared) {
    throw new Error('MWC core application is already prepared! WE CAN\'T EXTEND IT NOW!');
  } else {
    var pluginToBeInstalled = {};
    if (typeof pluginObjectOrName === 'string') {
      pluginToBeInstalled = require('' + pluginObjectOrName);
    } else {
      pluginToBeInstalled = pluginObjectOrName;
    }

    if (pluginToBeInstalled.extendCore) {
      this.extendCore(pluginToBeInstalled.extendCore);
    }
    if (pluginToBeInstalled.extendModel && typeof pluginToBeInstalled.extendModel === 'object') {
      for (var x in pluginToBeInstalled.extendModel) {
        this.extendModel(x, pluginObjectOrName.extendModel[x]);
      }
    }
    if(pluginToBeInstalled.setAppParameters && typeof pluginToBeInstalled.extendApp === 'undefined'){
      console.log('Plugin is outdated! Use extendApp instead of setAppParameters with same syntax!');
      pluginToBeInstalled.extendApp=pluginToBeInstalled.setAppParameters;
    }
    if (pluginToBeInstalled.extendApp) {
      this.extendApp(pluginToBeInstalled.extendApp);
    }
    if(pluginToBeInstalled.setAppMiddlewares && typeof pluginToBeInstalled.extendMiddleware === 'undefined'){
      console.log('Plugin is outdated! Use extendMiddleware instead of setAppMiddlewares with same syntax!');
      pluginToBeInstalled.extendMiddleware=pluginToBeInstalled.setAppMiddlewares;
    }
    if (pluginToBeInstalled.extendMiddleware) {
      this.extendMiddleware(pluginToBeInstalled.extendMiddleware);
    }
    if(pluginToBeInstalled.extendAppRoutes && typeof pluginToBeInstalled.extendRoutes === 'undefined'){
      console.log('Plugin is outdated! Use extendMiddleware instead of setAppMiddlewares with same syntax!');
      pluginToBeInstalled.extendRoutes=pluginToBeInstalled.extendAppRoutes;
    }
    if (pluginToBeInstalled.extendRoutes) {
      this.extendRoutes(pluginToBeInstalled.extendRoutes);
    }
    return this;
  }
};

MWC.prototype.extendListeners = function (eventName, eventHandlerFunction) {
  if (typeof eventName === "string" && typeof eventHandlerFunction === "function") {
    if (typeof this._listeners[eventName] === "undefined") {
      this._listeners[eventName] = eventHandlerFunction;
      return this;
    } else {
      throw new Error('Unable set listener for event ' + eventName + '! Event name is occupied!');
    }
  } else {
    throw new Error('#MWC.extendListeners(eventName,eventHandlerFunction) have wrong arguments!');
  }
};

MWC.prototype.ready = function () {
  var thisMWC = this;//because we sometimes issue closures with thisMWC
  thisMWC.prepared = true;

  //injecting redis
  thisMWC.redisClient = redisManager.create(thisMWC.config.redis);

  // initializing MongoDB and Core Models
  thisMWC.mongoose = mongooseManager.create(thisMWC.config.mongoUrl);
  thisMWC.mongoose.setConnectEvent(thisMWC);
  thisMWC.model = mongooseManager.initModels(thisMWC);

  //doing extendCore
  //extending core by extendCore
  thisMWC._extendCoreFunctions.map(function (settingsFunction) {
    if(typeof thisMWC[settingsFunction.field] === "undefined"){
      thisMWC[settingsFunction.field]=settingsFunction.value;
    } else {
      throw new Error('We try to overwrite kernel field with name of '+settingsFunction.field+'!');
    }
  });

  //loading custom models //todo - maybe redo
  thisMWC._additionalModels.map(function (customModel) {
    thisMWC.model[customModel.name] = customModel.initFunction(thisMWC.mongoose, thisMWC.config);
  });

  //initialize expressJS application
  thisMWC.app = appManager.create(thisMWC);
  appManager.extendApp(thisMWC);

  // set shutdown procedure
  process.on('SIGINT', thisMWC.shutdown);

  for(var eventName in thisMWC._listeners){
    thisMWC.on(eventName, thisMWC._listeners[eventName]);
  }

  return thisMWC;
};

MWC.prototype.listen = function (httpOrHttpsOrPort) {

  if (!this.prepared) {
    this.ready();
  }

  if (httpOrHttpsOrPort) {
    if (typeof httpOrHttpsOrPort === 'number' && httpOrHttpsOrPort > 0) {
      this.app.listen(httpOrHttpsOrPort);
      return;
    }

    if (httpOrHttpsOrPort instanceof http || httpOrHttpsOrPort instanceof https) {
      httpOrHttpsOrPort.createServer(this.app).listen(this.app.get('port'));
      return;
    }
    throw new Error('Function MWC.listen(httpOrHttpsOrPort) accepts objects of null, http, https or port\'s number as argument!');
  } else {
    this.app.listen(this.app.get('port'));//listening to default port
  }
};

MWC.prototype.setAppParameters = function(environment, settingsFunction){
  console.log('setAppParameters is outdated, use extendApp  with the same syntax');
  this.extendApp(environment, settingsFunction);
  return this;
};

MWC.prototype.extendMiddlewares = function(environment, path, settingsFunction){
  console.log('extendMiddlewares is outdated, use extendMiddleware with the same syntax');
  this.extendMiddleware(environment, path, settingsFunction);
  return this;
};

MWC.prototype.setAppMiddlewares = function(environment, path, settingsFunction){
  console.log('setAppMiddlewares is outdated, use extendMiddleware with the same syntax');
  this.extendMiddleware(environment, path, settingsFunction);
  return this;
};

MWC.prototype.extendAppRoutes = function(settingsFunction){
  console.log('extendAppRoutes is outdated, use extendRoutes with the same syntax');
  this.extendRoutes(settingsFunction);
  return this;
};

MWC.prototype.shutdown = function () {

  console.log('MWC IS GOING TO SHUT DOWN....');
  if(this.mongoose.connection){
    this.mongoose.connection.close();
  }
  this.redisClient.end();
  // calling .shutdown allows your process to exit normally
  toobusy.shutdown();
  process.exit();

};

MWC.prototype.injectEmit = function(object) {
  var thisMWC = this;
  object.emitMWC = function (eventName, eventContent) {
    thisMWC.emit(eventName, eventContent);
  };
};

/**
 * @ngdoc function
 * @name mwc.createRedisClient
 * @description
 * Create new redis client
 *
 * Use this function with great caution! Because usually redis-database-as-a-service providers have
 * strict connection limit!!! and every one redis client created like this consumes one connection!
 * Usually, MWC needs only one redis client connection
 * BTW, redis is NOT MySQL - we can't increase speed with connection pooling!
 * @returns {RedisClient} redis client
 */
MWC.prototype.createRedisClient = function() {
  return redisManager.create(this.config.redis);
};

/**
 * @ngdoc function
 * @name mwcKernel.create
 * @description
 * Create MWC object instance (factory)
 * @param {object} config - config object
 */
MWC.create = function(config) {
  return new MWC(config);
};

module.exports = exports = MWC.create;
<|endoftext|>


<commit_before>import React from 'react'
import {Link, State} from 'react-router'
import {isObject, chain, map} from 'lodash'

import toPrettyTerm from 'sto-helpers/lib/toPrettyTerm'
import {queryCourseDatabase} from '../helpers/courses'
import Course from './course'
import stickyfill from '../helpers/initStickyfill'

let SearchButton = React.createClass({
	mixins: [State],

	propTypes: {
		student: React.PropTypes.object.isRequired,
		toggle: React.PropTypes.func.isRequired,
	},

	componentDidMount() {
		stickyfill.add(this.getDOMNode())
	},

	componentWillUnmount() {
		stickyfill.remove(this.getDOMNode())
	},

	getInitialState() {
		return {
			isQuerying: false,
			hasQueried: false,
			results: [],
			queryString: '',
			query: null,
		}
	},

	onSubmit() {
		this.query(this.state.queryString)
	},

	onChange(evt) {
		this.setState({queryString: evt.target.value})
	},

	onKeyDown(evt) {
		if (evt.keyCode == 13) {
			this.onSubmit()
		}
	},

	processQueryResults(resultsAndStartQueryTime) {
		let [results, startQueryTime] = resultsAndStartQueryTime
		console.log('results', results)

		let searchResults = chain(results)
			.sortBy(c => `${c.deptnum}${c.sect || ''}`) // Sort the results
			.groupBy('term') // Group them by term
			.pairs() // Turn the object into an array of pairs
			// Sort the result arrays by the first element, the term,
			// because object keys don't have an implicit sort.
			.sortBy(group => group[0])
			.reverse() // reverse it, so the most recent is at the top
			.flatten() // then flatten so that it's all one flat list
			.value()

		console.log('search results', searchResults)
		let endQueryTime = performance.now()
		console.info(`query took ${(endQueryTime - startQueryTime)}ms.`)

		let startTime = performance.now()
		let courseObjects = map(searchResults, (courseOrTerm) => {
			if (!isObject(courseOrTerm)) {
				let prettyTerm = toPrettyTerm(courseOrTerm)

				return React.createElement('li',
					{key: prettyTerm, className: 'course-group'},
					prettyTerm)
			}
			return React.createElement('li',
				{key: courseOrTerm.clbid},
				React.createElement(Course, {info: courseOrTerm}))
		})

		let endTime = performance.now()
		console.info(`element creation took an additional ${(endTime - startTime)}ms.`)

		this.setState({results: courseObjects, hasQueried: true, query: null})
	},

	query(searchQuery) {
		if (searchQuery.length === 0 || this.state.query)
			return

		this.setState({results: [], hasQueried: false})
		let startQueryTime = performance.now()

		let query = queryCourseDatabase(searchQuery)
			.then(results => [results, startQueryTime])
			.then(this.processQueryResults)

		this.setState({query})
	},

	render() {
		let showNoResults = this.state.results.length === 0 && this.state.hasQueried
		let showIndicator = this.state.query

		return React.createElement('div', {className: 'search-sidebar'},
			React.createElement('header', {className: 'sidebar-heading'},
				React.createElement('h1', null, 'Search for Courses'),
				React.createElement('button', {
					className: 'close-sidebar',
					title: 'Close Sidebar',
					onClick: this.props.toggle,
				})),
			React.createElement('input', {
				type: 'search',
				placeholder: 'Search Courses',
				defaultValue: this.state.query,
				onChange: this.onChange,
				onKeyDown: this.onKeyDown,
				className: 'search-box',
				autoFocus: true,
			}),
			React.createElement('ul', {className: 'course-list'},
				showIndicator ?
					React.createElement('li', {className: 'loading'},
						React.createElement('div', {className: 'loading-spinner'},
							React.createElement('div', null))) :
					showNoResults ?
						React.createElement('li', {className: 'no-results'},
							'No Results Found') :
						this.state.results)
		)
	},
})

export default SearchButton
<commit_msg>Flatten twice in searchButton<commit_after>import React from 'react'
import {Link, State} from 'react-router'
import {isObject, chain, map} from 'lodash'

import toPrettyTerm from 'sto-helpers/lib/toPrettyTerm'
import {queryCourseDatabase} from '../helpers/courses'
import Course from './course'
import stickyfill from '../helpers/initStickyfill'

let SearchButton = React.createClass({
	mixins: [State],

	propTypes: {
		student: React.PropTypes.object.isRequired,
		toggle: React.PropTypes.func.isRequired,
	},

	componentDidMount() {
		stickyfill.add(this.getDOMNode())
	},

	componentWillUnmount() {
		stickyfill.remove(this.getDOMNode())
	},

	getInitialState() {
		return {
			isQuerying: false,
			hasQueried: false,
			results: [],
			queryString: '',
			query: null,
		}
	},

	onSubmit() {
		this.query(this.state.queryString)
	},

	onChange(evt) {
		this.setState({queryString: evt.target.value})
	},

	onKeyDown(evt) {
		if (evt.keyCode == 13) {
			this.onSubmit()
		}
	},

	processQueryResults(resultsAndStartQueryTime) {
		let [results, startQueryTime] = resultsAndStartQueryTime
		console.log('results', results)

		let searchResults = chain(results)
			.sortBy(c => `${c.deptnum}${c.sect || ''}`) // Sort the results
			.groupBy('term') // Group them by term
			.pairs() // Turn the object into an array of pairs
			// Sort the result arrays by the first element, the term,
			// because object keys don't have an implicit sort.
			.sortBy(group => group[0])
			.reverse() // reverse it, so the most recent is at the top
			.flatten() // flatten once, to merge the [date, courses] arrays
			.flatten() // then flatten once more, to raise the courses into the array
			.value()

		console.log('search results', searchResults)
		let endQueryTime = performance.now()
		console.info(`query took ${(endQueryTime - startQueryTime)}ms.`)

		let startTime = performance.now()
		let courseObjects = map(searchResults, (courseOrTerm) => {
			if (!isObject(courseOrTerm)) {
				let prettyTerm = toPrettyTerm(courseOrTerm)

				return React.createElement('li',
					{key: prettyTerm, className: 'course-group'},
					prettyTerm)
			}
			return React.createElement('li',
				{key: courseOrTerm.clbid},
				React.createElement(Course, {info: courseOrTerm}))
		})

		let endTime = performance.now()
		console.info(`element creation took an additional ${(endTime - startTime)}ms.`)

		this.setState({results: courseObjects, hasQueried: true, query: null})
	},

	query(searchQuery) {
		if (searchQuery.length === 0 || this.state.query)
			return

		this.setState({results: [], hasQueried: false})
		let startQueryTime = performance.now()

		let query = queryCourseDatabase(searchQuery)
			.then(results => [results, startQueryTime])
			.then(this.processQueryResults)

		this.setState({query})
	},

	render() {
		let showNoResults = this.state.results.length === 0 && this.state.hasQueried
		let showIndicator = this.state.query

		return React.createElement('div', {className: 'search-sidebar'},
			React.createElement('header', {className: 'sidebar-heading'},
				React.createElement('h1', null, 'Search for Courses'),
				React.createElement('button', {
					className: 'close-sidebar',
					title: 'Close Sidebar',
					onClick: this.props.toggle,
				})),
			React.createElement('input', {
				type: 'search',
				placeholder: 'Search Courses',
				defaultValue: this.state.query,
				onChange: this.onChange,
				onKeyDown: this.onKeyDown,
				className: 'search-box',
				autoFocus: true,
			}),
			React.createElement('ul', {className: 'course-list'},
				showIndicator ?
					React.createElement('li', {className: 'loading'},
						React.createElement('div', {className: 'loading-spinner'},
							React.createElement('div', null))) :
					showNoResults ?
						React.createElement('li', {className: 'no-results'},
							'No Results Found') :
						this.state.results)
		)
	},
})

export default SearchButton
<|endoftext|>


<commit_before>var robotjs = require('./build/Release/robotjs.node');

module.exports = robotjs;

module.exports.screen = {};

function bitmap (width, height, byteWidth, bitsPerPixel, bytesPerPixel, image)
{
    this.width = width;
    this.height = height;
    this.byteWidth = byteWidth;
    this.bitsPerPixel = bitsPerPixel;
    this.bytesPerPixel = bytesPerPixel;
    this.image = image;
}

bitmap.prototype.colorAt = function(x, y)
{
    return robotjs.getColor(this, x, y);
};

module.exports.screen.capture = function()
{
    b = robotjs.captureScreen();
    return new bitmap(b.width, b.height, b.byteWidth, b.bitsPerPixel, b.bytesPerPixel, b.image);
};<commit_msg>Remove unnecessary space.<commit_after>var robotjs = require('./build/Release/robotjs.node');

module.exports = robotjs;

module.exports.screen = {};

function bitmap(width, height, byteWidth, bitsPerPixel, bytesPerPixel, image)
{
    this.width = width;
    this.height = height;
    this.byteWidth = byteWidth;
    this.bitsPerPixel = bitsPerPixel;
    this.bytesPerPixel = bytesPerPixel;
    this.image = image;
}

bitmap.prototype.colorAt = function(x, y)
{
    return robotjs.getColor(this, x, y);
};

module.exports.screen.capture = function()
{
    b = robotjs.captureScreen();
    return new bitmap(b.width, b.height, b.byteWidth, b.bitsPerPixel, b.bytesPerPixel, b.image);
};<|endoftext|>