<commit_before>export default class FormHandler {
  constructor() {
    this.rangeAttach = $('.carousel__fieldset--range');
    this.amountsAttach = $('.carousel__fieldset--amount');
    this.carouselOuter = $('#carousel-outer');
    this.carouselInner = $('#carousel-inner');
    this.carouselSlides = $('.carousel-slide');
    this.prevButton = $('#prev');
    this.nextButton = $('#prev');
    this.submitButton = $('#submit');

    this.currFrequencyIndex = 1;
    this.currRangeIndex = 1;
    this.transformValue = 0;
    this.currSlide = 0;
    this.numSlides = this.carouselSlides.length;

    this.frequencyToRanges = [
      [1, 2, 3, 4],
      [5, 6, 7, 8],
      [9, 10, 11, 12]
    ];

    this.rangesToAmounts = [
      [13, 14, 15, 16],
      [17, 18, 19, 20],
      [21, 22, 23, 24]
    ];
  }

  // is existing range/frequency
  // takes which and returns a boolean

  // set new frequency range
  // takes which, value and then sets the value

  // get attr
  // takes element, attr name
  // returns attr value

  // get frequencyToRange value
  // takes index and returns array of values

  // get rangeToAmounts value
  // takes index and returns array of values

  // build range markup
  // takes array of values, returns markup

  // build amounts markup
  // takes array of values, returns markup

  // append to DOM
  // takes markup, attacher, returns nothing

  // insertAfter
  // takes markup, attacher, returns nothing

  // get outer container width
  // returns width of outer container

  // get width of outer container
  // takes nothing, returns width

  // set width of inner container
  // takes nothing, returns nothing
  // sets width of inner container to num slides * outer container width

  // add remove selected
  // takes nothing
  // if has selected class, return false
  // otherwise set selected, unselect others

  // isLastSlide
  // returns boolean

  // isFirstSlide
  // returns boolean

  // moveCarousel
  // takes forward or back
  // calls get width of outer container
  // transforms carousel by that amount

  // disablePrevNext
  // takes forward or back
  // disables button if meets condition

  // show submit button

  // *bind events
  // frequency click event
  // get index attribute
  // check if is existing range/frequency
  // if not, get frequencyToRange value
  // call set new range or frequency
  // call build range markup
  // append to DOM
  // range click event
  // get index attribute
  // check if existing
  // if not, get rangeToAmounts value
  // call build amounts markup
  // insertAfter
  // radio click event
  // call add remove selected
  // prev click event
  // check if is first slide
  // if not, decrement slideIndex
  // call disable with back
  // call move carousel w/ back
  // next click event
  // check if is last slide
  // if not, increment slideIndex
  // call disable with next
  // call move carousel w/ forward
  // if is last slide, show submit button

  // *inititialize carousel
  // get width of outer container
  // set width of inner container
}
<commit_msg>add carousel initialization logic<commit_after>export default class FormHandler {
  constructor(opts) {
    this.rangeAttach = opts.rangeAttach;
    this.amountsAttach = opts.amountsAttach;
    this.outerContainer = opts.outerContainer;
    this.innerContainer = opts.innerContainer;
    this.carouselSlides = opts.carouselSlides;
    this.prevButton = opts.prevButton;
    this.nextButton = opts.nextButton;
    this.submitButton = opts.submitButton;
    this.currFrequencyIndex = opts.startFrequencyIndex;
    this.currRangeIndex = opts.startRangeIndex;
    this.currSlide = opts.startSlide;
    this.numSlides = this.carouselSlides.length;
    this.frequencyToRanges = opts.frequencyToRanges;
    this.rangesToAmounts = opts.rangesToAmounts;
  }

  // returns integer of current carousel transform value
  getTransformValue() {
    return this.getOuterContainerWidth() * this.currSlide;
  }

  // returns integer width of outer container
  getOuterContainerWidth() {
    return this.outerContainer.width();
  }

  // sets width of inner container as
  // number of slides * width of outer container
  setInnerContainerWidth() {
    const innerContainerWidth = this.numSlides * this.getOuterContainerWidth();
    this.innerContainer.css('width', `${innerContainerWidth}px`);
  }

  // returns integer width of inner container
  getInnerContainerWidth() {
    return this.innerContainer.width();
  }

  // sets each slide to width of the outer container
  setSlideWidth() {
    const slideWidth = this.getOuterContainerWidth();

    this.carouselSlides.each(function(){
      $(this).css('width', `${slideWidth}px`);
    });
  }

  // shifts carousel forward or backward
  setTransform() {
    this.innerContainer.css('transform', `translateX(-${this.getTransformValue()}px)`);
  }

  // initialize carousel
  initCarousel() {
    this.setInnerContainerWidth();
    this.setSlideWidth();
    this.setTransform();
  }

  bindEvents() {

  }

  // is existing range/frequency
  // takes which and returns a boolean

  // set new frequency range
  // takes which, value and then sets the value

  // get attr
  // takes element, attr name
  // returns attr value

  // get frequencyToRange value
  // takes index and returns array of values

  // get rangeToAmounts value
  // takes index and returns array of values

  // build range markup
  // takes array of values, returns markup

  // build amounts markup
  // takes array of values, returns markup

  // append to DOM
  // takes markup, attacher, returns nothing

  // insertAfter
  // takes markup, attacher, returns nothing

  // get outer container width
  // returns width of outer container

  // get width of outer container
  // takes nothing, returns width

  // set width of inner container
  // takes nothing, returns nothing
  // sets width of inner container to num slides * outer container width

  // add remove selected
  // takes nothing
  // if has selected class, return false
  // otherwise set selected, unselect others

  // isLastSlide
  // returns boolean

  // isFirstSlide
  // returns boolean

  // moveCarousel
  // takes forward or back
  // calls get width of outer container
  // transforms carousel by that amount
  // after interval, removes ARIA live

  // disablePrevNext
  // takes forward or back
  // disables button if meets condition

  // accessible hide
  // add ARIA hidden attribute

  // show submit button

  // add/remove ARIA live

  // manual input is selected

  // validate manual input
  // ARIA invalid attribute should be set

  // create string and redirect

  // *bind events
  // FREQUENCY CLICK EVENT
  // get index attribute
  // check if is existing range/frequency
  // if not, get frequencyToRange value
  // call set new range or frequency
  // call build range markup
  // append to DOM
  // RANGE CLICK EVENT
  // get index attribute
  // check if existing
  // if not, get rangeToAmounts value
  // call build amounts markup
  // insertAfter
  // radio click event
  // call add remove selected
  // PREV CLICK EVENT
  // check if is first slide
  // if so, return false
  // if not call accessible hide on current
  // decrement slideIndex
  // call aria live on new current
  // call disable with back
  // call move carousel w/ back
  // NEXT CLICK EVENT
  // check if is last slide
  // if so, return false
  // if not, increment slideIndex
  // call disable with next
  // call move carousel w/ forward
  // if is last slide, show submit button
  // SUBMIT EVENT
  // check if manual input is selected
  // if so, check if input is numeric
  // if so, create string and redirect
}
<|endoftext|>


<commit_before>const { assign, omit } = require("lodash");
const Promise = require("bluebird");

const { EXHAUSTED } = require("./common");
const { getFrameCache } = require("./cache");

class Sequence {
  constructor () {
    this.stack = [];

    this.next = this.next.bind(this);

    // Frame-specific state:
    this.eventGenQueue = [];
    this.delegates = Object.create(null);
    this.cursor = 0;
  }

  pushFrame (delegate) {
    // Save state attached to parent frame.
    this.stack.push({
      eventGenQueue: this.eventGenQueue,
      delegates: this.delegates,
      cursor: this.cursor
    });

    // Initialize the new frame.
    this.eventGenQueue = [];
    this.delegates = Object.create(null);
    this.cursor = 0;

    // Let the delegate do its thing...
    delegate();
  }

  popFrame () {
    const parentFrame = this.stack.pop();
    if (parentFrame) {
      const { eventGenQueue, delegates, cursor } = parentFrame;
      this.eventGenQueue = eventGenQueue;
      this.delegates = delegates;
      this.cursor = cursor;

      return this.next();
    }
    return null;
  }

  emit (fn) {
    this.eventGenQueue.push(fn);
  }

  delegate (delegateFn) {
    this.delegates[this.eventGenQueue.length] = true;
    this.eventGenQueue.push(delegateFn);
  }

  delegateCached (node, delegateFn) {
    const cacheKey =
      node.props && node.props.cacheKey ||
      node.attrObj && node.attrObj.cacheKey;

    if (!cacheKey) {
      this.delegate(() => delegateFn(this, node));
      return;
    }

    this.delegates[this.eventGenQueue.length] = true;

    const _node = assign({}, node, {
      props: omit(node.props, ["cacheKey"])
    });

    const frameIterator = getFrameCache(_node, cacheKey, delegateFn, Sequence);

    // The callback will be invoked by `pushFrame`, followed by a call to `next`..
    this.eventGenQueue.push(() => {
      return frameIterator instanceof Promise ?
        frameIterator.then(_frameIterator => _frameIterator.patch(this)) :
        frameIterator.patch(this);
    });
  }

  /**
   * Return a value from this instance's event queue.  If the instance
   * is currently delegating its event generation, return the next
   * value from the delegate.  If the event-generator returns a new
   * Sequence, delegate event-generation to that sequence until it has
   * been exhausted.
   *
   * @return     {Any|EXHAUSTED}  Any value, or the EXHAUSTED symbol.
   */
  next () {
    const nextIsDelegate = this.delegates[this.cursor];
    const nextFn = this.eventGenQueue[this.cursor++];
    if (!nextFn) { return this.popFrame() || EXHAUSTED; }

    if (nextIsDelegate) {
      this.pushFrame(nextFn);
      return this.next();
    }

    return nextFn();
  }
}

module.exports = {
  Sequence,
  sequence: () => new Sequence()
};
<commit_msg>Check if cache returns thenable rather than bluebird promise<commit_after>const { assign, omit } = require("lodash");

const { EXHAUSTED } = require("./common");
const { getFrameCache } = require("./cache");

class Sequence {
  constructor () {
    this.stack = [];

    this.next = this.next.bind(this);

    // Frame-specific state:
    this.eventGenQueue = [];
    this.delegates = Object.create(null);
    this.cursor = 0;
  }

  pushFrame (delegate) {
    // Save state attached to parent frame.
    this.stack.push({
      eventGenQueue: this.eventGenQueue,
      delegates: this.delegates,
      cursor: this.cursor
    });

    // Initialize the new frame.
    this.eventGenQueue = [];
    this.delegates = Object.create(null);
    this.cursor = 0;

    // Let the delegate do its thing...
    delegate();
  }

  popFrame () {
    const parentFrame = this.stack.pop();
    if (parentFrame) {
      const { eventGenQueue, delegates, cursor } = parentFrame;
      this.eventGenQueue = eventGenQueue;
      this.delegates = delegates;
      this.cursor = cursor;

      return this.next();
    }
    return null;
  }

  emit (fn) {
    this.eventGenQueue.push(fn);
  }

  delegate (delegateFn) {
    this.delegates[this.eventGenQueue.length] = true;
    this.eventGenQueue.push(delegateFn);
  }

  delegateCached (node, delegateFn) {
    const cacheKey =
      node.props && node.props.cacheKey ||
      node.attrObj && node.attrObj.cacheKey;

    if (!cacheKey) {
      this.delegate(() => delegateFn(this, node));
      return;
    }

    this.delegates[this.eventGenQueue.length] = true;

    const _node = assign({}, node, {
      props: omit(node.props, ["cacheKey"])
    });

    const frameIterator = getFrameCache(_node, cacheKey, delegateFn, Sequence);

    // The callback will be invoked by `pushFrame`, followed by a call to `next`..
    this.eventGenQueue.push(() => {
      return typeof frameIterator.then === "function" ?
        frameIterator.then(_frameIterator => _frameIterator.patch(this)) :
        frameIterator.patch(this);
    });
  }

