<commit_before>import retry from 'async-retry';
import dns from 'dns';
import Now from '../lib';
import toHost from './to-host';
import chalk from 'chalk';

export default class Alias extends Now {

  async ls (target) {
    if (target) {
      const res = await this._fetch(`/now/deployments/${target}/aliases`);
      const body = await res.json();
      return body.aliases;
    }

    const res = await this._fetch('/now/aliases');
    const body = await res.json();
    return body.aliases;
  }

  async rm (alias) {
    const res = await this._fetch(`/now/aliases/${alias}`, {
      method: 'DELETE'
    });
    const body = await res.json();

    if (res.status !== 200) {
      const err = new Error('Deletion failed ' + body);
      err.userError = true;
      throw err;
    }

    console.log(`${chalk.cyan('> Success!')}`);
  }

  async set (deployment, alias) {
    const list = await this.list();
    let key, val;

    if (/\./.test(deployment)) {
      val = toHost(deployment);
      key = 'url';
    } else {
      val = deployment;
      key = 'uid';
    }

    const depl = list.find((d) => {
      if (d[key] === val) {
        if (this._debug) console.log(`> [debug] matched deployment ${d.uid} by ${key} ${val}`);
        return true;
      }

      // match prefix
      if (`${val}.now.sh` === d.url) {
        if (this._debug) console.log(`> [debug] matched deployment ${d.uid} by url ${d.url}`);
        return true;
      }

      return false;
    });

    if (!depl) {
      const err = new Error(`Deployment not found by "${deployment}". Run ${chalk.dim('`now ls`')} to see your deployments.`);
      err.userError = true;
      throw err;
    }

    // evaluate the alias
    if (!/\./.test(alias)) {
      if (this._debug) console.log(`> [debug] suffixing \`.now.sh\` to alias ${alias}`);
      alias = `${alias}.now.sh`;
    } else {
      alias = toHost(alias);
    }

    await this.createAlias(depl, alias);
    console.log(`${chalk.cyan('> Success!')} Set up alias ${chalk.bold(alias)}`);
  }

  async createAlias (depl, alias) {
    return this.retry(async (bail, attempt) => {
      if (this._debug) console.time(`> [debug] /now/deployments/${depl.uid}/aliases #${attempt}`);
      const res = await this._fetch(`/now/deployments/${depl.uid}/aliases`, {
        method: 'POST',
        body: { alias }
      });

      if (304 === res.status) return;

      const body = await res.json();
      if (this._debug) console.timeEnd(`> [debug] /now/deployments/${depl.uid}/aliases #${attempt}`);

      // no retry on authorization problems
      if (403 === res.status) {
        const code = body.error.code;

        if ('custom_domain_needs_upgrade' === code) {
          const err = new Error(`You are attempting to use a custom domain alias (${chalk.underline(chalk.cyan(alias))}), but this is only enabled for premium accounts. Please upgrade at ${chalk.underline('https://zeit.co/account')}`);
          err.userError = true;
          return bail(err);
        }

        if ('alias_in_use' === code) {
          const err = new Error(`The alias you are trying to configure (${chalk.underline(chalk.cyan(alias))}) is already in use by a different account.`);
          err.userError = true;
          return bail(err);
        }

        return bail(new Error('Authorization error'));
      }

      // all other errors
      if (body.error) {
        const code = body.error.code;

        if ('deployment_not_found' === code) {
          return bail(new Error('Deployment not found'));
        }

        if ('cert_missing' === code) {
          console.log(`> Provisioning certificate for ${chalk.underline(chalk.cyan(alias))}`);

          await this.verifyOwnership();
          await this.createCert();

          // try again, but now having provisioned the certificate
          return this.createAlias(depl, alias);
        }

        return bail(new Error(body.error.message));
      }

      // the two expected succesful cods are 200 and 304
      if (200 !== res.status && 304 !== res.status) {
        throw new Error('Unhandled error');
      }
    });
  }

  async verifyOwnership (domain) {
    return this.retry(async (bail, attempt) => {
      const targets = await resolve4('alias.zeit.co');

      if (!targets.length) {
        return bail(new Error('Unable to resolve alias.zeit.co'));
      }

      const ips = await resolve4(domain);
      if (!ips.length) {
        const err = new Error('The domain ${domain} A record in the DNS configuration is not returning any IPs.');
        err.userError = true;
        return bail(err);
      }

      for (const ip of ips) {
        if (!~targets.indexOf(ip)) {
          const err = new Error(`The domain ${domain} has an A record ${chalk.bold(ip)} that doesn\'t resolve to ${chalk.bold('alias.zeit.co')}. Make sure the appropriate \`ALIAS\` or \`CNAME\` records are configured.`);
          err.userError = true;
          return bail(err);
        }
      }
    });
  }

  async createCert (domain) {
    return this.retry(async (bail, attempt) => {
      if (this._debug) console.time(`> [debug] /certs #${attempt}`);
      const res = await this._fetch('/certs', {
        method: 'POST',
        body: {
          domains: [domain]
        }
      });

      const body = await res.json();
      if (this._debug) console.timeEnd(`> [debug] /certs #${attempt}`);

      if (body.error) {
        const { code } = body.error;

        if ('verification_failed' === code) {
          const err = new Error(`We couldn't verify ownership of the domain ${domain}. Make sure the appropriate \`ALIAS\` or \`CNAME\` records are configured and pointing to ${chalk.bold('alias.zeit.co')}.`);
          err.userError = true;
          return bail(err);
        }

        throw new Error(body.message);
      }

      if (200 !== res.status && 304 !== res.status) {
        throw new Error('Unhandled error');
      }
    });
  }

  retry (fn) {
    return retry(fn, { retries: 5, randomize: true, onRetry: this._onRetry });
  }

}

function resolve4 (host) {
  return new Promise((resolve, reject) => {
    return dns.resolve4(host, (err, answer) => {
      if (err) return reject(err);
      resolve(answer);
    });
  });
}
<commit_msg>`now alias ls`: accept deployment url<commit_after>import retry from 'async-retry';
import dns from 'dns';
import Now from '../lib';
import toHost from './to-host';
import chalk from 'chalk';

export default class Alias extends Now {

  async ls (deployment) {
    if (deployment) {
      const target = await this.findDeployment(deployment);
      const res = await this._fetch(`/now/deployments/${target.uid}/aliases`);
      const body = await res.json();
      return body.aliases;
    }

    const res = await this._fetch('/now/aliases');
    const body = await res.json();
    return body.aliases;
  }

  async rm (alias) {
    const res = await this._fetch(`/now/aliases/${alias}`, {
      method: 'DELETE'
    });
    const body = await res.json();

    if (res.status !== 200) {
      const err = new Error('Deletion failed ' + body);
      err.userError = true;
      throw err;
    }

    console.log(`${chalk.cyan('> Success!')}`);
  }

  async findDeployment (deployment) {
    const list = await this.list();
    let key, val;
    if (/\./.test(deployment)) {
      val = toHost(deployment);
      key = 'url';
    } else {
      val = deployment;
      key = 'uid';
    }

    const depl = list.find((d) => {
      if (d[key] === val) {
        if (this._debug) console.log(`> [debug] matched deployment ${d.uid} by ${key} ${val}`);
        return true;
      }

      // match prefix
      if (`${val}.now.sh` === d.url) {
        if (this._debug) console.log(`> [debug] matched deployment ${d.uid} by url ${d.url}`);
        return true;
      }

      return false;
    });

    return depl;
  }

  async set (deployment, alias) {
    const depl = await this.findDeployment(deployment);
    if (!depl) {
      const err = new Error(`Deployment not found by "${deployment}". Run ${chalk.dim('`now ls`')} to see your deployments.`);
      err.userError = true;
      throw err;
    }

    // evaluate the alias
    if (!/\./.test(alias)) {
      if (this._debug) console.log(`> [debug] suffixing \`.now.sh\` to alias ${alias}`);
      alias = `${alias}.now.sh`;
    } else {
      alias = toHost(alias);
    }

    await this.createAlias(depl, alias);
    console.log(`${chalk.cyan('> Success!')} Set up alias ${chalk.bold(alias)}`);
  }

  async createAlias (depl, alias) {
    return this.retry(async (bail, attempt) => {
      if (this._debug) console.time(`> [debug] /now/deployments/${depl.uid}/aliases #${attempt}`);
      const res = await this._fetch(`/now/deployments/${depl.uid}/aliases`, {
        method: 'POST',
        body: { alias }
      });

      if (304 === res.status) return;

      const body = await res.json();
      if (this._debug) console.timeEnd(`> [debug] /now/deployments/${depl.uid}/aliases #${attempt}`);

      // no retry on authorization problems
      if (403 === res.status) {
        const code = body.error.code;

        if ('custom_domain_needs_upgrade' === code) {
          const err = new Error(`You are attempting to use a custom domain alias (${chalk.underline(chalk.cyan(alias))}), but this is only enabled for premium accounts. Please upgrade at ${chalk.underline('https://zeit.co/account')}`);
          err.userError = true;
          return bail(err);
        }

        if ('alias_in_use' === code) {
          const err = new Error(`The alias you are trying to configure (${chalk.underline(chalk.cyan(alias))}) is already in use by a different account.`);
          err.userError = true;
          return bail(err);
        }

        return bail(new Error('Authorization error'));
      }

      // all other errors
      if (body.error) {
        const code = body.error.code;

        if ('deployment_not_found' === code) {
          return bail(new Error('Deployment not found'));
        }

        if ('cert_missing' === code) {
          console.log(`> Provisioning certificate for ${chalk.underline(chalk.cyan(alias))}`);

          await this.verifyOwnership();
          await this.createCert();

          // try again, but now having provisioned the certificate
          return this.createAlias(depl, alias);
        }

        return bail(new Error(body.error.message));
      }

      // the two expected succesful cods are 200 and 304
      if (200 !== res.status && 304 !== res.status) {
        throw new Error('Unhandled error');
      }
    });
  }

  async verifyOwnership (domain) {
    return this.retry(async (bail, attempt) => {
      const targets = await resolve4('alias.zeit.co');

      if (!targets.length) {
        return bail(new Error('Unable to resolve alias.zeit.co'));
      }

      const ips = await resolve4(domain);
      if (!ips.length) {
        const err = new Error('The domain ${domain} A record in the DNS configuration is not returning any IPs.');
        err.userError = true;
        return bail(err);
      }

      for (const ip of ips) {
        if (!~targets.indexOf(ip)) {
          const err = new Error(`The domain ${domain} has an A record ${chalk.bold(ip)} that doesn\'t resolve to ${chalk.bold('alias.zeit.co')}. Make sure the appropriate \`ALIAS\` or \`CNAME\` records are configured.`);
          err.userError = true;
          return bail(err);
        }
      }
    });
  }

  async createCert (domain) {
    return this.retry(async (bail, attempt) => {
      if (this._debug) console.time(`> [debug] /certs #${attempt}`);
      const res = await this._fetch('/certs', {
        method: 'POST',
        body: {
          domains: [domain]
        }
      });

      const body = await res.json();
      if (this._debug) console.timeEnd(`> [debug] /certs #${attempt}`);

      if (body.error) {
        const { code } = body.error;

        if ('verification_failed' === code) {
          const err = new Error(`We couldn't verify ownership of the domain ${domain}. Make sure the appropriate \`ALIAS\` or \`CNAME\` records are configured and pointing to ${chalk.bold('alias.zeit.co')}.`);
          err.userError = true;
          return bail(err);
        }

        throw new Error(body.message);
      }

      if (200 !== res.status && 304 !== res.status) {
        throw new Error('Unhandled error');
      }
    });
  }

