<commit_before>/*

multiplex.js - multiplex configuration dispatch example

The MIT License (MIT)

Copyright (c) 2013 Dale Schumacher, Tristan Slominski

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var root = require('tart');
var tart = require('../index.js');
var util = require('util');

var rootSponsor = root.minimal();
/*
var rootControl = tart.stepping();
var rootSponsor = rootControl.sponsor;
*/

var steppingA = tart.stepping();
var steppingB = tart.stepping();
var steppingC = tart.stepping();

/*
Create an actor behavior that calls a synchronous object method
using `message.arguments` as the argument list
and sending the return value to `message.customer`.
*/
var adapter = function adapter(obj, fn) {
    return function applyBeh(message) {
        message.customer(fn.apply(obj, message.arguments));
    };
};

var stepperA = rootSponsor(adapter(steppingA, steppingA.dispatch));
var stepperB = rootSponsor(adapter(steppingB, steppingB.dispatch));
var stepperC = rootSponsor(adapter(steppingC, steppingC.dispatch));

/*
Create an actor behavior that multiplexes
among a list of stepping configurations,
processing one event for each (round-robin)
until no events remain.
*/
var roundRobin = function roundRobin(steppers) {
    var m = steppers.length;
    var n = m;  // countdown to idle
    var i = 0;  // current stepper
    var dispatchBeh = function dispatchBeh() {
        steppers[i]({
            arguments: [],
            customer: this.self
        });
        this.behavior = effectBeh;  // wait for dispatch effect
    };
    var effectBeh = function effectBeh(effect) {
        if (effect) {
/*
            console.log(util.inspect(effect, {depth: null}));
*/
            n = m;  // reset idle countdown
        } else {
            --n;  // countdown idle steppers
        }
        if (n > 0) {
            ++i;  // advance to next stepper
            if (i >= m) {
                i = 0;
            }
            this.self();
            this.behavior = dispatchBeh;  // dispatch next event
        }
    };
    return dispatchBeh;
};

var multiplexer = rootSponsor(roundRobin([
    stepperA,
    stepperB,
    stepperC
]));

/*
Create an actor behavior that counts down to zero,
printing labelled messages to the console log.
*/
var countdown = function countdown(label) {
    return function countdownBeh(count) {
        console.log(label, count);
        if (--count > 0) {
            this.self(count);
        }
    };
};

var countdownA = steppingA.sponsor(countdown('--A--'));
var countdownB = steppingB.sponsor(countdown('--B--'));
var countdownC = steppingC.sponsor(countdown('--C--'));

countdownA(2);
countdownB(3);
countdownC(5);

multiplexer();  // start multiplexing
/*
rootControl.eventLoop({
    log: function(effect) {
        console.log(util.inspect(effect, {depth: null}));
    }
});
*/<commit_msg>Preparing for eventLoop variant<commit_after>/*

multiplex.js - multiplex configuration dispatch example

The MIT License (MIT)

Copyright (c) 2013 Dale Schumacher, Tristan Slominski

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var root = require('tart');
var tart = require('../index.js');
var util = require('util');

var rootSponsor = root.minimal();
/*
var rootControl = tart.stepping();
var rootSponsor = rootControl.sponsor;
*/

var steppingA = tart.stepping();
var steppingB = tart.stepping();
var steppingC = tart.stepping();

/*
Create an actor behavior that calls a synchronous object method
using `message.arguments` as the argument list
and sending the return value to `message.customer`.
*/
var adapter = function adapter(obj, fn) {
    return function applyBeh(message) {
        message.customer(fn.apply(obj, message.arguments));
    };
};

/*
Create an actor behavior that multiplexes
among a list of child configurations,
dispatching one event for each (round-robin)
until no events remain.
*/
var roundRobin = function roundRobin(children) {
    var m = children.length;
    var n = m;  // countdown to idle
    var i = 0;  // current child index
    var dispatchBeh = function dispatchBeh() {
        var child = children[i];
        child({
            arguments: [],
            customer: this.self
        });
        this.behavior = effectBeh;  // wait for dispatch effect
    };
    var effectBeh = function effectBeh(effect) {
        if (effect) {
/*
            console.log(util.inspect(effect, {depth: null}));
*/
            n = m;  // reset idle countdown
        } else {
            --n;  // countdown idle children
        }
        if (n > 0) {
            ++i;  // advance to next child
            if (i >= m) {
                i = 0;
            }
            this.self();
            this.behavior = dispatchBeh;  // dispatch next event
        }
    };
    return dispatchBeh;
};

/**/
var dispatchA = rootSponsor(adapter(steppingA, steppingA.dispatch));
var dispatchB = rootSponsor(adapter(steppingB, steppingB.dispatch));
var dispatchC = rootSponsor(adapter(steppingC, steppingC.dispatch));

var multiplexer = rootSponsor(roundRobin([
    dispatchA,
    dispatchC,
    dispatchB,
    dispatchC
]));
/**/

/*
Create an actor behavior that multiplexes
among a list of child configurations,
calling `eventLoop(options)` for each
until all event queues are exhausted.
*/
var multiplex = function multiplex(children) {
    var m = children.length;
    var n = m;  // countdown to idle
    var i = 0;  // current child index
    var dispatchBeh = function dispatchBeh() {
        var child = children[i];
        child.eventLoop({
            arguments: [ child.options ],
            customer: this.self
        });
        this.behavior = statusBeh;  // wait for eventLoop status
    };
    var statusBeh = function statusBeh(empty) {
    	console.log(i, empty);
        if (empty) {
            --n;  // countdown idle children
        } else {
            n = m;  // reset idle countdown
        }
        if (n > 0) {
            ++i;  // advance to next child
            if (i >= m) {
                i = 0;
            }
            this.self();
            this.behavior = dispatchBeh;  // dispatch next event
        }
    };
    return dispatchBeh;
};

/*
var eventLoopA = rootSponsor(adapter(steppingA, steppingA.eventLoop));
var eventLoopB = rootSponsor(adapter(steppingB, steppingB.eventLoop));
var eventLoopC = rootSponsor(adapter(steppingC, steppingC.eventLoop));

var multiplexer = rootSponsor(multiplex([
    { eventLoop:eventLoopA, options:{ count:1 } },
    { eventLoop:eventLoopB },
    { eventLoop:eventLoopC, options:{} }
]));
/**/

/*
Create an actor behavior that counts down to zero,
printing labelled messages to the console log.
*/
var countdown = function countdown(label) {
    return function countdownBeh(count) {
        console.log(label, count);
        if (--count > 0) {
            this.self(count);
        }
    };
};

var countdownA = steppingA.sponsor(countdown('--A--'));
var countdownB = steppingB.sponsor(countdown('--B--'));
var countdownC = steppingC.sponsor(countdown('--C--'));

countdownA(2);
countdownB(3);
countdownC(5);

multiplexer();  // start multiplexing
/*
rootControl.eventLoop({
    log: function(effect) {
        console.log(util.inspect(effect, {depth: null}));
    }
});
*/<|endoftext|>


<commit_before>/**
 * @module ezdep
 */

/**
 * Ezdep constructor function.
 * @constructor
 * @public
 * @param {object} conf - Ezdep config (both dependency data and config)
 * @return {object} this - Allows chain calls
 */
var Ezdep = function (conf) {
  /** Errors array, fills up if we don't stop on a single failed dependency */
  //this.errs = [];

  /** Module config, contains stuff like; use_throw: true */
  var ezdep_conf = {};
  /**
   * Actual dependency config, contains stuff like;
   * name: { data: 'Sam', type: 'string' }
   */
  var dep_conf = {};

  // Sets key value data pairs to this scope, so we emulate the Ezdep instance
  // to be a plain object. `new Ezdep({ url: { data: 'google.com' } })`
  // results in `{ url: 'google.com' }`. When a key value pair isn't dependency
  // data, remove it from conf so we can `setProto({ dep_conf: conf })`
  for (var key in conf) {
    if (conf.hasOwnProperty(key)) {
      if (!conf[key].data) {
        ezdep_conf[key] = conf[key];
        delete conf[key];
      }
      else {
        this[key] = conf[key].data;
      }
    }
  }

  this.setProto({
    dep_conf: conf,
    ezdep_conf: ezdep_conf
  });

  return this;
};

/**
 * @TODO
 */
Ezdep.prototype.checkDeps = function () {
  var dep_conf = this.dep_conf;

  if (!dep_conf) {
    this.err('@checkDeps: !dep_conf');
  }

  for (var key in dep_conf) {
    if (dep_conf.hasOwnProperty(key)) {
      this.checkSingleDep(key, dep_conf[key]);
      // @TODO handle succes and fail
    }
  }
};

/**
 * @param {string} single_key - @TODO
 * @param {object} single_value - @TODO
 */
