<commit_before>//Chris Samuel
//Github: Alayode
//2015-3-12

// Code School: Changing Declarations to Expressions

// Developers for the Forest of Function Expressions
// Theme Park have created a function declaration named forestFright,
// but they’ve decided not to keep the function in memory.
// Convert the function from a named function
// declaration to an anonymous function
// expression and assign it to a variable called runAway.

function forestFright() {
  var toAlert = "";
  for (var i = 0; i < 5; i++) {
    toAlert = toAlert + "Lions, Tigers, and Bears, Oh My!!\n";
  }
  alert(toAlert);
}

// First lets create a variable called runAway
var runAway;

//Next lets try remeber that when a function expression is added to a
//variable we can remove the name of the function from the "()"
// this will make it become an anonymous function.

function() {
  var toAlert = "";
  for (var i = 0; i < 5; i++) {
    toAlert = toAlert + "Lions, Tigers, and Bears, Oh My!!\n";
  }
  alert(toAlert);
}
<commit_msg>assigned the function to runAway<commit_after>//Chris Samuel
//Github: Alayode
//2015-3-12

// Code School: Changing Declarations to Expressions

// Developers for the Forest of Function Expressions
// Theme Park have created a function declaration named forestFright,
// but they’ve decided not to keep the function in memory.
// Convert the function from a named function
// declaration to an anonymous function
// expression and assign it to a variable called runAway.

function forestFright() {
  var toAlert = "";
  for (var i = 0; i < 5; i++) {
    toAlert = toAlert + "Lions, Tigers, and Bears, Oh My!!\n";
  }
  alert(toAlert);
}

// First lets create a variable called runAway
var runAway;

//Next lets try remeber that when a function expression is added to a
//variable we can remove the name of the function from the "()"
// this will make it become an anonymous function.

function() {
  var toAlert = "";
  for (var i = 0; i < 5; i++) {
    toAlert = toAlert + "Lions, Tigers, and Bears, Oh My!!\n";
  }
  alert(toAlert);
}

// now that it has no name it can called by assiging it to a
// variable. lets use the variable runAway

//this is another to use this function.
var runAway = function() {
  var toAlert = "";
  for (var i = 0; i < 5; i++) {
    toAlert = toAlert + "Lions, Tigers, and Bears, Oh My!!\n";
  }
  alert(toAlert);
};

runAway();
<|endoftext|>


<commit_before>const isNode =
	typeof process === 'object' &&
	typeof require === 'function' &&
	typeof window !== 'object' &&
	typeof importScripts !== 'function';

const rootScope = isNode ? global : self;

const BitcorePrivateKey = require('bitcore-lib/lib/privatekey');
const BitcoreTransaction = require('bitcore-lib/lib/transaction');
const FormData = require('form-data');
const {ReplaySubject, Subject} = require('rxjs');
const {map, mergeMap} = require('rxjs/operators');

const fetch =
	typeof rootScope.fetch === 'function' ?
		rootScope.fetch :
	isNode ?
		eval('require')('node-fetch') :
		require('whatwg-fetch');

const locks = {};

const lock = (id, f) => {
	if (!locks[id]) {
		locks[id] = Promise.resolve();
	}

	locks[id] = locks[id].catch(() => {}).then(() => f());

	return locks[id];
};

const request = (url, opts) => {
	let retries = 0;

	return lock('request', () => fetch(url, opts))
		.then(o => {
			if (o.status !== 200) {
				throw new Error(
					`Request failure: status ${o.status.toString()}`
				);
			}

			return o;
		})
		.catch(err => {
			if (retries > 10) {
				throw err;
			}
			++retries;

			return new Promise(resolve => {
				setTimeout(resolve, 250);
			}).then(() => request(url, opts));
		});
};

const satoshiConversion = 100000000;
const transactionFee = 5430;

const blockchainApiURL = 'https://blockchain.info/';
const blockchainWebSocketURL = 'wss://ws.blockchain.info/inv';

const blockchainAPI = (url, params = {}) => {
	if (params.cors !== false) {
		params.cors = true;
	}

	return `${blockchainApiURL + url}?${Object.keys(params)
		.map(k => `${k}=${params[k]}`)
		.join('&')}`;
};

const blockchainAPIRequest = (url, params) => {
	return request(blockchainAPI(url, params)).then(o => o.json());
};

const getExchangeRates = () => {
	return blockchainAPIRequest('ticker').then(o => {
		for (const k in o) {
			o[k] = o[k].last;
		}

		o.BTC = 1;

		return o;
	});
};

class Wallet {
	constructor (options = {}) {
		if (options instanceof Wallet) {
			this.address = options.address;
			this.isReadOnly = options.isReadOnly;
			this.localCurrency = options.localCurrency;
			this.key = options.key;
			this.originatingTransactions = options.originatingTransactions;
			this.subjects = {};

			return;
		}

		this.localCurrency = options.localCurrency || 'BTC';

		if (options.key) {
			this.key =
				typeof options.key === 'string' ?
					new BitcorePrivateKey(options.key, 'livenet') :
					BitcorePrivateKey.fromObject({
						bn: options.key,
						compressed: true,
						network: 'livenet'
					});
		}
		else if (!options.address) {
			this.key = new BitcorePrivateKey(undefined, 'livenet');
		}

		this.isReadOnly = !this.key;
		this.address = this.isReadOnly ?
			options.address :
			this.key.toAddress().toString();

		this.originatingTransactions = {};
		this.subjects = {};
	}

	_getExchangeRates ()  {
		return this.localCurrency === 'BTC' ?
			Promise.resolve({BTC: 1}) :
			getExchangeRates();
	}

	_friendlyTransaction (transaction, exchangeRate)  {
		const senderAddresses = {};
		const recipientAddresses = {};

		const valueIn = transaction.inputs
			.map(o => o.prev_out.value)
			.reduce((a, b) => a + b);

		const valueOut = transaction.out
			.map(o => o.value)
			.reduce((a, b) => a + b);

		const transactionData = {
			amount: undefined,
			valueInLocal: valueIn * exchangeRate,
			valueOutLocal: valueOut * exchangeRate,
			wasSentByMe: false
		};

		transactionData.amount = transactionData.valueOutLocal;

		for (const vin of transaction.inputs.map(o => o.prev_out)) {
			transactionData.wasSentByMe =
				transactionData.wasSentByMe || vin.addr === this.address;

			vin.valueLocal = vin.value * exchangeRate;

			senderAddresses[vin.addr] = true;
		}

		for (const vout of transaction.out) {
			vout.valueLocal = vout.value * exchangeRate;

			if (vout.addr) {
				if (senderAddresses[vout.addr]) {
					transactionData.amount -= vout.valueLocal;
				}
				else {
					recipientAddresses[vout.addr] = true;
				}
			}
		}

		return {
			amount: parseFloat(
				(transactionData.amount / satoshiConversion).toFixed(8)
			),
			baseTransaction: transaction,
			id: transaction.txid,
			isConfirmed: (transaction.confirmations || 0) >= 6,
			recipients: Object.keys(recipientAddresses),
			senders: Object.keys(senderAddresses),
			timestamp: transaction.time * 1000,
			wasSentByMe: transactionData.wasSentByMe
		};
	}

	_friendlyTransactions (transactions)  {
		return Promise.all([transactions, this._getExchangeRates()]).then(
			results => {
				const txs = results[0].txs || [];
				const exchangeRate = results[1][this.localCurrency];

				return txs.map(tx => friendlyTransaction(tx, exchangeRate));
			}
		);
	}

	_watchTransactions ()  {
		const subjectID = `_watchTransactions ${this.address}`;

		if (!this.subjects[subjectID]) {
			this.subjects[subjectID] = new Subject();

			const socket = new WebSocket(blockchainWebSocketURL);

			socket.onopen = () => {
				socket.send(
					JSON.stringify({op: 'addr_sub', addr: this.address})
				);
			};

			socket.onmessage = msg => {
				let txid;
				try {
					txid = JSON.parse(msg.data).x.hash;
				}
				catch (_) {}

				if (txid) {
					this.subjects[subjectID].next(JSON.parse(msg.data).x.hash);
				}
			};
		}

		return this.subjects[subjectID];
	}

	createTransaction (recipientAddress, amount)  {
		if (this.isReadOnly) {
			return Promise.reject(new Error('Read-only wallet'));
		}

		return Promise.all([
			this.getBalance(),
			blockchainAPIRequest('unspent', {active: this.address}).catch(
				() => ({
					unspent_outputs: []
				})
			)
		]).then(results => {
			const balance = results[0];

			const utxos = ((results[1] || {}).unspent_outputs || []).map(o => ({
				outputIndex: o.tx_output_n,
				satoshis: o.value,
				scriptPubKey: o.script,
				txid: o.tx_hash_big_endian
			}));

			amount = amount / balance._exchangeRates[this.localCurrency];

			if (amount > balance.btc) {
				throw new Error('Insufficient funds');
			}

			for (const utxo of utxos) {
				if (
					this.originatingTransactions[utxo.txid] &&
					!utxo.confirmations
				) {
					utxo.confirmations = 1;
				}
			}

			return (function createBitcoreTransaction (retries)  {
				try {
					return new BitcoreTransaction()
						.from(
							utxos.map(
								utxo =>
									new BitcoreTransaction.UnspentOutput(utxo)
							)
						)
						.to(
							recipientAddress.address ?
								recipientAddress.address :
							recipientAddress.getAddress ?
								recipientAddress.getAddress().toString() :
								recipientAddress,
							Math.floor(amount * satoshiConversion)
						)
						.change(this.address)
						.fee(transactionFee)
						.sign(this.key);
				}
				catch (e) {
					if (
						retries < 100 &&
						e.message.includes('totalNeededAmount')
					) {
						amount -= 0.000005;
						return createBitcoreTransaction(retries + 1);
					}
					else {
						throw e;
					}
				}
			})(0);
		});
	}

	getBalance ()  {
		return Promise.all([
			blockchainAPIRequest('balance', {active: this.address}),
			this._getExchangeRates()
		]).then(results => {
			let balance = 0;
			try {
				balance =
					results[0][this.address].final_balance / satoshiConversion;
			}
			catch (_) {}

			const exchangeRates = results[1];

			return {
				_exchangeRates: exchangeRates,
				btc: balance,
				local: parseFloat(
					(
						balance * (exchangeRates[this.localCurrency] || 0)
					).toFixed(2)
				)
			};
		});
	}

	getTransactionHistory ()  {
		return this._friendlyTransactions(
			blockchainAPIRequest(`rawaddr/${this.address}`)
		);
	}

	send (recipientAddress, amount)  {
		return this.createTransaction(recipientAddress, amount).then(
			transaction => {
				const txid = transaction.id;
				this.originatingTransactions[txid] = true;

				const formData = new FormData();
				formData.append('tx', transaction.serialize());

				return request(blockchainAPI('pushtx'), {
					body: formData,
					method: 'POST'
				}).then(o => o.text());
			}
		);
	}

	watchNewTransactions (shouldIncludeUnconfirmed)  {
		if (shouldIncludeUnconfirmed === undefined) {
			shouldIncludeUnconfirmed = true;
		}

		const subjectID = `watchNewTransactions ${this.address}`;

		if (!this.subjects[subjectID]) {
			this.subjects[subjectID] = this._watchTransactions().pipe(
				mergeMap(txid =>
					lock(subjectID, () =>
						this._friendlyTransactions(
							blockchainAPIRequest(`rawtx/${txid}`).then(o => [o])
						).then(newTransaction => newTransaction[0])
					)
				)
			);
		}

		return shouldIncludeUnconfirmed ?
			this.subjects[subjectID] :
			this.subjects[subjectID].pipe(
				map(transactions =>
					transactions.filter(transaction => transaction.isConfirmed)
				)
			);
	}