  /**
   * Return a value from this instance's event queue.  If the instance
   * is currently delegating its event generation, return the next
   * value from the delegate.  If the event-generator returns a new
   * Sequence, delegate event-generation to that sequence until it has
   * been exhausted.
   *
   * @return     {Any|EXHAUSTED}  Any value, or the EXHAUSTED symbol.
   */
  next () {
    const nextIsDelegate = this.delegates[this.cursor];
    const nextFn = this.eventGenQueue[this.cursor++];
    if (!nextFn) { return this.popFrame() || EXHAUSTED; }

    if (nextIsDelegate) {
      this.pushFrame(nextFn);
      return this.next();
    }

    return nextFn();
  }
}

module.exports = {
  Sequence,
  sequence: () => new Sequence()
};
<|endoftext|>


<commit_before>var xRegExp = require('xregexp').XRegExp;

var removeFormat = function(title) {
	if (!title) return '';
	title = title.replace(/(\*\*?)(.*?)\1/g, '$2');
	title = title.replace(/(__?)(.*?)\1/g, '$2');
	title = title.replace(/`(.*?)`/g, '$1');
	title = title.replace(/\s*\{[^\}]*\}$/g, '');
	title = title.replace(/\[([^\]]*)\]\[[^\]]*\]/g, '$1');
	title = title.replace(/\[([^\]]*)\]\([^\)]*\)/g, '$1');
	title = title.replace(/\[([^\]]+)\]/g, '$1');
	title = title.replace(/<([^\s>]+)>/g, '$1');
	return title;
};
module.exports.removeFormat = removeFormat;

var getAttributes = function(title) {
	var attribPattern = /\s\{((?:[^\}]|\"[^\"]*\")*)\}\s*$/;
	var idPattern = /(?:^|\s)#(\w+)/;
	var classPattern = /(?:^|\s)\.(\w+)/g;
	var keyValPattern = /(?:^|\s)(\w+)=(?:\"([^\"]*)\"|(\w+))/g;
	var attribMatch = attribPattern.exec(title);
	var attribString, idMatch, classMatch, keyValMatch;
	var result = {};
	if (attribMatch) {
		attribString = attribMatch[1];
		idMatch = idPattern.exec(attribString);
		if (idMatch) {
			result.id = idMatch[1];
		}
		classMatch = classPattern.exec(attribString);
		while(classMatch) {
			if (!result.classes) { result.classes = []; }
			result.classes.push(classMatch[1]);
			classMatch = classPattern.exec(attribString);
		}
		keyValMatch = keyValPattern.exec(attribString);
		while(keyValMatch) {
			result[keyValMatch[1]] = keyValMatch[2] || keyValMatch[3];
			keyValMatch = keyValPattern.exec(attribString);
		}
	}
	return result;
};
module.exports.getAttributes = getAttributes;

/*
Remove all formatting, links, etc.
Remove all footnotes.
Remove all punctuation, except underscores, hyphens, and periods.
Replace all spaces and newlines with hyphens.
Convert all alphabetic characters to lowercase.
Remove everything up to the first letter (identifiers may not begin with a number or punctuation mark).
If nothing is left after this, use the identifier 'section'.
*/

var anchor = function(title, cache) {
	var id = getAttributes(title).id;
	if (id) return id;
	title = removeFormat(title);
	title = title.replace(xRegExp('^[^\\p{L}]+', 'g'), '');
	title = title.trim();
	title = title.replace(/\s/g, '-');
	title = title.replace(xRegExp('[^\\p{L}\\d_\\-\\.]', 'g'), '');
	title = title.toLowerCase();
	if (title === '') {	title = 'section'; }
	return title;
};
module.exports.anchor = anchor;
<commit_msg>extendes character set for valid anchor ids<commit_after>var xRegExp = require('xregexp').XRegExp;

var removeFormat = function(title) {
	if (!title) return '';
	title = title.replace(/(\*\*?)(.*?)\1/g, '$2');
	title = title.replace(/(__?)(.*?)\1/g, '$2');
	title = title.replace(/`(.*?)`/g, '$1');
	title = title.replace(/\s*\{[^\}]*\}$/g, '');
	title = title.replace(/\[([^\]]*)\]\[[^\]]*\]/g, '$1');
	title = title.replace(/\[([^\]]*)\]\([^\)]*\)/g, '$1');
	title = title.replace(/\[([^\]]+)\]/g, '$1');
	title = title.replace(/<([^\s>]+)>/g, '$1');
	return title;
};
module.exports.removeFormat = removeFormat;