Ezdep.prototype.checkSingleDep = function (single_key, single_value) {
  var self = this;

  function is(type, data) {
    return self.is.call(self, type, data);
  }

  // @TODO internal ezdep error
  if (!single_key) {}
  if (!single_value) {}

  var data = single_value.data || undefined,
      type = single_value.type || undefined;

  // @TODO handle succes and fail
  if (type) {
    if (is(type, data)) {
      console.log('Type check passed for:', single_key);
    }
    else {
      console.log('Type check NOT passed for:', single_key);
    }
  }
  // @TODO handle succes and fail

  // @TODO below should go in a custom method: checkCustom

  var customs = single_value.customs;

  if (customs) {
    for (var custom_key in customs) {
      if (customs.hasOwnProperty(custom_key) &&
          self.isFunction(customs[custom_key])) {

        function done(passed, msg) {
          console.log('done', passed, msg);
        }

        var custom_results = customs[custom_key].call(self, data, done);

        //console.log(custom_results);
/*
        if (custom_results.passed) {
          console.log('passed custom');
        }
        else {
          console.log('not passed custom');
        }*/
      }
    }
  }

};

/**
 * @param {string} - Data type to check for
 * @param {any} - Data of which the type gets examined
 * @return {boolean} - Whether `data` is of type `type`
 */
Ezdep.prototype.is = function (type, data) {
  // @TODO
  if (!type) {}
  if (!data) {}

  var typeChecker = this[
    'is' + (type.charAt(0).toUpperCase() + type.slice(1))
  ];

  return (
    typeChecker && typeof typeChecker === 'function'
      ? typeChecker(data)
      : false
  );
};
/**
 * @TODO
 */
Ezdep.prototype.isArray = function (data) {
  return (
    data instanceof Array &&
    typeof data === 'object' &&
    data.length !== undefined
  );
};
/**
 * @TODO
 */
Ezdep.prototype.isString = function (data) {
  return (
    typeof data === 'string' &&
    data.length !== undefined
  );
};
/**
 * @TODO
 */
Ezdep.prototype.isFunction = function (data) {
  return (typeof data === 'function');
};
/**
 * @TODO
 */
Ezdep.prototype.isBoolean = function (data) {
  return (typeof data === 'boolean');
};

/**
 * Sets `this.__proto__` key value pairs.
 * @param {object} to_set - Key value pairs to set to this.__proto__
 */
Ezdep.prototype.setProto = function (to_set) {
  for (var key in to_set) {
    if (to_set.hasOwnProperty(key)) {
      this.__proto__[key] = to_set[key];
    }
  }
};

/**
 * Helper method that throws errors with given messages
 * @param {string} msg - Error message to append to default error message
 */
Ezdep.prototype.err = function (msg) {
  throw new Error('Internal ezdep error\n' + msg);
};

Ezdep.prototype.fail = function (msg) {

  var err_str = 'FAIL: ' + msg;

  if (this.ezdep_conf.use_throw) {
    throw new Error(err_str);
  }

  else {
    console.log(err_str);
  }

};

// Public API
module.exports = {
  Constructor: Ezdep
};<commit_msg>Started experimenting with `current_dep`<commit_after>/**
 * @module ezdep
 */

/**
 * Ezdep constructor function.
 * @constructor
 * @public
 * @param {object} conf - Ezdep config (both dependency data and config)
 * @return {object} this - Allows chain calls
 */
var Ezdep = function (conf) {
  /** Errors array, fills up if we don't stop on a single failed dependency */
  //this.errs = [];

  /** Module config, contains stuff like; use_throw: true */
  var ezdep_conf = {};
  /**
   * Actual dependency config, contains stuff like;
   * name: { data: 'Sam', type: 'string' }
   */
  var dep_conf = {};

  // Sets key value data pairs to this scope, so we emulate the Ezdep instance
  // to be a plain object. `new Ezdep({ url: { data: 'google.com' } })`
  // results in `{ url: 'google.com' }`. When a key value pair isn't dependency
  // data, remove it from conf so we can `setProto({ dep_conf: conf })`
  for (var key in conf) {
    if (conf.hasOwnProperty(key)) {
      if (!conf[key].data) {
        ezdep_conf[key] = conf[key];
        delete conf[key];
      }
      else {
        this[key] = conf[key].data;
      }
    }
  }

  this.setProto({
    dep_conf: conf,
    ezdep_conf: ezdep_conf
  });

  return this;
};

/**
 * @TODO
 */
Ezdep.prototype.checkDeps = function () {
  var dep_conf = this.dep_conf;

  if (!dep_conf) {
    this.err('@checkDeps: !dep_conf');
  }

  for (var key in dep_conf) {
    if (dep_conf.hasOwnProperty(key)) {

      this.current_dep = key;

      this.checkSingleDep(key, dep_conf[key]);
      // @TODO handle succes and fail
    }
  }
};

/**
 * @param {string} single_key - @TODO
 * @param {object} single_value - @TODO
 */
Ezdep.prototype.checkSingleDep = function (single_key, single_value) {
  var self = this;

  function is(type, data) {
    return self.is.call(self, type, data);
  }

  // @TODO internal ezdep error
  if (!single_key) {}
  if (!single_value) {}

  var data = single_value.data || undefined,
      type = single_value.type || undefined;

  // @TODO handle succes and fail
  if (type) {
    if (is(type, data)) {
      console.log('Type check passed for:', single_key);
    }
    else {
      console.log('Type check NOT passed for:', single_key);
    }
  }
  // @TODO handle succes and fail

  // @TODO below should go in a custom method: checkCustom

  var customs = single_value.customs;

  if (customs) {
    for (var custom_key in customs) {
      if (customs.hasOwnProperty(custom_key) &&
          self.isFunction(customs[custom_key])) {

        function done(passed, msg) {
          console.log('@' + self.current_dep + ':' + custom_key, 'passed:', passed, 'msg:', msg);
        }

        var custom_results = customs[custom_key].call(self, data, done);

        //console.log(custom_results);
/*
        if (custom_results.passed) {
          console.log('passed custom');
        }
        else {
          console.log('not passed custom');
        }*/
      }
    }
  }

};

/**
 * @param {string} - Data type to check for
 * @param {any} - Data of which the type gets examined
 * @return {boolean} - Whether `data` is of type `type`
 */
Ezdep.prototype.is = function (type, data) {
  // @TODO
  if (!type) {}
  if (!data) {}

  var typeChecker = this[
    'is' + (type.charAt(0).toUpperCase() + type.slice(1))
  ];

  return (
    typeChecker && typeof typeChecker === 'function'
      ? typeChecker(data)
      : false
  );
};
/**
 * @TODO
 */
Ezdep.prototype.isArray = function (data) {
  return (
    data instanceof Array &&
    typeof data === 'object' &&
    data.length !== undefined
  );
};
/**
 * @TODO
 */
Ezdep.prototype.isString = function (data) {
  return (
    typeof data === 'string' &&
    data.length !== undefined
  );
};
/**
 * @TODO
 */
Ezdep.prototype.isFunction = function (data) {
  return (typeof data === 'function');
};
/**
 * @TODO
 */
Ezdep.prototype.isBoolean = function (data) {
  return (typeof data === 'boolean');
};

/**
 * Sets `this.__proto__` key value pairs.
 * @param {object} to_set - Key value pairs to set to this.__proto__
 */
Ezdep.prototype.setProto = function (to_set) {
  for (var key in to_set) {
    if (to_set.hasOwnProperty(key)) {
      this.__proto__[key] = to_set[key];
    }
  }
};

/**
 * Helper method that throws errors with given messages
 * @param {string} msg - Error message to append to default error message
 */
Ezdep.prototype.err = function (msg) {
  throw new Error('Internal ezdep error\n' + msg);
};

Ezdep.prototype.fail = function (msg) {

  var err_str = 'FAIL: ' + msg;

  if (this.ezdep_conf.use_throw) {
    throw new Error(err_str);
  }

  else {
    console.log(err_str);
  }

};

// Public API
module.exports = {
  Constructor: Ezdep
};<|endoftext|>


<commit_before>//import //