	watchTransactionHistory (shouldIncludeUnconfirmed)  {
		if (shouldIncludeUnconfirmed === undefined) {
			shouldIncludeUnconfirmed = true;
		}

		const subjectID = `watchTransactionHistory ${this.address}`;

		if (!this.subjects[subjectID]) {
			this.subjects[subjectID] = new ReplaySubject(1);

			this.getTransactionHistory().then(transactions => {
				this.subjects[subjectID].next(transactions);

				this._watchTransactions()
					.pipe(
						mergeMap(() =>
							lock(subjectID, () => this.getTransactionHistory())
						)
					)
					.subscribe(this.subjects[subjectID]);
			});
		}

		return shouldIncludeUnconfirmed ?
			this.subjects[subjectID] :
			this.subjects[subjectID].pipe(
				map(transactions =>
					transactions.filter(transaction => transaction.isConfirmed)
				)
			);
	}
}

const simplebtc = {
	getExchangeRates,
	minimumTransactionAmount:
		BitcoreTransaction.DUST_AMOUNT / satoshiConversion,
	transactionFee: transactionFee / satoshiConversion,
	Wallet
};

simplebtc.simplebtc = simplebtc;
module.exports = simplebtc;
<commit_msg>minor cleanup<commit_after>const isNode =
	typeof process === 'object' &&
	typeof require === 'function' &&
	typeof window !== 'object' &&
	typeof importScripts !== 'function';

const rootScope = isNode ? global : self;

const BitcorePrivateKey = require('bitcore-lib/lib/privatekey');
const BitcoreTransaction = require('bitcore-lib/lib/transaction');
const FormData = require('form-data');
const {ReplaySubject, Subject} = require('rxjs');
const {map, mergeMap} = require('rxjs/operators');

const fetch =
	typeof rootScope.fetch === 'function' ?
		rootScope.fetch :
	isNode ?
		eval('require')('node-fetch') :
		require('whatwg-fetch');

const locks = {};

const lock = (id, f) => {
	if (!locks[id]) {
		locks[id] = Promise.resolve();
	}

	locks[id] = locks[id].catch(() => {}).then(() => f());

	return locks[id];
};

const request = (url, opts) => {
	let retries = 0;

	return lock('request', () => fetch(url, opts))
		.then(o => {
			if (o.status !== 200) {
				throw new Error(
					`Request failure: status ${o.status.toString()}`
				);
			}

			return o;
		})
		.catch(err => {
			if (retries > 10) {
				throw err;
			}
			++retries;

			return new Promise(resolve => {
				setTimeout(resolve, 250);
			}).then(() => request(url, opts));
		});
};

const satoshiConversion = 100000000;
const transactionFee = 5430;

const blockchainApiURL = 'https://blockchain.info/';
const blockchainWebSocketURL = 'wss://ws.blockchain.info/inv';

const blockchainAPI = (url, params = {}) => {
	if (params.cors !== false) {
		params.cors = true;
	}

	return `${blockchainApiURL + url}?${Object.keys(params)
		.map(k => `${k}=${params[k]}`)
		.join('&')}`;
};

const blockchainAPIRequest = (url, params) => {
	return request(blockchainAPI(url, params)).then(o => o.json());
};

const getExchangeRates = () => {
	return blockchainAPIRequest('ticker').then(o => {
		for (const k in o) {
			o[k] = o[k].last;
		}

		o.BTC = 1;

		return o;
	});
};

class Wallet {
	constructor (options = {}) {
		if (options instanceof Wallet) {
			this.address = options.address;
			this.isReadOnly = options.isReadOnly;
			this.localCurrency = options.localCurrency;
			this.key = options.key;
			this.originatingTransactions = options.originatingTransactions;
			this.subjects = {};

			return;
		}

		this.localCurrency = options.localCurrency || 'BTC';

		if (options.key) {
			this.key =
				typeof options.key === 'string' ?
					new BitcorePrivateKey(options.key, 'livenet') :
					BitcorePrivateKey.fromObject({
						bn: options.key,
						compressed: true,
						network: 'livenet'
					});
		}
		else if (!options.address) {
			this.key = new BitcorePrivateKey(undefined, 'livenet');
		}

		this.isReadOnly = !this.key;
		this.address = this.isReadOnly ?
			options.address :
			this.key.toAddress().toString();

		this.originatingTransactions = {};
		this.subjects = {};
	}

	_friendlyTransaction (transaction, exchangeRate)  {
		const senderAddresses = {};
		const recipientAddresses = {};

		const valueIn = transaction.inputs
			.map(o => o.prev_out.value)
			.reduce((a, b) => a + b);

		const valueOut = transaction.out
			.map(o => o.value)
			.reduce((a, b) => a + b);

		const transactionData = {
			amount: undefined,
			valueInLocal: valueIn * exchangeRate,
			valueOutLocal: valueOut * exchangeRate,
			wasSentByMe: false
		};

		transactionData.amount = transactionData.valueOutLocal;

		for (const vin of transaction.inputs.map(o => o.prev_out)) {
			transactionData.wasSentByMe =
				transactionData.wasSentByMe || vin.addr === this.address;

			vin.valueLocal = vin.value * exchangeRate;

			senderAddresses[vin.addr] = true;
		}

		for (const vout of transaction.out) {
			vout.valueLocal = vout.value * exchangeRate;

			if (vout.addr) {
				if (senderAddresses[vout.addr]) {
					transactionData.amount -= vout.valueLocal;
				}
				else {
					recipientAddresses[vout.addr] = true;
				}
			}
		}

		return {
			amount: parseFloat(
				(transactionData.amount / satoshiConversion).toFixed(8)
			),
			baseTransaction: transaction,
			id: transaction.txid,
			isConfirmed: (transaction.confirmations || 0) >= 6,
			recipients: Object.keys(recipientAddresses),
			senders: Object.keys(senderAddresses),
			timestamp: transaction.time * 1000,
			wasSentByMe: transactionData.wasSentByMe
		};
	}

	_friendlyTransactions (transactions)  {
		return Promise.all([transactions, this._getExchangeRates()]).then(
			results => {
				const txs = results[0].txs || [];
				const exchangeRate = results[1][this.localCurrency];

				return txs.map(tx => friendlyTransaction(tx, exchangeRate));
			}
		);
	}

	_getExchangeRates ()  {
		return this.localCurrency === 'BTC' ?
			Promise.resolve({BTC: 1}) :
			getExchangeRates();
	}

	_watchTransactions ()  {
		const subjectID = `_watchTransactions ${this.address}`;

		if (!this.subjects[subjectID]) {
			this.subjects[subjectID] = new Subject();

			const socket = new WebSocket(blockchainWebSocketURL);

			socket.onopen = () => {
				socket.send(
					JSON.stringify({op: 'addr_sub', addr: this.address})
				);
			};

			socket.onmessage = msg => {
				let txid;
				try {
					txid = JSON.parse(msg.data).x.hash;
				}
				catch (_) {}

				if (txid) {
					this.subjects[subjectID].next(JSON.parse(msg.data).x.hash);
				}
			};
		}

		return this.subjects[subjectID];
	}

	createTransaction (recipientAddress, amount)  {
		if (this.isReadOnly) {
			return Promise.reject(new Error('Read-only wallet'));
		}

		return Promise.all([
			this.getBalance(),
			blockchainAPIRequest('unspent', {active: this.address}).catch(
				() => ({
					unspent_outputs: []
				})
			)
		]).then(results => {
			const balance = results[0];

			const utxos = ((results[1] || {}).unspent_outputs || []).map(o => ({
				outputIndex: o.tx_output_n,
				satoshis: o.value,
				scriptPubKey: o.script,
				txid: o.tx_hash_big_endian
			}));

			amount = amount / balance._exchangeRates[this.localCurrency];

			if (amount > balance.btc) {
				throw new Error('Insufficient funds');
			}

			for (const utxo of utxos) {
				if (
					this.originatingTransactions[utxo.txid] &&
					!utxo.confirmations
				) {
					utxo.confirmations = 1;
				}
			}

			return (function createBitcoreTransaction (retries)  {
				try {
					return new BitcoreTransaction()
						.from(
							utxos.map(
								utxo =>
									new BitcoreTransaction.UnspentOutput(utxo)
							)
						)
						.to(
							recipientAddress.address ?
								recipientAddress.address :
							recipientAddress.getAddress ?
								recipientAddress.getAddress().toString() :
								recipientAddress,
							Math.floor(amount * satoshiConversion)
						)
						.change(this.address)
						.fee(transactionFee)
						.sign(this.key);
				}
				catch (e) {
					if (
						retries < 100 &&
						e.message.includes('totalNeededAmount')
					) {
						amount -= 0.000005;
						return createBitcoreTransaction(retries + 1);
					}
					else {
						throw e;
					}
				}
			})(0);
		});
	}

	getBalance ()  {
		return Promise.all([
			blockchainAPIRequest('balance', {active: this.address}),
			this._getExchangeRates()
		]).then(results => {
			let balance = 0;
			try {
				balance =
					results[0][this.address].final_balance / satoshiConversion;
			}
			catch (_) {}

			const exchangeRates = results[1];

			return {
				_exchangeRates: exchangeRates,
				btc: balance,
				local: parseFloat(
					(
						balance * (exchangeRates[this.localCurrency] || 0)
					).toFixed(2)
				)
			};
		});
	}

	getTransactionHistory ()  {
		return this._friendlyTransactions(
			blockchainAPIRequest(`rawaddr/${this.address}`)
		);
	}

	send (recipientAddress, amount)  {
		return this.createTransaction(recipientAddress, amount).then(
			transaction => {
				const txid = transaction.id;
				this.originatingTransactions[txid] = true;

				const formData = new FormData();
				formData.append('tx', transaction.serialize());

				return request(blockchainAPI('pushtx'), {
					body: formData,
					method: 'POST'
				}).then(o => o.text());
			}
		);
	}

	watchNewTransactions (shouldIncludeUnconfirmed)  {
		if (shouldIncludeUnconfirmed === undefined) {
			shouldIncludeUnconfirmed = true;
		}

		const subjectID = `watchNewTransactions ${this.address}`;

		if (!this.subjects[subjectID]) {
			this.subjects[subjectID] = this._watchTransactions().pipe(
				mergeMap(txid =>
					lock(subjectID, () =>
						this._friendlyTransactions(
							blockchainAPIRequest(`rawtx/${txid}`).then(o => [o])
						).then(newTransaction => newTransaction[0])
					)
				)
			);
		}

		return shouldIncludeUnconfirmed ?
			this.subjects[subjectID] :
			this.subjects[subjectID].pipe(
				map(transactions =>
					transactions.filter(transaction => transaction.isConfirmed)
				)
			);
	}

	watchTransactionHistory (shouldIncludeUnconfirmed)  {
		if (shouldIncludeUnconfirmed === undefined) {
			shouldIncludeUnconfirmed = true;
		}

		const subjectID = `watchTransactionHistory ${this.address}`;

		if (!this.subjects[subjectID]) {
			this.subjects[subjectID] = new ReplaySubject(1);

			this.getTransactionHistory().then(transactions => {
				this.subjects[subjectID].next(transactions);

				this._watchTransactions()
					.pipe(
						mergeMap(() =>
							lock(subjectID, () => this.getTransactionHistory())
						)
					)
					.subscribe(this.subjects[subjectID]);
			});
		}

		return shouldIncludeUnconfirmed ?
			this.subjects[subjectID] :
			this.subjects[subjectID].pipe(
				map(transactions =>
					transactions.filter(transaction => transaction.isConfirmed)
				)
			);
	}
}