var getAttributes = function(title) {
	var attribPattern = /\s\{((?:[^\}]|\"[^\"]*\")*)\}\s*$/;
	var idPattern = /(?:^|\s)#([\w-\:\.]+)/;
	var classPattern = /(?:^|\s)\.(\w+)/g;
	var keyValPattern = /(?:^|\s)(\w+)=(?:\"([^\"]*)\"|(\w+))/g;
	var attribMatch = attribPattern.exec(title);
	var attribString, idMatch, classMatch, keyValMatch;
	var result = {};
	if (attribMatch) {
		attribString = attribMatch[1];
		idMatch = idPattern.exec(attribString);
		if (idMatch) {
			result.id = idMatch[1];
		}
		classMatch = classPattern.exec(attribString);
		while(classMatch) {
			if (!result.classes) { result.classes = []; }
			result.classes.push(classMatch[1]);
			classMatch = classPattern.exec(attribString);
		}
		keyValMatch = keyValPattern.exec(attribString);
		while(keyValMatch) {
			result[keyValMatch[1]] = keyValMatch[2] || keyValMatch[3];
			keyValMatch = keyValPattern.exec(attribString);
		}
	}
	return result;
};
module.exports.getAttributes = getAttributes;

/*
Remove all formatting, links, etc.
Remove all footnotes.
Remove all punctuation, except underscores, hyphens, and periods.
Replace all spaces and newlines with hyphens.
Convert all alphabetic characters to lowercase.
Remove everything up to the first letter (identifiers may not begin with a number or punctuation mark).
If nothing is left after this, use the identifier 'section'.
*/

var anchor = function(title, cache) {
	var id = getAttributes(title).id;
	if (id) return id;
	title = removeFormat(title);
	title = title.replace(xRegExp('^[^\\p{L}]+', 'g'), '');
	title = title.trim();
	title = title.replace(/\s/g, '-');
	title = title.replace(xRegExp('[^\\p{L}\\d_\\-\\.]', 'g'), '');
	title = title.toLowerCase();
	if (title === '') {	title = 'section'; }
	return title;
};
module.exports.anchor = anchor;
<|endoftext|>


<commit_before>'use strict';

module.exports = function (users, token) {
  const currentUser = users.findClient(token);

  if (currentUser) {
    const partner = users.findClient(currentUser.partner);

    // Check if user has a partner
    if (partner) {
      // Disconnect user from partner.
      users.removePartner(currentUser.id);

      if (partner.socket.readyState == 1) {
        partner.socket.send(JSON.stringify({type: 'partner_disconnected', data: true}));
      }
    }

    // Remove disconnected user from clients list
    users.removeClient(currentUser.id);
  }

  users.decrementOnline();
}<commit_msg>Fixed issue with online count during disconnect.<commit_after>'use strict';

module.exports = function (users, token) {
  const currentUser = users.findClient(token);

  if (currentUser) {
    const partner = users.findClient(currentUser.partner);

    // Check if user has a partner
    if (partner) {
      // Disconnect user from partner.
      users.removePartner(currentUser.id);

      if (partner.socket.readyState == 1) {
        partner.socket.send(JSON.stringify({type: 'partner_disconnected', data: true}));
      }
    }

    // Remove disconnected user from clients list
    users.removeClient(currentUser.id);
    users.decrementOnline();
  }
}<|endoftext|>


<commit_before>import axios from '@/services/axios'
import authUser from '@/services/api/authUser'

let KEY, updateToken, clearToken

if (CORDOVA) {
  const { localStorage } = window

  KEY = 'token'

  clearToken = () => {
    localStorage.removeItem(KEY)
    clearHeader()
  }

  updateToken = token => {
    localStorage.setItem(KEY, token)
    setHeader(token)
  }

  const initialize = () => {
    const token = localStorage.getItem(KEY)
    if (token) setHeader(token)
  }

  const setHeader = token => {
    axios.defaults.headers.common.Authorization = `TOKEN ${token}`
  }

  const clearHeader = () => {
    delete axios.defaults.headers.common.Authorization
  }

  initialize()
}

export default {
  async login ({ email, password }) {
    if (CORDOVA) {
      const { token } = (await axios.post('/api/auth/token/', { username: email, password })).data
      updateToken(token)
      return authUser.get() // return the user info to match what the /api/auth/ endpoints returns
    }
    else {
      return (await axios.post('/api/auth/', { email, password })).data
    }
  },

  async logout () {
    if (CORDOVA) clearToken()
    return (await axios.post('/api/auth/logout/', {})).data
  },

  getToken () {
    if (CORDOVA) {
      return localStorage.getItem(KEY)
    }
  },
}
<commit_msg>Throw error if using getToken() outside cordova<commit_after>import axios from '@/services/axios'
import authUser from '@/services/api/authUser'

let KEY, updateToken, clearToken

if (CORDOVA) {
  const { localStorage } = window

  KEY = 'token'

  clearToken = () => {
    localStorage.removeItem(KEY)
    clearHeader()
  }

  updateToken = token => {
    localStorage.setItem(KEY, token)
    setHeader(token)
  }

  const initialize = () => {
    const token = localStorage.getItem(KEY)
    if (token) setHeader(token)
  }

  const setHeader = token => {
    axios.defaults.headers.common.Authorization = `TOKEN ${token}`
  }

  const clearHeader = () => {
    delete axios.defaults.headers.common.Authorization
  }

  initialize()
}

export default {
  async login ({ email, password }) {
    if (CORDOVA) {
      const { token } = (await axios.post('/api/auth/token/', { username: email, password })).data
      updateToken(token)
      return authUser.get() // return the user info to match what the /api/auth/ endpoints returns
    }
    else {
      return (await axios.post('/api/auth/', { email, password })).data
    }
  },

  async logout () {
    if (CORDOVA) clearToken()
    return (await axios.post('/api/auth/logout/', {})).data
  },

  getToken () {
    if (CORDOVA) {
      return localStorage.getItem(KEY)
    }
    else {
      throw new Error('getToken() is only available inside cordova environment')
    }
  },
}
<|endoftext|>


<commit_before>define( function () {

	'use strict';

	var resolveRef;

	// Resolve a full keypath from `ref` within the given `contextStack` (e.g.
	// `'bar.baz'` within the context stack `['foo']` might resolve to `'foo.bar.baz'`
	resolveRef = function ( ractive, ref, contextStack ) {

		var keypath, keys, lastKey, contextKeys, innerMostContext, postfix, parentKeypath, parentValue, wrapped, context, ancestorErrorMessage;

		ancestorErrorMessage = 'Could not resolve reference - too many "../" prefixes';

		// Implicit iterators - i.e. {{.}} - are a special case
		if ( ref === '.' ) {
			if ( !contextStack.length ) {
				return '';
			}

			keypath = contextStack[ contextStack.length - 1 ];
		}

		// If a reference begins with '.', it's either a restricted reference or
		// an ancestor reference...
		else if ( ref.charAt( 0 ) === '.' ) {

			// ...either way we need to get the innermost context
			context = contextStack[ contextStack.length - 1 ];
			contextKeys = context ? context.split( '.' ) : [];

			// ancestor references (starting "../") go up the tree
			if ( ref.substr( 0, 3 ) === '../' ) {
				while ( ref.substr( 0, 3 ) === '../' ) {
					if ( !contextKeys.length ) {
						throw new Error( ancestorErrorMessage );
					}

					contextKeys.pop();
					ref = ref.substring( 3 );
				}

				contextKeys.push( ref );
				keypath = contextKeys.join( '.' );
			}

			// not an ancestor reference - must be a restricted reference (prepended with ".")
			else if ( !context ) {
				keypath = ref.substring( 1 );
			}

			else {
				keypath = context + ref;
			}
		}

		else {
			keys = ref.split( '.' );
			lastKey = keys.pop();
			postfix = keys.length ? '.' + keys.join( '.' ) : '';

			// Clone the context stack, so we don't mutate the original
			contextStack = contextStack.concat();

			// Take each context from the stack, working backwards from the innermost context
			while ( contextStack.length ) {

				innerMostContext = contextStack.pop();
				parentKeypath = innerMostContext + postfix;

				parentValue = ractive.get( parentKeypath );

				if ( wrapped = ractive._wrapped[ parentKeypath ] ) {
					parentValue = wrapped.get();
				}

				if ( typeof parentValue === 'object' && parentValue !== null && parentValue.hasOwnProperty( lastKey ) ) {
					keypath = innerMostContext + '.' + ref;
					break;
				}
			}

			if ( !keypath && ractive.get( ref ) !== undefined ) {
				keypath = ref;
			}
		}

		return keypath ? keypath.replace( /^\./, '' ) : keypath;
	};

	return resolveRef;

});<commit_msg>improve keypath resolution algorithm, fix #403<commit_after>define( function () {

	'use strict';

	var ancestorErrorMessage = 'Could not resolve reference - too many "../" prefixes';

	// Resolve a full keypath from `ref` within the given `contextStack` (e.g.
	// `'bar.baz'` within the context stack `['foo']` might resolve to `'foo.bar.baz'`
	return function ( ractive, ref, contextStack ) {

		var keypath, keys, lastKey, contextKeys, innerMostContext, postfix, parentKeypath, parentValue, wrapped, context;

		// Implicit iterators - i.e. {{.}} - are a special case
		if ( ref === '.' ) {
			if ( !contextStack.length ) {
				return '';
			}

			keypath = contextStack[ contextStack.length - 1 ];
		}

		// If a reference begins with '.', it's either a restricted reference or
		// an ancestor reference...
		else if ( ref.charAt( 0 ) === '.' ) {

			// ...either way we need to get the innermost context
			context = contextStack[ contextStack.length - 1 ];
			contextKeys = context ? context.split( '.' ) : [];

			// ancestor references (starting "../") go up the tree
			if ( ref.substr( 0, 3 ) === '../' ) {
				while ( ref.substr( 0, 3 ) === '../' ) {
					if ( !contextKeys.length ) {
						throw new Error( ancestorErrorMessage );
					}

					contextKeys.pop();
					ref = ref.substring( 3 );
				}

				contextKeys.push( ref );
				keypath = contextKeys.join( '.' );
			}

			// not an ancestor reference - must be a restricted reference (prepended with ".")
			else if ( !context ) {
				keypath = ref.substring( 1 );
			}

			else {
				keypath = context + ref;
			}
		}

		else {
			keys = ref.split( '.' );
			lastKey = keys.pop();
			postfix = keys.length ? '.' + keys.join( '.' ) : '';

			// Clone the context stack, so we don't mutate the original
			contextStack = contextStack.concat();

			// Take each context from the stack, working backwards from the innermost context
			while ( contextStack.length ) {

				innerMostContext = contextStack.pop();
				parentKeypath = innerMostContext + postfix;

				parentValue = ractive.get( parentKeypath );

				if ( wrapped = ractive._wrapped[ parentKeypath ] ) {
					parentValue = wrapped.get();
				}

				if ( typeof parentValue === 'object' && parentValue !== null && parentValue[ lastKey ] !== undefined ) {
					keypath = innerMostContext + '.' + ref;
					break;
				}
			}

			if ( !keypath && ractive.get( ref ) !== undefined ) {
				keypath = ref;
			}
		}

		return keypath ? keypath.replace( /^\./, '' ) : keypath;
	};

});<|endoftext|>


<commit_before>/*!
The MIT License

Copyright (c) The Cytoscape Consortium

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

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

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
<commit_msg>add version to top<commit_after>/*!
Cytoscape.js {{VERSION}}

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

The MIT License

Copyright (c) The Cytoscape Consortium

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

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

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


<commit_before>$.register({
  rule: {
    host: /^sht\.io$/,
    path: /^\/\d+\/(.+)$/,
  },
  start: function (m) {
    'use strict';

    var url = atob(m.path[1]);
    url = url.match(/\{sht-io\}(.+)$/);
    $.openLink(url[1]);
  },
});

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<commit_msg>fix sht.io<commit_after>$.register({
  rule: {
    host: /^sht\.io$/,
    path: /^\/\d+\/(.+)$/,
  },
  start: function (m) {
    'use strict';

    var url = atob(m.path[1]);
    url = url.match(/\{sht-io\}(.+)\{sht-io\}.*\{sht-io\}/);
    $.openLink(url[1]);
  },
});

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<|endoftext|>


<commit_before>export default {
  name: 'RestCord (PHP)',
  language: 'php',
  generateFrom(data) {
    let embed = null;
    if (data.embed) {
      embed = JSON.stringify(data.embed, null, 4)
          .replace(/{/g, '[')
          .replace(/}/g, ']')
          .replace(/^    /gm, '        ')
          .replace(/^]/gm, '    ]');
    }

    return `<?php

$client->channel->createMessage([
    'channel.id' => $channelId,
    'content'    => "${data.content}",
    'embed'      => ${embed}
]);`;
  }
};
<commit_msg>kill eslint complaint about whitespace in regex<commit_after>export default {
  name: 'RestCord (PHP)',
  language: 'php',
  generateFrom(data) {
    let embed = null;
    if (data.embed) {
      embed = JSON.stringify(data.embed, null, 4)
          .replace(/{/g, '[')
          .replace(/}/g, ']')
          .replace(/^ {4}/gm, '        ')
          .replace(/^]/gm, '    ]');
    }

    return `<?php

$client->channel->createMessage([
    'channel.id' => $channelId,
    'content'    => "${data.content}",
    'embed'      => ${embed}
]);`;
  }
};
<|endoftext|>


<commit_before>import { css } from 'styled-components';

import { isLight, transparentize, FONT_DARK, FONT_LIGHT, TRANSITION_FAST } from 'style/theme';

const styles = theme => css`
  html:not([style-scope]):not(.style-scope) {
    --light-theme-text-color: ${theme.font_primary};
    --light-theme-secondary-color: ${theme.font_secondary};
  }

  body,
  body.material {
    background-color: ${theme.B500};
    color: ${theme.font_primary};
    transition: background ${TRANSITION_FAST};
  }

  ::-webkit-scrollbar {
    width: 11px;
    background: ${transparentize(theme.B400, 0.6)};
    transition: background ${TRANSITION_FAST};

    &:hover {
      background: ${transparentize(theme.B400, 0.7)};
    }

    &:active {
      background: ${transparentize(theme.B400, 0.65)};
    }
  }

  ::-webkit-scrollbar-track {
    background: ${transparentize(theme.B400, 0.6)};
    transition: background ${TRANSITION_FAST};

    &:hover {
      background: ${transparentize(theme.B400, 0.7)};
    }

    &:active {
      background: ${transparentize(theme.B400, 0.65)};
    }
  }

  ::-webkit-scrollbar-thumb {
    border-radius: 0;
    opacity: 0.7;

    &:hover {
      opacity: 0.8;
    }
    &:active {
      opacity: 0.75;
    }
  }

  #sliding-action-bar-container {
    background-color: ${theme.B400} !important;
    color: ${theme.font_primary} !important;

    paper-icon-button {
      color: ${theme.font_primary};

      &[disabled] {
        color: ${theme.font_primary};
        opacity: 0.4;
      }
    }
  }

  #music-content {
    color: ${theme.font_primary};
  }

  /* Links */
  .settings-footer a.footer-link,
  .music-source-empty-message,
  .nav-item-container,
  .simple-dialog a {
    color: ${theme.font_primary} !important;
  }

  a {
    color: ${theme.font_primary};
  }

  /* Top Toolbar */
  paper-header-panel#content-container {
    paper-toolbar {
      color: ${theme.font_primary};
    }

    &:not([style-scope]):not(.style-scope):not(.transparent) paper-toolbar#material-app-bar {
      border-bottom: 1px solid ${theme.B300} !important;
    }

    core-icon,
    iron-icon,
    sj-icon-button {
      color: ${theme.font_primary} !important;
    }

    sj-search-box {
      background-color: ${transparentize(theme.B600, 0.5)};
      color: ${theme.font_primary};

      &::-webkit-input-placeholder {
        color: ${theme.font_primary};
      }

      &[opened] {
        background-color: ${theme.B200};

        &::-webkit-input-placeholder {
          color: ${theme.font_secondary};
        }

        &:not([num-suggestions='0']) #input.sj-search-box {
          border-bottom-color: ${theme.B300};
        }
      }

      #input.sj-search-box {
        color: ${theme.font_primary};

        &::-webkit-input-placeholder {
          color: ${theme.font_primary};
        }
      }

      &[opened] {
        background-color: ${theme.B200};

        #input.sj-search-box::-webkit-input-placeholder {
          color: ${theme.font_secondary};
        }
      }

      core-icon,
      iron-icon,
      sj-icon-button {
        color: ${theme.font_primary} !important;
      }
    }

    sj-search-suggestion {
      &.query-selected,
      &:hover {
        background: ${theme.B25};
      }

      .sj-search-suggestion {
        color: ${theme.font_secondary} !important;
      }

      .sub-match.sj-search-suggestion {
        color: ${theme.font_primary} !important;
      }
    }
  }

  .sj-search-box sj-entity-suggestion.sj-search-box:last-of-type {
    border-bottom: 2px solid ${theme.B300} !important;
    box-shadow: 0 1px 0 0 ${transparentize(theme.B400, 0.5)} !important;
  }

  .sj-search-box[opened]:not([num-suggestions='0']) #suggestionList.sj-search-box {
    padding: 8px 0 0;
  }

  sj-entity-suggestion #title.sj-entity-suggestion {
    color: ${theme.font_primary} !important;
  }

  sj-entity-suggestion #subtitle.sj-entity-suggestion {
    color: ${theme.font_secondary} !important;
  }

  sj-entity-suggestion:hover,
  sj-entity-suggestion.query-selected {
    background-color: ${theme.B25} !important;
  }

  sj-home {
    #backgroundImageContainer.sj-home {
      height: 40vw;
      width: 80vw;
    }

    #gradient.sj-home:after {
      content: '';
      position: absolute;
      top: 0;
      right: 0;
      width: 100vw;
      height: 100vh;
      background: linear-gradient(
          to top,
          ${transparentize(theme.B400, 0.999)} 0%,
          ${transparentize(theme.B400, 0.15)} 75%
        ),
        linear-gradient(to right, ${transparentize(theme.B400, 0.999)} 0%, ${transparentize(theme.B400, 0.15)} 50%) !important;
    }

    &[selected='0'] .home-palette-id-1,
    &[selected='1'] .home-palette-id-1,
    &[selected='2'] .home-palette-id-1,
    &[selected='3'] .home-palette-id-1,
    &[selected='4'] .home-palette-id-1,
    &[selected='5'] .home-palette-id-1,
    &[selected='6'] .home-palette-id-1,
    &[selected='7'] .home-palette-id-1,
    &[selected='8'] .home-palette-id-1,
    &[selected='9'] .home-palette-id-1,
    &[selected='10'] .home-palette-id-1,
    &[selected='11'] .home-palette-id-1,
    &[selected='12'] .home-palette-id-1 {
      color: ${theme.font_primary} !important;
    }

    &[selected='0'] .home-palette-id-2,
    &[selected='1'] .home-palette-id-2,
    &[selected='2'] .home-palette-id-2,
    &[selected='3'] .home-palette-id-2,
    &[selected='4'] .home-palette-id-2,
    &[selected='5'] .home-palette-id-2,
    &[selected='6'] .home-palette-id-2,
    &[selected='7'] .home-palette-id-2,
    &[selected='8'] .home-palette-id-2,
    &[selected='9'] .home-palette-id-2,
    &[selected='10'] .home-palette-id-2,
    &[selected='11'] .home-palette-id-2,
    &[selected='12'] .home-palette-id-2,
    &[selected='0'] .home-palette-id-3,
    &[selected='1'] .home-palette-id-3,
    &[selected='2'] .home-palette-id-3,
    &[selected='3'] .home-palette-id-3,
    &[selected='4'] .home-palette-id-3,
    &[selected='5'] .home-palette-id-3,
    &[selected='6'] .home-palette-id-3,
    &[selected='7'] .home-palette-id-3,
    &[selected='8'] .home-palette-id-3,
    &[selected='9'] .home-palette-id-3,
    &[selected='10'] .home-palette-id-3,
    &[selected='11'] .home-palette-id-3,
    &[selected='12'] .home-palette-id-3 {
      color: ${theme.font_secondary} !important;
    }
  }

  /* Options Toolbar */
  #sliding_action_bar_container,
  #sliding_action_bar_container.material {
    background: ${theme.B300};
  }

  /* Icons */
  #player .now-playing-actions sj-icon-button,
  #player.material .now-playing-actions sj-icon-button,
  .header-row core-icon[icon='sort'],
  .header-row iron-icon[icon='sort'],
  .nav-item-container core-icon,
  .nav-item-container iron-icon,
  core-icon,
  iron-icon,
  sj-icon-button {
    color: ${theme.font_primary};
  }

  paper-header-panel#content-container #iflFab iron-icon {
    color: ${isLight(theme.A500) ? FONT_LIGHT : FONT_DARK} !important;
  }

  div.icon {
    filter: invert(100%);
  }