var _elm_lang$core$Native_Platform = function() {

// PROGRAMS

function addPublicModule(object, name, main)
{
	var embed = main ? makeEmbed(name, main) : mainIsUndefined(name);

	object['embed'] = embed;

	object['fullscreen'] = function fullscreen(flags)
	{
		return embed(document.body, flags);
	};
}

// PROGRAM FAIL

function mainIsUndefined(name)
{
	return function(domNode)
	{
		var message = 'Cannot initialize module `' + name +
			'` because it has no `main` value!\nWhat should I show on screen?';
		domNode.innerHTML = errorHtml(message);
		throw new Error(message);
	};
}

function errorHtml(message)
{
	return '
'
		+ '
Oops! Something went wrong when starting your Elm program.
'
		+ '
' + message + '
'
		+ '
';
}

// PROGRAM SUCCESS

function makeEmbed(moduleName, main)
{
	return function embed(rootDomNode, flags)
	{
		try
		{
			var program = mainToProgram(moduleName, main);
			return makeEmbedHelp(moduleName, program, rootDomNode, flags);
		}
		catch (e)
		{
			rootDomNode.innerHTML = errorHtml(e.message);
			throw e;
		}
	};
}

// MAIN TO PROGRAM

function mainToProgram(moduleName, wrappedMain)
{
	var main = wrappedMain.main;

	if (typeof main.init === 'undefined')
	{
		var emptyBag = batch(_elm_lang$core$Native_List.Nil);
		var noChange = _elm_lang$core$Native_Utils.Tuple2(
			_elm_lang$core$Native_Utils.Tuple0,
			emptyBag
		);

		return _elm_lang$virtual_dom$VirtualDom$programWithFlags({
			init: function() { return noChange; },
			view: function() { return main; },
			update: F2(function() { return noChange; }),
			subscriptions: function () { return emptyBag; }
		});
	}

	var flags = wrappedMain.flags;
	var init = flags
		? initWithFlags(moduleName, main.init, flags)
		: initWithoutFlags(moduleName, main.init);

	return _elm_lang$virtual_dom$VirtualDom$programWithFlags({
		init: init,
		view: main.view,
		update: main.update,
		subscriptions: main.subscriptions,
	});
}

function initWithoutFlags(moduleName, realInit)
{
	return function init(flags)
	{
		if (typeof flags !== 'undefined')
		{
			throw new Error(
				'You are giving module `' + moduleName + '` an argument in JavaScript.\n'
				+ 'This module does not take arguments though! You probably need to change the\n'
				+ 'initialization code to something like `Elm.' + moduleName + '.fullscreen()`'
			);
		}
		return realInit();
	};
}

function initWithFlags(moduleName, realInit, flagDecoder)
{
	return function init(flags)
	{
		var result = A2(_elm_lang$core$Native_Json.run, flagDecoder, flags);
		if (result.ctor === 'Err')
		{
			throw new Error(
				'You trying to initialize module `' + moduleName + '` with an unexpected argument.\n'
				+ 'When trying to convert it to a usable Elm value, I run into this problem:\n\n'
				+ result._0
			);
		}
		return realInit(result._0);
	};
}

// SETUP RUNTIME SYSTEM

function makeEmbedHelp(moduleName, program, rootDomNode, flags)
{
	var init = program.init;
	var update = program.update;
	var subscriptions = program.subscriptions;
	var view = program.view;
	var makeRenderer = program.renderer;

	// ambient state
	var managers = {};
	var renderer;

	// init and update state in main process
	var initApp = _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) {
		var results = init(flags);
		var model = results._0;
		renderer = makeRenderer(rootDomNode, enqueue, view(model));
		var cmds = results._1;
		var subs = subscriptions(model);
		dispatchEffects(managers, cmds, subs);
		callback(_elm_lang$core$Native_Scheduler.succeed(model));
	});

	function onMessage(msg, model)
	{
		return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) {
			var results = A2(update, msg, model);
			model = results._0;
			renderer.update(view(model));
			var cmds = results._1;
			var subs = subscriptions(model);
			dispatchEffects(managers, cmds, subs);
			callback(_elm_lang$core$Native_Scheduler.succeed(model));
		});
	}

	var mainProcess = spawnLoop(initApp, onMessage);

	function enqueue(msg)
	{
		_elm_lang$core$Native_Scheduler.rawSend(mainProcess, msg);
	}

	var ports = setupEffects(managers, enqueue);

	return ports ? { ports: ports } : {};
}

// EFFECT MANAGERS

var effectManagers = {};

function setupEffects(managers, callback)
{
	var ports;

	// setup all necessary effect managers
	for (var key in effectManagers)
	{
		var manager = effectManagers[key];

		if (manager.isForeign)
		{
			ports = ports || {};
			ports[key] = manager.tag === 'cmd'
				? setupOutgoingPort(key)
				: setupIncomingPort(key, callback);
		}

		managers[key] = makeManager(manager, callback);
	}

	return ports;
}

function makeManager(info, callback)
{
	var router = {
		main: callback,
		self: undefined
	};

	var tag = info.tag;
	var onEffects = info.onEffects;
	var onSelfMsg = info.onSelfMsg;

	function onMessage(msg, state)
	{
		if (msg.ctor === 'self')
		{
			return A3(onSelfMsg, router, msg._0, state);
		}

		var fx = msg._0;
		switch (tag)
		{
			case 'cmd':
				return A3(onEffects, router, fx.cmds, state);

			case 'sub':
				return A3(onEffects, router, fx.subs, state);

			case 'fx':
				return A4(onEffects, router, fx.cmds, fx.subs, state);
		}
	}

	var process = spawnLoop(info.init, onMessage);
	router.self = process;
	return process;
}

function sendToApp(router, msg)
{
	return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback)
	{
		router.main(msg);
		callback(_elm_lang$core$Native_Scheduler.succeed(_elm_lang$core$Native_Utils.Tuple0));
	});
}

function sendToSelf(router, msg)
{
	return A2(_elm_lang$core$Native_Scheduler.send, router.self, {
		ctor: 'self',
		_0: msg
	});
}

// HELPER for STATEFUL LOOPS

function spawnLoop(init, onMessage)
{
	var andThen = _elm_lang$core$Native_Scheduler.andThen;

	function loop(state)
	{
		var handleMsg = _elm_lang$core$Native_Scheduler.receive(function(msg) {
			return onMessage(msg, state);
		});
		return A2(andThen, handleMsg, loop);
	}

	var task = A2(andThen, init, loop);

	return _elm_lang$core$Native_Scheduler.rawSpawn(task);
}

// BAGS

function leaf(home)
{
	return function(value)
	{
		return {
			type: 'leaf',
			home: home,
			value: value
		};
	};
}

function batch(list)
{
	return {
		type: 'node',
		branches: list
	};
}

function map(tagger, bag)
{
	return {
		type: 'map',
		tagger: tagger,
		tree: bag
	}
}

// PIPE BAGS INTO EFFECT MANAGERS

function dispatchEffects(managers, cmdBag, subBag)
{
	var effectsDict = {};
	gatherEffects(true, cmdBag, effectsDict, null);
	gatherEffects(false, subBag, effectsDict, null);

	for (var home in effectsDict)
	{
		_elm_lang$core$Native_Scheduler.rawSend(managers[home], {
			ctor: 'fx',
			_0: effectsDict[home]
		});
	}
}

function gatherEffects(isCmd, bag, effectsDict, taggers)
{
	switch (bag.type)
	{
		case 'leaf':
			var home = bag.home;
			var effect = toEffect(isCmd, home, taggers, bag.value);
			effectsDict[home] = insert(isCmd, effect, effectsDict[home]);
			return;

		case 'node':
			var list = bag.branches;
			while (list.ctor !== '[]')
			{
				gatherEffects(isCmd, list._0, effectsDict, taggers);
				list = list._1;
			}
			return;

		case 'map':
			gatherEffects(isCmd, bag.tree, effectsDict, {
				tagger: bag.tagger,
				rest: taggers
			});
			return;
	}
}

function toEffect(isCmd, home, taggers, value)
{
	function applyTaggers(x)
	{
		while (taggers)
		{
			x = taggers.tagger(x);
			taggers = taggers.rest;
		}
		return x;
	}

	var map = isCmd
		? effectManagers[home].cmdMap
		: effectManagers[home].subMap;

	return A2(map, applyTaggers, value)
}

function insert(isCmd, newEffect, effects)
{
	effects = effects || {
		cmds: _elm_lang$core$Native_List.Nil,
		subs: _elm_lang$core$Native_List.Nil
	};
	if (isCmd)
	{
		effects.cmds = _elm_lang$core$Native_List.Cons(newEffect, effects.cmds);
		return effects;
	}
	effects.subs = _elm_lang$core$Native_List.Cons(newEffect, effects.subs);
	return effects;
}

// PORTS

function checkPortName(name)
{
	if (name in effectManagers)
	{
		throw new Error('There can only be one port named `' + name + '`, but your program has multiple.');
	}
}

// OUTGOING PORTS

function outgoingPort(name, converter)
{
	checkPortName(name);
	effectManagers[name] = {
		tag: 'cmd',
		cmdMap: outgoingPortMap,
		converter: converter,
		isForeign: true
	};
	return leaf(name);
}

var outgoingPortMap = F2(function cmdMap(tagger, value) {
	return value;
});

function setupOutgoingPort(name)
{
	var subs = [];
	var converter = effectManagers[name].converter;

	// CREATE MANAGER

	var init = _elm_lang$core$Native_Scheduler.succeed(null);

	function onEffects(router, cmdList, state)
	{
		while (cmdList.ctor !== '[]')
		{
			var value = converter(cmdList._0);
			for (var i = 0; i < subs.length; i++)
			{
				subs[i](value);
			}
			cmdList = cmdList._1;
		}
		return init;
	}

	effectManagers[name].init = init;
	effectManagers[name].onEffects = F3(onEffects);

	// PUBLIC API

	function subscribe(callback)
	{
		subs.push(callback);
	}

	function unsubscribe(callback)
	{
		var index = subs.indexOf(callback);
		if (index >= 0)
		{
			subs.splice(index, 1);
		}
	}

	return {
		subscribe: subscribe,
		unsubscribe: unsubscribe
	};
}

// INCOMING PORTS

function incomingPort(name, converter)
{
	checkPortName(name);
	effectManagers[name] = {
		tag: 'sub',
		subMap: incomingPortMap,
		converter: converter,
		isForeign: true
	};
	return leaf(name);
}

var incomingPortMap = F2(function subMap(tagger, finalTagger)
{
	return function(value)
	{
		return tagger(finalTagger(value));
	};
});