const simplebtc = {
	getExchangeRates,
	minimumTransactionAmount:
		BitcoreTransaction.DUST_AMOUNT / satoshiConversion,
	transactionFee: transactionFee / satoshiConversion,
	Wallet
};

simplebtc.simplebtc = simplebtc;
module.exports = simplebtc;
<|endoftext|>


<commit_before>import {Layer} from '../Layer';
import {IconDefault} from './Icon.Default';
import * as Util from '../../core/Util';
import {toLatLng as latLng} from '../../geo/LatLng';
import * as DomUtil from '../../dom/DomUtil';
import {MarkerDrag} from './Marker.Drag';

/*
 * @class Marker
 * @inherits Interactive layer
 * @aka L.Marker
 * L.Marker is used to display clickable/draggable icons on the map. Extends `Layer`.
 *
 * @example
 *
 * ```js
 * L.marker([50.5, 30.5]).addTo(map);
 * ```
 */

export var Marker = Layer.extend({

	// @section
	// @aka Marker options
	options: {
		// @option icon: Icon = *
		// Icon instance to use for rendering the marker.
		// See [Icon documentation](#L.Icon) for details on how to customize the marker icon.
		// If not specified, a common instance of `L.Icon.Default` is used.
		icon: new IconDefault(),

		// Option inherited from "Interactive layer" abstract class
		interactive: true,

		// @option draggable: Boolean = false
		// Whether the marker is draggable with mouse/touch or not.
		draggable: false,

		// @option autoPan: Boolean = false
		// Set it to `true` if you want the map to do panning animation when marker hits the edges.
		autoPan: false,

		// @option autoPanPadding: Point = Point(50, 50)
		// Equivalent of setting both top left and bottom right autopan padding to the same value.
		autoPanPadding: [50, 50],

		// @option autoPanSpeed: Number = 10
		// Number of pixels the map should move by.
		autoPanSpeed: 10,

		// @option keyboard: Boolean = true
		// Whether the marker can be tabbed to with a keyboard and clicked by pressing enter.
		keyboard: true,

		// @option title: String = ''
		// Text for the browser tooltip that appear on marker hover (no tooltip by default).
		title: '',

		// @option alt: String = ''
		// Text for the `alt` attribute of the icon image (useful for accessibility).
		alt: '',

		// @option zIndexOffset: Number = 0
		// By default, marker images zIndex is set automatically based on its latitude. Use this option if you want to put the marker on top of all others (or below), specifying a high value like `1000` (or high negative value, respectively).
		zIndexOffset: 0,

		// @option opacity: Number = 1.0
		// The opacity of the marker.
		opacity: 1,

		// @option riseOnHover: Boolean = false
		// If `true`, the marker will get on top of others when you hover the mouse over it.
		riseOnHover: false,

		// @option riseOffset: Number = 250
		// The z-index offset used for the `riseOnHover` feature.
		riseOffset: 250,

		// @option pane: String = 'markerPane'
		// `Map pane` where the markers icon will be added.
		pane: 'markerPane',

		// @option bubblingMouseEvents: Boolean = false
		// When `true`, a mouse event on this marker will trigger the same event on the map
		// (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).
		bubblingMouseEvents: false
	},

	/* @section
	 *
	 * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods:
	 */

	initialize: function (latlng, options) {
		Util.setOptions(this, options);
		this._latlng = latLng(latlng);
	},

	onAdd: function (map) {
		this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation;

		if (this._zoomAnimated) {
			map.on('zoomanim', this._animateZoom, this);
		}

		this._initIcon();
		this.update();
	},

	onRemove: function (map) {
		if (this.dragging && this.dragging.enabled()) {
			this.options.draggable = true;
			this.dragging.removeHooks();
		}
		delete this.dragging;

		if (this._zoomAnimated) {
			map.off('zoomanim', this._animateZoom, this);
		}

		this._removeIcon();
		this._removeShadow();
	},

	getEvents: function () {
		return {
			zoom: this.update,
			viewreset: this.update
		};
	},

	// @method getLatLng: LatLng
	// Returns the current geographical position of the marker.
	getLatLng: function () {
		return this._latlng;
	},

	// @method setLatLng(latlng: LatLng): this
	// Changes the marker position to the given point.
	setLatLng: function (latlng) {
		var oldLatLng = this._latlng;
		this._latlng = latLng(latlng);
		this.update();

		// @event move: Event
		// Fired when the marker is moved via [`setLatLng`](#marker-setlatlng) or by [dragging](#marker-dragging). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`.
		return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng});
	},

	// @method setZIndexOffset(offset: Number): this
	// Changes the [zIndex offset](#marker-zindexoffset) of the marker.
	setZIndexOffset: function (offset) {
		this.options.zIndexOffset = offset;
		return this.update();
	},

	// @method setIcon(icon: Icon): this
	// Changes the marker icon.
	setIcon: function (icon) {

		this.options.icon = icon;

		if (this._map) {
			this._initIcon();
			this.update();
		}

		if (this._popup) {
			this.bindPopup(this._popup, this._popup.options);
		}

		return this;
	},

	getElement: function () {
		return this._icon;
	},

	update: function () {

		if (this._icon && this._map) {
			var pos = this._map.latLngToLayerPoint(this._latlng).round();
			this._setPos(pos);
		}

		return this;
	},

	_initIcon: function () {
		var options = this.options,
		    classToAdd = 'leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');

		var icon = options.icon.createIcon(this._icon),
		    addIcon = false;

		// if we're not reusing the icon, remove the old one and init new one
		if (icon !== this._icon) {
			if (this._icon) {
				this._removeIcon();
			}
			addIcon = true;

			if (options.title) {
				icon.title = options.title;
			}

			if (icon.tagName === 'IMG') {
				icon.alt = options.alt || '';
			}
		}

		DomUtil.addClass(icon, classToAdd);

		if (options.keyboard) {
			icon.tabIndex = '0';
		}

		this._icon = icon;

		if (options.riseOnHover) {
			this.on({
				mouseover: this._bringToFront,
				mouseout: this._resetZIndex
			});
		}

		var newShadow = options.icon.createShadow(this._shadow),
		    addShadow = false;

		if (newShadow !== this._shadow) {
			this._removeShadow();
			addShadow = true;
		}

		if (newShadow) {
			DomUtil.addClass(newShadow, classToAdd);
			newShadow.alt = '';
		}
		this._shadow = newShadow;

		if (options.opacity < 1) {
			this._updateOpacity();
		}

		if (addIcon) {
			this.getPane().appendChild(this._icon);
		}
		this._initInteraction();
		if (newShadow && addShadow) {
			this.getPane('shadowPane').appendChild(this._shadow);
		}
	},

	_removeIcon: function () {
		if (this.options.riseOnHover) {
			this.off({
				mouseover: this._bringToFront,
				mouseout: this._resetZIndex
			});
		}

		DomUtil.remove(this._icon);
		this.removeInteractiveTarget(this._icon);

		this._icon = null;
	},

	_removeShadow: function () {
		if (this._shadow) {
			DomUtil.remove(this._shadow);
		}
		this._shadow = null;
	},

	_setPos: function (pos) {
		DomUtil.setPosition(this._icon, pos);

		if (this._shadow) {
			DomUtil.setPosition(this._shadow, pos);
		}

		this._zIndex = pos.y + this.options.zIndexOffset;

		this._resetZIndex();
	},

	_updateZIndex: function (offset) {
		this._icon.style.zIndex = this._zIndex + offset;
	},

	_animateZoom: function (opt) {
		var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();

		this._setPos(pos);
	},

	_initInteraction: function () {

		if (!this.options.interactive) { return; }

		DomUtil.addClass(this._icon, 'leaflet-interactive');

		this.addInteractiveTarget(this._icon);

		if (MarkerDrag) {
			var draggable = this.options.draggable;
			if (this.dragging) {
				draggable = this.dragging.enabled();
				this.dragging.disable();
			}

			this.dragging = new MarkerDrag(this);

			if (draggable) {
				this.dragging.enable();
			}
		}
	},

	// @method setOpacity(opacity: Number): this
	// Changes the opacity of the marker.
	setOpacity: function (opacity) {
		this.options.opacity = opacity;
		if (this._map) {
			this._updateOpacity();
		}

		return this;
	},

	_updateOpacity: function () {
		var opacity = this.options.opacity;

		DomUtil.setOpacity(this._icon, opacity);

		if (this._shadow) {
			DomUtil.setOpacity(this._shadow, opacity);
		}
	},

	_bringToFront: function () {
		this._updateZIndex(this.options.riseOffset);
	},

	_resetZIndex: function () {
		this._updateZIndex(0);
	},

	_getPopupAnchor: function () {
		return this.options.icon.options.popupAnchor;
	},

	_getTooltipAnchor: function () {
		return this.options.icon.options.tooltipAnchor;
	}
});

// factory L.marker(latlng: LatLng, options? : Marker options)