  retry (fn) {
    return retry(fn, { retries: 5, randomize: true, onRetry: this._onRetry });
  }

}

function resolve4 (host) {
  return new Promise((resolve, reject) => {
    return dns.resolve4(host, (err, answer) => {
      if (err) return reject(err);
      resolve(answer);
    });
  });
}
<|endoftext|>


<commit_before>const assert = require('assert')
const bitcoin = require('../../')
const dhttpCallback = require('dhttp/200')
// use Promises
const dhttp = options => new Promise((resolve, reject) => {
  return dhttpCallback(options, (err, data) => {
    if (err) return reject(err)
    else return resolve(data)
  })
})

const APIPASS = process.env.APIPASS || 'satoshi'
const APIURL = 'https://regtest.bitbank.cc/1'
const NETWORK = bitcoin.networks.testnet

function broadcast (txHex) {
  return dhttp({
    method: 'POST',
    url: APIURL + '/t/push',
    body: txHex
  })
}

function mine (count) {
  return dhttp({
    method: 'POST',
    url: APIURL + '/r/generate?count=' + count + '&key=' + APIPASS
  })
}

function height () {
  return dhttp({
    method: 'GET',
    url: APIURL + '/b/best/height'
  })
}

function _faucetRequest (address, value) {
  return dhttp({
    method: 'POST',
    url: APIURL + '/r/faucet?address=' + address + '&value=' + value + '&key=' + APIPASS
  })
}

async function faucet (address, value) {
  let count = 0
  let _unspents = []
  const sleep = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
  do {
    if (count > 0) {
      if (count >= 5) throw new Error('Missing Inputs')
      console.log('Missing Inputs, retry #' + count)
      await sleep(200)
    }

    const txId = await _faucetRequest(address, value)
      .then(
        v => v, // Pass success value as is
        async err => {
          // Bad Request error is fixed by making sure height is >= 432
          const currentHeight = await height()
          if (err.message === 'Bad Request' && currentHeight < 432) {
            await mine(432 - currentHeight)
            return _faucetRequest(address, value)
          } else {
            throw err
          }
        }
      )

    await sleep(100)

    const results = await unspents(address)

    _unspents = results.filter(x => x.txId === txId)

    count++
  } while (_unspents.length === 0)

  return _unspents.pop()
}

async function faucetComplex (output, value) {
  const keyPair = bitcoin.ECPair.makeRandom({ network: NETWORK })
  const p2pkh = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: NETWORK })

  const unspent = await faucet(p2pkh.address, value * 2)

  const txvb = new bitcoin.TransactionBuilder(NETWORK)
  txvb.addInput(unspent.txId, unspent.vout, null, p2pkh.output)
  txvb.addOutput(output, value)
  txvb.sign(0, keyPair)
  const txv = txvb.build()

  await broadcast(txv.toHex())

  return {
    txId: txv.getId(),
    vout: 0,
    value
  }
}

function fetch (txId) {
  return dhttp({
    method: 'GET',
    url: APIURL + '/t/' + txId + '/json'
  })
}

function unspents (address) {
  return dhttp({
    method: 'GET',
    url: APIURL + '/a/' + address + '/unspents'
  })
}

async function verify (txo) {
  const tx = await fetch(txo.txId)

  const txoActual = tx.outs[txo.vout]
  if (txo.address) assert.strictEqual(txoActual.address, txo.address)
  if (txo.value) assert.strictEqual(txoActual.value, txo.value)
}

function getAddress (node, network) {
  return bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address
}

function randomAddress () {
  return getAddress(bitcoin.ECPair.makeRandom({
    network: bitcoin.networks.testnet
  }), bitcoin.networks.testnet)
}

module.exports = {
  broadcast,
  dhttp,
  faucet,
  faucetComplex,
  fetch,
  height,
  mine,
  network: NETWORK,
  unspents,
  verify,
  randomAddress,
  RANDOM_ADDRESS: randomAddress()
}
<commit_msg>Randomize sleep times<commit_after>const assert = require('assert')
const bitcoin = require('../../')
const dhttpCallback = require('dhttp/200')
// use Promises
const dhttp = options => new Promise((resolve, reject) => {
  return dhttpCallback(options, (err, data) => {
    if (err) return reject(err)
    else return resolve(data)
  })
})

const APIPASS = process.env.APIPASS || 'satoshi'
const APIURL = 'https://regtest.bitbank.cc/1'
const NETWORK = bitcoin.networks.testnet

function broadcast (txHex) {
  return dhttp({
    method: 'POST',
    url: APIURL + '/t/push',
    body: txHex
  })
}

function mine (count) {
  return dhttp({
    method: 'POST',
    url: APIURL + '/r/generate?count=' + count + '&key=' + APIPASS
  })
}

function height () {
  return dhttp({
    method: 'GET',
    url: APIURL + '/b/best/height'
  })
}

function _faucetRequest (address, value) {
  return dhttp({
    method: 'POST',
    url: APIURL + '/r/faucet?address=' + address + '&value=' + value + '&key=' + APIPASS
  })
}

async function faucet (address, value) {
  let count = 0
  let _unspents = []
  const sleep = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
  const randInt = (min, max) => min + Math.floor((max - min + 1) * Math.random())
  do {
    if (count > 0) {
      if (count >= 5) throw new Error('Missing Inputs')
      console.log('Missing Inputs, retry #' + count)
      await sleep(randInt(150, 250))
    }

    const txId = await _faucetRequest(address, value)
      .then(
        v => v, // Pass success value as is
        async err => {
          // Bad Request error is fixed by making sure height is >= 432
          const currentHeight = await height()
          if (err.message === 'Bad Request' && currentHeight < 432) {
            await mine(432 - currentHeight)
            return _faucetRequest(address, value)
          } else {
            throw err
          }
        }
      )

    await sleep(randInt(50, 150))

    const results = await unspents(address)

    _unspents = results.filter(x => x.txId === txId)

    count++
  } while (_unspents.length === 0)

  return _unspents.pop()
}

async function faucetComplex (output, value) {
  const keyPair = bitcoin.ECPair.makeRandom({ network: NETWORK })
  const p2pkh = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: NETWORK })

  const unspent = await faucet(p2pkh.address, value * 2)

  const txvb = new bitcoin.TransactionBuilder(NETWORK)
  txvb.addInput(unspent.txId, unspent.vout, null, p2pkh.output)
  txvb.addOutput(output, value)
  txvb.sign(0, keyPair)
  const txv = txvb.build()

  await broadcast(txv.toHex())

  return {
    txId: txv.getId(),
    vout: 0,
    value
  }
}

function fetch (txId) {
  return dhttp({
    method: 'GET',
    url: APIURL + '/t/' + txId + '/json'
  })
}

function unspents (address) {
  return dhttp({
    method: 'GET',
    url: APIURL + '/a/' + address + '/unspents'
  })
}

async function verify (txo) {
  const tx = await fetch(txo.txId)

  const txoActual = tx.outs[txo.vout]
  if (txo.address) assert.strictEqual(txoActual.address, txo.address)
  if (txo.value) assert.strictEqual(txoActual.value, txo.value)
}

function getAddress (node, network) {
  return bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address
}

function randomAddress () {
  return getAddress(bitcoin.ECPair.makeRandom({
    network: bitcoin.networks.testnet
  }), bitcoin.networks.testnet)
}

module.exports = {
  broadcast,
  dhttp,
  faucet,
  faucetComplex,
  fetch,
  height,
  mine,
  network: NETWORK,
  unspents,
  verify,
  randomAddress,
  RANDOM_ADDRESS: randomAddress()
}
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */
function _FirebugConsole()
{
    this.log = function() { window._firebug.notifyFirebug(arguments, 'log', 'firebugAppendConsole'); }
    this.debug = function() { window._firebug.notifyFirebug(arguments, 'debug', 'firebugAppendConsole'); }
    this.info = function() { window._firebug.notifyFirebug(arguments, 'info', 'firebugAppendConsole'); }
    this.warn = function() { window._firebug.notifyFirebug(arguments, 'warn', 'firebugAppendConsole'); }
    this.error = function() { window._firebug.notifyFirebug(arguments, 'error', 'firebugAppendConsole'); }
    this.exception = function() { window._firebug.notifyFirebug(arguments, 'exception', 'firebugAppendConsole'); }
    this.assert = function() { window._firebug.notifyFirebug(arguments, 'assert', 'firebugAppendConsole'); }
    this.dir = function() { window._firebug.notifyFirebug(arguments, 'dir', 'firebugAppendConsole'); }
    this.dirxml = function() { window._firebug.notifyFirebug(arguments, 'dirxml', 'firebugAppendConsole'); }
    this.trace = function firebugDebuggerTracer() { debugger; }
    this.group = function() { window._firebug.notifyFirebug(arguments, 'group', 'firebugAppendConsole'); }
    this.groupEnd = function() { window._firebug.notifyFirebug(arguments, 'groupEnd', 'firebugAppendConsole'); }
    this.groupCollapsed = function() { window._firebug.notifyFirebug(arguments, 'groupCollapsed', 'firebugAppendConsole'); }
    this.time = function() { window._firebug.notifyFirebug(arguments, 'time', 'firebugAppendConsole'); }
    this.timeEnd = function() { window._firebug.notifyFirebug(arguments, 'timeEnd', 'firebugAppendConsole'); }
    this.profile = function() { window._firebug.notifyFirebug(arguments, 'profile', 'firebugAppendConsole'); }
    this.profileEnd = function() { window._firebug.notifyFirebug(arguments, 'profileEnd', 'firebugAppendConsole'); }
    this.count = function() { window._firebug.notifyFirebug(arguments, 'count', 'firebugAppendConsole'); }
    this.clear = function() { window._firebug.notifyFirebug(arguments, 'clear', 'firebugAppendConsole'); }

    // DBG this.uid = Math.random();

    this.notifyFirebug = function(objs, methodName, eventID)
    {
        var element = this.getFirebugElement();

        var event = document.createEvent("Events");
        event.initEvent(eventID, true, false);

        window._firebug.userObjects = [];
        for (var i=0; i<objs.length; i++)
            window._firebug.userObjects.push(objs[i]);

        var length = window._firebug.userObjects.length;
        element.setAttribute("methodName", methodName);

        // DBG element.setAttribute("uid", this.uid);

        // DBG if (length > 0)
        // DBG 	element.setAttribute("checkUserObjects", this.userObjects[0].toString());
        // DBG else
        // DBG 	element.setAttribute("checkUserObjects", "no userObjects");

        // DBG dump("FirebugConsole("+this.uid+") dispatching event "+methodName+" via "+eventID+" with "+length+ " user objects, [0]:"+this.userObjects[0]+"\n");
        //debugger;

        element.dispatchEvent(event);

        // DBG dump("FirebugConsole dispatched event "+methodName+" via "+eventID+" with "+length+ " user objects, [0]:"+this.userObjects[0]+"\n");

        var result;
        if (element.getAttribute("retValueType") == "array")
            result = [];

        if (!result && this.userObjects.length == length+1)
            return this.userObjects[length];

        for (var i=length; i<this.userObjects.length && result; i++)
            result.push(this.userObjects[i]);

        return result;
    };

    this.getFirebugElement = function()
    {
        if (!this.element)
            this.element = window._getFirebugConsoleElement();
        return this.element;
    },

    // ***********************************************************************
    // Console API

    this.__defineGetter__("firebug", function(){
        return this.getFirebugElement().getAttribute("FirebugVersion");
    });
}