`;

export default styles;
<commit_msg>Changed feeling lucky fab icon to have punch through effect<commit_after>import { css } from 'styled-components';

import { isLight, transparentize, FONT_DARK, FONT_LIGHT, TRANSITION_FAST } from 'style/theme';

const styles = theme => css`
  html:not([style-scope]):not(.style-scope) {
    --light-theme-text-color: ${theme.font_primary};
    --light-theme-secondary-color: ${theme.font_secondary};
  }

  body,
  body.material {
    background-color: ${theme.B500};
    color: ${theme.font_primary};
    transition: background ${TRANSITION_FAST};
  }

  ::-webkit-scrollbar {
    width: 11px;
    background: ${transparentize(theme.B400, 0.6)};
    transition: background ${TRANSITION_FAST};

    &:hover {
      background: ${transparentize(theme.B400, 0.7)};
    }

    &:active {
      background: ${transparentize(theme.B400, 0.65)};
    }
  }

  ::-webkit-scrollbar-track {
    background: ${transparentize(theme.B400, 0.6)};
    transition: background ${TRANSITION_FAST};

    &:hover {
      background: ${transparentize(theme.B400, 0.7)};
    }

    &:active {
      background: ${transparentize(theme.B400, 0.65)};
    }
  }

  ::-webkit-scrollbar-thumb {
    border-radius: 0;
    opacity: 0.7;

    &:hover {
      opacity: 0.8;
    }
    &:active {
      opacity: 0.75;
    }
  }

  #sliding-action-bar-container {
    background-color: ${theme.B400} !important;
    color: ${theme.font_primary} !important;

    paper-icon-button {
      color: ${theme.font_primary};

      &[disabled] {
        color: ${theme.font_primary};
        opacity: 0.4;
      }
    }
  }

  #music-content {
    color: ${theme.font_primary};
  }

  /* Links */
  .settings-footer a.footer-link,
  .music-source-empty-message,
  .nav-item-container,
  .simple-dialog a {
    color: ${theme.font_primary} !important;
  }

  a {
    color: ${theme.font_primary};
  }

  /* Top Toolbar */
  paper-header-panel#content-container {
    paper-toolbar {
      color: ${theme.font_primary};
    }

    &:not([style-scope]):not(.style-scope):not(.transparent) paper-toolbar#material-app-bar {
      border-bottom: 1px solid ${theme.B300} !important;
    }

    core-icon,
    iron-icon,
    sj-icon-button {
      color: ${theme.font_primary} !important;
    }

    sj-search-box {
      background-color: ${transparentize(theme.B600, 0.5)};
      color: ${theme.font_primary};

      &::-webkit-input-placeholder {
        color: ${theme.font_primary};
      }

      &[opened] {
        background-color: ${theme.B200};

        &::-webkit-input-placeholder {
          color: ${theme.font_secondary};
        }

        &:not([num-suggestions='0']) #input.sj-search-box {
          border-bottom-color: ${theme.B300};
        }
      }

      #input.sj-search-box {
        color: ${theme.font_primary};

        &::-webkit-input-placeholder {
          color: ${theme.font_primary};
        }
      }

      &[opened] {
        background-color: ${theme.B200};

        #input.sj-search-box::-webkit-input-placeholder {
          color: ${theme.font_secondary};
        }
      }

      core-icon,
      iron-icon,
      sj-icon-button {
        color: ${theme.font_primary} !important;
      }
    }

    sj-search-suggestion {
      &.query-selected,
      &:hover {
        background: ${theme.B25};
      }

      .sj-search-suggestion {
        color: ${theme.font_secondary} !important;
      }

      .sub-match.sj-search-suggestion {
        color: ${theme.font_primary} !important;
      }
    }
  }

  .sj-search-box sj-entity-suggestion.sj-search-box:last-of-type {
    border-bottom: 2px solid ${theme.B300} !important;
    box-shadow: 0 1px 0 0 ${transparentize(theme.B400, 0.5)} !important;
  }

  .sj-search-box[opened]:not([num-suggestions='0']) #suggestionList.sj-search-box {
    padding: 8px 0 0;
  }

  sj-entity-suggestion #title.sj-entity-suggestion {
    color: ${theme.font_primary} !important;
  }

  sj-entity-suggestion #subtitle.sj-entity-suggestion {
    color: ${theme.font_secondary} !important;
  }

  sj-entity-suggestion:hover,
  sj-entity-suggestion.query-selected {
    background-color: ${theme.B25} !important;
  }

  sj-home {
    #backgroundImageContainer.sj-home {
      height: 40vw;
      width: 80vw;
    }

    #gradient.sj-home:after {
      content: '';
      position: absolute;
      top: 0;
      right: 0;
      width: 100vw;
      height: 100vh;
      background: linear-gradient(
          to top,
          ${transparentize(theme.B400, 0.999)} 0%,
          ${transparentize(theme.B400, 0.15)} 75%
        ),
        linear-gradient(to right, ${transparentize(theme.B400, 0.999)} 0%, ${transparentize(theme.B400, 0.15)} 50%) !important;
    }

    &[selected='0'] .home-palette-id-1,
    &[selected='1'] .home-palette-id-1,
    &[selected='2'] .home-palette-id-1,
    &[selected='3'] .home-palette-id-1,
    &[selected='4'] .home-palette-id-1,
    &[selected='5'] .home-palette-id-1,
    &[selected='6'] .home-palette-id-1,
    &[selected='7'] .home-palette-id-1,
    &[selected='8'] .home-palette-id-1,
    &[selected='9'] .home-palette-id-1,
    &[selected='10'] .home-palette-id-1,
    &[selected='11'] .home-palette-id-1,
    &[selected='12'] .home-palette-id-1 {
      color: ${theme.font_primary} !important;
    }

    &[selected='0'] .home-palette-id-2,
    &[selected='1'] .home-palette-id-2,
    &[selected='2'] .home-palette-id-2,
    &[selected='3'] .home-palette-id-2,
    &[selected='4'] .home-palette-id-2,
    &[selected='5'] .home-palette-id-2,
    &[selected='6'] .home-palette-id-2,
    &[selected='7'] .home-palette-id-2,
    &[selected='8'] .home-palette-id-2,
    &[selected='9'] .home-palette-id-2,
    &[selected='10'] .home-palette-id-2,
    &[selected='11'] .home-palette-id-2,
    &[selected='12'] .home-palette-id-2,
    &[selected='0'] .home-palette-id-3,
    &[selected='1'] .home-palette-id-3,
    &[selected='2'] .home-palette-id-3,
    &[selected='3'] .home-palette-id-3,
    &[selected='4'] .home-palette-id-3,
    &[selected='5'] .home-palette-id-3,
    &[selected='6'] .home-palette-id-3,
    &[selected='7'] .home-palette-id-3,
    &[selected='8'] .home-palette-id-3,
    &[selected='9'] .home-palette-id-3,
    &[selected='10'] .home-palette-id-3,
    &[selected='11'] .home-palette-id-3,
    &[selected='12'] .home-palette-id-3 {
      color: ${theme.font_secondary} !important;
    }
  }

  /* Options Toolbar */
  #sliding_action_bar_container,
  #sliding_action_bar_container.material {
    background: ${theme.B300};
  }

  /* Icons */
  #player .now-playing-actions sj-icon-button,
  #player.material .now-playing-actions sj-icon-button,
  .header-row core-icon[icon='sort'],
  .header-row iron-icon[icon='sort'],
  .nav-item-container core-icon,
  .nav-item-container iron-icon,
  core-icon,
  iron-icon,
  sj-icon-button {
    color: ${theme.font_primary};
  }

  paper-header-panel#content-container #iflFab iron-icon {
    color: ${theme.B500} !important;
  }

  div.icon {
    filter: invert(100%);
  }