function setupIncomingPort(name, callback)
{
	var subs = _elm_lang$core$Native_List.Nil;
	var converter = effectManagers[name].converter;

	// CREATE MANAGER

	var init = _elm_lang$core$Native_Scheduler.succeed(null);

	function onEffects(router, subList, state)
	{
		subs = subList;
		return init;
	}

	effectManagers[name].init = init;
	effectManagers[name].onEffects = F3(onEffects);

	// PUBLIC API

	function send(value)
	{
		var result = A2(_elm_lang$core$Json_Decode$decodeValue, converter, value);
		if (result.ctor === 'Err')
		{
			throw new Error('Trying to send an unexpected type of value through port `' + name + '`:\n' + result._0);
		}

		var value = result._0;
		var temp = subs;
		while (temp.ctor !== '[]')
		{
			callback(temp._0(value));
			temp = temp._1;
		}
	}

	return { send: send };
}

return {
	// routers
	sendToApp: F2(sendToApp),
	sendToSelf: F2(sendToSelf),

	// global setup
	mainToProgram: mainToProgram,
	effectManagers: effectManagers,
	outgoingPort: outgoingPort,
	incomingPort: incomingPort,
	addPublicModule: addPublicModule,

	// effect bags
	leaf: leaf,
	batch: batch,
	map: F2(map)
};

}();<commit_msg>Make sure subscriptions actually get shut off<commit_after>//import //

var _elm_lang$core$Native_Platform = function() {

// PROGRAMS

function addPublicModule(object, name, main)
{
	var embed = main ? makeEmbed(name, main) : mainIsUndefined(name);

	object['embed'] = embed;

	object['fullscreen'] = function fullscreen(flags)
	{
		return embed(document.body, flags);
	};
}

// PROGRAM FAIL

function mainIsUndefined(name)
{
	return function(domNode)
	{
		var message = 'Cannot initialize module `' + name +
			'` because it has no `main` value!\nWhat should I show on screen?';
		domNode.innerHTML = errorHtml(message);
		throw new Error(message);
	};
}

function errorHtml(message)
{
	return '
'
		+ '
Oops! Something went wrong when starting your Elm program.
'
		+ '
' + message + '
'
		+ '
';
}

// PROGRAM SUCCESS

function makeEmbed(moduleName, main)
{
	return function embed(rootDomNode, flags)
	{
		try
		{
			var program = mainToProgram(moduleName, main);
			return makeEmbedHelp(moduleName, program, rootDomNode, flags);
		}
		catch (e)
		{
			rootDomNode.innerHTML = errorHtml(e.message);
			throw e;
		}
	};
}

// MAIN TO PROGRAM

function mainToProgram(moduleName, wrappedMain)
{
	var main = wrappedMain.main;

	if (typeof main.init === 'undefined')
	{
		var emptyBag = batch(_elm_lang$core$Native_List.Nil);
		var noChange = _elm_lang$core$Native_Utils.Tuple2(
			_elm_lang$core$Native_Utils.Tuple0,
			emptyBag
		);

		return _elm_lang$virtual_dom$VirtualDom$programWithFlags({
			init: function() { return noChange; },
			view: function() { return main; },
			update: F2(function() { return noChange; }),
			subscriptions: function () { return emptyBag; }
		});
	}

	var flags = wrappedMain.flags;
	var init = flags
		? initWithFlags(moduleName, main.init, flags)
		: initWithoutFlags(moduleName, main.init);

	return _elm_lang$virtual_dom$VirtualDom$programWithFlags({
		init: init,
		view: main.view,
		update: main.update,
		subscriptions: main.subscriptions,
	});
}

function initWithoutFlags(moduleName, realInit)
{
	return function init(flags)
	{
		if (typeof flags !== 'undefined')
		{
			throw new Error(
				'You are giving module `' + moduleName + '` an argument in JavaScript.\n'
				+ 'This module does not take arguments though! You probably need to change the\n'
				+ 'initialization code to something like `Elm.' + moduleName + '.fullscreen()`'
			);
		}
		return realInit();
	};
}

function initWithFlags(moduleName, realInit, flagDecoder)
{
	return function init(flags)
	{
		var result = A2(_elm_lang$core$Native_Json.run, flagDecoder, flags);
		if (result.ctor === 'Err')
		{
			throw new Error(
				'You trying to initialize module `' + moduleName + '` with an unexpected argument.\n'
				+ 'When trying to convert it to a usable Elm value, I run into this problem:\n\n'
				+ result._0
			);
		}
		return realInit(result._0);
	};
}

// SETUP RUNTIME SYSTEM

function makeEmbedHelp(moduleName, program, rootDomNode, flags)
{
	var init = program.init;
	var update = program.update;
	var subscriptions = program.subscriptions;
	var view = program.view;
	var makeRenderer = program.renderer;

	// ambient state
	var managers = {};
	var renderer;

	// init and update state in main process
	var initApp = _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) {
		var results = init(flags);
		var model = results._0;
		renderer = makeRenderer(rootDomNode, enqueue, view(model));
		var cmds = results._1;
		var subs = subscriptions(model);
		dispatchEffects(managers, cmds, subs);
		callback(_elm_lang$core$Native_Scheduler.succeed(model));
	});

	function onMessage(msg, model)
	{
		return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) {
			var results = A2(update, msg, model);
			model = results._0;
			renderer.update(view(model));
			var cmds = results._1;
			var subs = subscriptions(model);
			dispatchEffects(managers, cmds, subs);
			callback(_elm_lang$core$Native_Scheduler.succeed(model));
		});
	}

	var mainProcess = spawnLoop(initApp, onMessage);

	function enqueue(msg)
	{
		_elm_lang$core$Native_Scheduler.rawSend(mainProcess, msg);
	}

	var ports = setupEffects(managers, enqueue);

	return ports ? { ports: ports } : {};
}

// EFFECT MANAGERS

var effectManagers = {};

function setupEffects(managers, callback)
{
	var ports;

	// setup all necessary effect managers
	for (var key in effectManagers)
	{
		var manager = effectManagers[key];

		if (manager.isForeign)
		{
			ports = ports || {};
			ports[key] = manager.tag === 'cmd'
				? setupOutgoingPort(key)
				: setupIncomingPort(key, callback);
		}

		managers[key] = makeManager(manager, callback);
	}

	return ports;
}

function makeManager(info, callback)
{
	var router = {
		main: callback,
		self: undefined
	};

	var tag = info.tag;
	var onEffects = info.onEffects;
	var onSelfMsg = info.onSelfMsg;

	function onMessage(msg, state)
	{
		if (msg.ctor === 'self')
		{
			return A3(onSelfMsg, router, msg._0, state);
		}

		var fx = msg._0;
		switch (tag)
		{
			case 'cmd':
				return A3(onEffects, router, fx.cmds, state);

			case 'sub':
				return A3(onEffects, router, fx.subs, state);

			case 'fx':
				return A4(onEffects, router, fx.cmds, fx.subs, state);
		}
	}

	var process = spawnLoop(info.init, onMessage);
	router.self = process;
	return process;
}

function sendToApp(router, msg)
{
	return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback)
	{
		router.main(msg);
		callback(_elm_lang$core$Native_Scheduler.succeed(_elm_lang$core$Native_Utils.Tuple0));
	});
}

function sendToSelf(router, msg)
{
	return A2(_elm_lang$core$Native_Scheduler.send, router.self, {
		ctor: 'self',
		_0: msg
	});
}

// HELPER for STATEFUL LOOPS

function spawnLoop(init, onMessage)
{
	var andThen = _elm_lang$core$Native_Scheduler.andThen;

	function loop(state)
	{
		var handleMsg = _elm_lang$core$Native_Scheduler.receive(function(msg) {
			return onMessage(msg, state);
		});
		return A2(andThen, handleMsg, loop);
	}

	var task = A2(andThen, init, loop);

	return _elm_lang$core$Native_Scheduler.rawSpawn(task);
}

// BAGS

function leaf(home)
{
	return function(value)
	{
		return {
			type: 'leaf',
			home: home,
			value: value
		};
	};
}

function batch(list)
{
	return {
		type: 'node',
		branches: list
	};
}

function map(tagger, bag)
{
	return {
		type: 'map',
		tagger: tagger,
		tree: bag
	}
}

// PIPE BAGS INTO EFFECT MANAGERS

function dispatchEffects(managers, cmdBag, subBag)
{
	var effectsDict = {};
	gatherEffects(true, cmdBag, effectsDict, null);
	gatherEffects(false, subBag, effectsDict, null);

	for (var home in managers)
	{
		var fx = home in effectsDict
			? effectsDict[home]
			: {
				cmds: _elm_lang$core$Native_List.Nil,
				subs: _elm_lang$core$Native_List.Nil
			};

		_elm_lang$core$Native_Scheduler.rawSend(managers[home], { ctor: 'fx', _0: fx });
	}
}