// @factory L.marker(latlng: LatLng, options? : Marker options)
// Instantiates a Marker object given a geographical point and optionally an options object.
export function marker(latlng, options) {
	return new Marker(latlng, options);
}
<commit_msg>Reword docstrings for draggable markers (#6296)<commit_after>import {Layer} from '../Layer';
import {IconDefault} from './Icon.Default';
import * as Util from '../../core/Util';
import {toLatLng as latLng} from '../../geo/LatLng';
import * as DomUtil from '../../dom/DomUtil';
import {MarkerDrag} from './Marker.Drag';

/*
 * @class Marker
 * @inherits Interactive layer
 * @aka L.Marker
 * L.Marker is used to display clickable/draggable icons on the map. Extends `Layer`.
 *
 * @example
 *
 * ```js
 * L.marker([50.5, 30.5]).addTo(map);
 * ```
 */

export var Marker = Layer.extend({

	// @section
	// @aka Marker options
	options: {
		// @option icon: Icon = *
		// Icon instance to use for rendering the marker.
		// See [Icon documentation](#L.Icon) for details on how to customize the marker icon.
		// If not specified, a common instance of `L.Icon.Default` is used.
		icon: new IconDefault(),

		// Option inherited from "Interactive layer" abstract class
		interactive: true,

		// @option keyboard: Boolean = true
		// Whether the marker can be tabbed to with a keyboard and clicked by pressing enter.
		keyboard: true,

		// @option title: String = ''
		// Text for the browser tooltip that appear on marker hover (no tooltip by default).
		title: '',

		// @option alt: String = ''
		// Text for the `alt` attribute of the icon image (useful for accessibility).
		alt: '',

		// @option zIndexOffset: Number = 0
		// By default, marker images zIndex is set automatically based on its latitude. Use this option if you want to put the marker on top of all others (or below), specifying a high value like `1000` (or high negative value, respectively).
		zIndexOffset: 0,

		// @option opacity: Number = 1.0
		// The opacity of the marker.
		opacity: 1,

		// @option riseOnHover: Boolean = false
		// If `true`, the marker will get on top of others when you hover the mouse over it.
		riseOnHover: false,

		// @option riseOffset: Number = 250
		// The z-index offset used for the `riseOnHover` feature.
		riseOffset: 250,

		// @option pane: String = 'markerPane'
		// `Map pane` where the markers icon will be added.
		pane: 'markerPane',

		// @option bubblingMouseEvents: Boolean = false
		// When `true`, a mouse event on this marker will trigger the same event on the map
		// (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).
		bubblingMouseEvents: false,

		// @section Draggable marker options
		// @option draggable: Boolean = false
		// Whether the marker is draggable with mouse/touch or not.
		draggable: false,

		// @option autoPan: Boolean = false
		// Whether to pan the map when dragging this marker near its edge or not.
		autoPan: false,

		// @option autoPanPadding: Point = Point(50, 50)
		// Distance (in pixels to the left/right and to the top/bottom) of the
		// map edge to start panning the map.
		autoPanPadding: [50, 50],

		// @option autoPanSpeed: Number = 10
		// Number of pixels the map should pan by.
		autoPanSpeed: 10
	},

	/* @section
	 *
	 * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods:
	 */

	initialize: function (latlng, options) {
		Util.setOptions(this, options);
		this._latlng = latLng(latlng);
	},

	onAdd: function (map) {
		this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation;

		if (this._zoomAnimated) {
			map.on('zoomanim', this._animateZoom, this);
		}

		this._initIcon();
		this.update();
	},

	onRemove: function (map) {
		if (this.dragging && this.dragging.enabled()) {
			this.options.draggable = true;
			this.dragging.removeHooks();
		}
		delete this.dragging;

		if (this._zoomAnimated) {
			map.off('zoomanim', this._animateZoom, this);
		}

		this._removeIcon();
		this._removeShadow();
	},

	getEvents: function () {
		return {
			zoom: this.update,
			viewreset: this.update
		};
	},

	// @method getLatLng: LatLng
	// Returns the current geographical position of the marker.
	getLatLng: function () {
		return this._latlng;
	},

	// @method setLatLng(latlng: LatLng): this
	// Changes the marker position to the given point.
	setLatLng: function (latlng) {
		var oldLatLng = this._latlng;
		this._latlng = latLng(latlng);
		this.update();

		// @event move: Event
		// Fired when the marker is moved via [`setLatLng`](#marker-setlatlng) or by [dragging](#marker-dragging). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`.
		return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng});
	},

	// @method setZIndexOffset(offset: Number): this
	// Changes the [zIndex offset](#marker-zindexoffset) of the marker.
	setZIndexOffset: function (offset) {
		this.options.zIndexOffset = offset;
		return this.update();
	},

	// @method setIcon(icon: Icon): this
	// Changes the marker icon.
	setIcon: function (icon) {

		this.options.icon = icon;

		if (this._map) {
			this._initIcon();
			this.update();
		}

		if (this._popup) {
			this.bindPopup(this._popup, this._popup.options);
		}

		return this;
	},

	getElement: function () {
		return this._icon;
	},

	update: function () {

		if (this._icon && this._map) {
			var pos = this._map.latLngToLayerPoint(this._latlng).round();
			this._setPos(pos);
		}

		return this;
	},

	_initIcon: function () {
		var options = this.options,
		    classToAdd = 'leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');

		var icon = options.icon.createIcon(this._icon),
		    addIcon = false;

		// if we're not reusing the icon, remove the old one and init new one
		if (icon !== this._icon) {
			if (this._icon) {
				this._removeIcon();
			}
			addIcon = true;

			if (options.title) {
				icon.title = options.title;
			}

			if (icon.tagName === 'IMG') {
				icon.alt = options.alt || '';
			}
		}

		DomUtil.addClass(icon, classToAdd);

		if (options.keyboard) {
			icon.tabIndex = '0';
		}

		this._icon = icon;

		if (options.riseOnHover) {
			this.on({
				mouseover: this._bringToFront,
				mouseout: this._resetZIndex
			});
		}

		var newShadow = options.icon.createShadow(this._shadow),
		    addShadow = false;

		if (newShadow !== this._shadow) {
			this._removeShadow();
			addShadow = true;
		}

		if (newShadow) {
			DomUtil.addClass(newShadow, classToAdd);
			newShadow.alt = '';
		}
		this._shadow = newShadow;

		if (options.opacity < 1) {
			this._updateOpacity();
		}

		if (addIcon) {
			this.getPane().appendChild(this._icon);
		}
		this._initInteraction();
		if (newShadow && addShadow) {
			this.getPane('shadowPane').appendChild(this._shadow);
		}
	},

	_removeIcon: function () {
		if (this.options.riseOnHover) {
			this.off({
				mouseover: this._bringToFront,
				mouseout: this._resetZIndex
			});
		}

		DomUtil.remove(this._icon);
		this.removeInteractiveTarget(this._icon);

		this._icon = null;
	},

	_removeShadow: function () {
		if (this._shadow) {
			DomUtil.remove(this._shadow);
		}
		this._shadow = null;
	},

	_setPos: function (pos) {
		DomUtil.setPosition(this._icon, pos);

		if (this._shadow) {
			DomUtil.setPosition(this._shadow, pos);
		}

		this._zIndex = pos.y + this.options.zIndexOffset;

		this._resetZIndex();
	},

	_updateZIndex: function (offset) {
		this._icon.style.zIndex = this._zIndex + offset;
	},

	_animateZoom: function (opt) {
		var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();

		this._setPos(pos);
	},

	_initInteraction: function () {

		if (!this.options.interactive) { return; }

		DomUtil.addClass(this._icon, 'leaflet-interactive');

		this.addInteractiveTarget(this._icon);

		if (MarkerDrag) {
			var draggable = this.options.draggable;
			if (this.dragging) {
				draggable = this.dragging.enabled();
				this.dragging.disable();
			}

			this.dragging = new MarkerDrag(this);

			if (draggable) {
				this.dragging.enable();
			}
		}
	},

	// @method setOpacity(opacity: Number): this
	// Changes the opacity of the marker.
	setOpacity: function (opacity) {
		this.options.opacity = opacity;
		if (this._map) {
			this._updateOpacity();
		}

		return this;
	},

	_updateOpacity: function () {
		var opacity = this.options.opacity;

		DomUtil.setOpacity(this._icon, opacity);

		if (this._shadow) {
			DomUtil.setOpacity(this._shadow, opacity);
		}
	},

	_bringToFront: function () {
		this._updateZIndex(this.options.riseOffset);
	},

	_resetZIndex: function () {
		this._updateZIndex(0);
	},

	_getPopupAnchor: function () {
		return this.options.icon.options.popupAnchor;
	},

	_getTooltipAnchor: function () {
		return this.options.icon.options.tooltipAnchor;
	}
});

// factory L.marker(latlng: LatLng, options? : Marker options)

// @factory L.marker(latlng: LatLng, options? : Marker options)
// Instantiates a Marker object given a geographical point and optionally an options object.
export function marker(latlng, options) {
	return new Marker(latlng, options);
}
<|endoftext|>


<commit_before>function byte2Hex(n) {
    const nybHexString = '0123456789ABCDEF';
    return String(nybHexString.substr((n >> 4) & 0x0F, 1)) + nybHexString.substr(n & 0x0F, 1);
}

function RGB2Color(r, g, b) {
    return `#${byte2Hex(r)}${byte2Hex(g)}${byte2Hex(b)}`;
}

function colorText(i, maxExclusive, phaseParam) {
    let phase = phaseParam;
    if (phase == null) phase = 0;

    const center = 128;
    const width = 127;
    const frequency = (Math.PI * 2) / maxExclusive;

    const red = Math.sin(frequency * i + 2 + phase) * width + center;
    const green = Math.sin(frequency * i + 0 + phase) * width + center;
    const blue = Math.sin(frequency * i + 4 + phase) * width + center;

    const hexColor = RGB2Color(red, green, blue);

    return hexColor;
}

function setRoleColor(role, i, maxExclusive) {
    let nowIter = i;

    const newColor = colorText(nowIter, maxExclusive, 0);

    nowIter++;

    if (nowIter === maxExclusive) nowIter = 0;

    role.setColor(newColor)
    .catch(console.error); // 168, 184, 560, 175, 231, 179

    setTimeout(setRoleColor, 10, role, nowIter, maxExclusive);

    /* role.setColor(newColor)
    .then(() => setRoleColor(role, nowIter, maxExclusive))
    .catch(console.error); */
}

module.exports = Cmds.addCommand({
    cmds: [';effect', ';color', ';addeffect'],

    requires: {
        guild: true,
        loud: false,
    },

    desc: 'Magic',

    args: '',

    example: '',

    // /////////////////////////////////////////////////////////////////////////////////////////

    func: (cmd, args, msgObj, speaker, channel, guild) => {
        const Vaeben = Util.getRole('Vaeben', guild);
        setRoleColor(Vaeben, 0, 150);
    },
});
<commit_msg>Update<commit_after>function byte2Hex(n) {
    const nybHexString = '0123456789ABCDEF';
    return String(nybHexString.substr((n >> 4) & 0x0F, 1)) + nybHexString.substr(n & 0x0F, 1);
}

function RGB2Color(r, g, b) {
    return `#${byte2Hex(r)}${byte2Hex(g)}${byte2Hex(b)}`;
}

function colorText(i, maxExclusive, phaseParam) {
    let phase = phaseParam;
    if (phase == null) phase = 0;

    const center = 128;
    const width = 127;
    const frequency = (Math.PI * 2) / maxExclusive;

    const red = Math.sin(frequency * i + 2 + phase) * width + center;
    const green = Math.sin(frequency * i + 0 + phase) * width + center;
    const blue = Math.sin(frequency * i + 4 + phase) * width + center;

    const hexColor = RGB2Color(red, green, blue);

    return hexColor;
}

function setRoleColor(role, i, maxExclusive) {
    let nowIter = i;

    const newColor = colorText(nowIter, maxExclusive, 0);

    nowIter++;

    if (nowIter === maxExclusive) nowIter = 0;

    role.setColor(newColor)
    .catch(console.error); // 168, 184, 560, 175, 231, 179

    setTimeout(setRoleColor, 50, role, nowIter, maxExclusive);

    /* role.setColor(newColor)
    .then(() => setRoleColor(role, nowIter, maxExclusive))
    .catch(console.error); */
}

module.exports = Cmds.addCommand({
    cmds: [';effect', ';color', ';addeffect'],

    requires: {
        guild: true,
        loud: false,
    },

    desc: 'Magic',

    args: '',

    example: '',

    // /////////////////////////////////////////////////////////////////////////////////////////

    func: (cmd, args, msgObj, speaker, channel, guild) => {
        const Vaeben = Util.getRole('Vaeben', guild);
        setRoleColor(Vaeben, 0, 100);
    },
});
<|endoftext|>