`;

export default styles;
<|endoftext|>


<commit_before>'use strict';

jest.dontMock('../Autosuggest.js');

var React = require('react/addons');
var Autosuggest = require('../Autosuggest.js');
var TestUtils = React.addons.TestUtils;
var suburbs = ['Cheltenham', 'Mill Park', 'Mordialloc', 'Nunawading'];
var autosuggest, input, suggestions;

function getSuburbs(input, callback) {
  var regex = new RegExp('^' + input, 'i');

  callback(null, suburbs.filter(function(suburb) {
    return regex.test(suburb);
  }));
}

function setInputValue(value) {
  React.addons.TestUtils.Simulate.change(input, { target: { value: value } });
}

function expectSuggestions(expectedSuggestions) {
  suggestions = TestUtils.scryRenderedDOMComponentsWithClass(autosuggest, 'react-autosuggest__suggestion');
  expect(suggestions.length).toBe(expectedSuggestions.length);

  for (var i = 0; i < expectedSuggestions.length; i++) {
    expect(suggestions[i].getDOMNode().textContent === expectedSuggestions[i]);
  }
}

describe('Autosuggest', function() {
  describe('Basics', function() {
    beforeEach(function() {
      autosuggest = TestUtils.renderIntoDocument(
        <Autosuggest initialValue="my value" suggestions={getSuburbs} />
      );
      input = TestUtils.findRenderedDOMComponentWithTag(autosuggest, 'input');
    });

    it('should set initial value', function() {
      expect(input.getDOMNode().value).toBe('my value');
    });

    it('should not show suggestions by default', function() {
      expectSuggestions([]);
    });

    it('should show suggestions when matches exist', function() {
      setInputValue('m');
      expectSuggestions(['Mill Park', 'Mordialloc']);
    });

    it('should show suggestions when case insensitive matches exist', function() {
      setInputValue('NUNA');
      expectSuggestions(['Nunawading']);
    });

    it('should show not suggestions when no matches exist', function() {
      setInputValue('a');
      expectSuggestions([]);
    });
  });
});
<commit_msg>Add more tests<commit_after>'use strict';

jest.dontMock('../Autosuggest.js');

var React = require('react/addons');
var Autosuggest = require('../Autosuggest.js');
var TestUtils = React.addons.TestUtils;
var suburbs = ['Cheltenham', 'Mill Park', 'Mordialloc', 'Nunawading'];
var autosuggest, input, suggestions;

function getSuburbs(input, callback) {
  var regex = new RegExp('^' + input, 'i');

  callback(null, suburbs.filter(function(suburb) {
    return regex.test(suburb);
  }));
}

function setInputValue(value) {
  React.addons.TestUtils.Simulate.change(input, { target: { value: value } });
}

function clickSuggestion(suggestionIndex) {
  suggestions = TestUtils.scryRenderedDOMComponentsWithClass(autosuggest, 'react-autosuggest__suggestion');
  React.addons.TestUtils.Simulate.mouseDown(suggestions[suggestionIndex].getDOMNode());
}

function clickEscape() {
  React.addons.TestUtils.Simulate.keyDown(input, { keyCode: 27 });
}

function clickDown() {
  React.addons.TestUtils.Simulate.keyDown(input, { keyCode: 40 });
}

function clickUp() {
  React.addons.TestUtils.Simulate.keyDown(input, { keyCode: 38 });
}

function expectInputValue(expectedValue) {
  expect(input.value).toBe(expectedValue);
}

function expectSuggestions(expectedSuggestions) {
  suggestions = TestUtils.scryRenderedDOMComponentsWithClass(autosuggest, 'react-autosuggest__suggestion');
  expect(suggestions.length).toBe(expectedSuggestions.length);

  for (var i = 0; i < expectedSuggestions.length; i++) {
    expect(suggestions[i].getDOMNode().textContent === expectedSuggestions[i]);
  }
}

function expectFocusedSuggestion(suggestion) {
  var focusedSuggestions = TestUtils.scryRenderedDOMComponentsWithClass(autosuggest, 'react-autosuggest__suggestion--focused');

  if (suggestion === null) {
    expect(focusedSuggestions.length).toBe(0);
  } else {
    expect(focusedSuggestions.length).toBe(1);
    expect(focusedSuggestions[0].getDOMNode().textContent).toBe(suggestion);
  }
}

describe('Autosuggest', function() {
  describe('Basics', function() {
    beforeEach(function() {
      autosuggest = TestUtils.renderIntoDocument(
        <Autosuggest initialValue="my value" suggestions={getSuburbs} />
      );
      input = TestUtils.findRenderedDOMComponentWithTag(autosuggest, 'input').getDOMNode();
    });

    it('should set initial value', function() {
      expectInputValue('my value');
    });

    it('should not show suggestions by default', function() {
      expectSuggestions([]);
    });

    it('should show suggestions when matches exist', function() {
      setInputValue('m');
      expectSuggestions(['Mill Park', 'Mordialloc']);
    });

    it('should not focus on suggestion when suggestions are shown', function() {
      setInputValue('m');
      expectFocusedSuggestion(null);
    });

    it('should show suggestions when case insensitive matches exist', function() {
      setInputValue('NUNA');
      expectSuggestions(['Nunawading']);
    });

    it('should show not suggestions when no matches exist', function() {
      setInputValue('a');
      expectSuggestions([]);
    });

    it('should hide suggestions when ESC is clicked and suggestions are shown', function() {
      setInputValue('m');
      clickEscape();
      expectSuggestions([]);
    });

    it('should clear the input when ESC is clicked and suggestions are not shown', function() {
      setInputValue('m');
      clickEscape();
      clickEscape();
      expectInputValue('');
    });
  });

  describe('Interacting with suggestions', function() {
    beforeEach(function() {
      setInputValue('m');
    });

    it('should set input field value when suggestion is clicked', function() {
      clickSuggestion(1);
      expectInputValue('Mordialloc');
    });

    it('should focus on first suggestion and change input value when Down is clicked', function() {
      clickDown();
      expectFocusedSuggestion('Mill Park');
      expectInputValue('Mill Park');
    });

    it('should focus on next suggestion and change input value when Down is clicked again', function() {
      clickDown();
      clickDown();
      expectFocusedSuggestion('Mordialloc');
      expectInputValue('Mordialloc');
    });

    it('should remove focus from suggestions when last suggestion is focused and Down is clicked ', function() {
      clickDown();
      clickDown();
      clickDown();
      // TODO
      //expectFocusedSuggestion(null);
      //expectInputValue('m');
    });
  });
});
<|endoftext|>


<commit_before>(function(jQuery) {
"use strict";

var $ = jQuery;

Echo.Tests.module = function(name, config) {
	config.meta = config.meta || {};
	QUnit.module(name, {
		"setup": function() {
			_testSetup();
			config.setup && config.setup.call(this);
		},
		"teardown": function() {
			config.teardown && config.teardown.call(this);
			_testTeardown();
		},
		"meta": {
			"className": config.meta.className || "",
			"functions": config.meta.functions || []
		}
	});
};

Echo.Tests.test = function(name, callback, config) {
	config = _normalizeTestConfig(config);
	QUnit.test(name, function() {
		var self = this, args = arguments;
		_actualizeTestUser(config.user, function() {
			callback.apply(self, args);
		});
	});
};

Echo.Tests.asyncTest = function(name, callback, config) {
	config = _normalizeTestConfig(config);
	QUnit.test(name, function() {
		var self = this, args = arguments;
		// we might want individual timeout for each test
		// so we can't use QUnit.asyncTest, but we emulate it using QUnit.stop()
		QUnit.config.testTimeout = config.timeout;
		QUnit.stop();
		_actualizeTestUser(config.user, function() {
			callback.apply(self, args);
		});
	});
};

Echo.Tests.renderersTest = function(component, params, config) {
	params = $.extend({
		"appkey": "echo.jssdk.tests.aboutecho.com",
		"target": $("#qunit-fixture"),
		"ready": function() {}
	}, params || {});
	Echo.Tests.asyncTest("basic checks for renderers", function() {
		var handler = function() {
			var instance = this;
			var checker = function(name, element, suffix) {
				if (!element) {
					QUnit.ok(true, "Note: the test for the " + " \"" + name + "\"" + " renderer was not executed, because the template doesn't contain the respective element. This renderer works for another type of template." + suffix);
					return;
				}
				var oldElement = element.clone(true, true);
				var renderedElement = instance.view.render({"name": name});
				_testElementsConsistencyAfterRendering(name, oldElement, renderedElement, suffix);
			};
			$.each(instance.renderers, function(name, renderer) {
				QUnit.config.current.moduleTestEnvironment.meta.functions.push("renderers." + name);
				checker(name, instance.view.get(name));
			});
			var oldElements = Echo.Utils.foldl({}, instance.view._elements, function(element, acc, name) {
				acc[name] = element.clone(true, true);
			});
			instance.render();
			$.each(instance.renderers, function(name, element) {
				checker(name, oldElements[instance.cssPrefix + name], " (recursive rerendering case)");
			});
			QUnit.start();
		};
		var ready = params.ready;
		params.ready = function() {
			if (this.view.rendered()) {
				handler.call(this);
			} else {
				this.events.subscribe({
					"topic": component + ".onRender",
					"once": true,
					"handler": handler
				});
			}
			ready.call(this);
		};
		var Component = Echo.Utils.getComponent(component);
		new Component(params);
	}, config);
};

Echo.Tests.isolatedTest = function(test) {
	return function(cb) {
		var iframe = $('');
		$(document.body).append(iframe);
		iframe.on("load", function() {
			var win = iframe.get(0).contentWindow;
			var callback = function() {
				// cleanup first
				iframe.remove();
				// and then execute callback to advance to the next test
				cb();
			};
			test.call(win, callback);
		});
		iframe.attr("src", "about:blank");
	};
};

// methods useful if one wants to disable particular test easily
Echo.Tests._test = Echo.Tests._asyncTest = Echo.Tests._renderersTest = function() {
	Echo.Utils.log({
		"component": "Tests",
		"message": "[" + QUnit.config.currentModule + "] Disabled test: " + arguments[0]
	});
};

// private functions

function _testSetup() {
	//delete all event handlers in all contexts
	Echo.Events._subscriptions = {};
	Echo.Events._dataByHandlerId = {};

	// delete all accumulated stuff from Loader
	Echo.Loader.canvases = [];
	Echo.Loader.overrides = {};
	Echo.Loader.vars = {
		"state": {"resources": {}, "queue": []},
		"processing": false,
		"syncQueue": []
	};

	// clear qunit-fixture
	$("#qunit-fixture").empty();
};

function _testTeardown() {
	delete Echo.Tests.current.user;
	var meta = QUnit.config.current.moduleTestEnvironment.meta;
	if (!meta || meta.processed) return;
	meta.processed = true;
	$.each(meta.functions, function(i, name) {
		Echo.Tests.Stats.markFunctionTested(meta.className + "." + name);
	});
};

function _normalizeTestConfig(config) {
	return $.extend(true, {
		"timeout": 5000,
		"user": {
			"status": "anonymous"
		}
	}, config || {});
}

function _actualizeTestUser(config, callback) {
	Echo.Tests.current.user = config;
	callback();
};

function _testElementsConsistencyAfterRendering(name, oldElement, renderedElement, suffix) {
	var prefix = "Renderer \"" + name + "\": ";
	suffix = suffix || "";
	QUnit.ok(
		renderedElement instanceof jQuery && renderedElement.length === 1,
		prefix + "check contract" + suffix
	);
	QUnit.ok(
		renderedElement.jquery === oldElement.jquery,
		prefix + "check that element is still the same after second rendering" + suffix
	);
	QUnit.equal(
		renderedElement.children().length,
		oldElement.children().length,
		prefix + "check the number of children after second rendering of element" + suffix
	);
	// this variable contains regexp that will test rendered element
	// use case is renderer function has side effects (ex. date computation, random values etc)
	var oldText = oldElement.text().toLowerCase().replace(/([^\w\s])/g, "\\$1").replace(/\d+/g, "\\d+");
	QUnit.ok(
		(new RegExp("^" + oldText + "$")).test(renderedElement.text().toLowerCase()),
		prefix + "check that text representation of the element is still the same after second rendering" + suffix
	);
};
// TODO: remove this line when all tests use new format
Echo.Tests._testElementsConsistencyAfterRendering = _testElementsConsistencyAfterRendering;

})(Echo.jQuery);
<commit_msg>Simplify _testRenderers check<commit_after>(function(jQuery) {
"use strict";

var $ = jQuery;

Echo.Tests.module = function(name, config) {
	config.meta = config.meta || {};
	QUnit.module(name, {
		"setup": function() {
			_testSetup();
			config.setup && config.setup.call(this);
		},
		"teardown": function() {
			config.teardown && config.teardown.call(this);
			_testTeardown();
		},
		"meta": {
			"className": config.meta.className || "",
			"functions": config.meta.functions || []
		}
	});
};

Echo.Tests.test = function(name, callback, config) {
	config = _normalizeTestConfig(config);
	QUnit.test(name, function() {
		var self = this, args = arguments;
		_actualizeTestUser(config.user, function() {
			callback.apply(self, args);
		});
	});
};

Echo.Tests.asyncTest = function(name, callback, config) {
	config = _normalizeTestConfig(config);
	QUnit.test(name, function() {
		var self = this, args = arguments;
		// we might want individual timeout for each test
		// so we can't use QUnit.asyncTest, but we emulate it using QUnit.stop()
		QUnit.config.testTimeout = config.timeout;
		QUnit.stop();
		_actualizeTestUser(config.user, function() {
			callback.apply(self, args);
		});
	});
};

Echo.Tests.renderersTest = function(component, params, config) {
	params = $.extend({
		"appkey": "echo.jssdk.tests.aboutecho.com",
		"target": $("#qunit-fixture"),
		"ready": function() {}
	}, params || {});
	Echo.Tests.asyncTest("basic checks for renderers", function() {
		var handler = function() {
			var instance = this;
			var checker = function(name, element, suffix) {
				if (!element) {
					QUnit.ok(true, "Note: the test for the " + " \"" + name + "\"" + " renderer was not executed, because the template doesn't contain the respective element. This renderer works for another type of template." + suffix);
					return;
				}
				var oldElement = element.clone(true, true);
				var renderedElement = instance.view.render({"name": name});
				_testElementsConsistencyAfterRendering(name, oldElement, renderedElement, suffix);
			};
			$.each(instance.renderers, function(name, renderer) {
				QUnit.config.current.moduleTestEnvironment.meta.functions.push("renderers." + name);
				checker(name, instance.view.get(name));
			});
			var oldElements = Echo.Utils.foldl({}, instance.view._elements, function(element, acc, name) {
				acc[name] = element.clone(true, true);
			});
			instance.render();
			$.each(instance.renderers, function(name, element) {
				checker(name, oldElements[instance.cssPrefix + name], " (recursive rerendering case)");
			});
			QUnit.start();
		};
		var ready = params.ready;
		params.ready = function() {
			if (this.view.rendered()) {
				handler.call(this);
			} else {
				this.events.subscribe({
					"topic": component + ".onRender",
					"once": true,
					"handler": handler
				});
			}
			ready.call(this);
		};
		var Component = Echo.Utils.getComponent(component);
		new Component(params);
	}, config);
};

Echo.Tests.isolatedTest = function(test) {
	return function(cb) {
		var iframe = $('');
		$(document.body).append(iframe);
		iframe.on("load", function() {
			var win = iframe.get(0).contentWindow;
			var callback = function() {
				// cleanup first
				iframe.remove();
				// and then execute callback to advance to the next test
				cb();
			};
			test.call(win, callback);
		});
		iframe.attr("src", "about:blank");
	};
};

// methods useful if one wants to disable particular test easily
Echo.Tests._test = Echo.Tests._asyncTest = Echo.Tests._renderersTest = function() {
	Echo.Utils.log({
		"component": "Tests",
		"message": "[" + QUnit.config.currentModule + "] Disabled test: " + arguments[0]
	});
};

// private functions

function _testSetup() {
	//delete all event handlers in all contexts
	Echo.Events._subscriptions = {};
	Echo.Events._dataByHandlerId = {};

	// delete all accumulated stuff from Loader
	Echo.Loader.canvases = [];
	Echo.Loader.overrides = {};
	Echo.Loader.vars = {
		"state": {"resources": {}, "queue": []},
		"processing": false,
		"syncQueue": []
	};

	// clear qunit-fixture
	$("#qunit-fixture").empty();
};

function _testTeardown() {
	delete Echo.Tests.current.user;
	var meta = QUnit.config.current.moduleTestEnvironment.meta;
	if (!meta || meta.processed) return;
	meta.processed = true;
	$.each(meta.functions, function(i, name) {
		Echo.Tests.Stats.markFunctionTested(meta.className + "." + name);
	});
};

function _normalizeTestConfig(config) {
	return $.extend(true, {
		"timeout": 5000,
		"user": {
			"status": "anonymous"
		}
	}, config || {});
}

function _actualizeTestUser(config, callback) {
	Echo.Tests.current.user = config;
	callback();
};

function _testElementsConsistencyAfterRendering(name, oldElement, renderedElement, suffix) {
	var prefix = "Renderer \"" + name + "\": ";
	suffix = suffix || "";
	QUnit.ok(
		renderedElement instanceof jQuery && renderedElement.length === 1,
		prefix + "check contract" + suffix
	);
	QUnit.ok(
		renderedElement.jquery === oldElement.jquery,
		prefix + "check that element is still the same after second rendering" + suffix
	);
	QUnit.equal(
		renderedElement.children().length,
		oldElement.children().length,
		prefix + "check the number of children after second rendering of element" + suffix
	);
	// Some renderers may add computed numbers or dates to element HTML so it
	// may become different in the 2 sequential executions. We still consider such
	// renderers valid that's why we replace any number of digits in the element
	// text with a single "0" symbol for new text and old text to match
	var oldText = oldElement.text().toLowerCase().replace(/\d+/g, "0");
	var newText = renderedElement.text().toLowerCase().replace(/\d+/g, "0");
	QUnit.equal(
		newText,
		oldText,
		prefix + "check that text representation of the element is still the same after second rendering" + suffix
	);
};
// TODO: remove this line when all tests use new format
Echo.Tests._testElementsConsistencyAfterRendering = _testElementsConsistencyAfterRendering;

})(Echo.jQuery);
<|endoftext|>


<commit_before>"use strict";

var NodeSurface = require("../node/node_surface");

var TextSurface = function(node, surfaceProvider, options) {
  NodeSurface.call(this, node, surfaceProvider);
  options = options || {};
  this.property = options.property || "content";

  var self = this;

  if (options.property) {
    this.components.push(this.propertyComponent(options.property, options.propertyPath));
  } else {
    // NOTE: trying to get rid of the "NodeComponent" as everything is connected to a specific property.
    // this.components.push(this.nodeComponent()
    //   .length(function() {
    //     return self.node[self.property].length;
    //   })
    // );
    this.components.push(this.propertyComponent(self.property)
      .length(function() {
        return self.node[self.property].length;
      })
    );
  }
};

// This surface has not been refactored. We simply override the default implementation
// and use the existing implementation.
TextSurface.Prototype = function() {

  this.getCharPosition = function(el, offset) {
    if (!this.view) {
      throw new Error("No view attached.");
    }

    var frag;
    for (var i = 0; i < this.view._fragments.length; i++) {
      var f = this.view._fragments[i];
      if (f.el === el) {
        frag = f;
        break;
      }
    }

    if (!frag) {
      console.error("AAAAArg", el);
      throw new Error("Could not lookup el.");
    }
    var charPos = frag.charPos + offset;
    return charPos;
  };

  // Returns the corresponding DOM element position for the given character
  // --------
  //
  // A DOM position is specified by a tuple of element and offset.
  // In the case of text nodes it is a TEXT element.

  this.getDOMPosition = function(charPos) {
    if (!this.view) {
      throw new Error("No view attached.");
    }
    var result = this.view._lookupPostion(charPos);
    var frag = result[0];
    var offset = result[1];

    var range = document.createRange();
    range.setStart(frag.el, offset);
    return range;
  };

  this.getComponent = function() {
    return this.components[0];
  };
};
TextSurface.Prototype.prototype = NodeSurface.prototype;
TextSurface.prototype = new TextSurface.Prototype();

// A helper which turned out to be useful for editable textish properties
// --------
// The node view must provide a corresponding view under `childViews[property]`
TextSurface.textProperty = function(nodeSurface, property, propertyPath) {
  // TODO: it is not very convenient to create a Text sub-surface for a textish property:
  var options = { property: property };
  if (propertyPath) options[propertyPath] = propertyPath;
  var propertySurface = new TextSurface(nodeSurface.node, nodeSurface.surfaceProvider, options);
  var propertyComponent = propertySurface.components[0];
  propertyComponent.element(function() {
      return nodeSurface.view.childViews[property].el;
    })
    .length(function() {
      // HACK: somehow we need a plus one here... dunno
      return nodeSurface.node[property].length + 1;
    });
  propertyComponent.name = property;
  return propertyComponent;
};

module.exports = TextSurface;
<commit_msg>Fix text node surface for empty text nodes.<commit_after>"use strict";

var NodeSurface = require("../node/node_surface");

var TextSurface = function(node, surfaceProvider, options) {
  NodeSurface.call(this, node, surfaceProvider);
  options = options || {};
  this.property = options.property || "content";

  var self = this;

  if (options.property) {
    this.components.push(this.propertyComponent(options.property, options.propertyPath));
  } else {
    this.components.push(this.propertyComponent(self.property)
      .length(function() {
        return self.node[self.property].length;
      })
    );
  }
};

// This surface has not been refactored. We simply override the default implementation
// and use the existing implementation.
TextSurface.Prototype = function() {

  this.getCharPosition = function(el, offset) {
    if (!this.view) {
      throw new Error("No view attached.");
    }

    // Bootstrapping: cases that happened with empty text node.
    // In these cases we return charPos = 0
    if (this.view._fragments.length === 0 || el === this.view._fragments[0].el.parentElement) {
      return 0;
    }

    // Otherwise find the correct TEXT element
    var frag;
    for (var i = 0; i < this.view._fragments.length; i++) {
      var f = this.view._fragments[i];
      if (f.el === el) {
        frag = f;
        break;
      }
    }

    if (!frag) {
      console.error("AAAAArg", el);
      throw new Error("Could not lookup text element.");
    }

    var charPos = frag.charPos + offset;
    return charPos;
  };

  // Returns the corresponding DOM element position for the given character
  // --------
  //
  // A DOM position is specified by a tuple of element and offset.
  // In the case of text nodes it is a TEXT element.

  this.getDOMPosition = function(charPos) {
    if (!this.view) {
      throw new Error("No view attached.");
    }
    var result = this.view._lookupPostion(charPos);
    var frag = result[0];
    var offset = result[1];

    var range = document.createRange();
    range.setStart(frag.el, offset);
    return range;
  };

  this.getComponent = function() {
    return this.components[0];
  };
};
TextSurface.Prototype.prototype = NodeSurface.prototype;
TextSurface.prototype = new TextSurface.Prototype();

// A helper which turned out to be useful for editable textish properties
// --------
// The node view must provide a corresponding view under `childViews[property]`
TextSurface.textProperty = function(nodeSurface, property, propertyPath) {
  // TODO: it is not very convenient to create a Text sub-surface for a textish property:
  var options = { property: property };
  if (propertyPath) options[propertyPath] = propertyPath;
  var propertySurface = new TextSurface(nodeSurface.node, nodeSurface.surfaceProvider, options);
  var propertyComponent = propertySurface.components[0];
  propertyComponent.element(function() {
      return nodeSurface.view.childViews[property].el;
    })
    .length(function() {
      // HACK: somehow we need a plus one here... dunno
      return nodeSurface.node[property].length + 1;
    });
  propertyComponent.name = property;
  return propertyComponent;
};

module.exports = TextSurface;
<|endoftext|>


<commit_before>/*
 * moleculer
 * Copyright (c) 2017 Icebob (https://github.com/ice-services/moleculer)
 * MIT Licensed
 */

"use strict";

// Prefix for logger
const LOG_PREFIX = "TX";

/**
 * Base Transporter class
 *
 * @class BaseTransporter
 */
class BaseTransporter {

	/**
	 * Creates an instance of BaseTransporter.
	 *
	 * @param {any} opts
	 *
	 * @memberOf BaseTransporter
	 */
	constructor(opts) {
		this.opts = opts || {};
		this.connected = false;

		this.prefix = "MOL";

		if (this.opts.prefix) {
			this.prefix = this.opts.prefix;
		}
	}

	/**
	 * Init transporter
	 *
	 * @param {any} broker
	 *
	 * @memberOf BaseTransporter
	 */
	init(broker, messageHandler) {
		this.broker = broker;
		this.nodeID = broker.nodeID;
		this.logger = broker.getLogger("LOG_PREFIX");
		this.messageHandler = messageHandler;
	}

	/**
	 * Connect to the transporter server
	 *
	 * @memberOf BaseTransporter
	 */
	connect() {
		/* istanbul ignore next */
		throw new Error("Not implemented!");
	}

	/**
	 * Disconnect from the transporter server
	 *
	 * @memberOf BaseTransporter
	 */
	disconnect() {
		/* istanbul ignore next */
		throw new Error("Not implemented!");
	}

	subscribe(topic) {
		/* istanbul ignore next */
		throw new Error("Not implemented!");
	}

	publish(topic, packet) {
		/* istanbul ignore next */
		throw new Error("Not implemented!");
	}

}

module.exports = BaseTransporter;<commit_msg>fix log prefix<commit_after>/*
 * moleculer
 * Copyright (c) 2017 Icebob (https://github.com/ice-services/moleculer)
 * MIT Licensed
 */

"use strict";

// Prefix for logger
const LOG_PREFIX = "TX";

/**
 * Base Transporter class
 *
 * @class BaseTransporter
 */
class BaseTransporter {

	/**
	 * Creates an instance of BaseTransporter.
	 *
	 * @param {any} opts
	 *
	 * @memberOf BaseTransporter
	 */
	constructor(opts) {
		this.opts = opts || {};
		this.connected = false;

		this.prefix = "MOL";

		if (this.opts.prefix) {
			this.prefix = this.opts.prefix;
		}
	}

	/**
	 * Init transporter
	 *
	 * @param {any} broker
	 *
	 * @memberOf BaseTransporter
	 */
	init(broker, messageHandler) {
		this.broker = broker;
		this.nodeID = broker.nodeID;
		this.logger = broker.getLogger(LOG_PREFIX);
		this.messageHandler = messageHandler;
	}

	/**
	 * Connect to the transporter server
	 *
	 * @memberOf BaseTransporter
	 */
	connect() {
		/* istanbul ignore next */
		throw new Error("Not implemented!");
	}

	/**
	 * Disconnect from the transporter server
	 *
	 * @memberOf BaseTransporter
	 */
	disconnect() {
		/* istanbul ignore next */
		throw new Error("Not implemented!");
	}

	subscribe(topic) {
		/* istanbul ignore next */
		throw new Error("Not implemented!");
	}

	publish(topic, packet) {
		/* istanbul ignore next */
		throw new Error("Not implemented!");
	}

}

module.exports = BaseTransporter;<|endoftext|>


<commit_before>glift.keyMappings = {
  /**
   * Some keys must be bound with 'keydown' rather than key code
   * mappings.
   */
  _nameToCodeKeyDown: {
    BACKSPACE: 8,
    ESCAPE: 27,
    ARROW_LEFT:37,
    ARROW_UP:38,
    ARROW_RIGHT:39,
    ARROW_DOWN:40
  },

  _codeToNameKeyDown: undefined, // lazilyDefined

  /** Convert a key name (see above) to a standard key code. */
  nameToCode: function(name) {
    if (name.length !== 1) {
      if (/[A-Z](_[A-Z]+)+/.test(name)) {
        return glift.keyMappings._nameToCodeKeyDown[name] || null
      } else {
        return null
      }
    } else {
      return name.charCodeAt(0);
    }
  },

  /** Convert a standard key code to a key name (see above). */
  codeToName: function(keyCode) {
    if (!glift.keyMappings._codeToNameKeyDown) {
      // Bite the bullet and define the map.
      var newmap = {};
      for (var name in glift.keyMappings._nameToCodeKeyDown) {
        var keycode = glift.keyMappings._nameToCodeKeyDown[name]
        newmap[keycode] = name;
      }
      glift.keyMappings._codeToNameKeyDown = newmap;
    }
    if (glift.keyMappings._codeToNameKeyDown[keyCode]) {
      return glift.keyMappings._codeToNameKeyDown[keyCode];
    } else {
      return String.fromCharCode(keyCode) || null;
    }
  },

  /**
   * The master keybinding registry.
   *
   * Maps:
   *  InstanceId -> (to)
   *    KeyName -> (to)
   *      Function or Icon
   */
  _keyBindingMap: {},

  /**
   * Registers a keybinding function with a manager instance.
   *
   * id: Glift manager instance id.
   * keyName: string representing the keypress. Must be a member of _nameToCode.
   * funcOrIcon: The function or icon.name to register.
   */
  registerKeyAction: function(id, keyName, funcOrIcon) {
    var map = glift.keyMappings._keyBindingMap;
    if (!glift.keyMappings.nameToCode(keyName)) {
      // We don't know about this particular keyCode.  It might be an error, or
      // it might be that it needs to be added to the above.
      throw new Error('Unknown key name: ' + keyName);
    }

    if (!map[id]) {
      map[id] = {};
    }
    if (id && keyName && funcOrIcon) {
      map[id][keyName] = funcOrIcon;
    }
  },

  /** Remove all keys associated with an ID. */
  unregisterInstance: function(id) {
    if (glift.keyMappings._keyBindingMap[id]) {
      delete glift.keyMappings._keyBindingMap[id];
    }
  },

  /**
   * Gets a keybinding function or an icon path
   *
   * id: The glift manager instance id.
   * keyName: The number representing the instance.
   */
  getFuncOrIcon: function(id, keyName) {
    var map = glift.keyMappings._keyBindingMap;
    if (id && keyName && map[id] && map[id][keyName]) {
      return map[id][keyName];
    }
    return null;
  },

  /** Whether the listener has been initialized. */
  _initializedListener: false,

  /**
   * Initializes a global listener on keypresses.  Should only be really
   * initialized once, but it's ok to call this function more than once -- it
   * will be idempotent.
   */
  initKeybindingListener: function() {
    if (glift.keyMappings._initializedListener) {
      return;
    }
    var body = document.body;

    // Note: difference between keypress and keydown!
    //
    // We use keydown so we can capture the left/right arrow keys, but keypress
    // should be preferred since it's easier to get the char code.
    body.addEventListener('keydown', glift.keyMappings._keyHandlerFunc);
    body.addEventListener('keypress', glift.keyMappings._keyHandlerFunc);
    glift.keyMappings._initializedListener = true;
  },

  /**
   * Internal function for processing key-presses.
   */
  _keyHandlerFunc: function(keyEvent) {
    var keyName = glift.keyMappings.codeToName(keyEvent.which);// || e.charCode);
    if (keyEvent.type === 'keydown' && !(/[A-Z_]+/.test(keyName))) {
      // This key should be processed by the keypress event rather than this
      // one.
      return;
    }

    var activeId = glift.global.activeInstanceId;
    var bindingMap = glift.keyMappings._keyBindingMap;
    var funcOrIcon = glift.keyMappings.getFuncOrIcon(activeId, keyName);
    if (!funcOrIcon) { return; }

    var manager = glift.global.instanceRegistry[activeId];
    if (!manager) { return; }

    var widget = manager.getCurrentWidget();
    if (!widget) { return; }

    var argType = glift.util.typeOf(funcOrIcon)

    if (argType === 'function') {
      funcOrIcon(widget);
      if (event.preventDefault) event.preventDefault();
      else  event.returnValue = false; // IE
    } else if (argType === 'string') {
      // Assume it's an icon-action-path
      // icon namespaces look like: icons.arrowleft.mouseup
      var actionNamespace = funcOrIcon.split('.');
      var action = widget.actions[actionNamespace[0]];
      for (var i = 1; i < actionNamespace.length; i++) {
        action = action[actionNamespace[i]];
      }
      action(keyEvent, widget);
      if (event.preventDefault) event.preventDefault();
      else  event.returnValue = false; // IE
    }
  }
};
<commit_msg>Fix bug with keymappings.<commit_after>glift.keyMappings = {
  /**
   * Some keys must be bound with 'keydown' rather than key code
   * mappings.
   */
  _nameToCodeKeyDown: {
    BACKSPACE: 8,
    ESCAPE: 27,
    ARROW_LEFT:37,
    ARROW_UP:38,
    ARROW_RIGHT:39,
    ARROW_DOWN:40
  },

  _codeToNameKeyDown: undefined, // lazilyDefined

  /** Convert a key name (see above) to a standard key code. */
  nameToCode: function(name) {
    if (name.length !== 1) {
      if (/[A-Z](_[A-Z]*)+/.test(name)) {
        return glift.keyMappings._nameToCodeKeyDown[name] || null
      } else {
        return null
      }
    } else {
      return name.charCodeAt(0);
    }
  },

  /** Convert a standard key code to a key name (see above). */
  codeToName: function(keyCode) {
    if (!glift.keyMappings._codeToNameKeyDown) {
      // Bite the bullet and define the map.
      var newmap = {};
      for (var name in glift.keyMappings._nameToCodeKeyDown) {
        var keycode = glift.keyMappings._nameToCodeKeyDown[name]
        newmap[keycode] = name;
      }
      glift.keyMappings._codeToNameKeyDown = newmap;
    }
    if (glift.keyMappings._codeToNameKeyDown[keyCode]) {
      return glift.keyMappings._codeToNameKeyDown[keyCode];
    } else {
      return String.fromCharCode(keyCode) || null;
    }
  },

  /**
   * The master keybinding registry.
   *
   * Maps:
   *  InstanceId -> (to)
   *    KeyName -> (to)
   *      Function or Icon
   */
  _keyBindingMap: {},

  /**
   * Registers a keybinding function with a manager instance.
   *
   * id: Glift manager instance id.
   * keyName: string representing the keypress. Must be a member of _nameToCode.
   * funcOrIcon: The function or icon.name to register.
   */
  registerKeyAction: function(id, keyName, funcOrIcon) {
    var map = glift.keyMappings._keyBindingMap;
    if (!glift.keyMappings.nameToCode(keyName)) {
      // We don't know about this particular keyCode.  It might be an error, or
      // it might be that it needs to be added to the above.
      throw new Error('Unknown key name: ' + keyName);
    }

    if (!map[id]) {
      map[id] = {};
    }
    if (id && keyName && funcOrIcon) {
      map[id][keyName] = funcOrIcon;
    }
  },

  /** Remove all keys associated with an ID. */
  unregisterInstance: function(id) {
    if (glift.keyMappings._keyBindingMap[id]) {
      delete glift.keyMappings._keyBindingMap[id];
    }
  },

  /**
   * Gets a keybinding function or an icon path
   *
   * id: The glift manager instance id.
   * keyName: The number representing the instance.
   */
  getFuncOrIcon: function(id, keyName) {
    var map = glift.keyMappings._keyBindingMap;
    if (id && keyName && map[id] && map[id][keyName]) {
      return map[id][keyName];
    }
    return null;
  },

  /** Whether the listener has been initialized. */
  _initializedListener: false,

  /**
   * Initializes a global listener on keypresses.  Should only be really
   * initialized once, but it's ok to call this function more than once -- it
   * will be idempotent.
   */
  initKeybindingListener: function() {
    if (glift.keyMappings._initializedListener) {
      return;
    }
    var body = document.body;

    // Note: difference between keypress and keydown!
    //
    // We use keydown so we can capture the left/right arrow keys, but keypress
    // should be preferred since it's easier to get the char code.
    body.addEventListener('keydown', glift.keyMappings._keyHandlerFunc);
    body.addEventListener('keypress', glift.keyMappings._keyHandlerFunc);
    glift.keyMappings._initializedListener = true;
  },

  /**
   * Internal function for processing key-presses.
   */
  _keyHandlerFunc: function(keyEvent) {
    var keyName = glift.keyMappings.codeToName(keyEvent.which);// || e.charCode);
    if (keyEvent.type === 'keydown' && !(/[A-Z_]+/.test(keyName))) {
      // This key should be processed by the keypress event rather than this
      // one.
      return;
    }

    var activeId = glift.global.activeInstanceId;
    var bindingMap = glift.keyMappings._keyBindingMap;
    var funcOrIcon = glift.keyMappings.getFuncOrIcon(activeId, keyName);
    if (!funcOrIcon) { return; }

    var manager = glift.global.instanceRegistry[activeId];
    if (!manager) { return; }

    var widget = manager.getCurrentWidget();
    if (!widget) { return; }

    var argType = glift.util.typeOf(funcOrIcon)

    if (argType === 'function') {
      funcOrIcon(widget);
      if (event.preventDefault) event.preventDefault();
      else  event.returnValue = false; // IE
    } else if (argType === 'string') {
      // Assume it's an icon-action-path
      // icon namespaces look like: icons.arrowleft.mouseup
      var actionNamespace = funcOrIcon.split('.');
      var action = widget.actions[actionNamespace[0]];
      for (var i = 1; i < actionNamespace.length; i++) {
        action = action[actionNamespace[i]];
      }
      action(keyEvent, widget);
      if (event.preventDefault) event.preventDefault();
      else  event.returnValue = false; // IE
    }
  }
};
<|endoftext|>


<commit_before>import fs from 'fs';
import path from 'path';
import yaml from 'js-yaml';

const travisCommands = [
  // Reference: http://docs.travis-ci.com/user/customizing-the-build/#The-Build-Lifecycle
  'before_install',
  'install',
  'before_script',
  'script',
  'after_success or after_failure',
  'before_deploy',
  'deploy',
  'after_deploy',
  'after_script',
];

function concat(array, item) {
  return array.concat(item);
}

function getObjectValues(object) {
  return Object.keys(object).map(key => object[key]);
}

export default function getScripts(filepath, content = null) {
  const basename = path.basename(filepath);
  const fileContent = content !== null ? content : fs.readFileSync(filepath, 'utf-8');

  if (basename === 'package.json') {
    return getObjectValues(JSON.parse(fileContent).scripts || {});
  } else if (basename === '.travis.yml') {
    const metadata = yaml.safeLoad(content) || {};
    return travisCommands.map(cmd => metadata[cmd] || []).reduce(concat, []);
  }

  return [];
}
<commit_msg>Add cache logic to get script utility.<commit_after>import fs from 'fs';
import path from 'path';
import yaml from 'js-yaml';

const scriptCache = {};

function getCacheOrFile(key, fn) {
  if (scriptCache[key]) {
    return scriptCache[key];
  }

  const value = fn();
  scriptCache[key] = value;

  return value;
}

const travisCommands = [
  // Reference: http://docs.travis-ci.com/user/customizing-the-build/#The-Build-Lifecycle
  'before_install',
  'install',
  'before_script',
  'script',
  'after_success or after_failure',
  'before_deploy',
  'deploy',
  'after_deploy',
  'after_script',
];

function concat(array, item) {
  return array.concat(item);
}

function getObjectValues(object) {
  return Object.keys(object).map(key => object[key]);
}

export default function getScripts(filepath, content = null) {
  return getCacheOrFile(filepath, () => {
    const basename = path.basename(filepath);
    const fileContent = content !== null ? content : fs.readFileSync(filepath, 'utf-8');

    if (basename === 'package.json') {
      return getObjectValues(JSON.parse(fileContent).scripts || {});
    } else if (basename === '.travis.yml') {
      const metadata = yaml.safeLoad(content) || {};
      return travisCommands.map(cmd => metadata[cmd] || []).reduce(concat, []);
    }

    return [];
  });
}
<|endoftext|>


<commit_before>define(function(lang){

  'use strict';

  function scalePoints(points, scale){
    if(Array.isArray(points)){
      var newPoints = [];
      // TODO: move this to a faster forEach, possibly lo-dash's
      points.forEach(function(point){
        newPoints.push(scalePoints(point, scale));
      });
      points = newPoints;
    } else if(typeof scale === 'object'){
      points = {
        x: points.x * scale.x,
        y: points.y * scale.y
      };
    } else {
      points = {
        x: points.x * scale,
        y: points.y * scale
      };
    }
    return points;
  }

  return scalePoints;

});<commit_msg>remove lang param from scalePoints<commit_after>define(function(){

  'use strict';

  function scalePoints(points, scale){
    if(Array.isArray(points)){
      var newPoints = [];
      // TODO: move this to a faster forEach, possibly lo-dash's
      points.forEach(function(point){
        newPoints.push(scalePoints(point, scale));
      });
      points = newPoints;
    } else if(typeof scale === 'object'){
      points = {
        x: points.x * scale.x,
        y: points.y * scale.y
      };
    } else {
      points = {
        x: points.x * scale,
        y: points.y * scale
      };
    }
    return points;
  }

  return scalePoints;

});<|endoftext|>


<commit_before>/*

    VErtical Timeline - Responsive, jQuery-based vertical timeline generator
    Version 2.0.0
    Ryan Fitzgerald
    http://RyanFitzgerald.ca/
    ---
    Repo: http://github.com/ryanfitzgerald/vertical-timeline
    Issues: http://github.com/ryanfitzgerald/vertical-timeline/issues
    Licensed under MIT Open Source

 */

(function ( $ ) {

    // Check if element is in viewport
    var checkViewport = function(elem) {

        var rect = elem.getBoundingClientRect();

        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.right <= (window.innerWidth || document.documentElement.clientWidth)
        );
    }

    $.fn.verticalTimeline = function(options) {

        // Overide defaults, if any
        var settings = $.extend({
            startSide: 'left',
            alternate: true,
            animate: null,
            theme: null
        }, options);

        // Allow chaining and process each DOM node
        return this.each(function() {

            // Define variables
            $this = $(this); // Store reference to this
            $userContent = $this.children('div'); // user content

            // Add main class
            $this.addClass('vtimeline');

            // Create timeline divs
            $userContent.each(function() {
                // Add wrapping divs to each user div
                $(this).addClass('vtimeline-content')
                       .wrap('

');
            });

            // Add timeline icons
            $this.find('.vtimeline-point').each(function() {
                $(this).prepend('

');
            });

            // --- Orientation Setup ---
            // Add appropriate classes for non-alternating
            if (!settings.alternate) {
                $this.addClass('vtimeline-align-'+settings.startSide);
            }

            // --- Alternating Setup ---
            // Add alternating class if set to true
            if (settings.alternate && settings.startSide == 'left') {
                $this.find('.vtimeline-point:odd').each(function() {
                    $(this).addClass('vtimeline-right');
                });
            } else if (settings.alternate && settings.startSide == 'right') {
                $this.find('.vtimeline-point:even').each(function() {
                    $(this).addClass('vtimeline-right');
                });
            }

            // Add dates to the timeline if exists
            $this.find('.vtimeline-content').each(function() {
                var date = $(this).data('vtdate');
                if ($(this).data('vtdate')) { // Prepend if exists
                    $(this).parent().prepend(''+date+'');
                }
            });

            // --- Animation Setup ---
            // Fade the blocks in as they come into viewport
            if (settings.animate == "fade") {

                // Store animation type
                var animateType = settings.animate;

                // Apply animate style to blocks
                $this.find('.vtimeline-block').addClass("vt-"+animateType);

                // Initial check if in viewport
                $this.find('.vtimeline-block.vt-'+animateType).each(function() {
                    if (checkViewport($(this)[0])) {
                        $(this).removeClass("vt-"+animateType);
                    }
                });

                // Check elements on scroll
                $(window).on("scroll", function() {
                    $this.find('.vtimeline-block.vt-'+animateType).each(function() {
                        if (checkViewport($this)[0])) {
                            $(this).removeClass("vt-"+animateType);
                        }
                    });
                });

            }

        });

    };

}( jQuery ));
<commit_msg>remove parenthesis in viewport check<commit_after>/*

    VErtical Timeline - Responsive, jQuery-based vertical timeline generator
    Version 2.0.0
    Ryan Fitzgerald
    http://RyanFitzgerald.ca/
    ---
    Repo: http://github.com/ryanfitzgerald/vertical-timeline
    Issues: http://github.com/ryanfitzgerald/vertical-timeline/issues
    Licensed under MIT Open Source

 */

(function ( $ ) {

    // Check if element is in viewport
    var checkViewport = function(elem) {

        var rect = elem.getBoundingClientRect();

        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.right <= (window.innerWidth || document.documentElement.clientWidth)
        );
    }

    $.fn.verticalTimeline = function(options) {

        // Overide defaults, if any
        var settings = $.extend({
            startSide: 'left',
            alternate: true,
            animate: null,
            theme: null
        }, options);

        // Allow chaining and process each DOM node
        return this.each(function() {

            // Define variables
            $this = $(this); // Store reference to this
            $userContent = $this.children('div'); // user content

            // Add main class
            $this.addClass('vtimeline');

            // Create timeline divs
            $userContent.each(function() {
                // Add wrapping divs to each user div
                $(this).addClass('vtimeline-content')
                       .wrap('

');
            });

            // Add timeline icons
            $this.find('.vtimeline-point').each(function() {
                $(this).prepend('

');
            });

            // --- Orientation Setup ---
            // Add appropriate classes for non-alternating
            if (!settings.alternate) {
                $this.addClass('vtimeline-align-'+settings.startSide);
            }

            // --- Alternating Setup ---
            // Add alternating class if set to true
            if (settings.alternate && settings.startSide == 'left') {
                $this.find('.vtimeline-point:odd').each(function() {
                    $(this).addClass('vtimeline-right');
                });
            } else if (settings.alternate && settings.startSide == 'right') {
                $this.find('.vtimeline-point:even').each(function() {
                    $(this).addClass('vtimeline-right');
                });
            }

            // Add dates to the timeline if exists
            $this.find('.vtimeline-content').each(function() {
                var date = $(this).data('vtdate');
                if ($(this).data('vtdate')) { // Prepend if exists
                    $(this).parent().prepend(''+date+'');
                }
            });

            // --- Animation Setup ---
            // Fade the blocks in as they come into viewport
            if (settings.animate == "fade") {

                // Store animation type
                var animateType = settings.animate;

                // Apply animate style to blocks
                $this.find('.vtimeline-block').addClass("vt-"+animateType);

                // Initial check if in viewport
                $this.find('.vtimeline-block.vt-'+animateType).each(function() {
                    if (checkViewport($(this)[0])) {
                        $(this).removeClass("vt-"+animateType);
                    }
                });

                // Check elements on scroll
                $(window).on("scroll", function() {
                    $this.find('.vtimeline-block.vt-'+animateType).each(function() {
                        if (checkViewport($this)[0]) {
                            $(this).removeClass("vt-"+animateType);
                        }
                    });
                });

            }

        });

    };

}( jQuery ));
<|endoftext|>