window._getFirebugConsoleElement = function()  // could this be done in extension code? but only after load....
{
    var element = document.getElementById("_firebugConsole");
    if (!element)
    {
        if (document.documentElement.nodeName == document.documentElement.nodeName.toUpperCase())
            element = document.createElement("div");
        else
            element = document.createElementNS("http://www.w3.org/1999/xhtml","html:div"); // NS for XML/svg

        element.setAttribute("id", "_firebugConsole");
        element.firebugIgnore = true;
        element.setAttribute("style", "display:none");

        var body = document.body ? document.body : document.getElementsByTagName("body")[0];
        if (!body)
            body = document.documentElement;  // For non-HTML docs

        body.appendChild(element);
    }
    return element;
};
<commit_msg>Avoid anonymous functions injected by Firebug console (in order to see them in memory profiler).<commit_after>/* See license.txt for terms of usage */
function _FirebugConsole()
{
    this.log = function log() { window._firebug.notifyFirebug(arguments, 'log', 'firebugAppendConsole'); }
    this.debug = function debug() { window._firebug.notifyFirebug(arguments, 'debug', 'firebugAppendConsole'); }
    this.info = function info() { window._firebug.notifyFirebug(arguments, 'info', 'firebugAppendConsole'); }
    this.warn = function warn() { window._firebug.notifyFirebug(arguments, 'warn', 'firebugAppendConsole'); }
    this.error = function error() { window._firebug.notifyFirebug(arguments, 'error', 'firebugAppendConsole'); }
    this.exception = function exception() { window._firebug.notifyFirebug(arguments, 'exception', 'firebugAppendConsole'); }
    this.assert = function assert() { window._firebug.notifyFirebug(arguments, 'assert', 'firebugAppendConsole'); }
    this.dir = function dir() { window._firebug.notifyFirebug(arguments, 'dir', 'firebugAppendConsole'); }
    this.dirxml = function dirxml() { window._firebug.notifyFirebug(arguments, 'dirxml', 'firebugAppendConsole'); }
    this.trace = function firebugDebuggerTracer() { debugger; }
    this.group = function group() { window._firebug.notifyFirebug(arguments, 'group', 'firebugAppendConsole'); }
    this.groupEnd = function groupEnd() { window._firebug.notifyFirebug(arguments, 'groupEnd', 'firebugAppendConsole'); }
    this.groupCollapsed = function groupCollapsed() { window._firebug.notifyFirebug(arguments, 'groupCollapsed', 'firebugAppendConsole'); }
    this.time = function time() { window._firebug.notifyFirebug(arguments, 'time', 'firebugAppendConsole'); }
    this.timeEnd = function timeEnd() { window._firebug.notifyFirebug(arguments, 'timeEnd', 'firebugAppendConsole'); }
    this.profile = function profile() { window._firebug.notifyFirebug(arguments, 'profile', 'firebugAppendConsole'); }
    this.profileEnd = function profileEnd() { window._firebug.notifyFirebug(arguments, 'profileEnd', 'firebugAppendConsole'); }
    this.count = function count() { window._firebug.notifyFirebug(arguments, 'count', 'firebugAppendConsole'); }
    this.clear = function clear() { window._firebug.notifyFirebug(arguments, 'clear', 'firebugAppendConsole'); }

    // DBG this.uid = Math.random();

    this.notifyFirebug = function notifyFirebug(objs, methodName, eventID)
    {
        var element = this.getFirebugElement();

        var event = document.createEvent("Events");
        event.initEvent(eventID, true, false);

        window._firebug.userObjects = [];
        for (var i=0; i<objs.length; i++)
            window._firebug.userObjects.push(objs[i]);

        var length = window._firebug.userObjects.length;
        element.setAttribute("methodName", methodName);

        // DBG element.setAttribute("uid", this.uid);

        // DBG if (length > 0)
        // DBG 	element.setAttribute("checkUserObjects", this.userObjects[0].toString());
        // DBG else
        // DBG 	element.setAttribute("checkUserObjects", "no userObjects");

        // DBG dump("FirebugConsole("+this.uid+") dispatching event "+methodName+" via "+eventID+" with "+length+ " user objects, [0]:"+this.userObjects[0]+"\n");
        //debugger;

        element.dispatchEvent(event);

        // DBG dump("FirebugConsole dispatched event "+methodName+" via "+eventID+" with "+length+ " user objects, [0]:"+this.userObjects[0]+"\n");

        var result;
        if (element.getAttribute("retValueType") == "array")
            result = [];

        if (!result && this.userObjects.length == length+1)
            return this.userObjects[length];

        for (var i=length; i<this.userObjects.length && result; i++)
            result.push(this.userObjects[i]);

        return result;
    };

    this.getFirebugElement = function getFirebugElement()
    {
        if (!this.element)
            this.element = window._getFirebugConsoleElement();
        return this.element;
    },

    // ***********************************************************************
    // Console API

    this.__defineGetter__("firebug", function firebug() {
        return this.getFirebugElement().getAttribute("FirebugVersion");
    });
}

window._getFirebugConsoleElement = function _getFirebugConsoleElement()  // could this be done in extension code? but only after load....
{
    var element = document.getElementById("_firebugConsole");
    if (!element)
    {
        if (document.documentElement.nodeName == document.documentElement.nodeName.toUpperCase())
            element = document.createElement("div");
        else
            element = document.createElementNS("http://www.w3.org/1999/xhtml","html:div"); // NS for XML/svg

        element.setAttribute("id", "_firebugConsole");
        element.firebugIgnore = true;
        element.setAttribute("style", "display:none");

        var body = document.body ? document.body : document.getElementsByTagName("body")[0];
        if (!body)
            body = document.documentElement;  // For non-HTML docs

        body.appendChild(element);
    }
    return element;
};
<|endoftext|>


<commit_before>'use strict'

const t = require('tap')
const test = t.test
const request = require('request')
const Fastify = require('..')
const jsonParser = require('fast-json-body')

test('contentTypeParser method should exist', t => {
  t.plan(1)
  const fastify = Fastify()
  t.ok(fastify.addContentTypeParser)
})

test('contentTypeParser should add a custom parser', t => {
  t.plan(4)
  const fastify = Fastify()

  fastify.post('/', (req, reply) => {
    reply.send(req.body)
  })

  fastify.addContentTypeParser('application/jsoff', function (req, done) {
    jsonParser(req, function (err, body) {
      if (err) return done(err)
      done(body)
    })
  })

  fastify.listen(0, err => {
    t.error(err)

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port,
      body: '{"hello":"world"}',
      headers: {
        'Content-Type': 'application/jsoff'
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 200)
      t.deepEqual(body, JSON.stringify({ hello: 'world' }))
      fastify.close()
    })
  })
})

test('contentTypeParser should handle multiple custom parsers', t => {
  t.plan(7)
  const fastify = Fastify()

  fastify.post('/', (req, reply) => {
    reply.send(req.body)
  })

  fastify.post('/hello', (req, reply) => {
    reply.send(req.body)
  })

  function customParser (req, done) {
    jsonParser(req, function (err, body) {
      if (err) return done(err)
      done(body)
    })
  }

  fastify.addContentTypeParser('application/jsoff', customParser)
  fastify.addContentTypeParser('application/ffosj', customParser)

  fastify.listen(0, err => {
    t.error(err)
    fastify.server.unref()

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port,
      body: '{"hello":"world"}',
      headers: {
        'Content-Type': 'application/jsoff'
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 200)
      t.deepEqual(body, JSON.stringify({ hello: 'world' }))
    })

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port + '/hello',
      body: '{"hello":"world"}',
      headers: {
        'Content-Type': 'application/ffosj'
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 200)
      t.deepEqual(body, JSON.stringify({ hello: 'world' }))
    })
  })
})

test('contentTypeParser should handle errors', t => {
  t.plan(3)
  const fastify = Fastify()

  fastify.post('/', (req, reply) => {
    reply.send(req.body)
  })

  fastify.addContentTypeParser('application/jsoff', function (req, done) {
    done(new Error('kaboom!'))
  })

  fastify.listen(0, err => {
    t.error(err)

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port,
      body: '{"hello":"world"}',
      headers: {
        'Content-Type': 'application/jsoff'
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 500)
      fastify.close()
    })
  })
})

test('contentTypeParser should support encapsulation', t => {
  t.plan(6)
  const fastify = Fastify()

  fastify.register((instance, opts, next) => {
    instance.addContentTypeParser('application/jsoff', () => {})
    t.ok(instance.hasContentTypeParser('application/jsoff'))

    instance.register((instance, opts, next) => {
      instance.addContentTypeParser('application/ffosj', () => {})
      t.ok(instance.hasContentTypeParser('application/jsoff'))
      t.ok(instance.hasContentTypeParser('application/ffosj'))
      next()
    })

    next()
  })

  fastify.ready(err => {
    t.error(err)
    t.notOk(fastify.hasContentTypeParser('application/jsoff'))
    t.notOk(fastify.hasContentTypeParser('application/ffosj'))
  })
})

test('contentTypeParser should support encapsulation, second try', t => {
  t.plan(4)
  const fastify = Fastify()

  fastify.register((instance, opts, next) => {
    instance.post('/', (req, reply) => {
      reply.send(req.body)
    })

    instance.addContentTypeParser('application/jsoff', function (req, done) {
      jsonParser(req, function (err, body) {
        if (err) return done(err)
        done(body)
      })
    })

    next()
  })

  fastify.listen(0, err => {
    t.error(err)

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port,
      body: '{"hello":"world"}',
      headers: {
        'Content-Type': 'application/jsoff'
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 200)
      t.deepEqual(body, JSON.stringify({ hello: 'world' }))
      fastify.close()
    })
  })
})

test('contentTypeParser shouldn\'t support request with undefined "Content-Type"', t => {
  t.plan(3)
  const fastify = Fastify()

  fastify.post('/', (req, reply) => {
    reply.send(req.body)
  })

  fastify.addContentTypeParser('application/jsoff', function (req, done) {
    jsonParser(req, function (err, body) {
      if (err) return done(err)
      done(body)
    })
  })

  fastify.listen(0, err => {
    t.error(err)

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port,
      body: 'unknown content type!',
      headers: {
        // 'Content-Type': undefined
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 415)
      fastify.close()
    })
  })
})
<commit_msg>Att test - contentTypeParser should add a custom parse in OPTIONS<commit_after>'use strict'

const t = require('tap')
const test = t.test
const request = require('request')
const Fastify = require('..')
const jsonParser = require('fast-json-body')

test('contentTypeParser method should exist', t => {
  t.plan(1)
  const fastify = Fastify()
  t.ok(fastify.addContentTypeParser)
})