<commit_before>server = Bones.Server.extend({
    // Necessary to actually instantiate tile server.
    port:3001,

    initialize: function(app) {
        if (app.config.tilePort !== app.config.uiPort) {
            this.port = app.config.tilePort;
            this.enable('jsonp callback');
            this.use(new servers['Host'](app));
        } else {
            this.port = null;
        }

        this.config = app.config;
        this.config.header = { 'Cache-Control': 'max-age=' + 60 * 60 };
        this.initializeRoutes();
    },

    initializeRoutes: function() {
        _.bindAll(this, 'load', 'tile', 'grid', 'layer', 'download', 'status');

        this.param('tileset', this.load);

        // x.0.0 endpoints.
        this.get('/:version(1|2).0.0/:tileset/:z/:x/:y.(png|jpg|jpeg)', this.tile);
        this.get('/:version(1|2).0.0/:tileset/:z/:x/:y.grid.json', this.grid);
        this.get('/:version(1|2).0.0/:tileset/layer.json', this.layer);

        this.get('/download/:tileset.mbtiles', this.download);
        this.get('/status', this.status);
    },

    // Basic route for checking the health of the server.
    status: function(req, res, next) {
        res.send('TileStream', 200);
    },

    // Override start. We must call the callback regardless of whether the port
    // is set or not.
    start: function(callback) {
        if (this.port) {
            this.listen(this.port, callback);
        } else {
            callback();
        }
        return this;
    },

    validTilesetID: function(id) {
        return (/^[\w-]+$/i).test(id)
    },

    // Route middleware. Validate and load an mbtiles file specified in a tile
    // or download route.
    load: function(req, res, next, id) {
        if (!this.validTilesetID(id)) {
            return next(new Error.HTTP('Tileset does not exist', 404));
        }

        var model = new models.Tileset({ id: id }, req.query);
        model.fetch({
            success: function(model) {
                res.model = model;
                next();
            },
            error: function(model, err) {
                err.status = 404;
                next(err);
            }
        });
    },

    // MBTiles download.
    // @TODO: Current `maxAge` option is hardcoded into place. Find better
    // way to pass this through.
    download: function(req, res, next) {
        if (res.model.source.filename) {
            res.sendfile(res.model.source.filename, { maxAge: 3600 }, function(err, path) {
                // @TODO: log the error if one occurs.
                // We don't call next() here as HTTP headers/response has
                // already commenced by this point.
            });
        } else {
            next(new Error.HTTP("Tileset can't be downloaded", 404));
        }
    },

    // Tile endpoint
    tile: function(req, res, next) {
        var z = req.param('z'), x = req.param('x'), y = req.param('y');

        // 1.0.0: incoming request TMS => tilesource XYZ
        // 2.0.0: incoming request XYZ => tilesource XYZ
        if (req.param('version') === '1') y = Math.pow(2, z) - 1 - y;

        var headers = _.clone(this.config.header);
        res.model.source.getTile(z, x, y, function(err, tile, options) {
            if (err) {
                err.status = 404;
                next(err);
            } else {
                _.extend(headers, options || {});
                res.send(tile, headers);
            }
        });
    },

    // Grid endpoint.
    grid: function(req, res, next) {
        var z = req.param('z'), x = req.param('x'), y = req.param('y');

        // 1.0.0: incoming request TMS => tilesource XYZ
        // 2.0.0: incoming request XYZ => tilesource XYZ
        if (req.param('version') === '1') y = Math.pow(2, z) - 1 - y;

        var headers = _.clone(this.config.header);
        res.model.source.getGrid(z, x, y, function(err, grid, options) {
            if (err) {
                err.status = 404;
                next(err);
            } else {
                _.extend(headers, options || {});
                res.send(grid, headers);
            }
        });
    },

    // Layer endpoint.
    layer: function(req, res, next) {
        res.send(res.model.toJSON());
    }
});
<commit_msg>Add Cors server to Tile server.<commit_after>server = Bones.Server.extend({
    // Necessary to actually instantiate tile server.
    port:3001,

    initialize: function(app) {
        if (app.config.tilePort !== app.config.uiPort) {
            this.port = app.config.tilePort;
            this.enable('jsonp callback');
            this.use(new servers['Cors'](app));
            this.use(new servers['Host'](app));
        } else {
            this.port = null;
        }

        this.config = app.config;
        this.config.header = { 'Cache-Control': 'max-age=' + 60 * 60 };
        this.initializeRoutes();
    },

    initializeRoutes: function() {
        _.bindAll(this, 'load', 'tile', 'grid', 'layer', 'download', 'status');

        this.param('tileset', this.load);

        // x.0.0 endpoints.
        this.get('/:version(1|2).0.0/:tileset/:z/:x/:y.(png|jpg|jpeg)', this.tile);
        this.get('/:version(1|2).0.0/:tileset/:z/:x/:y.grid.json', this.grid);
        this.get('/:version(1|2).0.0/:tileset/layer.json', this.layer);

        this.get('/download/:tileset.mbtiles', this.download);
        this.get('/status', this.status);
    },

    // Basic route for checking the health of the server.
    status: function(req, res, next) {
        res.send('TileStream', 200);
    },

    // Override start. We must call the callback regardless of whether the port
    // is set or not.
    start: function(callback) {
        if (this.port) {
            this.listen(this.port, callback);
        } else {
            callback();
        }
        return this;
    },

    validTilesetID: function(id) {
        return (/^[\w-]+$/i).test(id)
    },

    // Route middleware. Validate and load an mbtiles file specified in a tile
    // or download route.
    load: function(req, res, next, id) {
        if (!this.validTilesetID(id)) {
            return next(new Error.HTTP('Tileset does not exist', 404));
        }

        var model = new models.Tileset({ id: id }, req.query);
        model.fetch({
            success: function(model) {
                res.model = model;
                next();
            },
            error: function(model, err) {
                err.status = 404;
                next(err);
            }
        });
    },

    // MBTiles download.
    // @TODO: Current `maxAge` option is hardcoded into place. Find better
    // way to pass this through.
    download: function(req, res, next) {
        if (res.model.source.filename) {
            res.sendfile(res.model.source.filename, { maxAge: 3600 }, function(err, path) {
                // @TODO: log the error if one occurs.
                // We don't call next() here as HTTP headers/response has
                // already commenced by this point.
            });
        } else {
            next(new Error.HTTP("Tileset can't be downloaded", 404));
        }
    },

    // Tile endpoint
    tile: function(req, res, next) {
        var z = req.param('z'), x = req.param('x'), y = req.param('y');

        // 1.0.0: incoming request TMS => tilesource XYZ
        // 2.0.0: incoming request XYZ => tilesource XYZ
        if (req.param('version') === '1') y = Math.pow(2, z) - 1 - y;

        var headers = _.clone(this.config.header);
        res.model.source.getTile(z, x, y, function(err, tile, options) {
            if (err) {
                err.status = 404;
                next(err);
            } else {
                _.extend(headers, options || {});
                res.send(tile, headers);
            }
        });
    },

    // Grid endpoint.
    grid: function(req, res, next) {
        var z = req.param('z'), x = req.param('x'), y = req.param('y');

        // 1.0.0: incoming request TMS => tilesource XYZ
        // 2.0.0: incoming request XYZ => tilesource XYZ
        if (req.param('version') === '1') y = Math.pow(2, z) - 1 - y;

        var headers = _.clone(this.config.header);
        res.model.source.getGrid(z, x, y, function(err, grid, options) {
            if (err) {
                err.status = 404;
                next(err);
            } else {
                _.extend(headers, options || {});
                res.send(grid, headers);
            }
        });
    },

    // Layer endpoint.
    layer: function(req, res, next) {
        res.send(res.model.toJSON());
    }
});
<|endoftext|>