function gatherEffects(isCmd, bag, effectsDict, taggers)
{
	switch (bag.type)
	{
		case 'leaf':
			var home = bag.home;
			var effect = toEffect(isCmd, home, taggers, bag.value);
			effectsDict[home] = insert(isCmd, effect, effectsDict[home]);
			return;

		case 'node':
			var list = bag.branches;
			while (list.ctor !== '[]')
			{
				gatherEffects(isCmd, list._0, effectsDict, taggers);
				list = list._1;
			}
			return;

		case 'map':
			gatherEffects(isCmd, bag.tree, effectsDict, {
				tagger: bag.tagger,
				rest: taggers
			});
			return;
	}
}

function toEffect(isCmd, home, taggers, value)
{
	function applyTaggers(x)
	{
		while (taggers)
		{
			x = taggers.tagger(x);
			taggers = taggers.rest;
		}
		return x;
	}

	var map = isCmd
		? effectManagers[home].cmdMap
		: effectManagers[home].subMap;

	return A2(map, applyTaggers, value)
}

function insert(isCmd, newEffect, effects)
{
	effects = effects || {
		cmds: _elm_lang$core$Native_List.Nil,
		subs: _elm_lang$core$Native_List.Nil
	};
	if (isCmd)
	{
		effects.cmds = _elm_lang$core$Native_List.Cons(newEffect, effects.cmds);
		return effects;
	}
	effects.subs = _elm_lang$core$Native_List.Cons(newEffect, effects.subs);
	return effects;
}

// PORTS

function checkPortName(name)
{
	if (name in effectManagers)
	{
		throw new Error('There can only be one port named `' + name + '`, but your program has multiple.');
	}
}

// OUTGOING PORTS

function outgoingPort(name, converter)
{
	checkPortName(name);
	effectManagers[name] = {
		tag: 'cmd',
		cmdMap: outgoingPortMap,
		converter: converter,
		isForeign: true
	};
	return leaf(name);
}

var outgoingPortMap = F2(function cmdMap(tagger, value) {
	return value;
});

function setupOutgoingPort(name)
{
	var subs = [];
	var converter = effectManagers[name].converter;

	// CREATE MANAGER

	var init = _elm_lang$core$Native_Scheduler.succeed(null);

	function onEffects(router, cmdList, state)
	{
		while (cmdList.ctor !== '[]')
		{
			var value = converter(cmdList._0);
			for (var i = 0; i < subs.length; i++)
			{
				subs[i](value);
			}
			cmdList = cmdList._1;
		}
		return init;
	}

	effectManagers[name].init = init;
	effectManagers[name].onEffects = F3(onEffects);

	// PUBLIC API

	function subscribe(callback)
	{
		subs.push(callback);
	}

	function unsubscribe(callback)
	{
		var index = subs.indexOf(callback);
		if (index >= 0)
		{
			subs.splice(index, 1);
		}
	}

	return {
		subscribe: subscribe,
		unsubscribe: unsubscribe
	};
}

// INCOMING PORTS

function incomingPort(name, converter)
{
	checkPortName(name);
	effectManagers[name] = {
		tag: 'sub',
		subMap: incomingPortMap,
		converter: converter,
		isForeign: true
	};
	return leaf(name);
}

var incomingPortMap = F2(function subMap(tagger, finalTagger)
{
	return function(value)
	{
		return tagger(finalTagger(value));
	};
});

function setupIncomingPort(name, callback)
{
	var subs = _elm_lang$core$Native_List.Nil;
	var converter = effectManagers[name].converter;

	// CREATE MANAGER

	var init = _elm_lang$core$Native_Scheduler.succeed(null);

	function onEffects(router, subList, state)
	{
		subs = subList;
		return init;
	}

	effectManagers[name].init = init;
	effectManagers[name].onEffects = F3(onEffects);

	// PUBLIC API

	function send(value)
	{
		var result = A2(_elm_lang$core$Json_Decode$decodeValue, converter, value);
		if (result.ctor === 'Err')
		{
			throw new Error('Trying to send an unexpected type of value through port `' + name + '`:\n' + result._0);
		}

		var value = result._0;
		var temp = subs;
		while (temp.ctor !== '[]')
		{
			callback(temp._0(value));
			temp = temp._1;
		}
	}

	return { send: send };
}

return {
	// routers
	sendToApp: F2(sendToApp),
	sendToSelf: F2(sendToSelf),

	// global setup
	mainToProgram: mainToProgram,
	effectManagers: effectManagers,
	outgoingPort: outgoingPort,
	incomingPort: incomingPort,
	addPublicModule: addPublicModule,

	// effect bags
	leaf: leaf,
	batch: batch,
	map: F2(map)
};

}();<|endoftext|>


<commit_before>define([
  'jquery',
  'underscore',
  'backbone',
  'views/sidebar',
  'views/topic',
  'views/topiclist',
  'views/hot',
  'views/sukela',
  'views/conf'
], function ($, _, Backbone, SidebarView, TopicView,
             TopicListView, HotView, SukelaView, ConfView) {
  var AppRouter = Backbone.Router.extend ({
    routes: {
      '': 'defaultAction',
      't/:order/:topic': 'topic',
      'hot/:channel': 'hotchannel',
      'hot': 'hot',
      'sukela': 'sukela',
      'conf': 'conf'
    },
  });

  var initialize = function () {
    var router = new AppRouter;
    router.on ('route:defaultAction', function () {
    });
    router.on ('route:topic', function (order, topic) {
      var topicView = new TopicView ();
      topicView.render (order, topic);
    });
    // FIXME: need to use all route definitions in AppRouter
    router.route (/^tl\/(.*?)$/, "topiclist");
    router.on ('route:topiclist', function (external_url) {
      var topicListView = new TopicListView ();
      topicListView.render (external_url);
    });
    router.on ('route:hot', function () {
      var hotView = new HotView ();
      hotView.render ();
    });
    router.on ('route:hotchannel', function (channel) {
      var hotView = new HotView ();
      hotView.render (channel);
    });
    router.on ('route:sukela', function () {
      var sukelaView = new SukelaView ();
      sukelaView.render ();
    });
    router.on ('route:conf', function () {
      var confView = new ConfView ();
      confView.render ();
    });
    Backbone.history.start ();
  };

  return {
    initialize: initialize
  };
});
<commit_msg>add debe router<commit_after>define([
  'jquery',
  'underscore',
  'backbone',
  'views/sidebar',
  'views/topic',
  'views/topiclist',
  'views/hot',
  'views/sukela',
  'views/debe',
  'views/conf'
], function ($, _, Backbone, SidebarView, TopicView,
             TopicListView, HotView, SukelaView, DebeView, ConfView) {
  var AppRouter = Backbone.Router.extend ({
    routes: {
      '': 'defaultAction',
      't/:order/:topic': 'topic',
      'hot/:channel': 'hotchannel',
      'hot': 'hot',
      'sukela': 'sukela',
      'debe': 'debe',
      'conf': 'conf'
    },
  });

  var initialize = function () {
    var router = new AppRouter;
    router.on ('route:defaultAction', function () {
    });
    router.on ('route:topic', function (order, topic) {
      var topicView = new TopicView ();
      topicView.render (order, topic);
    });
    // FIXME: need to use all route definitions in AppRouter
    router.route (/^tl\/(.*?)$/, "topiclist");
    router.on ('route:topiclist', function (external_url) {
      var topicListView = new TopicListView ();
      topicListView.render (external_url);
    });
    router.on ('route:hot', function () {
      var hotView = new HotView ();
      hotView.render ();
    });
    router.on ('route:hotchannel', function (channel) {
      var hotView = new HotView ();
      hotView.render (channel);
    });
    router.on ('route:sukela', function () {
      var sukelaView = new SukelaView ();
      sukelaView.render ();
    });
    router.on ('route:debe', function () {
      var debeView = new DebeView ();
      debeView.render ();
    });
    router.on ('route:conf', function () {
      var confView = new ConfView ();
      confView.render ();
    });
    Backbone.history.start ();
  };

  return {
    initialize: initialize
  };
});
<|endoftext|>


<commit_before>const Discord = require('discord.js');
const config = require("./config.json");