test('contentTypeParser should add a custom parser', t => {
  t.plan(3)
  const fastify = Fastify()

  fastify.post('/', (req, reply) => {
    reply.send(req.body)
  })

  fastify.options('/', (req, reply) => {
    reply.send(req.body)
  })

  fastify.addContentTypeParser('application/jsoff', function (req, done) {
    jsonParser(req, function (err, body) {
      if (err) return done(err)
      done(body)
    })
  })

  fastify.listen(0, err => {
    t.error(err)

    t.tearDown(() => fastify.close())

    t.test('in POST', t => {
      t.plan(3)

      request({
        method: 'POST',
        uri: 'http://localhost:' + fastify.server.address().port,
        body: '{"hello":"world"}',
        headers: {
          'Content-Type': 'application/jsoff'
        }
      }, (err, response, body) => {
        t.error(err)
        t.strictEqual(response.statusCode, 200)
        t.deepEqual(body, JSON.stringify({ hello: 'world' }))
      })
    })

    t.test('in OPTIONS', t => {
      t.plan(3)

      request({
        method: 'OPTIONS',
        uri: 'http://localhost:' + fastify.server.address().port,
        body: '{"hello":"world"}',
        headers: {
          'Content-Type': 'application/jsoff'
        }
      }, (err, response, body) => {
        t.error(err)
        t.strictEqual(response.statusCode, 200)
        t.deepEqual(body, JSON.stringify({ hello: 'world' }))
      })
    })
  })
})

test('contentTypeParser should handle multiple custom parsers', t => {
  t.plan(7)
  const fastify = Fastify()

  fastify.post('/', (req, reply) => {
    reply.send(req.body)
  })

  fastify.post('/hello', (req, reply) => {
    reply.send(req.body)
  })

  function customParser (req, done) {
    jsonParser(req, function (err, body) {
      if (err) return done(err)
      done(body)
    })
  }

  fastify.addContentTypeParser('application/jsoff', customParser)
  fastify.addContentTypeParser('application/ffosj', customParser)

  fastify.listen(0, err => {
    t.error(err)
    fastify.server.unref()

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port,
      body: '{"hello":"world"}',
      headers: {
        'Content-Type': 'application/jsoff'
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 200)
      t.deepEqual(body, JSON.stringify({ hello: 'world' }))
    })

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port + '/hello',
      body: '{"hello":"world"}',
      headers: {
        'Content-Type': 'application/ffosj'
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 200)
      t.deepEqual(body, JSON.stringify({ hello: 'world' }))
    })
  })
})

test('contentTypeParser should handle errors', t => {
  t.plan(3)
  const fastify = Fastify()

  fastify.post('/', (req, reply) => {
    reply.send(req.body)
  })

  fastify.addContentTypeParser('application/jsoff', function (req, done) {
    done(new Error('kaboom!'))
  })

  fastify.listen(0, err => {
    t.error(err)

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port,
      body: '{"hello":"world"}',
      headers: {
        'Content-Type': 'application/jsoff'
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 500)
      fastify.close()
    })
  })
})

test('contentTypeParser should support encapsulation', t => {
  t.plan(6)
  const fastify = Fastify()

  fastify.register((instance, opts, next) => {
    instance.addContentTypeParser('application/jsoff', () => {})
    t.ok(instance.hasContentTypeParser('application/jsoff'))

    instance.register((instance, opts, next) => {
      instance.addContentTypeParser('application/ffosj', () => {})
      t.ok(instance.hasContentTypeParser('application/jsoff'))
      t.ok(instance.hasContentTypeParser('application/ffosj'))
      next()
    })

    next()
  })

  fastify.ready(err => {
    t.error(err)
    t.notOk(fastify.hasContentTypeParser('application/jsoff'))
    t.notOk(fastify.hasContentTypeParser('application/ffosj'))
  })
})

test('contentTypeParser should support encapsulation, second try', t => {
  t.plan(4)
  const fastify = Fastify()

  fastify.register((instance, opts, next) => {
    instance.post('/', (req, reply) => {
      reply.send(req.body)
    })

    instance.addContentTypeParser('application/jsoff', function (req, done) {
      jsonParser(req, function (err, body) {
        if (err) return done(err)
        done(body)
      })
    })

    next()
  })

  fastify.listen(0, err => {
    t.error(err)

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port,
      body: '{"hello":"world"}',
      headers: {
        'Content-Type': 'application/jsoff'
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 200)
      t.deepEqual(body, JSON.stringify({ hello: 'world' }))
      fastify.close()
    })
  })
})

test('contentTypeParser shouldn\'t support request with undefined "Content-Type"', t => {
  t.plan(3)
  const fastify = Fastify()

  fastify.post('/', (req, reply) => {
    reply.send(req.body)
  })

  fastify.addContentTypeParser('application/jsoff', function (req, done) {
    jsonParser(req, function (err, body) {
      if (err) return done(err)
      done(body)
    })
  })

  fastify.listen(0, err => {
    t.error(err)

    request({
      method: 'POST',
      uri: 'http://localhost:' + fastify.server.address().port,
      body: 'unknown content type!',
      headers: {
        // 'Content-Type': undefined
      }
    }, (err, response, body) => {
      t.error(err)
      t.strictEqual(response.statusCode, 415)
      fastify.close()
    })
  })
})
<|endoftext|>


<commit_before>/*// accordion.js v2.0
//
// Copyright (c) 2007 stickmanlabs
// Author: Kevin P Miller | http://www.stickmanlabs.com
//
// Accordion is freely distributable under the terms of an MIT-style license.
//
// I don't care what you think about the file size...
//   Be a pro:
//	    http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
//      http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
//

-----------------------------------------------------------------------------------------------

if (typeof Effect == 'undefined')
	throw("accordion.js requires including script.aculo.us' effects.js library!");

var accordion = Class.create();
accordion.prototype = {

	//
	//  Setup the Variables
	//
	showAccordion : null,
	currentAccordion : null,
	duration : null,
	effects : [],
	animating : false,

	//
	//  Initialize the accordions
	//
	initialize: function(container, options) {
	  if (!$(container)) {
	    throw(container+" doesn't exist!");
	    return false;
	  }

		this.options = Object.extend({
			resizeSpeed : 8,
			classNames : {
				toggle : 'accordion_toggle',
				toggleActive : 'accordion_toggle_active',
				content : 'accordion_content'
			},
			defaultSize : {
				height : null,
				width : null
			},
			direction : 'vertical',
			onEvent : 'click'
		}, options || {});

		this.duration = ((11-this.options.resizeSpeed)*0.15);

		var accordions = $$('#'+container+' .'+this.options.classNames.toggle);
		accordions.each(function(accordion) {
			Event.observe(accordion, this.options.onEvent, this.activate.bind(this, accordion), false);
			if (this.options.onEvent == 'click') {
			  accordion.onclick = function() {return false;};
			}

			if (this.options.direction == 'horizontal') {
				var options = $H({width: '0px', display : 'none'});
			} else {
				var options = $H({height: '0px', display:'none'});
			}
			options.merge({display: 'none'});

			this.currentAccordion = $(accordion.next(0)).setStyle(options);
		}.bind(this));
	},

	//
	//  Activate an accordion
	//
	activate : function(accordion) {
		if (this.animating) {
			return false;
		}

		this.effects = [];

		this.currentAccordion = $(accordion.next(0));
		this.currentAccordion.setStyle({
			display: 'block'
		});

		this.currentAccordion.previous(0).addClassName(this.options.classNames.toggleActive);

		if (this.options.direction == 'horizontal') {
			this.scaling = $H({
				scaleX: true,
				scaleY: false
			});
		} else {
			this.scaling = $H({
				scaleX: false,
				scaleY: true
			});
		}

		if (this.currentAccordion == this.showAccordion) {
		  this.deactivate();
		} else {
		  this._handleAccordion();
		}
	},
	//
	// Deactivate an active accordion
	//
	deactivate : function() {
		var options = $H({
		  duration: this.duration,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			queue: {
				position: 'end',
				scope: 'accordionAnimation'
			},
			scaleMode: {
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			},
			afterFinish: function() {
				this.showAccordion.setStyle({
          height: 'auto',
					display: 'none'
				});
				this.showAccordion = null;
				this.animating = false;
			}.bind(this)
		});
    options.merge(this.scaling);

    this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);

		new Effect.Scale(this.showAccordion, 0, options);
	},

  //
  // Handle the open/close actions of the accordion
  //
	_handleAccordion : function() {
		var options = $H({
			sync: true,
			scaleFrom: 0,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			scaleMode: {
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			}
		});
		options.merge(this.scaling);

		this.effects.push(
			new Effect.Scale(this.currentAccordion, 100, options)
		);

		if (this.showAccordion) {
			this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);

			options = $H({
				sync: true,
				scaleContent: false,
				transition: Effect.Transitions.sinoidal
			});
			options.merge(this.scaling);

			this.effects.push(
				new Effect.Scale(this.showAccordion, 0, options)
			);
		}

    new Effect.Parallel(this.effects, {
			duration: this.duration,
			queue: {
				position: 'end',
				scope: 'accordionAnimation'
			},
			beforeStart: function() {
				this.animating = true;
			}.bind(this),
			afterFinish: function() {
				if (this.showAccordion) {
					this.showAccordion.setStyle({
						display: 'none'
					});
				}
				$(this.currentAccordion).setStyle({
				  height: 'auto'
				});
				this.showAccordion = this.currentAccordion;
				this.animating = false;
			}.bind(this)
		});
	}
}
	*/

/* Simple Accordion Script
 * Requires Prototype and Script.aculo.us Libraries
 * By: Brian Crescimanno <brian.crescimanno@gmail.com>
 * http://briancrescimanno.com
 * This work is licensed under the Creative Commons Attribution-Share Alike 3.0
 * http://creativecommons.org/licenses/by-sa/3.0/us/
 */

if (typeof Effect == 'undefined')
  throw("You must have the script.aculo.us library to use this accordion");

var Accordion = Class.create({

    initialize: function(id, defaultExpandedCount) {
        if(!$(id)) throw("Attempted to initalize accordion with id: "+ id + " which was not found.")
;
        this.accordion = $(id);
        this.options = {
            toggleClass: "accordion-toggle",
            toggleActive: "accordion-toggle-active",
            contentClass: "accordion-content"
        }
        this.contents = this.accordion.select('div.'+this.options.contentClass);
        this.isAnimating = false;
        this.maxHeight = 0;
        this.current = defaultExpandedCount ? this.contents[defaultExpandedCount-1] : this.contents[0
];
        this.toExpand = null;

        this.checkMaxHeight();
        this.initialHide();
        this.attachInitialMaxHeight();

        var clickHandler =  this.clickHandler.bindAsEventListener(this);
        this.accordion.observe('click', clickHandler);
    },

    expand: function(el) {
        this.toExpand = el.next('div.'+this.options.contentClass);
        if(this.current != this.toExpand){
			this.toExpand.show();
            this.animate();
        }
    },

    checkMaxHeight: function() {
        for(var i=0; i<this.contents.length; i++) {
            if(this.contents[i].getHeight() > this.maxHeight) {
                this.maxHeight = this.contents[i].getHeight();
            }
        }
    },

    attachInitialMaxHeight: function() {
		this.current.previous('div.'+this.options.toggleClass).addClassName(this.options.toggleActive);
        if(this.current.getHeight() != this.maxHeight) this.current.setStyle({height: this.maxHeight
+"px"});
    },

    clickHandler: function(e) {
        var el = e.element();
        if(el.hasClassName(this.options.toggleClass) && !this.isAnimating) {
            this.expand(el);
        }
    },

    initialHide: function(){
        for(var i=0; i<this.contents.length; i++){
            if(this.contents[i] != this.current) {
                this.contents[i].hide();
                this.contents[i].setStyle({height: 0});
            }
        }
    },

    animate: function() {
        var effects = new Array();
        var options = {
            sync: true,
            scaleFrom: 0,
            scaleContent: false,
            transition: Effect.Transitions.sinoidal,
            scaleMode: {
                originalHeight: this.maxHeight,
                originalWidth: this.accordion.getWidth()
            },
            scaleX: false,
            scaleY: true
        };

        effects.push(new Effect.Scale(this.toExpand, 100, options));

        options = {
            sync: true,
            scaleContent: false,
            transition: Effect.Transitions.sinoidal,
            scaleX: false,
            scaleY: true
        };

        effects.push(new Effect.Scale(this.current, 0, options));

        var myDuration = 0.75;

        new Effect.Parallel(effects, {
            duration: myDuration,
            fps: 35,
            queue: {
                position: 'end',
                scope: 'accordion'
            },
            beforeStart: function() {
                this.isAnimating = true;
                this.current.previous('div.'+this.options.toggleClass).removeClassName(this.options.toggleActive
);
                this.toExpand.previous('div.'+this.options.toggleClass).addClassName(this.options.toggleActive
);
            }.bind(this),
            afterFinish: function() {
                this.current.hide();
                this.toExpand.setStyle({ height: this.maxHeight+"px" });
                this.current = this.toExpand;
                this.isAnimating = false;
            }.bind(this)
        });
    }

});