<commit_before>define(function()
{
    "use strict";
    var Phase =
    {
        SETUP: "setup",

        PLANNING_START: "planningStart",
        PLANNING_END: "planningEnd",

        ACTIVATION_START: "activationStart",
        ACTIVATION_REVEAL_DIAL: "activationRevealDial",
        ACTIVATION_SET_TEMPLATE: "activationSetTemplate",
        ACTIVATION_EXECUTE_MANEUVER: "activationExecuteManeuver",
        ACTIVATION_CHECK_PILOT_STRESS: "activationCheckPilotStress",
        ACTIVATION_CLEAN_UP: "activationCleanUp",
        ACTIVATION_GAIN_ENERGY: "activationGainEnergy",
        ACTIVATION_ALLOCATE_ENERGY: "activationAllocateEnergy",
        ACTIVATION_USE_ENERGY: "activationUseEnergy",
        ACTIVATION_PERFORM_ACTION: "activationPerformAction",
        ACTIVATION_END: "activationEnd",

        COMBAT_START: "combatStart",
        COMBAT_DECLARE_TARGET: "combatDeclareTarget",
        COMBAT_ROLL_ATTACK_DICE: "combatRollAttackDice",
        COMBAT_MODIFY_ATTACK_DICE: "combatModifyAttackDice",
        COMBAT_ROLL_DEFENSE_DICE: "combatRollDefenseDice",
        COMBAT_MODIFY_DEFENSE_DICE: "combatModifyDefenseDice",
        COMBAT_COMPARE_RESULTS: "combatCompareResults",
        COMBAT_DEAL_DAMAGE: "combatDealDamage",
        COMBAT_END: "combatEnd",

        END_START: "endStart",
        END_END: "endEnd",

        properties:
        {
            "setup":
            {
                name: "Setup",
                value: "setup",
            },
            "planningStart":
            {
                name: "Planning (start)",
                value: "planningStart",
            },
            "planningEnd":
            {
                name: "Planning (end)",
                value: "planningEnd",
            },
            "activationStart":
            {
                name: "Activation (start)",
                value: "activationStart",
            },
            "activationRevealDial":
            {
                name: "Activation (reveal dial)",
                value: "activationRevealDial",
            },
            "activationSetTemplate":
            {
                name: "Activation (set template)",
                value: "activationSetTemplate",
            },
            "activationExecuteManeuver":
            {
                name: "Activation (execute maneuver)",
                value: "activationExecuteManeuver",
            },
            "activationCheckPilotStress":
            {
                name: "Activation (check pilot stress)",
                value: "activationCheckPilotStress",
            },
            "activationCleanUp":
            {
                name: "Activation (clean up)",
                value: "activationCleanUp",
            },
            "activationGainEnergy":
            {
                name: "Activation (gain energy)",
                value: "activationGainEnergy",
            },
            "activationAllocateEnergy":
            {
                name: "Activation (allocate energy)",
                value: "activationAllocateEnergy",
            },
            "activationUseEnergy":
            {
                name: "Activation (use energy)",
                value: "activationUseEnergy",
            },
            "activationPerformAction":
            {
                name: "Activation (perform action)",
                value: "activationPerformAction",
            },
            "activationEnd":
            {
                name: "Activation (end)",
                value: "activationEnd",
            },
            "combatStart":
            {
                name: "Combat (start)",
                value: "combatStart",
            },
            "combatDeclareTarget":
            {
                name: "Combat (declare target)",
                value: "combatDeclareTarget",
            },
            "combatRollAttackDice":
            {
                name: "Combat (roll attack dice)",
                value: "combatRollAttackDice",
            },
            "combatModifyAttackDice":
            {
                name: "Combat (modify attack dice)",
                value: "combatModifyAttackDice",
            },
            "combatRollDefenseDice":
            {
                name: "Combat (roll defense dice)",
                value: "combatRollDefenseDice",
            },
            "combatModifyDefenseDice":
            {
                name: "Combat (modify defense dice)",
                value: "combatModifyDefenseDice",
            },
            "combatCompareResults":
            {
                name: "Combat (compare results)",
                value: "combatCompareResults",
            },
            "combatDealDamage":
            {
                name: "Combat (deal damage)",
                value: "combatDealDamage",
            },
            "combatEnd":
            {
                name: "Combat (end)",
                value: "combatEnd",
            },
            "endStart":
            {
                name: "End (start)",
                value: "endStart",
            },
            "endEnd":
            {
                name: "End (end)",
                value: "endEnd",
            },
        },

        values: function()
        {
            return Object.getOwnPropertyNames(Phase.properties);
        },
    };

    if (Object.freeze)
    {
        Object.freeze(Phase);
    }

    return Phase;
});
<commit_msg>Re-architect the way the upgrade abilities are defined and used.<commit_after>define(function()
{
    "use strict";
    var Phase = {
        SETUP: "setup",

        PLANNING_START: "planningStart",
        PLANNING_END: "planningEnd",

        ACTIVATION_START: "activationStart",
        ACTIVATION_REVEAL_DIAL: "activationRevealDial",
        ACTIVATION_SET_TEMPLATE: "activationSetTemplate",
        ACTIVATION_EXECUTE_MANEUVER: "activationExecuteManeuver",
        ACTIVATION_CHECK_PILOT_STRESS: "activationCheckPilotStress",
        ACTIVATION_CLEAN_UP: "activationCleanUp",
        ACTIVATION_GAIN_ENERGY: "activationGainEnergy",
        ACTIVATION_ALLOCATE_ENERGY: "activationAllocateEnergy",
        ACTIVATION_USE_ENERGY: "activationUseEnergy",
        ACTIVATION_PERFORM_ACTION: "activationPerformAction",
        ACTIVATION_END: "activationEnd",

        COMBAT_START: "combatStart",
        COMBAT_DECLARE_TARGET: "combatDeclareTarget",
        COMBAT_ROLL_ATTACK_DICE: "combatRollAttackDice",
        COMBAT_MODIFY_ATTACK_DICE: "combatModifyAttackDice",
        COMBAT_ROLL_DEFENSE_DICE: "combatRollDefenseDice",
        COMBAT_MODIFY_DEFENSE_DICE: "combatModifyDefenseDice",
        COMBAT_COMPARE_RESULTS: "combatCompareResults",
        COMBAT_NOTIFY_DAMAGE: "combatNotifyDamage",
        COMBAT_DEAL_DAMAGE: "combatDealDamage",
        COMBAT_AFTER_DEAL_DAMAGE: "combatAfterDealDamage",
        COMBAT_END: "combatEnd",

        END_START: "endStart",
        END_END: "endEnd",

        properties:
        {
            "setup":
            {
                name: "Setup",
                value: "setup",
            },
            "planningStart":
            {
                name: "Planning (start)",
                value: "planningStart",
            },
            "planningEnd":
            {
                name: "Planning (end)",
                value: "planningEnd",
            },
            "activationStart":
            {
                name: "Activation (start)",
                value: "activationStart",
            },
            "activationRevealDial":
            {
                name: "Activation (reveal dial)",
                value: "activationRevealDial",
            },
            "activationSetTemplate":
            {
                name: "Activation (set template)",
                value: "activationSetTemplate",
            },
            "activationExecuteManeuver":
            {
                name: "Activation (execute maneuver)",
                value: "activationExecuteManeuver",
            },
            "activationCheckPilotStress":
            {
                name: "Activation (check pilot stress)",
                value: "activationCheckPilotStress",
            },
            "activationCleanUp":
            {
                name: "Activation (clean up)",
                value: "activationCleanUp",
            },
            "activationGainEnergy":
            {
                name: "Activation (gain energy)",
                value: "activationGainEnergy",
            },
            "activationAllocateEnergy":
            {
                name: "Activation (allocate energy)",
                value: "activationAllocateEnergy",
            },
            "activationUseEnergy":
            {
                name: "Activation (use energy)",
                value: "activationUseEnergy",
            },
            "activationPerformAction":
            {
                name: "Activation (perform action)",
                value: "activationPerformAction",
            },
            "activationEnd":
            {
                name: "Activation (end)",
                value: "activationEnd",
            },
            "combatStart":
            {
                name: "Combat (start)",
                value: "combatStart",
            },
            "combatDeclareTarget":
            {
                name: "Combat (declare target)",
                value: "combatDeclareTarget",
            },
            "combatRollAttackDice":
            {
                name: "Combat (roll attack dice)",
                value: "combatRollAttackDice",
            },
            "combatModifyAttackDice":
            {
                name: "Combat (modify attack dice)",
                value: "combatModifyAttackDice",
            },
            "combatRollDefenseDice":
            {
                name: "Combat (roll defense dice)",
                value: "combatRollDefenseDice",
            },
            "combatModifyDefenseDice":
            {
                name: "Combat (modify defense dice)",
                value: "combatModifyDefenseDice",
            },
            "combatCompareResults":
            {
                name: "Combat (compare results)",
                value: "combatCompareResults",
            },
            "combatNotifyDamage":
            {
                name: "Combat (notify damage)",
                value: "combatNotifyDamage",
            },
            "combatDealDamage":
            {
                name: "Combat (deal damage)",
                value: "combatDealDamage",
            },
            "combatAfterDealDamage":
            {
                name: "Combat (after deal damage)",
                value: "combatAfterDealDamage",
            },
            "combatEnd":
            {
                name: "Combat (end)",
                value: "combatEnd",
            },
            "endStart":
            {
                name: "End (start)",
                value: "endStart",
            },
            "endEnd":
            {
                name: "End (end)",
                value: "endEnd",
            },
        },

        values: function()
        {
            return Object.getOwnPropertyNames(Phase.properties);
        },
    };

    if (Object.freeze)
    {
        Object.freeze(Phase);
    }

    return Phase;
});
<|endoftext|>


<commit_before>/*!
 * jCarousel Swipe Plugin v@VERSION
 * http://sorgalla.com/jcarousel/
 *
 * Copyright 2011, Jan Sorgalla
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * or GPL Version 2 (http://www.opensource.org/licenses/gpl-2.0.php) licenses.
 *
 * Date: @DATE
 */