exports.run = async (bot, message) => {
    var embed = new Discord.RichEmbed()
  .setTitle("Restricted")
    .setColor("#f45f42")
  .addField("You are restricted from this command", "Its for the bot owner only!")
  const randomColor = "#000000".replace(/0/g, function () { return (~~(Math.random() * 16)).toString(16); });
  const clean = text => {
    if(message.author.id !== config.ownerID) return message.channel.send({ embed: embed });
  if (typeof(text) === "string")
    return text.replace(/`/g, "`" + String.fromCharCode(8203)).replace(/@/g, "@" + String.fromCharCode(8203));
  else
      return text;
}
  const args = message.content.split(" ").slice(1);
  if (!args) return message.reply("Put what args you want")
    try {
      const code = args.join(" ");
      let evaled = eval(code);

      if (typeof evaled !== "string")
        evaled = require("util").inspect(evaled);
        var embed2 = new Discord.RichEmbed()
        .setTitle("Evaled:")
        .setColor(randomColor)
        .addField("Evaled: :inbox_tray:",  ``\`\`js\n${args}\n\`\`\``)
        .addField("Output: :outbot_tray:", clean(evaled), {code:"xl"})
        message.channel.send({ embed: embed2 )};
    } catch (err) {
      message.channel.send(``ERROR\` \`\`\`xl\n${clean(err)}\n\`\`\``);
    }};
<commit_msg>Update eval.js<commit_after>const Discord = require('discord.js');
const config = require("./config.json");

exports.run = async (bot, message) => {
    var embed = new Discord.RichEmbed()
  .setTitle("Restricted")
    .setColor("#f45f42")
  .addField("You are restricted from this command", "Its for the bot owner only!")
  const randomColor = "#000000".replace(/0/g, function () { return (~~(Math.random() * 16)).toString(16); });
  const clean = text => {
    if(message.author.id !== config.ownerID) return message.channel.send({ embed: embed });
  if (typeof(text) === "string")
    return text.replace(/`/g, "`" + String.fromCharCode(8203)).replace(/@/g, "@" + String.fromCharCode(8203));
  else
      return text;
}
  const args = message.content.split(" ").slice(1);
  if (!args) return message.reply("Put what args you want")
    try {
      const code = args.join(" ");
      let evaled = eval(code);

      if (typeof evaled !== "string")
        evaled = require("util").inspect(evaled);
        var embed2 = new Discord.RichEmbed()
        .setTitle("Evaled:")
        .setColor(randomColor)
        .addField("Evaled: :inbox_tray:",  ````js\n${args}\n````)
        .addField("Output: :outbot_tray:", clean(evaled), {code:"xl"})
        message.channel.send({ embed: embed2 )};
    } catch (err) {
      message.channel.send(``ERROR\` \`\`\`xl\n${clean(err)}\n\`\`\``);
    }};
<|endoftext|>


<commit_before>var EzIrc  = (function() {
  'use strict';

  var irc = require('slate-irc');
  var tls = require('tls');
  var q = require('q');
  var _ = require('./toolbelt');
  var l = require('./log')('EzIrc');

  var EzIrc = {
    connect: function(options) {
      l.verbose('Connecting')
      var deferred = q.defer();
      connectToHost(options)
      .then(function(stream) {
        var client = irc(stream);
        client.use(endwho());
        client.use(channelModeIs());
        client.use(endBanList());
        client.promises = {};
        client.joinedChannels = [];
        client.connectionOptions = options;
        addPromise(client, 'connect', deferred);
        client.on('errors', onIrcError);
        client.on('welcome', onIrcWelcome);
        client.on('nick', function(e) {client.currentNick = e.new;});
        client.on('join', onIrcJoin);
        client.on('mode', onIrcMode);
        client.on('endwho', onIrcEndWho);
        client.on('data', onIrcData);
        return client;
      })
      .then(function(client) {
        if (options.serverPassword)
          client.pass(options.serverPassword);
        setNick(client, options.nick);
        client.user(options.userid || options.nick || 'user', options.username);
        return client;
      })
      .done();
      return deferred.promise;
    },

    join: function(client, channel) {
      if (_.contains(client.joinedChannels, channel))
        return q(client);
      var deferred = q.defer();
      var joinPromise = addPromise(client, 'join');
      client.join(channel);
      joinPromise
      .then(function(client) {
        return mode(client, channel, '');
      })
      .then(function(client) {
        var whoPromise = addPromise(client, 'who');
        client.write('WHO ' + channel + '\r\n');
        return whoPromise;
      })
      .then(function(client) {
        var chanModePromise = addPromise(client, 'mode');
        client.mode(channel, 'b');
        return chanModePromise;
      })
      .then(function(client) {
        client.joinedChannels.push(channel);
        deferred.resolve(client);
      })
      .done();

      return deferred.promise;
    },

    onMessage: function (client, callback) {
      client.on('message', function(event) {
        callback(client, event);
      })
    }
  };

  var endwho = function() {
    return function(irc) {
      irc.on('data', function(msg){
        if ('RPL_ENDOFWHO' != msg.command) return;
        var e = {};
        e.msg = msg.trailing;
        irc.emit('endwho', e);
      });
    }
  };

  var channelModeIs = function() {
    return function(irc){
      irc.on('data', function(msg){
        if ('RPL_CHANNELMODEIS' != msg.command) return;
        var params = msg.params.split(' ');
        var e = {};
        e.target = params[0];
        e.mode = params[1] || msg.trailing;
        e.client = params[2];
        irc.emit('mode', e);
      });
    }
  }

  var endBanList = function() {
    return function(irc){
      irc.on('data', function(msg){
        if ('RPL_ENDOFBANLIST' != msg.command) return;
        var params = msg.params.split(' ');
        var e = {};
        e.target = params[0];
        e.mode = params[1] || msg.trailing;
        e.client = params[2];
        irc.emit('mode', e);
      });
    }
  }

  var addPromise = function(client, promiseType, deferred) {
    deferred = deferred || q.defer()
    if (!_.has(client.promises, promiseType))
      client.promises[promiseType] = [];
    client.promises[promiseType].push(deferred);
    return deferred.promise;
  }

  var resolvePromise = function(client, promiseType) {
    var arr = client.promises[promiseType];
    if (arr) {
      var promise = arr.shift();
      if (promise) promise.resolve(client);
    }
  }

  var connectToHost = function(options) {
    var deferred = q.defer();
    var stream = tls.connect(options, function(err) {
      if (err)
        deferred.reject(err);
      deferred.resolve(stream);
    });
    return deferred.promise;
  }

  var setNick = function(client, nick) {
    client.desiredNick = nick || client.desiredNick;
    if (!client.nickAttempts)
      client.nickAttempts = 0;
    if (client.nickAttempts > 1)
      client.nick(client.desiredNick + (client.nickAttempts - 1));
    else if (client.nickAttempts == 1)
      client.nick(client.desiredNick + '_');
    else
      client.nick(client.desiredNick);
    client.nickAttempts++;
  }

  var onIrcError = function(e) {
    var client = this;
    switch(e.cmd) {
      case 'ERR_NICKNAMEINUSE':
        setNick(client);
        break;
    }
  }

  var onIrcData = function(msg) {
    l.silly('Got incoming message %j', msg, {});
  };

  var onIrcWelcome = function(e) {
    var client = this;
    client.currentNick = e;
    initializeConnection(client)
    .then(function(client) {
      resolvePromise(client, 'connect');
      return client;
    })
    .done();
  }

  var onIrcJoin = function(e) {
    var client = this;
    if (e.nick === client.currentNick)
      resolvePromise(client, 'join');
  }

  var onIrcMode = function(e) {
    var client = this;
    resolvePromise(client, 'mode');
  }

  var onIrcEndWho = function(e) {
    var client = this;
    resolvePromise(client, 'who');
  }

  var initializeConnection = function(client) {
    var deferred = q.defer();
    mode(client, client.currentNick, '+i')
    .then(function(client) {
      client.whois(client.currentNick, function(e) {
        deferred.resolve(client);
      });
    })
    return deferred.promise;
  }

  var mode = function(client, target, flags) {
    var chanModePromise = addPromise(client, 'mode');
    client.mode(target, flags);
    return chanModePromise;
  }

  String.prototype.endsWith = function(suffix) {
      return this.indexOf(suffix, this.length - suffix.length) !== -1;
  };

  return EzIrc;
}());

module.exports = EzIrc;
<commit_msg>Support non-tls connections<commit_after>var EzIrc  = (function() {
  'use strict';

  var irc = require('slate-irc');
  var tls = require('tls');
  var net = require('net');
  var q = require('q');
  var _ = require('./toolbelt');
  var l = require('./log')('EzIrc');

  var EzIrc = {
    connect: function(options) {
      l.verbose('Connecting')
      var deferred = q.defer();
      connectToHost(options)
      .then(function(stream) {
        var client = irc(stream);
        client.use(endwho());
        client.use(channelModeIs());
        client.use(endBanList());
        client.promises = {};
        client.joinedChannels = [];
        client.connectionOptions = options;
        addPromise(client, 'connect', deferred);
        client.on('errors', onIrcError);
        client.on('welcome', onIrcWelcome);
        client.on('nick', function(e) {client.currentNick = e.new;});
        client.on('join', onIrcJoin);
        client.on('mode', onIrcMode);
        client.on('endwho', onIrcEndWho);
        client.on('data', onIrcData);
        return client;
      })
      .then(function(client) {
        if (options.serverPassword)
          client.pass(options.serverPassword);
        setNick(client, options.nick);
        client.user(options.userid || options.nick || 'user', options.username);
        return client;
      })
      .done();
      return deferred.promise;
    },

    join: function(client, channel) {
      if (_.contains(client.joinedChannels, channel))
        return q(client);
      var deferred = q.defer();
      var joinPromise = addPromise(client, 'join');
      client.join(channel);
      joinPromise
      .then(function(client) {
        return mode(client, channel, '');
      })
      .then(function(client) {
        var whoPromise = addPromise(client, 'who');
        client.write('WHO ' + channel + '\r\n');
        return whoPromise;
      })
      .then(function(client) {
        var chanModePromise = addPromise(client, 'mode');
        client.mode(channel, 'b');
        return chanModePromise;
      })
      .then(function(client) {
        client.joinedChannels.push(channel);
        deferred.resolve(client);
      })
      .done();

      return deferred.promise;
    },

    onMessage: function (client, callback) {
      client.on('message', function(event) {
        callback(client, event);
      })
    }
  };

  var endwho = function() {
    return function(irc) {
      irc.on('data', function(msg){
        if ('RPL_ENDOFWHO' != msg.command) return;
        var e = {};
        e.msg = msg.trailing;
        irc.emit('endwho', e);
      });
    }
  };

  var channelModeIs = function() {
    return function(irc){
      irc.on('data', function(msg){
        if ('RPL_CHANNELMODEIS' != msg.command) return;
        var params = msg.params.split(' ');
        var e = {};
        e.target = params[0];
        e.mode = params[1] || msg.trailing;
        e.client = params[2];
        irc.emit('mode', e);
      });
    }
  }

  var endBanList = function() {
    return function(irc){
      irc.on('data', function(msg){
        if ('RPL_ENDOFBANLIST' != msg.command) return;
        var params = msg.params.split(' ');
        var e = {};
        e.target = params[0];
        e.mode = params[1] || msg.trailing;
        e.client = params[2];
        irc.emit('mode', e);
      });
    }
  }

  var addPromise = function(client, promiseType, deferred) {
    deferred = deferred || q.defer()
    if (!_.has(client.promises, promiseType))
      client.promises[promiseType] = [];
    client.promises[promiseType].push(deferred);
    return deferred.promise;
  }

  var resolvePromise = function(client, promiseType) {
    var arr = client.promises[promiseType];
    if (arr) {
      var promise = arr.shift();
      if (promise) promise.resolve(client);
    }
  }

  var connectToHost = function(options) {
    var deferred = q.defer();
    var connector = options.useTLS ? tls : net;
    var stream = connector.connect(options, function(err) {
      if (err)
        deferred.reject(err);
      deferred.resolve(stream);
    });
    return deferred.promise;
  }

  var setNick = function(client, nick) {
    client.desiredNick = nick || client.desiredNick;
    if (!client.nickAttempts)
      client.nickAttempts = 0;
    if (client.nickAttempts > 1)
      client.nick(client.desiredNick + (client.nickAttempts - 1));
    else if (client.nickAttempts == 1)
      client.nick(client.desiredNick + '_');
    else
      client.nick(client.desiredNick);
    client.nickAttempts++;
  }

  var onIrcError = function(e) {
    var client = this;
    switch(e.cmd) {
      case 'ERR_NICKNAMEINUSE':
        setNick(client);
        break;
    }
  }

  var onIrcData = function(msg) {
    l.silly('Got incoming message %j', msg, {});
  };

  var onIrcWelcome = function(e) {
    var client = this;
    client.currentNick = e;
    initializeConnection(client)
    .then(function(client) {
      resolvePromise(client, 'connect');
      return client;
    })
    .done();
  }

  var onIrcJoin = function(e) {
    var client = this;
    if (e.nick === client.currentNick)
      resolvePromise(client, 'join');
  }

  var onIrcMode = function(e) {
    var client = this;
    resolvePromise(client, 'mode');
  }

  var onIrcEndWho = function(e) {
    var client = this;
    resolvePromise(client, 'who');
  }

  var initializeConnection = function(client) {
    var deferred = q.defer();
    mode(client, client.currentNick, '+i')
    .then(function(client) {
      client.whois(client.currentNick, function(e) {
        deferred.resolve(client);
      });
    })
    return deferred.promise;
  }

  var mode = function(client, target, flags) {
    var chanModePromise = addPromise(client, 'mode');
    client.mode(target, flags);
    return chanModePromise;
  }

  String.prototype.endsWith = function(suffix) {
      return this.indexOf(suffix, this.length - suffix.length) !== -1;
  };

  return EzIrc;
}());

module.exports = EzIrc;
<|endoftext|>


<commit_before>// Magic scroll things.
// This binds cool animations to the scroll level in such a way that the
// animations' progress can be controlled by scrolling. This does what
// ScrollMagic does except without the bugs.

const elem = {
  homeWrapper: document.getElementById('home-wrapper'),
  homeContainer: document.querySelector('#home-wrapper .container'),
  // These properties are computed based on properties previously defined, so they have to be in
  // getters, but they still become static properties after their first call because of
  // Object.defineProperty
  get homeTitle() {
    // Override after first call to ensure it consistently refers to the same element
    Object.defineProperty(this, 'homeTitle', { value: this.homeWrapper.getElementsByTagName('h1')[0] });
    return this.homeTitle;
  },

  laptop(hash) {
    // 'home' -> ''
    const h = hash === 'home' ? '' : hash;
    return document.querySelector(`.laptop3d[data-laptop-hash='${h}']`);
  },
  laptopContent(hash) { return this.laptop(hash).getElementsByClassName('screen')[0]; },

  laptopsContainer: document.getElementsByClassName('laptops-container')[0],
  laptopsStretcher: document.getElementsByClassName('laptops-stretcher')[0],
};

// HOME TRANSITION LOGIC =========================================================================

let homePageIsInLaptop = false;
let textIsInLaptop = false;
function updatePageShrink(progress) {
  // Blends two values based on "progress" made between them.
  function tween(a, b) {
    return a + ((b - a) * progress);
  }
  // Returns the center of a passed ClientRect object (or similar)
  function getCenter(rect) {
    return { x: (rect.left + rect.right) / 2, y: (rect.top + rect.bottom) / 2 };
  }

  // FIT HOME PAGE TO LAPTOP SCREEN

  if (progress < 1) {
    if (homePageIsInLaptop) {
      elem.homeContainer.style.position = 'fixed';
      elem.homeContainer.style.top = elem.homeContainer.style.left = 0;
      elem.homeContainer.style.width = '100vw'; elem.homeContainer.style.height = '100vh';
      elem.homeWrapper.appendChild(elem.homeContainer);
      homePageIsInLaptop = false;
    }
    // Beginning and end positions
    const w = window.innerWidth; const h = window.innerHeight;
    const posA = { left: 0, top: 0, right: w, bottom: h, width: w, height: h };
    const posB = elem.laptopContent('home').getBoundingClientRect();
    // Calculate translation
    // Center is used for calculating translation because element is scaled about the center)
    const centerA = getCenter(posA); const centerB = getCenter(posB);
    const translationNeeded = { x: centerB.x - centerA.x, y: centerB.y - centerA.y };
    // Calculate scale
    const scaleNeeded = { x: posB.width / posA.width, y: posB.height / posA.height };
    // Apply transformations
    elem.homeContainer.style.transform = [
      // Translate
      `translateX(${tween(0, translationNeeded.x)}px)`,
      `translateY(${tween(0, translationNeeded.y)}px)`,
      // Scale
      `scaleX(${tween(1, scaleNeeded.x)})`,
      `scaleY(${tween(1, scaleNeeded.y)})`,
    ].join(' ');
  } else if (!homePageIsInLaptop) {
    elem.homeContainer.style.position = 'absolute';
    elem.homeContainer.style.transform = '';
    // This should be easy but Blink insists on rendering .front behind .back if I give
    // position: relative to .screen, so .container has to be manually positioned relative to .front
    const screenBezel = window.sassHeightVariable * 0.85;
    elem.homeContainer.style.top = elem.homeContainer.style.left = `${screenBezel}vw`;
    elem.homeContainer.style.width = `${window.sassLengthVariable - (2 * screenBezel) - 0.6}vw`; // 0.6 is border width
    elem.homeContainer.style.height = `${window.sassWidthVariable - (2.5 * screenBezel) - 0.6}vw`; // 2.5 because bottom bezel is bigger
    elem.laptopContent('home').appendChild(elem.homeContainer);
    homePageIsInLaptop = true;
  }

  // FIT NAME TO LAPTOP SCREEN

  if (progress < 1) {
    if (textIsInLaptop) {
      elem.homeTitle.style.position = 'fixed';
      elem.homeWrapper.appendChild(elem.homeTitle);
      textIsInLaptop = false;
    }
    const centerA = { x: window.innerWidth / 2, y: window.innerHeight / 2 };
    const centerB = getCenter(elem.laptopContent('home').getBoundingClientRect());
    const translationNeeded = { x: centerB.x - centerA.x, y: centerB.y - centerA.y };
    elem.homeTitle.style.transform = [
      'translate(-50%, -50%)',
      `translateX(${tween(0, translationNeeded.x)}px)`,
      `translateY(${tween(0, translationNeeded.y)}px)`,
      `scale(${tween(1, 0.5)})`,
    ].join(' ');
  } else if (!textIsInLaptop) {
    elem.homeTitle.style.position = 'absolute';
    elem.homeTitle.style.transform = 'translate(-50%, -50%) scale(0.5)';
    // CSS animations replay on every appendChild. It only needs to play once (when the page loads),
    // so we just remove it before it has a chance to play again the first time it's appended
    elem.homeTitle.style.animation = 'none';
    elem.laptopContent('home').appendChild(elem.homeTitle);
    textIsInLaptop = true;
  }

  // MISCELLANEOUS

  // ADJUST CANVAS SETTINGS

  const canvasRect = window.gol.elem.getBoundingClientRect();
  // How much canvas has been downscaled overall? Averages X and Y scale factors to get a holistic
  // scale factor
  const horizontalScaleFactor = (canvasRect.width / window.innerWidth);
  const verticalScaleFactor = (canvasRect.height / window.innerHeight);
  const averageScaleFactor = (horizontalScaleFactor + verticalScaleFactor) / 2;
  window.gol.idealCellSize = 20 * averageScaleFactor;
  window.gol.needsSizeUpdate = true;
}

// SCROLL LISTENER =================================================================================

function onscroll() {
  const scroll = window.scrollY;

  // Pages shrinking into laptops

  const shrinkProgress = scroll / (window.innerHeight / 2);
  if (scroll < 5) requestAnimationFrame(() => updatePageShrink(0));
  else if (scroll > window.innerHeight / 2) requestAnimationFrame(() => updatePageShrink(1));
  else requestAnimationFrame(() => updatePageShrink(window.ease.outSin(shrinkProgress)));

  // Carousel

  const largerScreenDimension = Math.max(window.innerWidth, window.innerHeight);

  // Adjust carousel position
  const start = elem.laptopsStretcher.offsetTop;
  const end = start + (largerScreenDimension * 1.5);

  const carouselProgress = (scroll - start) / (end - start);
  requestAnimationFrame(() => {
    // window.carousel.position = carouselProgress * window.carousel.maxIndex;
  });

  // Update navigation bar opacity
  const navProgress = scroll / (window.innerHeight / 2);
  document.getElementById('navigation').style.opacity = (shrinkProgress * 0.75) + 0.25;
  // Update navigation trigger opacity in the opposite direction
  document.getElementById('navigation-trigger').style.opacity = 1 - (shrinkProgress * 0.75);
}

window.onscroll = onscroll;

document.addEventListener('scroll', onscroll);
window.addEventListener('resize', onscroll);
<commit_msg>Put lower limit on navigation toggle opacity<commit_after>// Magic scroll things.
// This binds cool animations to the scroll level in such a way that the
// animations' progress can be controlled by scrolling. This does what
// ScrollMagic does except without the bugs.

const elem = {
  homeWrapper: document.getElementById('home-wrapper'),
  homeContainer: document.querySelector('#home-wrapper .container'),
  // These properties are computed based on properties previously defined, so they have to be in
  // getters, but they still become static properties after their first call because of
  // Object.defineProperty
  get homeTitle() {
    // Override after first call to ensure it consistently refers to the same element
    Object.defineProperty(this, 'homeTitle', { value: this.homeWrapper.getElementsByTagName('h1')[0] });
    return this.homeTitle;
  },

  laptop(hash) {
    // 'home' -> ''
    const h = hash === 'home' ? '' : hash;
    return document.querySelector(`.laptop3d[data-laptop-hash='${h}']`);
  },
  laptopContent(hash) { return this.laptop(hash).getElementsByClassName('screen')[0]; },

  laptopsContainer: document.getElementsByClassName('laptops-container')[0],
  laptopsStretcher: document.getElementsByClassName('laptops-stretcher')[0],
};

// HOME TRANSITION LOGIC =========================================================================

let homePageIsInLaptop = false;
let textIsInLaptop = false;
function updatePageShrink(progress) {
  // Blends two values based on "progress" made between them.
  function tween(a, b) {
    return a + ((b - a) * progress);
  }
  // Returns the center of a passed ClientRect object (or similar)
  function getCenter(rect) {
    return { x: (rect.left + rect.right) / 2, y: (rect.top + rect.bottom) / 2 };
  }

  // FIT HOME PAGE TO LAPTOP SCREEN

  if (progress < 1) {
    if (homePageIsInLaptop) {
      elem.homeContainer.style.position = 'fixed';
      elem.homeContainer.style.top = elem.homeContainer.style.left = 0;
      elem.homeContainer.style.width = '100vw'; elem.homeContainer.style.height = '100vh';
      elem.homeWrapper.appendChild(elem.homeContainer);
      homePageIsInLaptop = false;
    }
    // Beginning and end positions
    const w = window.innerWidth; const h = window.innerHeight;
    const posA = { left: 0, top: 0, right: w, bottom: h, width: w, height: h };
    const posB = elem.laptopContent('home').getBoundingClientRect();
    // Calculate translation
    // Center is used for calculating translation because element is scaled about the center)
    const centerA = getCenter(posA); const centerB = getCenter(posB);
    const translationNeeded = { x: centerB.x - centerA.x, y: centerB.y - centerA.y };
    // Calculate scale
    const scaleNeeded = { x: posB.width / posA.width, y: posB.height / posA.height };
    // Apply transformations
    elem.homeContainer.style.transform = [
      // Translate
      `translateX(${tween(0, translationNeeded.x)}px)`,
      `translateY(${tween(0, translationNeeded.y)}px)`,
      // Scale
      `scaleX(${tween(1, scaleNeeded.x)})`,
      `scaleY(${tween(1, scaleNeeded.y)})`,
    ].join(' ');
  } else if (!homePageIsInLaptop) {
    elem.homeContainer.style.position = 'absolute';
    elem.homeContainer.style.transform = '';
    // This should be easy but Blink insists on rendering .front behind .back if I give
    // position: relative to .screen, so .container has to be manually positioned relative to .front
    const screenBezel = window.sassHeightVariable * 0.85;
    elem.homeContainer.style.top = elem.homeContainer.style.left = `${screenBezel}vw`;
    elem.homeContainer.style.width = `${window.sassLengthVariable - (2 * screenBezel) - 0.6}vw`; // 0.6 is border width
    elem.homeContainer.style.height = `${window.sassWidthVariable - (2.5 * screenBezel) - 0.6}vw`; // 2.5 because bottom bezel is bigger
    elem.laptopContent('home').appendChild(elem.homeContainer);
    homePageIsInLaptop = true;
  }

  // FIT NAME TO LAPTOP SCREEN

  if (progress < 1) {
    if (textIsInLaptop) {
      elem.homeTitle.style.position = 'fixed';
      elem.homeWrapper.appendChild(elem.homeTitle);
      textIsInLaptop = false;
    }
    const centerA = { x: window.innerWidth / 2, y: window.innerHeight / 2 };
    const centerB = getCenter(elem.laptopContent('home').getBoundingClientRect());
    const translationNeeded = { x: centerB.x - centerA.x, y: centerB.y - centerA.y };
    elem.homeTitle.style.transform = [
      'translate(-50%, -50%)',
      `translateX(${tween(0, translationNeeded.x)}px)`,
      `translateY(${tween(0, translationNeeded.y)}px)`,
      `scale(${tween(1, 0.5)})`,
    ].join(' ');
  } else if (!textIsInLaptop) {
    elem.homeTitle.style.position = 'absolute';
    elem.homeTitle.style.transform = 'translate(-50%, -50%) scale(0.5)';
    // CSS animations replay on every appendChild. It only needs to play once (when the page loads),
    // so we just remove it before it has a chance to play again the first time it's appended
    elem.homeTitle.style.animation = 'none';
    elem.laptopContent('home').appendChild(elem.homeTitle);
    textIsInLaptop = true;
  }

  // MISCELLANEOUS

  // ADJUST CANVAS SETTINGS

  const canvasRect = window.gol.elem.getBoundingClientRect();
  // How much canvas has been downscaled overall? Averages X and Y scale factors to get a holistic
  // scale factor
  const horizontalScaleFactor = (canvasRect.width / window.innerWidth);
  const verticalScaleFactor = (canvasRect.height / window.innerHeight);
  const averageScaleFactor = (horizontalScaleFactor + verticalScaleFactor) / 2;
  window.gol.idealCellSize = 20 * averageScaleFactor;
  window.gol.needsSizeUpdate = true;
}

// SCROLL LISTENER =================================================================================

function onscroll() {
  const scroll = window.scrollY;

  // Pages shrinking into laptops

  const shrinkProgress = scroll / (window.innerHeight / 2);
  if (scroll < 5) requestAnimationFrame(() => updatePageShrink(0));
  else if (scroll > window.innerHeight / 2) requestAnimationFrame(() => updatePageShrink(1));
  else requestAnimationFrame(() => updatePageShrink(window.ease.outSin(shrinkProgress)));

  // Carousel

  const largerScreenDimension = Math.max(window.innerWidth, window.innerHeight);

  // Adjust carousel position
  const start = elem.laptopsStretcher.offsetTop;
  const end = start + (largerScreenDimension * 1.5);

  const carouselProgress = (scroll - start) / (end - start);
  requestAnimationFrame(() => {
    // window.carousel.position = carouselProgress * window.carousel.maxIndex;
  });

  // Update navigation bar opacity
  const navProgress = scroll / (window.innerHeight / 2);
  document.getElementById('navigation').style.opacity = (shrinkProgress * 0.75) + 0.25;
  // Update navigation trigger opacity in the opposite direction
  document.getElementById('navigation-trigger').style.opacity = Math.max(0.25, 1 - (shrinkProgress * 0.75));
}

window.onscroll = onscroll;

document.addEventListener('scroll', onscroll);
window.addEventListener('resize', onscroll);
<|endoftext|>