document.observe("dom:loaded", function(){
    accordion = new Accordion("test-accordion", 2);
})<commit_msg>accordion<commit_after>// accordion.js v2.0
//
// Copyright (c) 2007 stickmanlabs
// Author: Kevin P Miller | http://www.stickmanlabs.com
//
// Accordion is freely distributable under the terms of an MIT-style license.
//
// I don't care what you think about the file size...
//   Be a pro:
//	    http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
//      http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
//
//################################################################################################################
// BJ : Note - MODIFIED this script
//################################################################################################################

if (typeof Effect == 'undefined')
  throw("You must have the script.aculo.us library to use this accordion");

var Accordion = Class.create({

    initialize: function(id, defaultExpandedCount) {
        if(!$(id)) throw("Attempted to initalize accordion with id: "+ id + " which was not found.");
        this.accordion = $(id);
        this.options = {
            toggleClass: "accordion-toggle",
            toggleActive: "accordion-toggle-active",
            contentClass: "accordion-content"
        }
        this.contents = this.accordion.select('div.'+this.options.contentClass);
        this.isAnimating = false;
        this.maxHeight = 0;
        this.current = defaultExpandedCount ? this.contents[defaultExpandedCount-1] : this.contents[0];
        this.toExpand = null;

        this.checkMaxHeight();
        this.initialHide();
        this.attachInitialMaxHeight();

        var clickHandler =  this.clickHandler.bindAsEventListener(this);
        //this.accordion.observe('click', clickHandler);
        this.contents.each(function(el){
        	el.previous(0).observe('click', clickHandler);
        });
    },

    expand: function(el) {
        this.toExpand = el.next('div.'+this.options.contentClass);
        if(this.current != this.toExpand){
			this.toExpand.show();
            this.animate();
        }
    },

    checkMaxHeight: function() {
        for(var i=0; i<this.contents.length; i++) {
            if(this.contents[i].getHeight() > this.maxHeight) {
                this.maxHeight = this.contents[i].getHeight();
            }
        }
    },

    attachInitialMaxHeight: function() {
		this.current.previous('div.'+this.options.toggleClass).addClassName(this.options.toggleActive);
        if(this.current.getHeight() != this.maxHeight) this.current.setStyle({height: this.maxHeight+"px"});
    },

    clickHandler: function(e) {
        var el = e.element();
        if(el.hasClassName(this.options.toggleClass) && !this.isAnimating) {
            this.expand(el);
        }
    },

    initialHide: function(){
        for(var i=0; i<this.contents.length; i++){
            if(this.contents[i] != this.current) {
                this.contents[i].hide();
                this.contents[i].setStyle({height: 0});
            }
        }
    },

    animate: function() {
        var effects = new Array();
        var options = {
            sync: true,
            scaleFrom: 0,
            scaleContent: false,
            transition: Effect.Transitions.sinoidal,
            scaleMode: {
                originalHeight: this.maxHeight,
                originalWidth: this.accordion.getWidth()
            },
            scaleX: false,
            scaleY: true
        };

        effects.push(new Effect.Scale(this.toExpand, 100, options));

        options = {
            sync: true,
            scaleContent: false,
            transition: Effect.Transitions.sinoidal,
            scaleX: false,
            scaleY: true
        };

        effects.push(new Effect.Scale(this.current, 0, options));

        var myDuration = 0.75;

        new Effect.Parallel(effects, {
            duration: myDuration,
            fps: 35,
            queue: {
                position: 'end',
                scope: 'accordion'
            },
            beforeStart: function() {
                this.isAnimating = true;
                this.current.previous('div.'+this.options.toggleClass).removeClassName(this.options.toggleActive);
                this.toExpand.previous('div.'+this.options.toggleClass).addClassName(this.options.toggleActive);
            }.bind(this),
            afterFinish: function() {
                this.current.hide();
                this.toExpand.setStyle({ height: 'auto' });
                this.current = this.toExpand;
                this.isAnimating = false;
            }.bind(this)
        });
    }

});
<|endoftext|>


<commit_before>// @flow weak

import React, { PureComponent, PropTypes } from 'react';
import { easePoly } from 'd3-ease';
import { BASE_DURATION } from '../module/constants';
import { dims } from '../module';

const colors = { APPEAR: '#3C564B', UPDATE: '#A5937C', REMOVE: '#4D2B1D' };

class Text extends PureComponent {
  static propTypes = {
    data: PropTypes.shape({
      xValue: PropTypes.number.isRequired,
      letter: PropTypes.string.isRequired,
    }).isRequired,
    type: PropTypes.string.isRequired,
    removeNode: PropTypes.func.isRequired,
  };

  text = null; // Root text ref set in render method

  onAppear() {
    const { type, data: { xValue } } = this.props;

    return {
      text: {
        x: xValue,
        y: [0, dims[1] / 2],
        fill: colors[type],
        opacity: [1e-6, 1],
      },
      timing: { duration: BASE_DURATION, ease: easePoly },
    };
  }

  onUpdate() {
    const { type, data: { xValue } } = this.props;

    return {
      text: {
        x: [xValue],
        y: [dims[1] / 2],
        fill: colors[type],
        opacity: [1],
      },
      timing: { duration: BASE_DURATION, ease: easePoly },
    };
  }

  onRemove() {
    const { type, data: { xValue }, removeNode } = this.props;

    return {
      text: {
        x: [xValue],
        y: [dims[1]],
        fill: colors[type],
        opacity: [1e-6],
      },
      timing: { duration: BASE_DURATION, ease: easePoly },
      events: { end: removeNode },
    };
  }

  render() {
    const { data: { letter } } = this.props;

    return (
      <text
        ref={(d) => { this.text = d; }}
        dy="-.35em"
        style={{ font: 'bold 30px monospace' }}
      >{letter}</text>
    );
  }
}

export default Text;

<commit_msg>set attrs using state<commit_after>// @flow weak

import React, { PureComponent, PropTypes } from 'react';
import { easePoly } from 'd3-ease';
import { BASE_DURATION } from '../module/constants';
import { dims } from '../module';

const colors = { APPEAR: '#3C564B', UPDATE: '#A5937C', REMOVE: '#4D2B1D' };

class Text extends PureComponent {
  static propTypes = {
    data: PropTypes.shape({
      xValue: PropTypes.number.isRequired,
      letter: PropTypes.string.isRequired,
    }).isRequired,
    type: PropTypes.string.isRequired,
    // removeNode: PropTypes.func.isRequired,
  };

  constructor(props) {
    super(props);

    this.state = {
      text: {
        x: props.data.xValue,
        y: 0,
        fill: colors[props.type],
        opacity: 1e-6,
      },
    };
  }

  text = null; // Root text ref set in render method

  onAppear() {
    const { type, data: { xValue } } = this.props;

    return {
      text: {
        x: xValue,
        y: [0, dims[1] / 2],
        fill: colors[type],
        opacity: [1],
      },
      timing: { duration: BASE_DURATION, ease: easePoly },
    };
  }

  // onUpdate() {
  //   const { type, data: { xValue } } = this.props;

  //   return {
  //     text: {
  //       x: [xValue],
  //       y: [dims[1] / 2],
  //       fill: colors[type],
  //       opacity: [1],
  //     },
  //     timing: { duration: BASE_DURATION, ease: easePoly },
  //   };
  // }

  // onRemove() {
  //   const { type, data: { xValue }, removeNode } = this.props;

  //   return {
  //     text: {
  //       x: [xValue],
  //       y: [dims[1]],
  //       fill: colors[type],
  //       opacity: [1e-6],
  //     },
  //     timing: { duration: BASE_DURATION, ease: easePoly },
  //     events: { end: removeNode },
  //   };
  // }

  render() {
    const { data: { letter } } = this.props;

    return (
      <text
        ref={(d) => { this.text = d; }}
        dy="-.35em"
        style={{ font: 'bold 30px monospace' }}
        {...this.state.text}
      >{letter}</text>
    );
  }
}

export default Text;

<|endoftext|>


<commit_before>String.prototype.capitalized = function()
{
	return this.replace(/\b[a-z]/g, function(match){
		return match.toUpperCase();
	});
};

var Proto = new Object;

Proto.setSlot = function(name, value)
{
	this[name] = value;

	return this;
};

Proto.setSlots = function(slots)
{
	var self = this;
	Object.eachSlot(slots, function(name, initialValue){
		self.setSlot(name, initialValue);
	});
	return this;
}

var uniqueIdCounter = 0;

var Object_hasProto = (Object.prototype.__proto__ !== undefined);
var Object_clone = Object.clone;

Proto.setSlots({
  subclass: function() {
    var obj = Object_clone(this);
		if (!Object_hasProto)
		{
			obj.__proto__ = this;
		}
		obj._uniqueId = ++ uniqueIdCounter;
		return obj;
  },

	clone: function()
	{
		var obj = this.subclass();
		obj.init();

		return obj;
	},

	withSets: function(sets)
	{
		return this.clone().performSets(sets);
	},

	withSlots: function(slots)
	{
		return this.clone().setSlots(slots);
	},

	init: function(){},

	uniqueId: function()
	{
		return this._uniqueId;
	},

	toString: function()
	{
		return this._type;
	},

	setSlotsIfAbsent: function(slots)
	{
		var self = this;
		Object.eachSlot(slots, function(name, value){
			if (!self[name])
			{
				self.setSlot(name, value);
			}
		});
		return this;
	},

	newSlot: function(name, initialValue)
	{
		if(typeof(name) != "string") throw "name must be a string";

		if(initialValue === undefined) { initialValue = null };

		var privateName = "_" + name;
		this[privateName] = initialValue;
		this[name] = function()
		{
			return this[privateName];
		}

		this["set" + name.capitalized()] = function(newValue)
		{
			this[privateName] = newValue;
			//return this.updateSlot(name, newValue);
			return this;
		}
		return this;
	},

	updateSlot: function(name, newValue)
	{
		var privateName = "_" + name;

		var oldValue = this[privateName];
		if (oldValue != newValue)
		{
			this[privateName] = newValue;
			//this.mySlotChanged(name, oldValue, newValue);
		}

		return this;
	},

	mySlotChanged: function(slotName, oldValue, newValue)
	{
		this.perform(slotName + "SlotChanged", oldValue, newValue);
	},

	ownsSlot: function(name)
	{
		return this.hasOwnProperty(name);
	},

	aliasSlot: function(slotName, aliasName)
	{
		this[aliasName] = this[slotName];
		this["set" + aliasName.capitalized()] = this["set" + slotName.capitalized()];
		return this;
	},

	argsAsArray: function(args)
	{
		return Array.prototype.slice.call(args);
	},

	newSlots: function(slots)
	{
		var self = this;
		Object.eachSlot(slots, function(slotName, initialValue){
			self.newSlot(slotName, initialValue);
		});

		return this;
	},

	canPerform: function(message)
	{
		return this[message] && typeof(this[message]) == "function";
	},

	performWithArgList: function(message, argList)
	{
		return this[message].apply(this, argList);
	},

	perform: function(message)
	{
		if (this[message] && this[message].apply)
		{
			return this[message].apply(this, this.argsAsArray(arguments).slice(1));
		}
		else
		{
			return this;
		}
	},

	setterNameForSlot: function(name)
	{
		return "set" + name.capitalized();
	},

	performSet: function(name, value)
	{
		return this.perform("set" + name.capitalized(), value);
	},

	performSets: function(slots)
	{
		var self = this;
		Object.eachSlot(slots, function(name, value){
			self.perform("set" + name.capitalized(), value);
		});

		return this;
	}
});