jCarousel.plugin('swipe', function($) {
    var jCarousel = this;

    return {
        started:  false,
        moved:    false,
        startX:   null,
        startY:   null,
        startPos: null,
        width:    0,
        _init: function() {
            this.eventNames = {
                mousedown: ($.vmouse ? 'v' : '') + 'mousedown.' + this.pluginName,
                mousemove: ($.vmouse ? 'v' : '') + 'mousemove.' + this.pluginName,
                mouseup:   ($.vmouse ? 'v' : '') + 'mouseup.'   + this.pluginName
            };

            this.carousel().element()
                .bind(this.eventNames.mousedown, $.proxy(this._start, this))
                .bind(this.eventNames.mouseup, $.proxy(this._stop, this))
                .bind(this.eventNames.mousemove, $.proxy(this._move, this))
                .bind('mouseleave.' + this.pluginName, $.proxy(this._stop, this));
        },
        _start: function(e) {
            var carousel = this.carousel();

            carousel.list().stop(true, false);
            carousel.animating = false;

            this.started  = true;
            this.moved    = false;
            this.startPos = jCarousel.intval(carousel.list().css(carousel.lt));
            this.startX   = jCarousel.intval(typeof e.pageX !== 'undefined' ? e.pageX : e.originalEvent.pageX);
            this.startY   = jCarousel.intval(typeof e.pageY !== 'undefined' ? e.pageY : e.originalEvent.pageY);

            var width  = 0,
                margin = 0,
                // Remove right/bottom margin from total width
                lrb    = carousel.vertical ?
                             'bottom' :
                             (carousel.rtl ? 'left'  : 'right');

            carousel.items().each(function() {
                var el = $(this);
                width += carousel._dimension(el);
                margin = el.css('margin-' + lrb);
            });

            this.width = width - jCarousel.intval(margin);

            e.stopPropagation();
            e.preventDefault();

            return this;
        },
        _stop: function() {
            if (!this.moved) {
                return this;
            }

            var scrollNearest = function() {
                var self    = this,
                    items   = this.items(),
                    pos     = this.list().position()[this.lt],
                    current = items.eq(0),
                    stop    = false,
                    lrb     = this.vertical ? 'bottom' : (this.rtl ? 'left'  : 'right');

                if (this.rtl && !this.vertical) {
                    pos = (pos + this.list().width() - this._clipping()) * -1;
                }

                items.each(function() {
                    var el  = $(this),
                        dim = self._dimension(el);

                    pos += dim;
                    current = el;

                    if (stop) {
                        return false;
                    }

                    if (pos >= 0) {
                        var limit = (dim / 2) + jCarousel.intval(el.css('margin-' + lrb));

                        if (Math.abs(pos) < limit) {
                            stop = true;
                        } else {
                            return false;
                        }
                    }
                });

                this.scroll(current);
            };

            var carousel = this.carousel();

            if (carousel.rtl && !carousel.vertical) {
                var right = !carousel.circular ? jCarousel.intval(carousel.list().css('right')) : 0;

                if (right > 0) {
                    carousel.scroll(0);
                } else if (right < -(this.width - carousel._clipping())) {
                    carousel.scroll(-1);
                } else {
                    scrollNearest.apply(carousel);
                }
            } else {
                var left = !carousel.circular ? jCarousel.intval(carousel.list().css(carousel.lt)) : 0;

                if (left > 0) {
                    carousel.scroll(0);
                } else if (left < -(this.width - carousel._clipping())) {
                    carousel.scroll(-1);
                } else {
                    scrollNearest.apply(carousel);
                }
            }

            this.started = this.moved = false;
            this.startPos = this.startX = this.startY = null;

            return this;
        },
        _move: function(e) {
            if (!this.started) {
                return this;
            }

            this.moved = true;

            var carousel = this.carousel();

            var distance = carousel.vertical ?
                               this.startY - jCarousel.intval(typeof e.pageY !== 'undefined' ? e.pageY : e.originalEvent.pageY) :
                               this.startX - jCarousel.intval(typeof e.pageX !== 'undefined' ? e.pageX : e.originalEvent.pageX);

            carousel.list()
                .stop(true, false)
                .css(carousel.lt, Math.ceil(this.startPos - distance) + 'px');

            return this;
        }
    };
});
<commit_msg>Always reset in _stop() (Fixes #299<commit_after>/*!
 * jCarousel Swipe Plugin v@VERSION
 * http://sorgalla.com/jcarousel/
 *
 * Copyright 2011, Jan Sorgalla
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * or GPL Version 2 (http://www.opensource.org/licenses/gpl-2.0.php) licenses.
 *
 * Date: @DATE
 */
jCarousel.plugin('swipe', function($) {
    var jCarousel = this;

    return {
        started:  false,
        moved:    false,
        startX:   null,
        startY:   null,
        startPos: null,
        width:    0,
        _init: function() {
            this.eventNames = {
                mousedown: ($.vmouse ? 'v' : '') + 'mousedown.' + this.pluginName,
                mousemove: ($.vmouse ? 'v' : '') + 'mousemove.' + this.pluginName,
                mouseup:   ($.vmouse ? 'v' : '') + 'mouseup.'   + this.pluginName
            };

            this.carousel().element()
                .bind(this.eventNames.mousedown, $.proxy(this._start, this))
                .bind(this.eventNames.mouseup, $.proxy(this._stop, this))
                .bind(this.eventNames.mousemove, $.proxy(this._move, this))
                .bind('mouseleave.' + this.pluginName, $.proxy(this._stop, this));
        },
        _start: function(e) {
            var carousel = this.carousel();

            carousel.list().stop(true, false);
            carousel.animating = false;

            this.started  = true;
            this.moved    = false;
            this.startPos = jCarousel.intval(carousel.list().css(carousel.lt));
            this.startX   = jCarousel.intval(typeof e.pageX !== 'undefined' ? e.pageX : e.originalEvent.pageX);
            this.startY   = jCarousel.intval(typeof e.pageY !== 'undefined' ? e.pageY : e.originalEvent.pageY);

            var width  = 0,
                margin = 0,
                // Remove right/bottom margin from total width
                lrb    = carousel.vertical ?
                             'bottom' :
                             (carousel.rtl ? 'left'  : 'right');

            carousel.items().each(function() {
                var el = $(this);
                width += carousel._dimension(el);
                margin = el.css('margin-' + lrb);
            });

            this.width = width - jCarousel.intval(margin);

            e.stopPropagation();
            e.preventDefault();

            return this;
        },
        _stop: function() {
            var moved = this.moved;

            this.started = this.moved = false;
            this.startPos = this.startX = this.startY = null;

            if (!moved) {
                return this;
            }

            var scrollNearest = function() {
                var self    = this,
                    items   = this.items(),
                    pos     = this.list().position()[this.lt],
                    current = items.eq(0),
                    stop    = false,
                    lrb     = this.vertical ? 'bottom' : (this.rtl ? 'left'  : 'right');

                if (this.rtl && !this.vertical) {
                    pos = (pos + this.list().width() - this._clipping()) * -1;
                }

                items.each(function() {
                    var el  = $(this),
                        dim = self._dimension(el);

                    pos += dim;
                    current = el;

                    if (stop) {
                        return false;
                    }

                    if (pos >= 0) {
                        var limit = (dim / 2) + jCarousel.intval(el.css('margin-' + lrb));

                        if (Math.abs(pos) < limit) {
                            stop = true;
                        } else {
                            return false;
                        }
                    }
                });

                this.scroll(current);
            };

            var carousel = this.carousel();

            if (carousel.rtl && !carousel.vertical) {
                var right = !carousel.circular ? jCarousel.intval(carousel.list().css('right')) : 0;

                if (right > 0) {
                    carousel.scroll(0);
                } else if (right < -(this.width - carousel._clipping())) {
                    carousel.scroll(-1);
                } else {
                    scrollNearest.apply(carousel);
                }
            } else {
                var left = !carousel.circular ? jCarousel.intval(carousel.list().css(carousel.lt)) : 0;

                if (left > 0) {
                    carousel.scroll(0);
                } else if (left < -(this.width - carousel._clipping())) {
                    carousel.scroll(-1);
                } else {
                    scrollNearest.apply(carousel);
                }
            }

            return this;
        },
        _move: function(e) {
            if (!this.started) {
                return this;
            }

            this.moved = true;

            var carousel = this.carousel();

            var distance = carousel.vertical ?
                               this.startY - jCarousel.intval(typeof e.pageY !== 'undefined' ? e.pageY : e.originalEvent.pageY) :
                               this.startX - jCarousel.intval(typeof e.pageX !== 'undefined' ? e.pageX : e.originalEvent.pageX);

            carousel.list()
                .stop(true, false)
                .css(carousel.lt, Math.ceil(this.startPos - distance) + 'px');

            return this;
        }
    };
});
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2009 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2010 by Kris Maglione <maglione.k at Gmail>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
"use strict";

/** @scope modules */

/**
 * @instance browser
 */
const Browser = Module("browser", {
}, {
    incrementURL: function (count) {
        let matches = buffer.URL.match(/(.*?)(\d+)(\D*)$/);
        dactyl.assert(matches);

        let [, pre, number, post] = matches;
        let newNumber = parseInt(number, 10) + count;
        let newNumberStr = String(newNumber > 0 ? newNumber : 0);
        if (number.match(/^0/)) { // add 0009<C-a> should become 0010
            while (newNumberStr.length < number.length)
                newNumberStr = "0" + newNumberStr;
        }

        dactyl.open(pre + newNumberStr + post);
    }
}, {
    options: function () {
        options.add(["encoding", "enc"],
            "Sets the current buffer's character encoding",
            "string", "UTF-8",
            {
                scope: Option.SCOPE_LOCAL,
                getter: function () config.browser.docShell.QueryInterface(Ci.nsIDocCharset).charset,
                setter: function (val) {
                    if (options["encoding"] == val)
                        return val;

                    // Stolen from browser.jar/content/browser/browser.js, more or less.
                    try {
                        config.browser.docShell.QueryInterface(Ci.nsIDocCharset).charset = val;
                        PlacesUtils.history.setCharsetForURI(getWebNavigation().currentURI, val);
                        getWebNavigation().reload(Ci.nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
                    }
                    catch (e) { dactyl.reportError(e); }
                    return null;
                },
                completer: function (context) completion.charset(context)
            });
    },

    mappings: function () {
        mappings.add([modes.NORMAL],
            ["y"], "Yank current location to the clipboard",
            function () { dactyl.clipboardWrite(buffer.URL, true); });

        // opening websites
        mappings.add([modes.NORMAL],
            ["o"], "Open one or more URLs",
            function () { commandline.open(":", "open ", modes.EX); });

        mappings.add([modes.NORMAL], ["O"],
            "Open one or more URLs, based on current location",
            function () { commandline.open(":", "open " + buffer.URL, modes.EX); });

        mappings.add([modes.NORMAL], ["t"],
            "Open one or more URLs in a new tab",
            function () { commandline.open(":", "tabopen ", modes.EX); });

        mappings.add([modes.NORMAL], ["T"],
            "Open one or more URLs in a new tab, based on current location",
            function () { commandline.open(":", "tabopen " + buffer.URL, modes.EX); });

        mappings.add([modes.NORMAL], ["w"],
            "Open one or more URLs in a new window",
            function () { commandline.open(":", "winopen ", modes.EX); });

        mappings.add([modes.NORMAL], ["W"],
            "Open one or more URLs in a new window, based on current location",
            function () { commandline.open(":", "winopen " + buffer.URL, modes.EX); });

        mappings.add([modes.NORMAL],
            ["<C-a>"], "Increment last number in URL",
            function (count) { Browser.incrementURL(Math.max(count, 1)); },
            { count: true });

        mappings.add([modes.NORMAL],
            ["<C-x>"], "Decrement last number in URL",
            function (count) { Browser.incrementURL(-Math.max(count, 1)); },
            { count: true });

        mappings.add([modes.NORMAL], ["~"],
            "Open home directory",
            function () { dactyl.open("~"); });

        mappings.add([modes.NORMAL], ["gh"],
            "Open homepage",
            function () { BrowserHome(); });

        mappings.add([modes.NORMAL], ["gH"],
            "Open homepage in a new tab",
            function () {
                let homepages = gHomeButton.getHomePage();
                dactyl.open(homepages, { from: "homepage", where: dactyl.NEW_TAB });
            });

        mappings.add([modes.NORMAL], ["gu"],
            "Go to parent directory",
            function (count) {
                function isDirectory(url) {
                    if (/^file:\/|^\//.test(url)) {
                        let file = io.File(url);
                        return file.exists() && file.isDirectory();
                    }
                    else {
                        // for all other locations just check if the URL ends with /
                        return /\/$/.test(url);
                    }
                }

                count = Math.max(count, 1);

                let url = buffer.URL;
                for (let i = 0; i < count; i++) {
                    if (isDirectory(url))
                        url = url.replace(/^(.*?:)(.*?)([^\/]+\/*)$/, "$1$2/");
                    else
                        url = url.replace(/^(.*?:)(.*?)(\/+[^\/]+)$/, "$1$2/");
                }
                url = url.replace(/^(.*:\/+.*?)\/+$/, "$1/"); // get rid of more than 1 / at the end

                if (url == buffer.URL)
                    dactyl.beep();
                else
                    dactyl.open(url);
            },
            { count: true });

        mappings.add([modes.NORMAL], ["gU"],
            "Go to the root of the website",
            function () {
                let uri = window.content.document.location;
                dactyl.assert(!/(about|mailto):/.test(uri.protocol)); // exclude these special protocols for now
                dactyl.open(uri.protocol + "//" + (uri.host || "") + "/");
            });

        mappings.add([modes.NORMAL], ["<C-l>"],
            "Redraw the screen",
            function () { commands.get("redraw").action(); });
    },

    commands: function () {
        commands.add(["downl[oads]", "dl"],
            "Show progress of current downloads",
            function () {
                dactyl.open("chrome://mozapps/content/downloads/downloads.xul",
                    { from: "downloads"});
            },
            { argCount: "0" });

        commands.add(["o[pen]"],
            "Open one or more URLs in the current tab",
            function (args) {
                if (args[0])
                    dactyl.open(args[0]);
                else
                    dactyl.open("about:blank");
            }, {
                completer: function (context) completion.url(context),
                domains: function (args) array.compact(dactyl.parseURLs(args[0] || "").map(
                    function (url) util.getHost(url))),
                literal: 0,
                privateData: true
            });

        commands.add(["redr[aw]"],
            "Redraw the screen",
            function () {
                window.QueryInterface(Ci.nsIInterfaceRequestor)
                      .getInterface(Ci.nsIDOMWindowUtils).redraw();
                statusline.updateUrl();
                commandline.clear();
            },
            { argCount: "0" });
    }
});

// vim: set fdm=marker sw=4 ts=4 et:
<commit_msg>Refactor the gu mapping action.<commit_after>// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2009 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2010 by Kris Maglione <maglione.k at Gmail>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
"use strict";

/** @scope modules */

/**
 * @instance browser
 */
const Browser = Module("browser", {
}, {
    incrementURL: function (count) {
        let matches = buffer.URL.match(/(.*?)(\d+)(\D*)$/);
        dactyl.assert(matches);

        let [, pre, number, post] = matches;
        let newNumber = parseInt(number, 10) + count;
        let newNumberStr = String(newNumber > 0 ? newNumber : 0);
        if (number.match(/^0/)) { // add 0009<C-a> should become 0010
            while (newNumberStr.length < number.length)
                newNumberStr = "0" + newNumberStr;
        }

        dactyl.open(pre + newNumberStr + post);
    }
}, {
    options: function () {
        options.add(["encoding", "enc"],
            "Sets the current buffer's character encoding",
            "string", "UTF-8",
            {
                scope: Option.SCOPE_LOCAL,
                getter: function () config.browser.docShell.QueryInterface(Ci.nsIDocCharset).charset,
                setter: function (val) {
                    if (options["encoding"] == val)
                        return val;

                    // Stolen from browser.jar/content/browser/browser.js, more or less.
                    try {
                        config.browser.docShell.QueryInterface(Ci.nsIDocCharset).charset = val;
                        PlacesUtils.history.setCharsetForURI(getWebNavigation().currentURI, val);
                        getWebNavigation().reload(Ci.nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
                    }
                    catch (e) { dactyl.reportError(e); }
                    return null;
                },
                completer: function (context) completion.charset(context)
            });
    },

    mappings: function () {
        mappings.add([modes.NORMAL],
            ["y"], "Yank current location to the clipboard",
            function () { dactyl.clipboardWrite(buffer.URL, true); });

        // opening websites
        mappings.add([modes.NORMAL],
            ["o"], "Open one or more URLs",
            function () { commandline.open(":", "open ", modes.EX); });

        mappings.add([modes.NORMAL], ["O"],
            "Open one or more URLs, based on current location",
            function () { commandline.open(":", "open " + buffer.URL, modes.EX); });

        mappings.add([modes.NORMAL], ["t"],
            "Open one or more URLs in a new tab",
            function () { commandline.open(":", "tabopen ", modes.EX); });

        mappings.add([modes.NORMAL], ["T"],
            "Open one or more URLs in a new tab, based on current location",
            function () { commandline.open(":", "tabopen " + buffer.URL, modes.EX); });

        mappings.add([modes.NORMAL], ["w"],
            "Open one or more URLs in a new window",
            function () { commandline.open(":", "winopen ", modes.EX); });

        mappings.add([modes.NORMAL], ["W"],
            "Open one or more URLs in a new window, based on current location",
            function () { commandline.open(":", "winopen " + buffer.URL, modes.EX); });

        mappings.add([modes.NORMAL],
            ["<C-a>"], "Increment last number in URL",
            function (count) { Browser.incrementURL(Math.max(count, 1)); },
            { count: true });

        mappings.add([modes.NORMAL],
            ["<C-x>"], "Decrement last number in URL",
            function (count) { Browser.incrementURL(-Math.max(count, 1)); },
            { count: true });

        mappings.add([modes.NORMAL], ["~"],
            "Open home directory",
            function () { dactyl.open("~"); });

        mappings.add([modes.NORMAL], ["gh"],
            "Open homepage",
            function () { BrowserHome(); });

        mappings.add([modes.NORMAL], ["gH"],
            "Open homepage in a new tab",
            function () {
                let homepages = gHomeButton.getHomePage();
                dactyl.open(homepages, { from: "homepage", where: dactyl.NEW_TAB });
            });

        mappings.add([modes.NORMAL], ["gu"],
            "Go to parent directory",
            function (count) {
                count = Math.max(count, 1);
                let url = util.newURI(buffer.URL);
                let path = url.path;

                while (count-- && path != "/")
                    path = path.replace(/[^\/]+\/?$/, "")

                let newUrl = url.prePath + path

                if (newUrl != buffer.URL)
                    dactyl.open(newUrl);
                else
                    dactyl.beep();
            },
            { count: true });

        mappings.add([modes.NORMAL], ["gU"],
            "Go to the root of the website",
            function () {
                let uri = window.content.document.location;
                dactyl.assert(!/(about|mailto):/.test(uri.protocol)); // exclude these special protocols for now
                dactyl.open(uri.protocol + "//" + (uri.host || "") + "/");
            });

        mappings.add([modes.NORMAL], ["<C-l>"],
            "Redraw the screen",
            function () { commands.get("redraw").action(); });
    },

    commands: function () {
        commands.add(["downl[oads]", "dl"],
            "Show progress of current downloads",
            function () {
                dactyl.open("chrome://mozapps/content/downloads/downloads.xul",
                    { from: "downloads"});
            },
            { argCount: "0" });

        commands.add(["o[pen]"],
            "Open one or more URLs in the current tab",
            function (args) {
                if (args[0])
                    dactyl.open(args[0]);
                else
                    dactyl.open("about:blank");
            }, {
                completer: function (context) completion.url(context),
                domains: function (args) array.compact(dactyl.parseURLs(args[0] || "").map(
                    function (url) util.getHost(url))),
                literal: 0,
                privateData: true
            });

        commands.add(["redr[aw]"],
            "Redraw the screen",
            function () {
                window.QueryInterface(Ci.nsIInterfaceRequestor)
                      .getInterface(Ci.nsIDOMWindowUtils).redraw();
                statusline.updateUrl();
                commandline.clear();
            },
            { argCount: "0" });
    }
});

// vim: set fdm=marker sw=4 ts=4 et:
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'TableCellRefinement',
  refines: 'foam.core.Property',
  properties: [
    {
      name: 'tableCellView',
      value: function(obj) {
        return obj[this.name];
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2',
  name: 'TableBody',
  extends: 'foam.u2.Element',

  requires: [
    'foam.u2.TableCellRefinement'
  ],

  properties: [
    [ 'nodeName', 'tbody' ],
    [ 'properties_' ]
  ],

  methods: [
    function addObj(obj) {
      var e = this.start('tr')
      for ( var j = 0 ; j < this.properties_.length ; j++ ) {
        var prop = this.properties_[j];
        e = e.start('td').add(prop.tableCellView(obj, e)).end();
      }
      e.end();
    }
  ]
});

foam.CLASS({
  package: 'foam.u2',
  name: 'TableBodySink',
  implements: ['foam.dao.Sink'],
  requires: [
    'foam.u2.TableBody'
  ],
  properties: [
    'properties_',
    {
      name: 'body',
      factory: function() { return this.TableBody.create({ properties_: this.properties_ }); }
    }
  ],
  methods: [
    function put(obj) {
      this.body.addObj(obj);
    }
  ]
});

foam.CLASS({
  package: 'foam.u2',
  name: 'TableView',
  extends: 'foam.u2.Element',

  properties: [
    {
      class: 'Class2',
      name: 'of',
      expression: function(data) {
        return data.of;
      }
    },
    [ 'nodeName', 'table' ],
    {
      name: 'properties_',
      expression: function(properties, of) {
        var cls = this.of$cls;
        return properties.map(function(p) { return cls.getAxiomByName(p); });
      }
    },
    {
      name: 'properties',
      expression: function(of) {
        if ( ! this.of$cls ) return undefined;

        var tableProperties = this.of$cls.getAxiomByName('tableProperties');

        if ( tableProperties ) return tableProperties.properties;

        return this.of$cls.getAxiomsByClass(foam.core.Property)
            .filter(function(p) { return ! p.hidden; })
            .map(foam.core.Property.NAME.f)
      }
    },
    {
      name: 'data',
      postSet: function(old, nu) {
        old && old.on.unsub(this.onDAOUpdate);
        nu && nu.on.sub(this.onDAOUpdate);
        this.onDAOUpdate();
      }
    },
    {
      name: 'header',
      expression: function(properties_) {
        var E = this.E('thead');
        var e = E;

        if ( ! properties_ ) {
          return e.add("'of' or 'properties' is required for table view configuration.");
        }

        e = e.start('tr');
        for ( var i = 0 ; i < properties_.length ; i++ ) {
          e = e.start('td').add(properties_[i].label).end();
        }
        e = e.end();

        return E;
      }
    },
    {
      name: 'body',
      factory: function() { return this.E('tbody'); }
    }
  ],

  methods: [
    function initE() {
      this.onDAOUpdate();
      return this.add(this.header$, this.body$);
    }
  ],

  listeners: [
    {
      name: 'onDAOUpdate',
      isFramed: true,
      code: function() {
        this.data.select(foam.u2.TableBodySink.create({ properties_: this.properties_ }, this)).then(
          function(a) { this.body = a.body; }.bind(this));
      }
    }
  ]
});
<commit_msg>TableView: Click to sort columns<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'TableCellRefinement',
  refines: 'foam.core.Property',
  properties: [
    {
      name: 'tableCellView',
      value: function(obj) {
        return obj[this.name];
      }
    }
  ]
});

foam.CLASS({
  package: 'foam.u2',
  name: 'TableBody',
  extends: 'foam.u2.Element',

  requires: [
    'foam.u2.TableCellRefinement'
  ],

  properties: [
    [ 'nodeName', 'tbody' ],
    [ 'properties_' ]
  ],

  methods: [
    function addObj(obj) {
      var e = this.start('tr')
      for ( var j = 0 ; j < this.properties_.length ; j++ ) {
        var prop = this.properties_[j];
        e = e.start('td').add(prop.tableCellView(obj, e)).end();
      }
      e.end();
    }
  ]
});

foam.CLASS({
  package: 'foam.u2',
  name: 'TableBodySink',
  implements: ['foam.dao.Sink'],
  requires: [
    'foam.u2.TableBody'
  ],
  properties: [
    'properties_',
    {
      name: 'body',
      factory: function() { return this.TableBody.create({ properties_: this.properties_ }); }
    }
  ],
  methods: [
    function put(obj) {
      this.body.addObj(obj);
    }
  ]
});

foam.CLASS({
  package: 'foam.u2',
  name: 'TableView',
  extends: 'foam.u2.Element',

  requires: [
    'foam.mlang.order.Desc',
    'foam.u2.Entity'
  ],

  properties: [
    {
      class: 'Class2',
      name: 'of',
      expression: function(data) {
        return data.of;
      }
    },
    [ 'nodeName', 'table' ],
    {
      name: 'properties_',
      expression: function(properties, of) {
        var cls = this.of$cls;
        return properties.map(function(p) { return cls.getAxiomByName(p); });
      }
    },
    {
      name: 'properties',
      expression: function(of) {
        if ( ! this.of$cls ) return undefined;

        var tableProperties = this.of$cls.getAxiomByName('tableProperties');

        if ( tableProperties ) return tableProperties.properties;

        return this.of$cls.getAxiomsByClass(foam.core.Property)
            .filter(function(p) { return ! p.hidden; })
            .map(foam.core.Property.NAME.f)
      }
    },
    {
      name: 'data',
      postSet: function(old, nu) {
        old && old.on.unsub(this.onDAOUpdate);
        nu && nu.on.sub(this.onDAOUpdate);
        this.onDAOUpdate();
      }
    },
    {
      name: 'header',
      expression: function(properties_) {
        var E = this.E('thead');
        var e = E;

        if ( ! properties_ ) {
          return e.add("'of' or 'properties' is required for table view configuration.");
        }

        e = e.start('tr');
        for ( var i = 0 ; i < properties_.length ; i++ ) {
          var sorting$ = this.sortOrder$.map(function(prop, order) {
            if ( ! order ) return '';
            var desc = this.Desc.isInstance(order);
            var baseOrder = desc ? order.arg1 : order;
            if ( prop.name === baseOrder.name ) {
              return desc ? this.Entity.create({ name: 'darr' }) :
                  this.Entity.create({ name: 'uarr' });
            }
            return '';
          }.bind(this, properties_[i]));

          e = e.start('td')
              .enableCls(this.myCls('sorting'), sorting$)
              .start('span')
                  .cssClass(this.myCls('sort-direction'))
                  .add(sorting$)
              .end()
              .add(properties_[i].label)
              .on('click', this.sortBy.bind(this, properties_[i]))
              .end();
        }
        e = e.end();

        return E;
      }
    },
    {
      name: 'body',
      factory: function() { return this.E('tbody'); }
    },
    {
      name: 'sortOrder'
    }
  ],

  methods: [
    function initE() {
      this.onDAOUpdate();
      return this.add(this.header$, this.body$);
    },
    function sortBy(prop) {
      // Two cases: same as the current prop, or different.
      var sortName = this.sortOrder ?
          (this.Desc.isInstance(this.sortOrder) ? this.sortOrder.arg1.name :
              this.sortOrder.name) :
          '';
      if ( sortName === prop.name ) {
        // Invert the previous order.
        this.sortOrder = this.Desc.isInstance(this.sortOrder) ?
            prop : this.Desc.create({ arg1: prop });
      } else {
        // Set it to the new column.
        this.sortOrder = prop;
      }
      this.onDAOUpdate();
    }
  ],

  listeners: [
    {
      name: 'onDAOUpdate',
      isFramed: true,
      code: function() {
        var dao = this.data;
        if ( this.sortOrder ) {
          dao = dao.orderBy(this.sortOrder);
        }
        dao.select(foam.u2.TableBodySink.create({
          properties_: this.properties_
        }, this)).then(function(a) {
          this.body = a.body;
        }.bind(this));
      }
    }
  ],

  axioms: [
    foam.u2.CSS.create({
      code: function CSS() {/*
        ^sorting {
          font-weight: bold;
        }

        ^sort-direction {
          display: none;
          margin-right: 8px;
        }
        ^sorting ^sort-direction {
          display: initial;
        }
      */}
    })
  ]
});
<|endoftext|>