Proto.toString = function()
{
	return this.type() + "." + this.uniqueId();
}

Proto.newSlot("type", "ideal.Proto");

module.exports = Proto;<commit_msg>Proto.extend instead of subclass<commit_after>String.prototype.capitalized = function()
{
	return this.replace(/\b[a-z]/g, function(match){
		return match.toUpperCase();
	});
};

var Proto = new Object;

Proto.setSlot = function(name, value)
{
	this[name] = value;

	return this;
};

Proto.setSlots = function(slots)
{
	var self = this;
	Object.eachSlot(slots, function(name, initialValue){
		self.setSlot(name, initialValue);
	});
	return this;
}

var uniqueIdCounter = 0;

var Object_hasProto = (Object.prototype.__proto__ !== undefined);
var Object_clone = Object.clone;

Proto.setSlots({
    extend: function() {
        var obj = Object_clone(this);
        if (!Object_hasProto) {
            obj.__proto__ = this;
        }
        obj._uniqueId = ++ uniqueIdCounter;
        return obj;
    },

    subclass: function() {
        console.warn("subclass is deprecated in favor of extend");
        return this.extend.call(this);
    },

	clone: function()
	{
		var obj = this.extend();
		obj.init();

		return obj;
	},

	withSets: function(sets)
	{
		return this.clone().performSets(sets);
	},

	withSlots: function(slots)
	{
		return this.clone().setSlots(slots);
	},

	init: function(){},

	uniqueId: function()
	{
		return this._uniqueId;
	},

	toString: function()
	{
		return this._type;
	},

	setSlotsIfAbsent: function(slots)
	{
		var self = this;
		Object.eachSlot(slots, function(name, value){
			if (!self[name])
			{
				self.setSlot(name, value);
			}
		});
		return this;
	},

	newSlot: function(name, initialValue)
	{
		if(typeof(name) != "string") throw "name must be a string";

		if(initialValue === undefined) { initialValue = null };

		var privateName = "_" + name;
		this[privateName] = initialValue;
		this[name] = function()
		{
			return this[privateName];
		}

		this["set" + name.capitalized()] = function(newValue)
		{
			this[privateName] = newValue;
			//return this.updateSlot(name, newValue);
			return this;
		}
		return this;
	},

	updateSlot: function(name, newValue)
	{
		var privateName = "_" + name;

		var oldValue = this[privateName];
		if (oldValue != newValue)
		{
			this[privateName] = newValue;
			//this.mySlotChanged(name, oldValue, newValue);
		}

		return this;
	},

	mySlotChanged: function(slotName, oldValue, newValue)
	{
		this.perform(slotName + "SlotChanged", oldValue, newValue);
	},

	ownsSlot: function(name)
	{
		return this.hasOwnProperty(name);
	},

	aliasSlot: function(slotName, aliasName)
	{
		this[aliasName] = this[slotName];
		this["set" + aliasName.capitalized()] = this["set" + slotName.capitalized()];
		return this;
	},

	argsAsArray: function(args)
	{
		return Array.prototype.slice.call(args);
	},

	newSlots: function(slots)
	{
		var self = this;
		Object.eachSlot(slots, function(slotName, initialValue){
			self.newSlot(slotName, initialValue);
		});

		return this;
	},

	canPerform: function(message)
	{
		return this[message] && typeof(this[message]) == "function";
	},

	performWithArgList: function(message, argList)
	{
		return this[message].apply(this, argList);
	},

	perform: function(message)
	{
		if (this[message] && this[message].apply)
		{
			return this[message].apply(this, this.argsAsArray(arguments).slice(1));
		}
		else
		{
			return this;
		}
	},

	setterNameForSlot: function(name)
	{
		return "set" + name.capitalized();
	},

	performSet: function(name, value)
	{
		return this.perform("set" + name.capitalized(), value);
	},

	performSets: function(slots)
	{
		var self = this;
		Object.eachSlot(slots, function(name, value){
			self.perform("set" + name.capitalized(), value);
		});

		return this;
	}
});

Proto.toString = function()
{
	return this.type() + "." + this.uniqueId();
}

Proto.newSlot("type", "ideal.Proto");

module.exports = Proto;<|endoftext|>


<commit_before>/**
 * Sticky Notes
 *
 * An open source lightweight pastebin application
 *
 * @package     StickyNotes
 * @author      Sayak Banerjee
 * @copyright   (c) 2014 Sayak Banerjee <mail@sayakbanerjee.com>. All rights reserved.
 * @license     http://www.opensource.org/licenses/bsd-license.php
 * @link        http://sayakbanerjee.com/sticky-notes
 * @since       Version 1.0
 * @filesource
 */

/**
 * Stores the current URL
 *
 * @var string
 */
var currentUrl = window.location;

/**
 * This is the main entry point of the script
 *
 * @return void
 */
function stickyNotes()
{
	// Initialize AJAX components
	initAjaxComponents();

	// Initialize AJAX navigation
	initAjaxNavigation();

	// Initialize code wrapping
	initWrapToggle();

	// Initialize the code editor
	initEditor();

	// Initialize tab persistence
	initTabPersistence();

	// Initialize line reference
	initLineReference();

	// Initialize bootstrap components
	initBootstrap();
}

/**
 * Scans for and processes AJAX components
 *
 * Each AJAX component can have 4 parameters:
 *  - realtime  : Indicates if the component involves realtime data
 *  - onload    : The AJAX request will be triggered automatically
 *  - component : The utility component to request
 *  - extra     : Any extra data that will be sent to the server
 *
 * @return void
 */
function initAjaxComponents()
{
	var count = 1;

	// Setup AJAX requests
	$('[data-toggle="ajax"]').each(function()
	{
		var id = 'stickynotes-' + count++;
		var onload = $(this).attr('data-onload') === 'true';
		var realtime = $(this).attr('data-realtime') === 'true';
		var component = $(this).attr('data-component');
		var extra = $(this).attr('data-extra');

		// Set the id of this element
		$(this).attr('data-id', id);

		// AJAX URL and component must be defined
		if (ajaxUrl !== undefined && component !== undefined)
		{
			var getUrl = ajaxUrl + '/' + component + (extra !== undefined ? '/' + extra : '');

			var callback = function(e)
			{
				// Add the loading icon
				var iconWhite = $(this).hasClass('btn') ? 'icon-white' : '';

				$(this).html('');

				// Send the AJAX request
				$.ajax({
					url: getUrl,
					data: { key: Math.random(), ajax: 1 },
					context: $('[data-id="' + id + '"]'),
					success: function(response)
					{
						// Dump the HTML in the element
						$(this).html(response);

						// If response is link, set it as href as well
						if (response.indexOf('http') === 0)
						{
							$(this).attr('href', response);
							$(this).removeAttr('data-toggle');
							$(this).off('click');
						}

						// Load JS triggers
						stickyNotes();
					}
				});

				if (e !== undefined)
				{
					e.preventDefault();
				}
			};

			// Execute the AJAX callback
			if (onload)
			{
				if (realtime)
				{
					setInterval(callback, 1000);
				}
				else
				{
					setTimeout(callback);
				}
			}
			else
			{
				$(this).off('click').on('click', callback);
			}
		}
	});
}

/**
 * Enabled AJAX navigation across the site
 *
 * @return void
 */
function initAjaxNavigation()
{
	if (ajaxNav !== undefined && ajaxNav)
	{
		// AJAX callback
		var callback = function(e) {
			var navMethod = $(this).prop('tagName') == 'A' ? 'GET' : 'POST';
			var seek = $(this).attr('data-seek');

			// Set up data based on method
			switch (navMethod)
			{
				case 'GET':
					navUrl = $(this).attr('href');
					payload = 'ajax=1';
					break;

				case 'POST':
					navUrl = $(this).attr('action');
					payload = $(this).serialize() + '&ajax=1';
					break;
			}

			// Send an AJAX request for all but anchor links
			if (navUrl !== undefined && !$('.loader').is(':visible'))
			{
				$('.loader').show();

				$.ajax({
					url: navUrl,
					method: navMethod,
					context: $('body'),
					data: payload,
					success: function(response, status, info)
					{
						// Write the response to the container
						if (response.indexOf('<!DOCTYPE html>') == -1)
						{
							$(this).html(response);
						}
						else
						{
							document.open();
							document.write(response);
							document.close();
						}

						// Change the page URL
						currentUrl = info.getResponseHeader('StickyNotes-Url');
						window.history.pushState({ html: response }, '', currentUrl);

						// Seek to top of the page
						$.scrollTo(0, 200);

						// Load JS triggers again
						stickyNotes();
					},
					error: function()
					{
						window.location = navUrl;
					}
				});

				e.preventDefault();
			}
		};

		// Execute callback on all non-admin, non-anchor links without an 'onclick' attribute
		$('body').find('a:not([href*="/admin"]):not([href*="#"]):not([onclick])').off('click').on('click', callback);

		// Execute callback on all designated forms
		$('body').find('form[data-navigate="ajax"]').off('submit').on('submit', callback);

		// URL change monitor
		setInterval(function()
		{
			if (currentUrl != window.location)
			{
				currentUrl = window.location;

				// Load the selected page
				$('.loader').show();

				$.get(window.location, function(response)
				{
					document.open();
					document.write(response);
					document.close();
				});
			}
		}, 300);
	}
}

/**
 * Activates the code wrapping toggle function
 *
 * @return void
 */
function initWrapToggle()
{
	$('[data-toggle="wrap"]').off('click').on('click', function(e)
	{
		var isWrapped = $('.pre div').css('white-space') != 'nowrap';
		var newValue = isWrapped ? 'nowrap' : 'inherit';

		$('.pre div').css('white-space', newValue);

		e.preventDefault();
	});
}

/**
 * Activates the paste editor
 *
 * @return void
 */
function initEditor()
{
	// Insert tab in the code box
	$('[name="data"]').off('keydown').on('keydown', function (e)
	{
		if (e.keyCode == 9)
		{
			var myValue = "\t";
			var startPos = this.selectionStart;
			var endPos = this.selectionEnd;
			var scrollTop = this.scrollTop;

			this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos,this.value.length);
			this.focus();
			this.selectionStart = startPos + myValue.length;
			this.selectionEnd = startPos + myValue.length;
			this.scrollTop = scrollTop;

			e.preventDefault();
		}
	});

	// Tick the private checkbox if password is entered
	$('[name="password"]').off('keyup').on('keyup', function()
	{
		$('[name="private"]').attr('checked', $(this).val().length > 0);
	});
}

/**
 * Activates some bootstrap components
 *
 * @return void
 */
function initBootstrap()
{
	// Activate tooltips
	$('[data-toggle="tooltip"]').tooltip();
}

/**
 * Saves the tab state on all pages
 *
 * @return void
 */
function initTabPersistence()
{
	// Restore the previous tab state
	$('.nav-tabs').each(function()
	{
		var id = $(this).attr('id');
		var index = $.cookie('stickynotes_tabstate');

		if (index !== undefined)
		{
			$('.nav-tabs > li:eq(' + index + ') a').tab('show');
		}
	});

	// Save the current tab state
	$('.nav-tabs > li > a').on('shown.bs.tab', function (e)
	{
		var id = $(this).parents('.nav-tabs').attr('id');
		var index = $(this).parents('li').index();

		$.cookie('stickynotes_tabstate', index);
	})

	// Clear tab state when navigated to a different page
	if ($('.nav-tabs').length == 0)
	{
		$.cookie('stickynotes_tabstate', null);
	}
}

/**
 * Highlights lines upon clicking them on the #show page
 *
 * @return void
 */
function initLineReference()
{
	if ($('section#show').length != 0)
	{
		var line = 1;

		// First, we allocate unique IDs to all lines
		$('.pre li').each(function()
		{
			$(this).attr('id', 'line-' + line++);
		});

		// Next, navigate to an ID if the user requested it
		var anchor = window.location.hash;

		if (anchor.length > 0)
		{
			window.location = anchor;

			$(anchor).addClass('highlight');
		}

		// Click to change anchor
		$('.pre li').off('mouseup').on('mouseup', function()
		{
			if (window.getSelection() == '')
			{
				window.location.hash = '#' + $(this).attr('id');

				$('.pre li').removeClass('highlight');
				$(this).addClass('highlight');
			}
		});
	}
}

/**
 * Draws a Google chart in a container
 *
 * @return void
 */
function initAreaChart()
{
	if (chartData !== undefined && chartContainer !== undefined)
	{
		// Create an instance of line chart
		var chart = new google.visualization.AreaChart(chartContainer);

		// Define chart options
		var options = {
			colors: [ '#428bca', '#d9534f' ],
			areaOpacity: 0.1,
			lineWidth: 4,
			pointSize: 8,
			hAxis: {
				textStyle: {
					color: '#666'
				},
				gridlines: {
					color: 'transparent'
				},
				baselineColor: '#eeeeee',
				format:'MMM d'
			},
			vAxis: {
				textStyle: {
					color: '#666'
				},
				gridlines: {
					color: '#eee'
				}
			},
			chartArea: {
				left: 50,
				top: 10,
				width: '100%',
				height: 210
			},
			legend: {
				position: 'bottom'
			}
		};

		// Draw the line chart
		chart.draw(chartData, options);
	}

	// Redraw chart on window resize
	$(window).off('resize').on('resize', initAreaChart);
}

/**
 * Invoke the entry point on DOM ready
 */
$(stickyNotes);
<commit_msg>Dont use window.location - it returns a ref<commit_after>/**
 * Sticky Notes
 *
 * An open source lightweight pastebin application
 *
 * @package     StickyNotes
 * @author      Sayak Banerjee
 * @copyright   (c) 2014 Sayak Banerjee <mail@sayakbanerjee.com>. All rights reserved.
 * @license     http://www.opensource.org/licenses/bsd-license.php
 * @link        http://sayakbanerjee.com/sticky-notes
 * @since       Version 1.0
 * @filesource
 */

/**
 * Stores the current URL
 *
 * @var string
 */
var currentUrl = $(location).attr('href');

/**
 * This is the main entry point of the script
 *
 * @return void
 */
function stickyNotes()
{
	// Initialize AJAX components
	initAjaxComponents();

	// Initialize AJAX navigation
	initAjaxNavigation();

	// Initialize code wrapping
	initWrapToggle();

	// Initialize the code editor
	initEditor();

	// Initialize tab persistence
	initTabPersistence();

	// Initialize line reference
	initLineReference();

	// Initialize bootstrap components
	initBootstrap();
}

/**
 * Scans for and processes AJAX components
 *
 * Each AJAX component can have 4 parameters:
 *  - realtime  : Indicates if the component involves realtime data
 *  - onload    : The AJAX request will be triggered automatically
 *  - component : The utility component to request
 *  - extra     : Any extra data that will be sent to the server
 *
 * @return void
 */
function initAjaxComponents()
{
	var count = 1;

	// Setup AJAX requests
	$('[data-toggle="ajax"]').each(function()
	{
		var id = 'stickynotes-' + count++;
		var onload = $(this).attr('data-onload') === 'true';
		var realtime = $(this).attr('data-realtime') === 'true';
		var component = $(this).attr('data-component');
		var extra = $(this).attr('data-extra');

		// Set the id of this element
		$(this).attr('data-id', id);

		// AJAX URL and component must be defined
		if (ajaxUrl !== undefined && component !== undefined)
		{
			var getUrl = ajaxUrl + '/' + component + (extra !== undefined ? '/' + extra : '');

			var callback = function(e)
			{
				// Add the loading icon
				var iconWhite = $(this).hasClass('btn') ? 'icon-white' : '';

				$(this).html('');

				// Send the AJAX request
				$.ajax({
					url: getUrl,
					data: { key: Math.random(), ajax: 1 },
					context: $('[data-id="' + id + '"]'),
					success: function(response)
					{
						// Dump the HTML in the element
						$(this).html(response);

						// If response is link, set it as href as well
						if (response.indexOf('http') === 0)
						{
							$(this).attr('href', response);
							$(this).removeAttr('data-toggle');
							$(this).off('click');
						}

						// Load JS triggers
						stickyNotes();
					}
				});

				if (e !== undefined)
				{
					e.preventDefault();
				}
			};

			// Execute the AJAX callback
			if (onload)
			{
				if (realtime)
				{
					setInterval(callback, 1000);
				}
				else
				{
					setTimeout(callback);
				}
			}
			else
			{
				$(this).off('click').on('click', callback);
			}
		}
	});
}

/**
 * Enabled AJAX navigation across the site
 *
 * @return void
 */
function initAjaxNavigation()
{
	if (ajaxNav !== undefined && ajaxNav)
	{
		// AJAX callback
		var callback = function(e) {
			var navMethod = $(this).prop('tagName') == 'A' ? 'GET' : 'POST';
			var seek = $(this).attr('data-seek');

			// Set up data based on method
			switch (navMethod)
			{
				case 'GET':
					navUrl = $(this).attr('href');
					payload = 'ajax=1';
					break;

				case 'POST':
					navUrl = $(this).attr('action');
					payload = $(this).serialize() + '&ajax=1';
					break;
			}

			// Send an AJAX request for all but anchor links
			if (navUrl !== undefined && !$('.loader').is(':visible'))
			{
				$('.loader').show();

				$.ajax({
					url: navUrl,
					method: navMethod,
					context: $('body'),
					data: payload,
					success: function(response, status, info)
					{
						// Write the response to the container
						if (response.indexOf('<!DOCTYPE html>') == -1)
						{
							$(this).html(response);
						}
						else
						{
							document.open();
							document.write(response);
							document.close();
						}

						// Change the page URL
						currentUrl = info.getResponseHeader('StickyNotes-Url');
						window.history.pushState({ html: response }, '', currentUrl);

						// Seek to top of the page
						$.scrollTo(0, 200);

						// Load JS triggers again
						stickyNotes();
					},
					error: function()
					{
						window.location = navUrl;
					}
				});

				e.preventDefault();
			}
		};

		// Execute callback on all non-admin, non-anchor links without an 'onclick' attribute
		$('body').find('a:not([href*="/admin"]):not([href*="#"]):not([onclick])').off('click').on('click', callback);

		// Execute callback on all designated forms
		$('body').find('form[data-navigate="ajax"]').off('submit').on('submit', callback);

		// URL change monitor
		setInterval(function()
		{
			var href = $(location).attr('href');

			if (currentUrl != href)
			{
				currentUrl = href;

				// Load the selected page
				$('.loader').show();

				$.get(href, function(response)
				{
					document.open();
					document.write(response);
					document.close();
				});
			}
		}, 300);
	}
}

/**
 * Activates the code wrapping toggle function
 *
 * @return void
 */
function initWrapToggle()
{
	$('[data-toggle="wrap"]').off('click').on('click', function(e)
	{
		var isWrapped = $('.pre div').css('white-space') != 'nowrap';
		var newValue = isWrapped ? 'nowrap' : 'inherit';

		$('.pre div').css('white-space', newValue);

		e.preventDefault();
	});
}

/**
 * Activates the paste editor
 *
 * @return void
 */
function initEditor()
{
	// Insert tab in the code box
	$('[name="data"]').off('keydown').on('keydown', function (e)
	{
		if (e.keyCode == 9)
		{
			var myValue = "\t";
			var startPos = this.selectionStart;
			var endPos = this.selectionEnd;
			var scrollTop = this.scrollTop;

			this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos,this.value.length);
			this.focus();
			this.selectionStart = startPos + myValue.length;
			this.selectionEnd = startPos + myValue.length;
			this.scrollTop = scrollTop;

			e.preventDefault();
		}
	});

	// Tick the private checkbox if password is entered
	$('[name="password"]').off('keyup').on('keyup', function()
	{
		$('[name="private"]').attr('checked', $(this).val().length > 0);
	});
}

/**
 * Activates some bootstrap components
 *
 * @return void
 */
function initBootstrap()
{
	// Activate tooltips
	$('[data-toggle="tooltip"]').tooltip();
}

/**
 * Saves the tab state on all pages
 *
 * @return void
 */
function initTabPersistence()
{
	// Restore the previous tab state
	$('.nav-tabs').each(function()
	{
		var id = $(this).attr('id');
		var index = $.cookie('stickynotes_tabstate');

		if (index !== undefined)
		{
			$('.nav-tabs > li:eq(' + index + ') a').tab('show');
		}
	});

	// Save the current tab state
	$('.nav-tabs > li > a').on('shown.bs.tab', function (e)
	{
		var id = $(this).parents('.nav-tabs').attr('id');
		var index = $(this).parents('li').index();

		$.cookie('stickynotes_tabstate', index);
	})

	// Clear tab state when navigated to a different page
	if ($('.nav-tabs').length == 0)
	{
		$.cookie('stickynotes_tabstate', null);
	}
}

/**
 * Highlights lines upon clicking them on the #show page
 *
 * @return void
 */
function initLineReference()
{
	if ($('section#show').length != 0)
	{
		var line = 1;

		// First, we allocate unique IDs to all lines
		$('.pre li').each(function()
		{
			$(this).attr('id', 'line-' + line++);
		});

		// Next, navigate to an ID if the user requested it
		var anchor = window.location.hash;

		if (anchor.length > 0)
		{
			window.location = anchor;

			$(anchor).addClass('highlight');
		}

		// Click to change anchor
		$('.pre li').off('mouseup').on('mouseup', function()
		{
			if (window.getSelection() == '')
			{
				window.location.hash = '#' + $(this).attr('id');

				$('.pre li').removeClass('highlight');
				$(this).addClass('highlight');
			}
		});
	}
}

/**
 * Draws a Google chart in a container
 *
 * @return void
 */
function initAreaChart()
{
	if (chartData !== undefined && chartContainer !== undefined)
	{
		// Create an instance of line chart
		var chart = new google.visualization.AreaChart(chartContainer);

		// Define chart options
		var options = {
			colors: [ '#428bca', '#d9534f' ],
			areaOpacity: 0.1,
			lineWidth: 4,
			pointSize: 8,
			hAxis: {
				textStyle: {
					color: '#666'
				},
				gridlines: {
					color: 'transparent'
				},
				baselineColor: '#eeeeee',
				format:'MMM d'
			},
			vAxis: {
				textStyle: {
					color: '#666'
				},
				gridlines: {
					color: '#eee'
				}
			},
			chartArea: {
				left: 50,
				top: 10,
				width: '100%',
				height: 210
			},
			legend: {
				position: 'bottom'
			}
		};

		// Draw the line chart
		chart.draw(chartData, options);
	}

	// Redraw chart on window resize
	$(window).off('resize').on('resize', initAreaChart);
}

/**
 * Invoke the entry point on DOM ready
 */
$(stickyNotes);
<|endoftext|>


<commit_before>/* ==========================================================
 * bootstrap-placeholder.js v2.0.0
 * http://jasny.github.com/bootstrap/javascript.html#placeholder
 *
 * Based on work by Daniel Stocks (http://webcloud.se)
 * ==========================================================
 * Copyright 2012 Jasny BV.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

/* TODO: turn this into a proper bootstrap plugin */

$(function () {
      $('*[data-fileupload]').each(function () {
          var container = $(this);
          var input = $(this).find(':file');
          var name = input.attr('name');
          if (input.length == 0) return;

          var preview = $(this).find('.fileupload-preview');
          if (preview.css('display') != 'inline' && preview.css('height') != 'none') preview.css('line-height', preview.css('height'));

          var remove = $(this).find('*[data-dismiss="fileupload"]');

          var hidden_input = $(this).find(':hidden[name="'+name+'"]');
          if (!hidden_input.length) {
              hidden_input = $('<input type="hidden" />');
              container.prepend(hidden_input);
          }

          var type = container.attr('data-fileupload') == "image" ? "image" : "file";

          input.change(function(e) {
              hidden_input.val('');
              hidden_input.attr('name', '')
              input.attr('name', name);

              var file = e.target.files[0];

              if (type == "image" && preview.length && (typeof file.type !== "undefined" ? file.type.match('image.*') : file.name.match('\\.(gif|png|jpg)$')) && typeof FileReader !== "undefined") {
                  var reader = new FileReader();

                  reader.onload = function(e) {
                     preview.html('');
                     container.addClass('fileupload-exists').removeClass('fileupload-new');
                  }

                  reader.readAsDataURL(file);
              } else {
                  preview.html(escape(file.name));
                  container.addClass('fileupload-exists').removeClass('fileupload-new');
              }
          });

          remove.click(function() {
              hidden_input.val('');
              hidden_input.attr('name', name);
              input.attr('name', '');

              preview.html('');
              container.addClass('fileupload-new').removeClass('fileupload-exists');

              return false;
          });
      })
});
<commit_msg>updated to allow call the script dinamically for individual elements with the funtion 'filuuploader' instead of apply to every element on the DOM with the script load<commit_after>/* ==========================================================
* bootstrap-placeholder.js v2.0.0
* http://jasny.github.com/bootstrap/javascript.html#placeholder
*
* Based on work by Daniel Stocks (http://webcloud.se)
* ==========================================================
* Copyright 2012 Jasny BV.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */

(function( $ ){
    $.fn.fileuploader = function () {
        this.each(function () {
            var container = $(this);
            var input = $(this).find(':file');
            var name = input.attr('name');
            if (input.length == 0) return;

            var preview = $(this).find('.fileupload-preview');
            if (preview.css('display') != 'inline' && preview.css('height') != 'none') preview.css('line-height', preview.css('height'));

            var remove = $(this).find('*[data-dismiss="fileupload"]');

            var hidden_input = $(this).find(':hidden[name="'+name+'"]');
            if (!hidden_input.length) {
                hidden_input = $('<input type="hidden" />');
                container.prepend(hidden_input);
            }

            var type = container.attr('data-fileupload') == "image" ? "image" : "file";
            input.attr('name', '');

            input.change(function(e) {
                hidden_input.val('');
                hidden_input.attr('name', '')
                input.attr('name', name);

                var file = e.target.files[0];

                if (type == "image" && preview.length && (typeof file.type !== "undefined" ? file.type.match('image.*') : file.name.match('\\.(gif|png|jpg)$')) && typeof FileReader !== "undefined") {
                    var reader = new FileReader();

                    reader.onload = function(e) {
                        preview.html('');
                        container.addClass('fileupload-exists').removeClass('fileupload-new');
                    }

                    reader.readAsDataURL(file);
                } else {
                    preview.html(escape(file.name));
                    container.addClass('fileupload-exists').removeClass('fileupload-new');
                }
            });

            remove.click(function() {
                hidden_input.val('');
                hidden_input.attr('name', name);
                input.attr('name', '');

                preview.html('');
                container.addClass('fileupload-new').removeClass('fileupload-exists');

                return false;
            });
        });
    }
})( jQuery );<|endoftext|>


<commit_before><commit_msg>Update project countupjs to 1.6.0<commit_after><|endoftext|>


<commit_before>Rickshaw.namespace('Rickshaw.Graph.Axis.Y');

Rickshaw.Graph.Axis.Y = Rickshaw.Class.create( {

	initialize: function(args) {

		this.graph = args.graph;
		this.orientation = args.orientation || 'right';

		this.pixelsPerTick = args.pixelsPerTick || 75;
		if (args.ticks) this.staticTicks = args.ticks;
		if (args.tickValues) this.tickValues = args.tickValues;

		this.tickSize = args.tickSize || 4;
		this.ticksTreatment = args.ticksTreatment || 'plain';

		this.tickFormat = args.tickFormat || function(y) { return y };

		this.berthRate = 0.10;

		if (args.element) {

			this.element = args.element;
			this.vis = d3.select(args.element)
				.append("svg:svg")
				.attr('class', 'rickshaw_graph y_axis');

			this.element = this.vis[0][0];
			this.element.style.position = 'relative';

			this.setSize({ width: args.width, height: args.height });

		} else {
			this.vis = this.graph.vis;
		}

		var self = this;
		this.graph.onUpdate( function() { self.render() } );
	},

	setSize: function(args) {

		args = args || {};

		if (!this.element) return;

		if (typeof window !== 'undefined') {

			var style = window.getComputedStyle(this.element.parentNode, null);
			var elementWidth = parseInt(style.getPropertyValue('width'), 10);

			if (!args.auto) {
				var elementHeight = parseInt(style.getPropertyValue('height'), 10);
			}
		}

		this.width = args.width || elementWidth || this.graph.width * this.berthRate;
		this.height = args.height || elementHeight || this.graph.height;

		this.vis
			.attr('width', this.width)
			.attr('height', this.height * (1 + this.berthRate));

		var berth = this.height * this.berthRate;

		if (this.orientation == 'left') {
			this.element.style.top = -1 * berth + 'px';
		}
	},

	render: function() {

		if (this.graph.height !== this._renderHeight) this.setSize({ auto: true });

		this.ticks = this.staticTicks || Math.floor(this.graph.height / this.pixelsPerTick);

		var axis = this._drawAxis(this.graph.y);

		this._drawGrid(axis);

		this._renderHeight = this.graph.height;
	},

	_drawAxis: function(scale) {
		var axis = d3.svg.axis().scale(scale).orient(this.orientation);
		axis.tickFormat(this.tickFormat);
		if (this.tickValues) axis.tickValues(this.tickValues);

		if (this.orientation == 'left') {
			var berth = this.height * this.berthRate;
			var transform = 'translate(' + this.width + ', ' + berth + ')';
		}

		if (this.element) {
			this.vis.selectAll('*').remove();
		}

		this.vis
			.append("svg:g")
			.attr("class", ["y_ticks", this.ticksTreatment].join(" "))
			.attr("transform", transform)
			.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));

		return axis;
	},

	_drawGrid: function(axis) {
		var gridSize = (this.orientation == 'right' ? 1 : -1) * this.graph.width;

		this.graph.vis
			.append("svg:g")
			.attr("class", "y_grid")
			.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize));
	}
} );
<commit_msg>Only auto resize the y-axis on re-renders, not first render.<commit_after>Rickshaw.namespace('Rickshaw.Graph.Axis.Y');

Rickshaw.Graph.Axis.Y = Rickshaw.Class.create( {

	initialize: function(args) {

		this.graph = args.graph;
		this.orientation = args.orientation || 'right';

		this.pixelsPerTick = args.pixelsPerTick || 75;
		if (args.ticks) this.staticTicks = args.ticks;
		if (args.tickValues) this.tickValues = args.tickValues;

		this.tickSize = args.tickSize || 4;
		this.ticksTreatment = args.ticksTreatment || 'plain';

		this.tickFormat = args.tickFormat || function(y) { return y };

		this.berthRate = 0.10;

		if (args.element) {

			this.element = args.element;
			this.vis = d3.select(args.element)
				.append("svg:svg")
				.attr('class', 'rickshaw_graph y_axis');

			this.element = this.vis[0][0];
			this.element.style.position = 'relative';

			this.setSize({ width: args.width, height: args.height });

		} else {
			this.vis = this.graph.vis;
		}

		var self = this;
		this.graph.onUpdate( function() { self.render() } );
	},

	setSize: function(args) {

		args = args || {};

		if (!this.element) return;

		if (typeof window !== 'undefined') {

			var style = window.getComputedStyle(this.element.parentNode, null);
			var elementWidth = parseInt(style.getPropertyValue('width'), 10);

			if (!args.auto) {
				var elementHeight = parseInt(style.getPropertyValue('height'), 10);
			}
		}

		this.width = args.width || elementWidth || this.graph.width * this.berthRate;
		this.height = args.height || elementHeight || this.graph.height;

		this.vis
			.attr('width', this.width)
			.attr('height', this.height * (1 + this.berthRate));

		var berth = this.height * this.berthRate;

		if (this.orientation == 'left') {
			this.element.style.top = -1 * berth + 'px';
		}
	},

	render: function() {

		if (this._renderHeight !== undefined && this.graph.height !== this._renderHeight) this.setSize({ auto: true });

		this.ticks = this.staticTicks || Math.floor(this.graph.height / this.pixelsPerTick);

		var axis = this._drawAxis(this.graph.y);

		this._drawGrid(axis);

		this._renderHeight = this.graph.height;
	},

	_drawAxis: function(scale) {
		var axis = d3.svg.axis().scale(scale).orient(this.orientation);
		axis.tickFormat(this.tickFormat);
		if (this.tickValues) axis.tickValues(this.tickValues);

		if (this.orientation == 'left') {
			var berth = this.height * this.berthRate;
			var transform = 'translate(' + this.width + ', ' + berth + ')';
		}

		if (this.element) {
			this.vis.selectAll('*').remove();
		}

		this.vis
			.append("svg:g")
			.attr("class", ["y_ticks", this.ticksTreatment].join(" "))
			.attr("transform", transform)
			.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));

		return axis;
	},

	_drawGrid: function(axis) {
		var gridSize = (this.orientation == 'right' ? 1 : -1) * this.graph.width;

		this.graph.vis
			.append("svg:g")
			.attr("class", "y_grid")
			.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize));
	}
} );
<|endoftext|>