<commit_before>'use strict'

//libraries
import m from 'mithril'
import _ from 'lodash'

//stles
import style from '../../css/filter.scss'

//polythene icons
import starIcon from 'mmsvg/google/msvg/toggle/star'
import plusIcon from 'mmsvg/google/msvg/content/add'
import dollarIcon from 'mmsvg/google/msvg/editor/attach-money'

const ratingClickHandler = function(index) {
  const ctrl = this
  ctrl.filter.add('rating', index)
}

const priceClickHandler = function(index) {
  const ctrl = this
  ctrl.filter.add('price', index)
}

const categoryClickHandler = function(category) {
  const ctrl = this
  ctrl.filter.add('category', category)
}

const renderOptions = function(menuType) {
  const ctrl = this

  let icon
  let clickHandler
  let cls
  if (menuType === 'rating') {
    icon = starIcon
    clickHandler = ratingClickHandler
    cls = style['star-icon']
  } else {
    icon = dollarIcon
    clickHandler = priceClickHandler
    cls = style['price-icon']
  }
  const rows = new Array(4)

  return m(`ul.${style['menu-rows']}`, [
    _.map(rows, (row, index) => {
      const numberOfIcons = index + 1
      const iconsArr = new Array(numberOfIcons)
      return m(`li.${style['menu-row']}`, { onclick: clickHandler.bind(ctrl, index) }, [
        m(`ul`, [
          _.map(iconsArr, (_, i) => {
            if (i === 3)
              return m(`li.${style['plus-icon']}`, { key: i }, m('span', plusIcon))
            return m(`li.${cls}`, { key: i }, m('span', icon))
          })
      ])])
    })
  ])
}

const renderTypeMenu = function(categories) {
  const ctrl = this

  return m(`ul.${style['food-menu']}`, [
    _.map(categories(), (category, index) => {
      // const numberOfIcons = index + 1
      // const iconsArr = new Array(numberOfIcons)
      return m(`li.${style['menu-row']}`, m('span', { class: category.active() ? `${style['active']}` : '', onclick: categoryClickHandler.bind(ctrl, category.name()) }, category.name()))
    })
  ])

  // return _.map(, (category) => {
  //   //code
  // })
}

const renderFilterMenu = function(args) {
  const ctrl = this
  const parentCtrl = args

  return m(`.${style['filter-menu']}`, [
    (ctrl.clickedFilterSection() === 'rating') ? renderOptions.call(ctrl, 'rating') : '',
    (ctrl.clickedFilterSection() === 'type') ? renderTypeMenu.call(ctrl, ctrl.categories) : '',
    (ctrl.clickedFilterSection() === 'price') ? renderOptions.call(ctrl, 'price') : ''

    ])
}

const fltr = function() {
  const ctrl = this

  const unfilteredRestaurants = m.prop(_.cloneDeep(ctrl.restaurants()))

  const filter = {
    status: m.prop(0),
    active: m.prop({
      price: m.prop(0),
      rating: m.prop(0),
      category: m.prop([])
    }),
  }

  const filterPrice = function(rests) {
    return _.filter(rests(), (restaurant) => {
            const price = filter.active().price()
            if (price < 3) {
              return restaurant.priceTier() === price
            } else {
              return restaurant.priceTier() > 3
            }
          })
  }

  const filterRating = function(rests) {
    return _.filter(rests(), (restaurant) => {
            const rating = Math.floor(restaurant.rating)
            const activeRating = filter.active().rating()
            if (rating < 3) {
              if( activeRating <= rating && activeRating + 1 < rating ) {
                return 1
              }
            } else {
              return rating > 3
            }
          })
  }

  const filterCategory = function(rests, category) {

    return _.filter(rests(), (restaurant) => {
            const index = _.indexOf(restaurant.categories, category)
            if(index !== -1) {
              return 1
            }
          })

  }

  const applyFilter = function(restaurants) {

    const rests = m.prop(_.cloneDeep(unfilteredRestaurants()))

    if (filter.active().price()) {
      rests(filterPrice(rests))
    }

    if (filter.active().rating()) {
      rests(filterRating(rests))
    }

    if (filter.active().category().length) {
      _.forEach(filter.active().category(), (category) => {
        rests(filterCategory(rests, category))
      })
    }

    ctrl.restaurants(rests)
    m.redraw()
  }

  filter.reset = function() {
    ctrl.restaurants(_.cloneDeep(unfilteredRestaurants()))
  }

  return {
    add(type, value) {
      console.log( type, value )
      switch(type) {
        case 'price':
          if(filter.active().price()) {
            if(filter.active().price() !== value) {
              filter.active().price(value)
              applyFilter()
            } else {
              // applyFullFilter
            }
          } else {
            filter.active().price(value)
            // apply price filter give .. ctrl.restaurants()
            filterPrice(ctrl.restaurants)
            m.redraw()
          }
          break
        case 'rating':
          if(filter.active().rating()) {
            if(filter.active().rating() !== value) {
              filter.active().rating(value)
              applyFilter()
            } else {
              // applyFullFilter
            }
          } else {
            filter.active().rating(value)
            // apply rating filter give .. ctrl.restaurants()
            filterRating(ctrl.restaurants)
            m.redraw()
          }
          break
        case 'category':
          console.log(filter.active().category().length)
          if (filter.active().category().length) {
            const index = _.indexOf(filter.active().category(), value)
            console.log( index)
            if (index === -1) {
              // apply category filter
              filter.active().category().push(value)
              filterCategory(ctrl.restaurants, value)
              m.redraw()
            } else {
              _.pullAt(filter.active().category(), index)
              // applyFullFilter
              applyFilter()
            }

          } else {
            filter.active().category().push(value)
            console.log(filter.active().category())
            // apply category filter, pass ctrl.restaurnts()]
            // filterCategory(ctrl.restaurants, value)
            // console.log(filterCategory(ctrl.restaurants, value))
            console.log(ctrl.restaurants())
            ctrl.restaurants(filterCategory(ctrl.restaurants, value))
            console.log(ctrl.restaurants())
            m.redraw()
          }
          break
        default:
          break
      }
    }
  }
}

const FilterMenu = {

  controller(args) {
    const Ctrl = {
      restaurants: args.restaurants,
      categories: args.categories,
      clickedFilterSection: m.prop('type')
    }
    Ctrl.filter = fltr.call(Ctrl)
    return Ctrl
  },
  view(ctrl, args) {
    return renderFilterMenu.call(ctrl, args)
  }

}

export default FilterMenu<commit_msg>feature: category filter fully working<commit_after>'use strict'

//libraries
import m from 'mithril'
import _ from 'lodash'

//stles
import style from '../../css/filter.scss'

//polythene icons
import starIcon from 'mmsvg/google/msvg/toggle/star'
import plusIcon from 'mmsvg/google/msvg/content/add'
import dollarIcon from 'mmsvg/google/msvg/editor/attach-money'

const ratingClickHandler = function(index) {
  const ctrl = this
  ctrl.filter.add('rating', index)
}

const priceClickHandler = function(index) {
  const ctrl = this
  ctrl.filter.add('price', index)
}

const categoryClickHandler = function(category) {
  const ctrl = this
  ctrl.filter.add('category', category)
}

const renderOptions = function(menuType) {
  const ctrl = this

  let icon
  let clickHandler
  let cls
  if (menuType === 'rating') {
    icon = starIcon
    clickHandler = ratingClickHandler
    cls = style['star-icon']
  } else {
    icon = dollarIcon
    clickHandler = priceClickHandler
    cls = style['price-icon']
  }
  const rows = new Array(4)

  return m(`ul.${style['menu-rows']}`, [
    _.map(rows, (row, index) => {
      const numberOfIcons = index + 1
      const iconsArr = new Array(numberOfIcons)
      return m(`li.${style['menu-row']}`, { onclick: clickHandler.bind(ctrl, index) }, [
        m(`ul`, [
          _.map(iconsArr, (_, i) => {
            if (i === 3)
              return m(`li.${style['plus-icon']}`, { key: i }, m('span', plusIcon))
            return m(`li.${cls}`, { key: i }, m('span', icon))
          })
      ])])
    })
  ])
}

const renderTypeMenu = function(categories) {
  const ctrl = this

  return m(`ul.${style['food-menu']}`, [
    _.map(categories(), (category, index) => {
      // const numberOfIcons = index + 1
      // const iconsArr = new Array(numberOfIcons)
      return m(`li.${style['menu-row']}`, m('span', { class: category.active() ? `${style['active']}` : '', onclick: categoryClickHandler.bind(ctrl, category.name()) }, category.name()))
    })
  ])

  // return _.map(, (category) => {
  //   //code
  // })
}

const renderFilterMenu = function(args) {
  const ctrl = this
  const parentCtrl = args

  return m(`.${style['filter-menu']}`, [
    (ctrl.clickedFilterSection() === 'rating') ? renderOptions.call(ctrl, 'rating') : '',
    (ctrl.clickedFilterSection() === 'type') ? renderTypeMenu.call(ctrl, ctrl.categories) : '',
    (ctrl.clickedFilterSection() === 'price') ? renderOptions.call(ctrl, 'price') : ''

    ])
}

const fltr = function() {
  const ctrl = this

  const unfilteredRestaurants = m.prop(_.cloneDeep(ctrl.restaurants()))

  const filter = {
    status: m.prop(0),
    active: m.prop({
      price: m.prop(0),
      rating: m.prop(0),
      category: m.prop([])
    }),
  }

  const filterPrice = function(rests) {
    return _.filter(rests(), (restaurant) => {
            const price = filter.active().price()
            if (price < 3) {
              return restaurant.priceTier() === price
            } else {
              return restaurant.priceTier() > 3
            }
          })
  }

  const filterRating = function(rests) {
    return _.filter(rests(), (restaurant) => {
            const rating = Math.floor(restaurant.rating)
            const activeRating = filter.active().rating()
            if (rating < 3) {
              if( activeRating <= rating && activeRating + 1 < rating ) {
                return 1
              }
            } else {
              return rating > 3
            }
          })
  }

  const filterCategory = function(rests, category) {

    return _.filter(rests(), (restaurant) => {
            const index = _.indexOf(restaurant.categories, category)
            console.log('restaurants categories')
            console.log(restaurant.categories)
            console.log('INDEX OF CATEGORY IN RESTARANTS CATEGORY ARRAY')
            console.log(index)
            if(index !== -1) {
              return 1
            }
          })

  }

  const applyFilter = function() {

    const rests = m.prop(_.cloneDeep(unfilteredRestaurants()))
    console.log(rests())

    if (filter.active().price()) {
      rests(filterPrice(rests))
    }

    if (filter.active().rating()) {
      rests(filterRating(rests))
    }

    if (filter.active().category().length) {
      _.forEach(filter.active().category(), (category) => {
        console.log(category)
        rests(filterCategory(rests, category))
      })
    }

    ctrl.restaurants(rests())
    m.redraw()
  }

  filter.reset = function() {
    ctrl.restaurants(_.cloneDeep(unfilteredRestaurants()))
  }

  return {
    add(type, value) {
      console.log( type, value )
      switch(type) {
        case 'price':
          if(filter.active().price()) {
            if(filter.active().price() !== value) {
              filter.active().price(value)
              applyFilter()
            } else {
              // applyFullFilter
            }
          } else {
            filter.active().price(value)
            // apply price filter give .. ctrl.restaurants()
            filterPrice(ctrl.restaurants)
            m.redraw()
          }
          break
        case 'rating':
          if(filter.active().rating()) {
            if(filter.active().rating() !== value) {
              filter.active().rating(value)
              applyFilter()
            } else {
              // applyFullFilter
            }
          } else {
            filter.active().rating(value)
            // apply rating filter give .. ctrl.restaurants()
            filterRating(ctrl.restaurants)
            m.redraw()
          }
          break
        case 'category':
          console.log(filter.active().category().length)
          if (filter.active().category().length) {
            const index = _.indexOf(filter.active().category(), value)
            console.log('INDEX OF CATEGORY IN ACTIVE FILTER CATEGORY')
            console.log(index)
            if (index === -1) {
              // apply category filter
              filter.active().category().push(value)
              ctrl.restaurants(filterCategory(ctrl.restaurants, value))
              m.redraw()
            } else {
              _.pullAt(filter.active().category(), index)
              // applyFullFilter
              applyFilter()
            }

          } else {
            filter.active().category().push(value)
            // apply category filter, pass ctrl.restaurnts()]
            // filterCategory(ctrl.restaurants, value)
            // console.log(filterCategory(ctrl.restaurants, value))
            ctrl.restaurants(filterCategory(ctrl.restaurants, value))
            m.redraw()
          }
          break
        default:
          break
      }
    }
  }
}

const FilterMenu = {

  controller(args) {
    const Ctrl = {
      restaurants: args.restaurants,
      categories: args.categories,
      clickedFilterSection: m.prop('type')
    }
    Ctrl.filter = fltr.call(Ctrl)
    return Ctrl
  },
  view(ctrl, args) {
    return renderFilterMenu.call(ctrl, args)
  }

}

export default FilterMenu<|endoftext|>


<commit_before>quail.elementAttributesAreValid = function() {
	quail.components.htmlSource.getHtml(function(html, parsed) {
		if(!parsed) {
			return;
		}
		quail.components.htmlSource.traverse(parsed, function(element) {
			if(typeof element.raw === 'undefined') {
				return;
			}
			var selector = element.selector.join('>').trim();
			//Element has mis-matched quotes
			var quotes = element.raw.match(/\'|\"/g);
			if (quotes && quotes.length % 2 !== 0) {
				quail.testFails('elementAttributesAreValid', quail.html.find(selector));
			}

			//Element attributes not separated by a space
			if(element.raw.search(/([a-z]*)=(\'|\")([a-z\.]*)(\'|\")[a-z]/i) > -1) {
				quail.testFails('elementAttributesAreValid', quail.html.find(selector));
			}

			//Element with space as an attribute is not surrounded by quotes
			var splitElement = element.raw.split('=');
			splitElement.shift();
			$.each(splitElement, function() {
				if(this.search(/\'|\"/) === -1 && this.search(/\s/i) > -1) {
					quail.testFails('elementAttributesAreValid', quail.html.find(selector));
				}
			});
		});
	});
};
<commit_msg>Coding standard.<commit_after>quail.elementAttributesAreValid = function() {
	quail.components.htmlSource.getHtml(function(html, parsed) {
		if (!parsed) {
			return;
		}
		quail.components.htmlSource.traverse(parsed, function(element) {
			if (typeof element.raw === 'undefined') {
				return;
			}
			var selector = element.selector.join('>').trim();
			//Element has mis-matched quotes
			var quotes = element.raw.match(/\'|\"/g);
			if (quotes && quotes.length % 2 !== 0) {
				quail.testFails('elementAttributesAreValid', quail.html.find(selector));
			}

			//Element attributes not separated by a space
			if (element.raw.search(/([a-z]*)=(\'|\")([a-z\.]*)(\'|\")[a-z]/i) > -1) {
				quail.testFails('elementAttributesAreValid', quail.html.find(selector));
			}

			//Element with space as an attribute is not surrounded by quotes
			var splitElement = element.raw.split('=');
			splitElement.shift();
			$.each(splitElement, function() {
				if (this.search(/\'|\"/) === -1 && this.search(/\s/i) > -1) {
					quail.testFails('elementAttributesAreValid', quail.html.find(selector));
				}
			});
		});
	});
};
<|endoftext|>


<commit_before>//
// RUNTIME TYPE CHECKING
//

export {
  isArray,
  isArguments,
  isBoolean,
  isEventEmitter,
  isFunction,
  isPojo,
  isString,
  isTemplateLiteral,
  isNumber,
  isThisValue,
  isNull,
  isUnset,
  ArgTypeError,
  ObjTypeError
}

//
// isType
//

// isEventEmitter
//
function isEventEmitter(obj) {
  return (
    isObject(obj) &&
    isFunction(obj.emit) &&
    (isFunction(obj.addListener) || isFunction(obj.on)) &&
    (isFunction(obj.removeListener) || isFunction(obj.off))
  )
}

isEventEmitter.displayName = 'isEventEmitter'

// isUnset
//
function isUnset(obj) {
  return obj === null || obj === undefined
}

isArray.displayName = 'isUnset'

// isArray
//
function isArray(obj) {
  return Array.isArray(obj)
}

isArray.displayName = 'isArray'

// isArguments
//
function isArguments(obj) {
  if (!isObject(obj)) {
    return false
  }
  const hasMap = isFunction(obj.map)
  const hasLength = isNumber(obj.length)
  const hasObjectPrototype = obj.__proto__ === Object.prototype
  return hasObjectPrototype && hasLength && !hasMap
}

isArguments.displayName = 'isArguments'

// isBoolean
//
function isBoolean(obj) {
  return obj === true || obj === false
}

isBoolean.displayName = 'isBoolean'

// isFunction
//
function isFunction(obj) {
  return typeof obj === 'function'
}

isFunction.displayName = 'isFunction'

// isString
//
function isString(obj) {
  return typeof obj === 'string'
}

isString.displayName = 'isString'

// isNull
//
function isNull(obj) {
  return obj === null
}

isNull.displayName = 'isNull'

// isNumber
//
function isNumber(obj) {
  return typeof obj === 'number'
}

isNumber.displayName = 'isNumber'

// isObject
//
function isObject(obj) {
  return typeof obj === 'object' && obj !== null
}

isObject.displayName = 'isObject'

// isPojo
//
function isPojo(obj) {
  if (obj === null || !isObject(obj)) {
    return false
  }
  return Object.getPrototypeOf(obj) === Object.prototype
}

isPojo.displayName = 'isPojo'

// isTemplateLiteral
//
function isTemplateLiteral(obj) {
  if (isString(obj)) {
    return true
  }
  if (!isArray(obj)) {
    return false
  }
  return obj.every(isString)
}

isTemplateLiteral.displayName = 'isTemplateLiteral'

// isThisValue
//
function isThisValue(value) {
  function inObject(obj) {
    return obj === value
  }
  inObject.displayName = `isThisValue(${value})`
  return inObject
}

//
// ArgTypeError
//

const typeErrorStringIfFnReturnsFalse = (argName, argTypeFn, arg) => {
  return argTypeFn(arg)
    ? undefined
    : (argTypeFn.displayName || argTypeFn.name) +
        `(${argName}) did not return true`
}

const typeErrorStringIfTypeOfFails = (argName, argType, arg) => {
  return typeof arg === argType
    ? undefined
    : `Argument "${argName}" should be a ${argType}`
}

const typeErrorStringFromArgument = argMap => (arg, index) => {
  if (index >= argMap.length) {
    return
  }

  const { argName, argType } = argMap[index]
  if (arg === undefined) {
    return `Argument undefined: "${argName}"`
  }

  const permittedArgTypes = Array.isArray(argType) ? argType : [argType]

  const errorDescs = permittedArgTypes
    .map(argType =>
      isFunction(argType)
        ? typeErrorStringIfFnReturnsFalse(argName, argType, arg)
        : typeErrorStringIfTypeOfFails(argName, argType, arg)
    )
    .filter(isString)

  const multipleTypesSpecified = permittedArgTypes.length > 1
  const shouldError = multipleTypesSpecified
    ? errorDescs.length > 1
    : errorDescs.length

  if (shouldError) {
    return (
      errorDescs.join('\n| ') +
      `\n> typeof ${argName} === ${typeof arg}(${JSON.stringify(arg)})`
    )
  }
}

/**
 * Helper for enforcing correct argument-types.
 *
 * @private
 * @param {string} namespace
 *
 * @example
 * const argTypeError = ArgTypeError('namespace#')
 *
 * function myFn (myArg1, myArg2) {
 *   const err = argTypeError({
 *     myArg1: isString,
 *     myArg2: isBoolean
 *   })('myFn')(myArg1, myArg2)
 *   if (err) {
 *     throw new TypeError(err)
 *   }
 * }
 */

function ArgTypeError(namespace) {
  return typeMap => {
    const argMap = Object.entries(typeMap).map(([argName, argType]) => ({
      argName,
      argType
    }))

    return fnName => (...args) => {
      const processedArgs = Array.from(args, x =>
        isArguments(x) ? Array.from(x) : x
      ).flat(1)

      const err = processedArgs
        .map(typeErrorStringFromArgument(argMap))
        .filter(isString)

      if (!err.length) {
        return
      }

      const signature = Object.keys(typeMap).join(', ')
      return (
        `\n${namespace || ''}${fnName}(${signature}):\n` +
        `${err.map(err => `| ${err}`).join('\n')}`
      )
    }
  }
}

function ObjTypeError(namespace) {
  return typeMap => {
    const keys = Object.keys(typeMap)
    const objTypeError = ArgTypeError(namespace)(typeMap)
    return fnName => obj => {
      const values = valuesOf(obj, { keys })
      const err = objTypeError(fnName)(...values)
      return err
    }
  }
}

function valuesOf(obj, options) {
  const { keys } = options
  if (!Array.isArray(keys)) {
    return Object.values(obj)
  }
  return keys.reduce((acc, key) => {
    return [...acc, obj[key]]
  }, [])
}
<commit_msg>Fix isArguments, isPojo<commit_after>//
// RUNTIME TYPE CHECKING
//

export {
  isArray,
  isArguments,
  isBoolean,
  isEventEmitter,
  isFunction,
  isPojo,
  isString,
  isTemplateLiteral,
  isNumber,
  isThisValue,
  isNull,
  isUnset,
  ArgTypeError,
  ObjTypeError
}

//
// isType
//

// isEventEmitter
//
function isEventEmitter(obj) {
  return (
    isObject(obj) &&
    isFunction(obj.emit) &&
    (isFunction(obj.addListener) || isFunction(obj.on)) &&
    (isFunction(obj.removeListener) || isFunction(obj.off))
  )
}

isEventEmitter.displayName = 'isEventEmitter'

// isUnset
//
function isUnset(obj) {
  return obj === null || obj === undefined
}

isArray.displayName = 'isUnset'

// isArray
//
function isArray(obj) {
  return Array.isArray(obj)
}

isArray.displayName = 'isArray'

// isArguments
//
function isArguments(obj) {
  return Object.prototype.toString.call(obj) === '[object Arguments]'
}

isArguments.displayName = 'isArguments'

// isBoolean
//
function isBoolean(obj) {
  return obj === true || obj === false
}

isBoolean.displayName = 'isBoolean'

// isFunction
//
function isFunction(obj) {
  return typeof obj === 'function'
}

isFunction.displayName = 'isFunction'

// isString
//
function isString(obj) {
  return typeof obj === 'string'
}

isString.displayName = 'isString'

// isNull
//
function isNull(obj) {
  return obj === null
}

isNull.displayName = 'isNull'

// isNumber
//
function isNumber(obj) {
  return typeof obj === 'number'
}

isNumber.displayName = 'isNumber'

// isObject
//
function isObject(obj) {
  return typeof obj === 'object' && obj !== null
}

isObject.displayName = 'isObject'

// isPojo
//
function isPojo(obj) {
  if (obj === null || !isObject(obj) || isArguments(obj)) {
    return false
  }
  return Object.getPrototypeOf(obj) === Object.prototype
}

isPojo.displayName = 'isPojo'

// isTemplateLiteral
//
function isTemplateLiteral(obj) {
  if (isString(obj)) {
    return true
  }
  if (!isArray(obj)) {
    return false
  }
  return obj.every(isString)
}

isTemplateLiteral.displayName = 'isTemplateLiteral'

// isThisValue
//
function isThisValue(value) {
  function inObject(obj) {
    return obj === value
  }
  inObject.displayName = `isThisValue(${value})`
  return inObject
}

//
// ArgTypeError
//

const typeErrorStringIfFnReturnsFalse = (argName, argTypeFn, arg) => {
  return argTypeFn(arg)
    ? undefined
    : (argTypeFn.displayName || argTypeFn.name) +
        `(${argName}) did not return true`
}

const typeErrorStringIfTypeOfFails = (argName, argType, arg) => {
  return typeof arg === argType
    ? undefined
    : `Argument "${argName}" should be a ${argType}`
}

const typeErrorStringFromArgument = argMap => (arg, index) => {
  if (index >= argMap.length) {
    return
  }

  const { argName, argType } = argMap[index]
  if (arg === undefined) {
    return `Argument undefined: "${argName}"`
  }

  const permittedArgTypes = Array.isArray(argType) ? argType : [argType]

  const errorDescs = permittedArgTypes
    .map(argType =>
      isFunction(argType)
        ? typeErrorStringIfFnReturnsFalse(argName, argType, arg)
        : typeErrorStringIfTypeOfFails(argName, argType, arg)
    )
    .filter(isString)

  const multipleTypesSpecified = permittedArgTypes.length > 1
  const shouldError = multipleTypesSpecified
    ? errorDescs.length > 1
    : errorDescs.length

  if (shouldError) {
    return (
      errorDescs.join('\n| ') +
      `\n> typeof ${argName} === ${typeof arg}(${JSON.stringify(arg)})`
    )
  }
}

/**
 * Helper for enforcing correct argument-types.
 *
 * @private
 * @param {string} namespace
 *
 * @example
 * const argTypeError = ArgTypeError('namespace#')
 *
 * function myFn (myArg1, myArg2) {
 *   const err = argTypeError({
 *     myArg1: isString,
 *     myArg2: isBoolean
 *   })('myFn')(myArg1, myArg2)
 *   if (err) {
 *     throw new TypeError(err)
 *   }
 * }
 */

function ArgTypeError(namespace) {
  return typeMap => {
    const argMap = Object.entries(typeMap).map(([argName, argType]) => ({
      argName,
      argType
    }))

    return fnName => (...args) => {
      const processedArgs = Array.from(args, x =>
        isArguments(x) ? Array.from(x) : x
      ).flat(1)

      const err = processedArgs
        .map(typeErrorStringFromArgument(argMap))
        .filter(isString)

      if (!err.length) {
        return
      }

      const signature = Object.keys(typeMap).join(', ')
      return (
        `\n${namespace || ''}${fnName}(${signature}):\n` +
        `${err.map(err => `| ${err}`).join('\n')}`
      )
    }
  }
}

function ObjTypeError(namespace) {
  return typeMap => {
    const keys = Object.keys(typeMap)
    const objTypeError = ArgTypeError(namespace)(typeMap)
    return fnName => obj => {
      const values = valuesOf(obj, { keys })
      const err = objTypeError(fnName)(...values)
      return err
    }
  }
}

function valuesOf(obj, options) {
  const { keys } = options
  if (!Array.isArray(keys)) {
    return Object.values(obj)
  }
  return keys.reduce((acc, key) => {
    return [...acc, obj[key]]
  }, [])
}
<|endoftext|>


<commit_before>var fs = require('fs'),
	path = require('path');
	var data = [];

for (var i = 0; i < 1000000; i++) {
	var item = {
		id: i,
		name: "name_" + Math.random(36),
		value: Math.random().toString(24)
	};
	data.push(item);
}
data = JSON.stringify(data, null, 4);
fs.writeFile(path.join(__dirname, 'test.json'), data, function (err) {
	if (err) throw err;
});
<commit_msg>adding commandline arguments to generating data<commit_after>var fs = require('fs'),
	args = require('minimist')(process.argv.slice(2)),
	path = require('path'),
	size = args.size || 1000000,
	filename = args.filename || 'test.json',
	data = [];

if (args.help) {
	console.log("command line options");
	console.log("--size: \t number of documents to generate.");
	console.log("\t\t defaults to `1000000`");
	console.log("");
	console.log("--filename: \t the file name of the JSON document that is generated. defaults to `test.json`");
	console.log("\t\t defaults to `test.json``");
	console.log("");
	console.log("example:");
	console.log("node generate-data.js --size 100 --filename foobar.json");
	console.log("");

	process.exit();
}

for (var i = 0; i < size; i++) {
	var item = {
		id: i,
		name: "name_" + Math.random(36),
		value: Math.random().toString(24)
	};
	data.push(item);
}
data = JSON.stringify(data, null, 4);
fs.writeFile(path.join(__dirname, filename), data, function (err) {
	if (err) throw err;
});
<|endoftext|>


<commit_before>function c(){this.a={}}c.prototype={get:function(a){return this.a[a]},add:function(a,b){this.a[a]=b;return this.a[a]},remove:function(a){var b;if(this.a[a]===void 0)return!1;b=this.a[a];delete this.a[a];return b},b:function(){var a,b,d;b=[];d=this.a;for(a in d)d.hasOwnProperty(a)&&b.push(a);return b},c:function(){var a,b,d,f,e;e=[];f=this.b();for(a=0;a<f.length;a+=1){d=!1;for(b=0;b<e.length;b+=1)if(this.get(f[a])===e[b]){d=!0;break}d||e.push(this.get(f[a]))}return e}};window.List=c;
c.prototype.get=c.prototype.get;c.prototype.add=c.prototype.add;c.prototype.remove=c.prototype.remove;c.prototype.keys=c.prototype.b;c.prototype.values=c.prototype.c;
<commit_msg>len() added<commit_after>function c(){this.a={}}
c.prototype={get:function(a){return this.a[a]},add:function(a,b){this.a[a]=b;return this.a[a]},remove:function(a){var b;if(this.a[a]===void 0)return!1;b=this.a[a];delete this.a[a];return b},b:function(){var a,b,d;b=[];d=this.a;for(a in d)d.hasOwnProperty(a)&&b.push(a);return b},d:function(){var a,b,d,f,e;e=[];f=this.b();for(a=0;a<f.length;a+=1){d=!1;for(b=0;b<e.length;b+=1)if(this.get(f[a])===e[b]){d=!0;break}d||e.push(this.get(f[a]))}return e},c:function(){var a,b;a=0;for(b in this.a)a+=1;return a}};
window.List=c;c.prototype.get=c.prototype.get;c.prototype.add=c.prototype.add;c.prototype.remove=c.prototype.remove;c.prototype.keys=c.prototype.b;c.prototype.values=c.prototype.d;c.prototype.len=c.prototype.c;
<|endoftext|>


<commit_before>/**
 * Client-side script for manipulating the debug panel on Rhymix.
 *
 * @file debug.js
 * @author Kijin Sung <kijin@kijinsung.com>
 */
$(function() {

	"use strict";

	// Find debug panel elements.
	var panel = $("#rhymix_debug_panel");
	var button = $("#rhymix_debug_button");

	// Initialize the debug button.
	var button_link = $('').text("DEBUG").appendTo(button).click(function(event) {
		event.preventDefault();
		var max_width = Math.min(540, $(window).width());
		panel.css({ width: max_width, left: max_width * -1 }).show().animate({ left: 0 }, 200);
		button.hide();
	});

	// Initialize the debug panel.
	var header = $('

').appendTo(panel);
	header.append('
RHYMIX DEBUG
');
	header.append($('+').click(function(event) {
		panel.animate({ width: "100%" }, 300);
	}));
	header.append($('×').click(function(event) {
		event.preventDefault();
		panel.animate({ left: panel.width() * -1 }, 200, function() {
			panel.hide();
			button.show();
		});
	}));

	// Define a function for adding debug data to the panel.
	window.rhymix_debug_add_data = function(data, open) {

		// Define loop variables.
		var i, j, entry, num, backtrace, description;

		// New pages are open by default.
		if (open !== true && open !== false)
		{
			open = true;
		}

		// Create the page.
		var page = $('

').appendTo(panel);
		var page_body = $('

').appendTo(page);
		if (!open)
		{
			page_body.hide();
		}

		// Create the page header.
		var page_header = $('

').prependTo(page).click(function() {
			$(this).find("a.debug_page_collapse").triggerHandler("click");
		});
		page_header.append($('

').text(data.page_title).attr("title", data.url));
		page_header.append($('').text(open ? "▲" : "▼").click(function(event) {
			event.preventDefault();
			event.stopPropagation();
			if (page_body.is(":visible")) {
				page_body.slideUp(200);
				$(this).text("▼");
			} else {
				page_body.slideDown(200);
				$(this).text("▲");
			}
		}));

		// Add general information.
		page_body.append($('

').text('General Information'));
		entry = $('

').appendTo(page_body);
		var metadata = $('

').appendTo(entry);
		metadata.append($('

').text('Request: ' + data.request.method + (data.request.method !== "GET" ? (' - ' + data.request.size + ' bytes') : "")));
		metadata.append($('

').text('Response: ' + data.response.method + ' - ' + data.response.size + ' bytes'));
		metadata.append($('

').text('Total Time: ' + data.timing.total));
		metadata.append($('

').text('Query Time: ' + data.timing.db_query));

		// Add debug entries.
		if (data.entries && data.entries.length) {
			page_body.append($('

').text('Debug Entries (' + data.entries.length + ')'));
			for (i in data.entries) {
				entry = $('

').appendTo(page_body);
				num = parseInt(i) + 1; if (num < 10) num = "0" + num;
				entry.text(num + ". " + data.entries[i].message);
				backtrace = $('

').appendTo(entry);
				for (j in data.entries[i].backtrace) {
					if (data.entries[i].backtrace[j].file) {
						backtrace.append($('

').text(data.entries[i].backtrace[j].file + ":" + data.entries[i].backtrace[j].line));
					}
				}
			}
		}

		// Add errors.
		if (data.errors && data.errors.length) {
			page_body.append($('

').text('Errors (' + data.errors.length + ')'));
			for (i in data.errors) {
				entry = $('

').appendTo(page_body);
				num = parseInt(i) + 1; if (num < 10) num = "0" + num;
				entry.text(num + ". " + data.errors[i].type + ": " + data.errors[i].message);
				backtrace = $('

').appendTo(entry);
				for (j in data.errors[i].backtrace) {
					if (data.errors[i].backtrace[j].file) {
						backtrace.append($('

').text(data.errors[i].backtrace[j].file + ":" + data.errors[i].backtrace[j].line));
					}
				}
			}
		}

		// Add queries.
		if (data.queries && data.queries.length) {
			page_body.append($('

').text('Queries (' + data.queries.length + ')'));
			for (i in data.queries) {
				entry = $('

').appendTo(page_body);
				num = parseInt(i) + 1; if (num < 10) num = "0" + num;
				entry.text(num + ". " + data.queries[i].query_string);
				description = $('

').appendTo(entry);
				if (data.queries[i].file && data.queries[i].line) {
					description.append($('

').text("Caller: " + data.queries[i].file + ":" + data.queries[i].line).append("
(" + data.queries[i].method + ")"));
					description.append($('

').text("Connection: " + data.queries[i].query_connection));
					description.append($('

').text("Query ID: " + data.queries[i].query_id));
					description.append($('

').text("Query Time: " + (data.queries[i].query_time ? (data.queries[i].query_time.toFixed(4) + " sec") : "")));
				}
				description.append($('

').text("Result: " + ((data.queries[i].message === "success" || !data.queries[i].message) ? "success" : ("error " + data.queries[i].error_code + " " + data.queries[i].message))));
			}
		}

		// If there are errors, turn the button text red.

		if (data.errors && data.errors.length) {
			button_link.addClass("has_errors");
		}
	};

	// Add debug data from the previous request.
	if (window.rhymix_debug_previous) {
		window.rhymix_debug_previous.page_title = 'PREVIOUS POST : ' + window.rhymix_debug_previous.ajax_module + "." + window.rhymix_debug_previous.ajax_act;
		rhymix_debug_add_data(window.rhymix_debug_previous, false);
	}

	// Add debug data from the current request.
	if (window.rhymix_debug_content) {
		window.rhymix_debug_content.page_title = 'MAIN PAGE';
		rhymix_debug_add_data(window.rhymix_debug_content, true);
	}

	// Add debug data from pending AJAX requests.
	if (window.rhymix_debug_pending_data) {
		while (window.rhymix_debug_pending_data.length) {
			rhymix_debug_add_data(window.rhymix_debug_pending_data.shift());
		}
	}
});
<commit_msg>Add slow queries, triggers, and widgets to debug panel output<commit_after>/**
 * Client-side script for manipulating the debug panel on Rhymix.
 *
 * @file debug.js
 * @author Kijin Sung <kijin@kijinsung.com>
 */
$(function() {

	"use strict";

	// Find debug panel elements.
	var panel = $("#rhymix_debug_panel");
	var button = $("#rhymix_debug_button");

	// Initialize the debug button.
	var button_link = $('').text("DEBUG").appendTo(button).click(function(event) {
		event.preventDefault();
		var max_width = Math.min(540, $(window).width());
		panel.css({ width: max_width, left: max_width * -1 }).show().animate({ left: 0 }, 200);
		button.hide();
	});

	// Initialize the debug panel.
	var header = $('

').appendTo(panel);
	header.append('
RHYMIX DEBUG
');
	header.append($('+').click(function(event) {
		panel.animate({ width: "100%" }, 300);
	}));
	header.append($('×').click(function(event) {
		event.preventDefault();
		panel.animate({ left: panel.width() * -1 }, 200, function() {
			panel.hide();
			button.show();
		});
	}));

	// Define a function for adding debug data to the panel.
	window.rhymix_debug_add_data = function(data, open) {

		// Define loop variables.
		var i, j, entry, num, backtrace, description;

		// New pages are open by default.
		if (open !== true && open !== false)
		{
			open = true;
		}

		// Create the page.
		var page = $('

').appendTo(panel);
		var page_body = $('

').appendTo(page);
		if (!open)
		{
			page_body.hide();
		}

		// Create the page header.
		var page_header = $('

').prependTo(page).click(function() {
			$(this).find("a.debug_page_collapse").triggerHandler("click");
		});
		page_header.append($('

').text(data.page_title).attr("title", data.url));
		page_header.append($('').text(open ? "▲" : "▼").click(function(event) {
			event.preventDefault();
			event.stopPropagation();
			if (page_body.is(":visible")) {
				page_body.slideUp(200);
				$(this).text("▼");
			} else {
				page_body.slideDown(200);
				$(this).text("▲");
			}
		}));

		// Add general information.
		page_body.append($('

').text('General Information'));
		entry = $('

').appendTo(page_body);
		var metadata = $('

').appendTo(entry);
		metadata.append($('

').text('Request: ' + data.request.method + (data.request.method !== "GET" ? (' - ' + data.request.size + ' bytes') : "")));
		metadata.append($('

').text('Response: ' + data.response.method + ' - ' + data.response.size + ' bytes'));
		metadata.append($('

').text('Total Time: ' + data.timing.total));
		metadata.append($('

').text('Query Time: ' + data.timing.db_query));

		// Add debug entries.
		if (data.entries && data.entries.length) {
			page_body.append($('

').text('Debug Entries (' + data.entries.length + ')'));
			for (i in data.entries) {
				entry = $('

').appendTo(page_body);
				num = parseInt(i) + 1; if (num < 10) num = "0" + num;
				entry.text(num + ". " + data.entries[i].message);
				backtrace = $('

').appendTo(entry);
				for (j in data.entries[i].backtrace) {
					if (data.entries[i].backtrace[j].file) {
						backtrace.append($('

').text(data.entries[i].backtrace[j].file + ":" + data.entries[i].backtrace[j].line));
					}
				}
			}
		}

		// Add errors.
		if (data.errors && data.errors.length) {
			page_body.append($('

').text('Errors (' + data.errors.length + ')'));
			for (i in data.errors) {
				entry = $('

').appendTo(page_body);
				num = parseInt(i) + 1; if (num < 10) num = "0" + num;
				entry.text(num + ". " + data.errors[i].type + ": " + data.errors[i].message);
				backtrace = $('

').appendTo(entry);
				for (j in data.errors[i].backtrace) {
					if (data.errors[i].backtrace[j].file) {
						backtrace.append($('

').text(data.errors[i].backtrace[j].file + ":" + data.errors[i].backtrace[j].line));
					}
				}
			}
		}

		// Add queries.
		if (data.queries && data.queries.length) {
			page_body.append($('

').text('Queries (' + data.queries.length + ')'));
			for (i in data.queries) {
				entry = $('

').appendTo(page_body);
				num = parseInt(i) + 1; if (num < 10) num = "0" + num;
				entry.text(num + ". " + data.queries[i].query_string);
				description = $('

').appendTo(entry);
				if (data.queries[i].file && data.queries[i].line) {
					description.append($('

').text("Caller: " + data.queries[i].file + ":" + data.queries[i].line).append("
(" + data.queries[i].method + ")"));
					description.append($('

').text("Connection: " + data.queries[i].query_connection));
					description.append($('

').text("Query ID: " + data.queries[i].query_id));
					description.append($('

').text("Query Time: " + (data.queries[i].query_time ? (data.queries[i].query_time.toFixed(4) + " sec") : "")));
				}
				description.append($('

').text("Result: " + ((data.queries[i].message === "success" || !data.queries[i].message) ? "success" : ("error " + data.queries[i].error_code + " " + data.queries[i].message))));
			}
		}

		// Add slow queries.
		if (data.slow_queries && data.slow_queries.length) {
			page_body.append($('

').text('Slow Queries (' + data.slow_queries.length + ')'));
			for (i in data.slow_queries) {
				entry = $('

').appendTo(page_body);
				num = parseInt(i) + 1; if (num < 10) num = "0" + num;
				entry.text(num + ". " + data.slow_queries[i].query_string);
				description = $('

').appendTo(entry);
				if (data.slow_queries[i].file && data.slow_queries[i].line) {
					description.append($('

').text("Caller: " + data.slow_queries[i].file + ":" + data.slow_queries[i].line).append("
(" + data.slow_queries[i].method + ")"));
					description.append($('

').text("Connection: " + data.slow_queries[i].query_connection));
					description.append($('

').text("Query ID: " + data.slow_queries[i].query_id));
					description.append($('

').text("Query Time: " + (data.slow_queries[i].query_time ? (data.slow_queries[i].query_time.toFixed(4) + " sec") : "")));
				}
				description.append($('

').text("Result: " + ((data.slow_queries[i].message === "success" || !data.slow_queries[i].message) ? "success" : ("error " + data.slow_queries[i].error_code + " " + data.slow_queries[i].message))));
			}
		}

		// Add slow triggers.
		if (data.slow_triggers && data.slow_triggers.length) {
			page_body.append($('

').text('Slow Triggers (' + data.slow_triggers.length + ')'));
			for (i in data.slow_triggers) {
				entry = $('

').appendTo(page_body);
				num = parseInt(i) + 1; if (num < 10) num = "0" + num;
				entry.text(num + ". " + data.slow_triggers[i].trigger_name);
				description = $('

').appendTo(entry);
				description.append($('

').text("Target: " + data.slow_triggers[i].trigger_target));
				description.append($('

').text("Exec Time: " + (data.slow_triggers[i].trigger_time ? (data.slow_triggers[i].trigger_time.toFixed(4) + " sec") : "")));
			}
		}

		// Add slow widgets.
		if (data.slow_widgets && data.slow_widgets.length) {
			page_body.append($('

').text('Slow Widgets (' + data.slow_widgets.length + ')'));
			for (i in data.slow_widgets) {
				entry = $('

').appendTo(page_body);
				num = parseInt(i) + 1; if (num < 10) num = "0" + num;
				entry.text(num + ". " + data.slow_widgets[i].widget_name);
				description = $('

').appendTo(entry);
				description.append($('

').text("Exec Time: " + (data.slow_widgets[i].widget_time ? (data.slow_widgets[i].widget_time.toFixed(4) + " sec") : "")));
			}
		}

		// If there are errors, turn the button text red.
		if (data.errors && data.errors.length) {
			button_link.addClass("has_errors");
		}
	};

	// Add debug data from the previous request.
	if (window.rhymix_debug_previous) {
		window.rhymix_debug_previous.page_title = 'PREVIOUS POST : ' + window.rhymix_debug_previous.ajax_module + "." + window.rhymix_debug_previous.ajax_act;
		rhymix_debug_add_data(window.rhymix_debug_previous, false);
	}

	// Add debug data from the current request.
	if (window.rhymix_debug_content) {
		window.rhymix_debug_content.page_title = 'MAIN PAGE';
		rhymix_debug_add_data(window.rhymix_debug_content, true);
	}

	// Add debug data from pending AJAX requests.
	if (window.rhymix_debug_pending_data) {
		while (window.rhymix_debug_pending_data.length) {
			rhymix_debug_add_data(window.rhymix_debug_pending_data.shift());
		}
	}
});
<|endoftext|>


<commit_before>define([
	'./aspect',
	'./async',
	'./compose',
	'../has!host-browser?./dom',
	'./global',
	'./has',
	'./io-query',
	'./lang',
	'./properties',
	'./on',
	'./request',
	'./CallbackQueue',
	// './Deferred', // remove temporarily
	'./Evented',
	'./Promise',
	'./Registry',
	'./SideTable'
], 1);<commit_msg>Update core/tests/unit<commit_after>define([
	'./aspect',
	'./async',
	'./compose',
	'../has!host-browser?./dom',
	'./global',
	'./has',
	'./io-query',
	'./lang',
	'./properties',
	'./on',
	'./request',
	'./stores',
	'./CallbackQueue',
	// './Deferred', // remove temporarily
	'./Evented',
	'./Promise',
	'./Registry',
	'./SideTable'
], 1);<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

const program = require('commander');
const util = require('util');

const pkg = require('./../package.json');
const miteApi = require('mite-api');
const config = require('./config');
const commandOptions = require('./lib/options');
const { handleError, MissingRequiredArgumentError } = require('./lib/errors');

program
  .version(pkg.version)
  .description(
    `Creates a new project while using the given argument parameters \
as starting values. Note that some users are not able to create new projects.`
  )
  .option.apply(program, commandOptions.toArgs(commandOptions.archived, 'Defines the archived state'))
  .option.apply(program, commandOptions.toArgs(commandOptions.budget, null, 'hours'))
  .option.apply(program, commandOptions.toArgs(commandOptions.budgetType))
  .option(
    '--customer-id <customerId>',
    'Optional id of the customer this project should belong to.'
  )
  .option.apply(program, commandOptions.toArgs(commandOptions.hourlyRate))
  .option(
    '--name <name>',
    'Required name of the project'
  )
  .option(
    '--note <note>',
    'Optional Note of the project',
  )
  .on('--help', () => console.log(`
Examples:

  Create a new project with a overall budget of 5000:
    mite project new --customer-id 123456 \
--name "Side Project B" \
--hourly-rate 80.00 \
--budget 5000 \
--budget-type cents
`));

function main(name) {
  if (typeof name !== 'string' || !name) {
    throw new MissingRequiredArgumentError('Missing or empty required option --name <name>');
  }

  const data = {
    ...(typeof program.archived === 'boolean' && { archived: program.archived }),
    ...(program.budgetType && { budget_type: program.budgetType }),
    ...(program.budget && { budget: program.budget }),
    ...(program.customerId && { 'customer_id': program.customerId }),
    ...(typeof program.hourlyRate === 'number' && { hourly_rate: program.hourlyRate }),
    ...(typeof name === 'string' && { name: name }),
    ...(typeof program.note === 'string' && { note: program.note })
  };

  const mite = miteApi(config.get());
  return util.promisify(mite.addProject)(data)
    .then(body => {
      const projectId = body.project.id;
      console.log(`Successfully created project (id: ${projectId}).

Please use web-interface to modify complicated service & hourly rates settings:
https://${config.get('account')}.mite.yo.lk/reports/projects/${projectId}`);
    });
}

try {
  program.parse(process.argv);
  main(program.name).catch(handleError);
} catch (err) {
  handleError(err);
}
<commit_msg>fix(project-new): correct default for budgetType<commit_after>#!/usr/bin/env node
'use strict';

const program = require('commander');
const util = require('util');

const pkg = require('./../package.json');
const miteApi = require('mite-api');
const config = require('./config');
const commandOptions = require('./lib/options');
const { handleError, MissingRequiredArgumentError } = require('./lib/errors');

program
  .version(pkg.version)
  .description(
    `Creates a new project while using the given argument parameters \
as starting values. Note that some users are not able to create new projects.`
  )
  .option.apply(program, commandOptions.toArgs(commandOptions.archived, 'Defines the archived state'))
  .option.apply(program, commandOptions.toArgs(commandOptions.budget))
  .option.apply(program, commandOptions.toArgs(commandOptions.budgetType, null, 'minutes'))
  .option(
    '--customer-id <customerId>',
    'Optional id of the customer this project should belong to.'
  )
  .option.apply(program, commandOptions.toArgs(commandOptions.hourlyRate))
  .option(
    '--name <name>',
    'Required name of the project'
  )
  .option(
    '--note <note>',
    'Optional Note of the project',
  )
  .on('--help', () => console.log(`
Examples:

  Create a new project with a overall budget of 5000:
    mite project new --customer-id 123456 \
--name "Side Project B" \
--hourly-rate 80.00 \
--budget 5000 \
--budget-type cents
`));

function main(name) {
  if (typeof name !== 'string' || !name) {
    throw new MissingRequiredArgumentError('Missing or empty required option --name <name>');
  }

  const data = {
    ...(typeof program.archived === 'boolean' && { archived: program.archived }),
    ...(program.budgetType && { budget_type: program.budgetType }),
    ...(program.budget && { budget: program.budget }),
    ...(program.customerId && { 'customer_id': program.customerId }),
    ...(typeof program.hourlyRate === 'number' && { hourly_rate: program.hourlyRate }),
    ...(typeof name === 'string' && { name: name }),
    ...(typeof program.note === 'string' && { note: program.note })
  };

  console.log(data);

  const mite = miteApi(config.get());
  return util.promisify(mite.addProject)(data)
    .then(body => {
      const projectId = body.project.id;
      console.log(`Successfully created project (id: ${projectId}).

Please use web-interface to modify complicated service & hourly rates settings:
https://${config.get('account')}.mite.yo.lk/reports/projects/${projectId}`);
    });
}

try {
  program.parse(process.argv);
  main(program.name).catch(handleError);
} catch (err) {
  handleError(err);
}
<|endoftext|>


<commit_before>(function () {
    'use strict';
    /**
     * 'Share' widget for GNU social
     * http://code.chromic.org/project/view/2/
     *
     * We make a few assumptions about the target instance:
     *   1) The API root is in the default location
     *   2) Fancy URLs are enabled
     *   3) CORS is allowed
     *   4) The Bookmark plugin is enabled
     *
     * If 1), 3) or 4) are wrong, we fall back to a regular
     * notice (instead of a bookmark notice)
     *
     * If 2) is wrong the user will be directed to a 404 :(
     */

    // TODO: input sanitation [1], [2]
    // TODO: server-side fallback if JS is disabled

    var createForm,
        bindClicks,
        frm,
        shareAsNotice,
        shareAsBookmark,
        extractURLParams,
        shareURL,
        shareTitle;

    shareAsNotice = function (title, url, domain) {
        window.location.href = 'http://' + domain + '/notice/new?status_textarea=' + title + ' ' + url; // [1]
    };

    shareAsBookmark = function (title, url, domain) {
        window.location.href = 'http://' + domain + '/main/bookmark/new?url=' + url + '&title=' + title; // [2]
    };

    extractURLParams = function (queryStr) {
        var parts = queryStr.substr(1).split('&'),
            i, len, keyVal, params = {};

        for (i = 0, len = parts.length; i < len; i += 1) {
            keyVal = parts[i].split('=');
            params[keyVal[0]] = keyVal[1];
        }

        return params;
    };

    // Create the form that we'll re-use throughout the page
    createForm = function () {
        var err = document.createElement('div');
        err.setAttribute('class', 'gs-share-err');
        err.setAttribute('tabindex', '-1');
        err.textContent = 'The account id provided is invalid';

        frm = document.createElement('form');

        frm.setAttribute('class', 'gs-share-form');
        frm.setAttribute('tabindex', '-1');
        frm.setAttribute('aria-hidden', 'true');

        frm.innerHTML = 'Your account ID:' +
            '<input type="text" id="gs-account" placeholder="user@example.org" />
' +
            '<input type="checkbox" checked id="gs-bookmark" /> Share as a bookmark
' +
            '<input type="submit" />';
        frm.insertBefore(err, frm.firstChild);

        // Submit handler
        frm.addEventListener('submit', function (e) {
            e.preventDefault();

            var accountParts = document.getElementById('gs-account').value.split('@'),
                username, domain, xhr, bookmarkURL;

            if (accountParts.length === 2) {
                err.setAttribute('aria-hidden', 'true');

                username = accountParts[0];
                domain = accountParts[1];
                bookmarkURL = 'http://' + domain + '/api/bookmarks/' + username + '.json';

                // Try bookmark
                if (document.getElementById('gs-bookmark').checked) {
                    xhr = new XMLHttpRequest();

                    xhr.onreadystatechange = function () {
                        if (xhr.readyState === 4) {
                            if (xhr.status === 200) { // Success
                                shareAsBookmark(shareTitle, shareURL, domain);
                            } else { // Failure, fallback to regular notice
                                shareAsNotice(shareTitle, shareURL, domain);
                            }
                        }
                    };

                    xhr.open('GET', bookmarkURL, true);
                    xhr.send();
                } else { // Regular notice
                    shareAsNotice(shareTitle, shareURL, domain);
                }
            } else { // Invalid account id
                err.setAttribute('aria-hidden', 'false');
                err.focus();
            }
        });

        // Keydown handler
        frm.addEventListener('keydown', function (e) {
            if (e.keyCode === 27) { // Escape key closes the dialog
                frm.parentElement.getElementsByClassName('js-gs-share')[0].focus();
                frm.setAttribute('aria-hidden', 'true');
            }
        });

        document.body.appendChild(frm);
    };

    bindClicks = function () {
        document.addEventListener('click', function (e) {
            var target = e.target,
                urlParams;

            // Don't do anything on right/middle click or if ctrl or shift was pressed while left-clicking
            if (!e.button && !e.ctrlKey && !e.shiftKey) {
                if (target.className.match(/js-gs-share/)) {
                    e.preventDefault();

                    // Check for submission information in href first
                    if (target.search !== undefined) {
                        urlParams = extractURLParams(target.search);
                        shareURL   = urlParams.url;
                        shareTitle = urlParams.title;
                    } else { // If it's not there, try data-* attributes. If not, use current document url and title
                        shareURL   = target.getAttribute('data-url') || window.location.href;
                        shareTitle = target.getAttribute('data-title') || document.title;
                    }

                    // Move form after the clicked link
                    target.parentNode.appendChild(frm);

                    // Show form
                    frm.setAttribute('aria-hidden', 'false');

                    // Focus on form
                    frm.focus();
                }
            }
        });
    };

    createForm();
    bindClicks();
}());
<commit_msg>Clicking outside the popup closes it<commit_after>(function () {
    'use strict';
    /**
     * 'Share' widget for GNU social
     * http://code.chromic.org/project/view/2/
     *
     * We make a few assumptions about the target instance:
     *   1) The API root is in the default location
     *   2) Fancy URLs are enabled
     *   3) CORS is allowed
     *   4) The Bookmark plugin is enabled
     *
     * If 1), 3) or 4) are wrong, we fall back to a regular
     * notice (instead of a bookmark notice)
     *
     * If 2) is wrong the user will be directed to a 404 :(
     */

    // TODO: input sanitation [1], [2]
    // TODO: server-side fallback if JS is disabled

    var createForm,
        bindClicks,
        frm,
        shareAsNotice,
        shareAsBookmark,
        extractURLParams,
        shareURL,
        shareTitle;

    shareAsNotice = function (title, url, domain) {
        window.location.href = 'http://' + domain + '/notice/new?status_textarea=' + title + ' ' + url; // [1]
    };

    shareAsBookmark = function (title, url, domain) {
        window.location.href = 'http://' + domain + '/main/bookmark/new?url=' + url + '&title=' + title; // [2]
    };

    extractURLParams = function (queryStr) {
        var parts = queryStr.substr(1).split('&'),
            i, len, keyVal, params = {};

        for (i = 0, len = parts.length; i < len; i += 1) {
            keyVal = parts[i].split('=');
            params[keyVal[0]] = keyVal[1];
        }

        return params;
    };

    // Create the form that we'll re-use throughout the page
    createForm = function () {
        var err = document.createElement('div');
        err.setAttribute('class', 'gs-share-err');
        err.setAttribute('tabindex', '-1');
        err.textContent = 'The account id provided is invalid';

        frm = document.createElement('form');

        frm.setAttribute('class', 'gs-share-form');
        frm.setAttribute('tabindex', '-1');
        frm.setAttribute('aria-hidden', 'true');

        frm.innerHTML = 'Your account ID:' +
            '<input type="text" id="gs-account" placeholder="user@example.org" />
' +
            '<input type="checkbox" checked id="gs-bookmark" /> Share as a bookmark
' +
            '<input type="submit" />';
        frm.insertBefore(err, frm.firstChild);

        // Submit handler
        frm.addEventListener('submit', function (e) {
            e.preventDefault();

            var accountParts = document.getElementById('gs-account').value.split('@'),
                username, domain, xhr, bookmarkURL;

            if (accountParts.length === 2) {
                err.setAttribute('aria-hidden', 'true');

                username = accountParts[0];
                domain = accountParts[1];
                bookmarkURL = 'http://' + domain + '/api/bookmarks/' + username + '.json';

                // Try bookmark
                if (document.getElementById('gs-bookmark').checked) {
                    xhr = new XMLHttpRequest();

                    xhr.onreadystatechange = function () {
                        if (xhr.readyState === 4) {
                            if (xhr.status === 200) { // Success
                                shareAsBookmark(shareTitle, shareURL, domain);
                            } else { // Failure, fallback to regular notice
                                shareAsNotice(shareTitle, shareURL, domain);
                            }
                        }
                    };

                    xhr.open('GET', bookmarkURL, true);
                    xhr.send();
                } else { // Regular notice
                    shareAsNotice(shareTitle, shareURL, domain);
                }
            } else { // Invalid account id
                err.setAttribute('aria-hidden', 'false');
                err.focus();
            }
        });

        // Keydown handler
        frm.addEventListener('keydown', function (e) {
            if (e.keyCode === 27) { // Escape key closes the dialog
                frm.parentElement.getElementsByClassName('js-gs-share')[0].focus();
                frm.setAttribute('aria-hidden', 'true');
            }
        });

        document.body.appendChild(frm);
    };

    bindClicks = function () {
        document.addEventListener('click', function (e) {
            var target = e.target,
                urlParams;

            // Don't do anything on right/middle click or if ctrl or shift was pressed while left-clicking
            if (!e.button && !e.ctrlKey && !e.shiftKey) {
                if (target.className.match(/js-gs-share/)) {
                    e.preventDefault();

                    // Check for submission information in href first
                    if (target.search !== undefined) {
                        urlParams = extractURLParams(target.search);
                        shareURL   = urlParams.url;
                        shareTitle = urlParams.title;
                    } else { // If it's not there, try data-* attributes. If not, use current document url and title
                        shareURL   = target.getAttribute('data-url') || window.location.href;
                        shareTitle = target.getAttribute('data-title') || document.title;
                    }

                    // Move form after the clicked link
                    target.parentNode.appendChild(frm);

                    // Show form
                    frm.setAttribute('aria-hidden', 'false');

                    // Focus on form
                    frm.focus();
                } else if (!frm.contains(target)) {
                    frm.setAttribute('aria-hidden', 'true');
                }
            }
        });
    };

    createForm();
    bindClicks();
}());
<|endoftext|>


<commit_before>// ==UserScript==
// @name        GitHub Code Colors
// @version     1.2.0
// @description A userscript that adds a color swatch next to the code color definition
// @license     MIT
// @author      Rob Garrison
// @namespace   https://github.com/Mottie
// @include     https://github.com/*
// @run-at      document-idle
// @grant       GM.addStyle
// @grant       GM_addStyle
// @require     https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?updated=20180103
// @require     https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=597950
// @icon        https://assets-cdn.github.com/pinned-octocat.svg
// @updateURL   https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-code-colors.user.js
// @downloadURL https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-code-colors.user.js
// ==/UserScript==
(() => {
	"use strict";

	GM.addStyle(`
		.ghcc-block { width:12px; height:12px; display:inline-block;
			vertical-align:middle; margin-right:4px; border-radius:3px;
			border:1px solid rgba(119, 119, 119, 0.5); }
	`);

	const namedColors = [
		"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
		"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
		"burlywood", "cadetblue", "chartreuse", "chocolate", "coral",
		"cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
		"darkgoldenrod", "darkgray", "darkgrey", "darkgreen", "darkkhaki",
		"darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred",
		"darksalmon", "darkseagreen", "darkslateblue", "darkslategray",
		"darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue",
		"dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite",
		"forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod",
		"gray", "grey", "green", "greenyellow", "honeydew", "hotpink",
		"indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush",
		"lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan",
		"lightgoldenrodyellow", "lightgray", "lightgrey", "lightgreen",
		"lightpink", "lightsalmon", "lightseagreen", "lightskyblue",
		"lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
		"lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine",
		"mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
		"mediumslateblue", "mediumspringgreen", "mediumturquoise",
		"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
		"navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange",
		"orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise",
		"palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum",
		"powderblue", "purple", "rebeccapurple", "red", "rosybrown", "royalblue",
		"saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna",
		"silver", "skyblue", "slateblue", "slategray", "slategrey", "snow",
		"springgreen", "steelblue", "tan", "teal", "thistle", "tomato",
		"turquoise", "violet", "wheat", "white", "whitesmoke", "yellow",
		"yellowgreen"
	].join("|");

	const regexNamed = new RegExp("^(" + namedColors + ")$", "i");
	// Ex: #123, #123456 or 0x123456 (unix style colors, used by three.js)
	const regexHex = /^(#|0x)([0-9A-F]{6,8}|[0-9A-F]{3,4})$/i;
	// Ex: rgb(0,0,0) or rgba(0,0,0,0.2)
	const regexRGB = /^rgba?(\([^\)]+\))?/i;
	const regexRGBA = /rgba/i;
	// Ex: hsl(0,0%,0%) or hsla(0,0%,0%,0.2);
	const regexHSL = /^hsla?(\([^\)]+\))?/i;

	// Misc regex
	const regexQuotes = /['"]/g;
	const regexUnix = /^0x/;
	const regexPercent = /%%/g;

	// Don't use a div, because GitHub-Dark adds a :hover background
	// color definition on divs
	const block = document.createElement("span");
	block.className = "ghcc-block";

	function addNode(el, val) {
		const node = block.cloneNode();
		node.style.backgroundColor = val;
		// Don't add node if color is invalid
		if (node.style.backgroundColor !== "") {
			el.insertBefore(node, el.childNodes[0]);
		}
	}

	function getTextContent(el) {
		return el ? el.textContent : "";
	}

	function rgb(els, el, txt) {
		// Color in a string contains everything
		if (el.classList.contains("pl-s")) {
			txt = txt.match(regexRGB)[0];
		} else {
			// Rgb(a) colors contained in multiple "pl-c1" spans
			let indx = regexRGBA.test(txt) ? 4 : 3;
			const tmp = [];
			while (indx) {
				tmp.push(getTextContent(els.shift()));
				indx--;
			}
			txt += "(" + tmp.join(",") + ")";
		}
		addNode(el, txt);
		return els;
	}

	function hsl(els, el, txt) {
		const tmp = /a$/i.test(txt);
		if (el.classList.contains("pl-s")) {
			// Color in a string contains everything
			txt = txt.match(regexHSL)[0];
		} else {
			// Traverse this HTML... & els only contains the pl-c1 nodes
			// hsl(1,
			// 1%,
			// 1%);
			// using getTextContent in case of invalid css
			txt = txt + "(" + getTextContent(els.shift()) + "," +
				getTextContent(els.shift()) + "%," +
				// Hsla needs one more parameter
				getTextContent(els.shift()) + "%" +
				(tmp ? "," + getTextContent(els.shift()) : "") + ")";
		}
		// Sometimes (previews only?) the .pl-k span is nested inside
		// the .pl-c1 span, so we end up with "%%"
		addNode(el, txt.replace(regexPercent, "%"));
		return els;
	}

	// Loop with delay to allow user interaction
	function* addBlock(els) {
		while (els.length) {
			let el = els.shift();
			let txt = el.textContent;
			if (el.parentNode.classList.contains("pl-c1")) {
				// Ignore nested pl-c1 (see https://git.io/vFx8y)
			} else if (!el.querySelector(".ghcc-block")) {
				if (el.classList.contains("pl-s")) {
					txt = txt.replace(regexQuotes, "");
				}
				if (regexHex.test(txt) || regexNamed.test(txt)) {
					addNode(el, txt.replace(regexUnix, "#"));
				} else if (regexRGB.test(txt)) {
					els = rgb(els, el, txt);
				} else if (regexHSL.test(txt)) {
					els = hsl(els, el, txt);
				}
			}
			yield els;
		}
	}

	function addColors() {
		if (document.querySelector(".highlight")) {
			let status;
			// .pl-c1 targets css hex colors, "rgb" and "hsl"
			const els = [...document.querySelectorAll(".pl-c1, .pl-s")];
			const iter = addBlock(els);
			const loop = () => {
				for (let i = 0; i < 40; i++) {
					status = iter.next();
				}
				if (!status.done) {
					requestAnimationFrame(loop);
				}
			};
			loop();
		}
	}
	document.addEventListener("ghmo:container", addColors);
	document.addEventListener("ghmo:preview", addColors);
	addColors();

})();
<commit_msg>Code-color: Fix JS error<commit_after>// ==UserScript==
// @name        GitHub Code Colors
// @version     1.2.1
// @description A userscript that adds a color swatch next to the code color definition
// @license     MIT
// @author      Rob Garrison
// @namespace   https://github.com/Mottie
// @include     https://github.com/*
// @run-at      document-idle
// @grant       GM.addStyle
// @grant       GM_addStyle
// @require     https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?updated=20180103
// @require     https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=597950
// @icon        https://assets-cdn.github.com/pinned-octocat.svg
// @updateURL   https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-code-colors.user.js
// @downloadURL https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-code-colors.user.js
// ==/UserScript==
(() => {
	"use strict";

	GM.addStyle(`
		.ghcc-block { width:12px; height:12px; display:inline-block;
			vertical-align:middle; margin-right:4px; border-radius:3px;
			border:1px solid rgba(119, 119, 119, 0.5); }
	`);

	const namedColors = [
		"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
		"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
		"burlywood", "cadetblue", "chartreuse", "chocolate", "coral",
		"cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
		"darkgoldenrod", "darkgray", "darkgrey", "darkgreen", "darkkhaki",
		"darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred",
		"darksalmon", "darkseagreen", "darkslateblue", "darkslategray",
		"darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue",
		"dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite",
		"forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod",
		"gray", "grey", "green", "greenyellow", "honeydew", "hotpink",
		"indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush",
		"lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan",
		"lightgoldenrodyellow", "lightgray", "lightgrey", "lightgreen",
		"lightpink", "lightsalmon", "lightseagreen", "lightskyblue",
		"lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
		"lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine",
		"mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
		"mediumslateblue", "mediumspringgreen", "mediumturquoise",
		"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
		"navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange",
		"orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise",
		"palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum",
		"powderblue", "purple", "rebeccapurple", "red", "rosybrown", "royalblue",
		"saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna",
		"silver", "skyblue", "slateblue", "slategray", "slategrey", "snow",
		"springgreen", "steelblue", "tan", "teal", "thistle", "tomato",
		"turquoise", "violet", "wheat", "white", "whitesmoke", "yellow",
		"yellowgreen"
	].join("|");

	const regexNamed = new RegExp("^(" + namedColors + ")$", "i");
	// Ex: #123, #123456 or 0x123456 (unix style colors, used by three.js)
	const regexHex = /^(#|0x)([0-9A-F]{6,8}|[0-9A-F]{3,4})$/i;
	// Ex: rgb(0,0,0) or rgba(0,0,0,0.2)
	const regexRGB = /^rgba?(\([^\)]+\))?/i;
	const regexRGBA = /rgba/i;
	// Ex: hsl(0,0%,0%) or hsla(0,0%,0%,0.2);
	const regexHSL = /^hsla?(\([^\)]+\))?/i;

	// Misc regex
	const regexQuotes = /['"]/g;
	const regexUnix = /^0x/;
	const regexPercent = /%%/g;

	// Don't use a div, because GitHub-Dark adds a :hover background
	// color definition on divs
	const block = document.createElement("span");
	block.className = "ghcc-block";

	function addNode(el, val) {
		const node = block.cloneNode();
		node.style.backgroundColor = val;
		// Don't add node if color is invalid
		if (node.style.backgroundColor !== "") {
			el.insertBefore(node, el.childNodes[0]);
		}
	}

	function getTextContent(el) {
		return el ? el.textContent : "";
	}

	function rgb(els, el, txt) {
		// Color in a string contains everything
		if (el.classList.contains("pl-s")) {
			txt = txt.match(regexRGB)[0];
		} else {
			// Rgb(a) colors contained in multiple "pl-c1" spans
			let indx = regexRGBA.test(txt) ? 4 : 3;
			const tmp = [];
			while (indx) {
				tmp.push(getTextContent(els.shift()));
				indx--;
			}
			txt += "(" + tmp.join(",") + ")";
		}
		addNode(el, txt);
		return els;
	}

	function hsl(els, el, txt) {
		const tmp = /a$/i.test(txt);
		if (el.classList.contains("pl-s")) {
			// Color in a string contains everything
			txt = txt.match(regexHSL)[0];
		} else {
			// Traverse this HTML... & els only contains the pl-c1 nodes
			// hsl(1,
			// 1%,
			// 1%);
			// using getTextContent in case of invalid css
			txt = txt + "(" + getTextContent(els.shift()) + "," +
				getTextContent(els.shift()) + "%," +
				// Hsla needs one more parameter
				getTextContent(els.shift()) + "%" +
				(tmp ? "," + getTextContent(els.shift()) : "") + ")";
		}
		// Sometimes (previews only?) the .pl-k span is nested inside
		// the .pl-c1 span, so we end up with "%%"
		addNode(el, txt.replace(regexPercent, "%"));
		return els;
	}

	// Loop with delay to allow user interaction
	function* addBlock(els) {
		while (els.length) {
			let el = els.shift();
			let txt = el.textContent;
			if (el.parentNode && el.parentNode.classList.contains("pl-c1")) {
				// Ignore nested pl-c1 (see https://git.io/vFx8y)
			} else if (!el.querySelector(".ghcc-block")) {
				if (el.classList.contains("pl-s")) {
					txt = txt.replace(regexQuotes, "");
				}
				if (regexHex.test(txt) || regexNamed.test(txt)) {
					addNode(el, txt.replace(regexUnix, "#"));
				} else if (regexRGB.test(txt)) {
					els = rgb(els, el, txt);
				} else if (regexHSL.test(txt)) {
					els = hsl(els, el, txt);
				}
			}
			yield els;
		}
	}

	function addColors() {
		if (document.querySelector(".highlight")) {
			let status;
			// .pl-c1 targets css hex colors, "rgb" and "hsl"
			const els = [...document.querySelectorAll(".pl-c1, .pl-s")];
			const iter = addBlock(els);
			const loop = () => {
				for (let i = 0; i < 40; i++) {
					status = iter.next();
				}
				if (!status.done) {
					requestAnimationFrame(loop);
				}
			};
			loop();
		}
	}
	document.addEventListener("ghmo:container", addColors);
	document.addEventListener("ghmo:preview", addColors);
	addColors();

})();
<|endoftext|>


<commit_before>// TODO: make this work.
// if yuo go to localhost:3000 the app
// there is expected crud to be working here
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');

// express.static will serve everything
// with in client as a static resource
// also, it will server the index.html on the
// root of that directory on a GET to '/'
app.use(express.static('client'));

// body parser makes it possible to post JSON to the server
// we can accss data we post on as req.body
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

var lions = [];
var id = 0;

// TODO: make the REST routes to perform CRUD on lions

app.get('/lions', function(req, res) {
	console.log(req.body)
	res.status(200).send(lions);
});

app.get('/lions/:id', function(req, res) {
	console.log(req.body.params)
	res.status(200).send(lions[req.params.id]);
});

app.post('/lions/', function(req, res) {
	lions.push(req.body);
	res.status(201).send(lions[id]);
	id++;
});

app.put('/lions/:id', function(req, res) {
	res.status().send();
});

app.delete('/lions/:id', function(req, res) {
	res.status().send();
});

app.listen(3000, function() {
	console.log('on port 3000');
});
<commit_msg>Finish PUT route<commit_after>// TODO: make this work.
// if yuo go to localhost:3000 the app
// there is expected crud to be working here
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');

// express.static will serve everything
// with in client as a static resource
// also, it will server the index.html on the
// root of that directory on a GET to '/'
app.use(express.static('client'));

// body parser makes it possible to post JSON to the server
// we can accss data we post on as req.body
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

var lions = [];
var id = 0;

// TODO: make the REST routes to perform CRUD on lions

app.get('/lions', function(req, res) {
	console.log(req.body)
	res.status(200).send(lions);
});

app.get('/lions/:id', function(req, res) {
	console.log(req.body.params)
	res.status(200).send(lions[req.params.id]);
});

app.post('/lions/', function(req, res) {
	lions.push(req.body);
	res.status(201).send(lions[id]);
	id++;
});

app.put('/lions/:id', function(req, res) {
	lions[req.params.id] = req.body;
	res.status(200).send(lions[req.params.id]);
});

app.delete('/lions/:id', function(req, res) {
	res.status(200).send();
});

app.listen(3000, function() {
	console.log('on port 3000');
});
<|endoftext|>


<commit_before>/*
* Copyright 2010-2012 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
 * @toc {User Interface} Context Menu
 * @featureID blackberry.ui.contextmenu
 * @BB10X
 * @RIPPLE
 * @namespace The contextmenu namespace provides the facility to interact with the context menu api to control whether context menus are enabled, listen to events, add items to appear based on the context, and set the theme of the context menu.
 *
 *
Context Menu

 *
Webworks applications can choose to use an in app contextmenu as opposed to the default operating system menu. The
 * contextmenu provides several facilities to developers to allow them to control the elements that appear in the menu, as
 * well as listen to specific events related to the context menu being triggered and displayed.
 *

 *
 *
Enabling

 *
The contextmenu can be enabled by calling the blackberry.ui.contextmenu.enabled property. When set to true, the
 * contextmenu will capture the context menu events, and pass any events that the user has registered for. When set to false
 * the contextmenu will default to the system, and the developer will have no access to the events described below.
 *

 *
 */
blackberry.ui.contextmenu = {

/**
 * @description Context Menu enabled allows the developer to enabled and disable crosscut context menus for their application.
 * @param {boolean} enabled property that sets the contextmenu to enabled or disabled
 * @type boolean
 * @example
 * <script type="text/javascript">
 *
 * function disabledContextMenu() {
 *     blackberry.ui.contextmenu.enabled = false;
 * }
 *
 * if(!blackberry.ui.contextmenu.enabled){
 *     console.log("context menu is currently disabled");
 *     }
 * </script>
 *
 */
 enabled : Boolean,

 /**
 * @description Allows the developer to add custom items to the context menu. The items will be appended to the end of the list
 * of operating system defined functions. Developers must provide the following parameters to successfully add items to the context
 * menu.
 * @param {String[]} contexts An array of constants defining which contexts this new item should appear.
 * @param {Object} action An object which defines the menu item to be added.
 * @param {String} action.actionId A property that uniquely defines the action to be added to the context menu.
 * @param {String} action.label A string that will be displayed to the user describing the custom context to be performed. ie: Edit
 * @param {String} action.icon A path to the an image to display in the context menu
 * @callback {Function} callback A function which runs when the menu item action is executed
 * @BB10X
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *
 * function addMyItem() {
 *     var myItem = {actionId: 'MyItem', label: 'My Item', icon:'http://mysite.com/icon.png'},
 *         contexts = [blackberry.ui.contextmenu.CONTEXT_IMAGE, blackberry.ui.contextmenu.CONTEXT_INPUT];
 *     blackberry.ui.contextmenu.addItem(contexts, myItem, function() { console.log('hi') });
 * }
 *
 *
 *  //Override the system Copy action by actionId using the ACTION_COPY constant
 *  function overridePlatformWithIcon() {
 *   var myItem = {actionId: blackberry.ui.contextmenu.ACTION_COPY, label: 'Custom Copy!',
 *       icon:'local:///icon.png'},
 *       contexts = [blackberry.ui.contextmenu.CONTEXT_ALL];
 *
 *   blackberry.ui.contextmenu.addItem(contexts, myItem, function() {
 *       alert("Wow you succesfully overrode the platform menu item Copy");
 *   });
 * }
 *  //Override the system Copy action by actionId using the ACTION_SAVE_IMAGE constant
 *  // this example does not provide a icon, and uses the system default
 *  function overridePlatformNoIcon() {
 *   var myItem = {actionId: blackberry.ui.contextmenu.ACTION_SAVE_IMAGE, label: 'Save Image'},
 *       contexts = [blackberry.ui.contextmenu.CONTEXT_ALL];
 *
 *   blackberry.ui.contextmenu.addItem(contexts, myItem, function() {
 *       alert("Custom Save using system icon");
 *   });
 * }
 * </script>
 */
 addItem : function (){},

 /**
 * @description Allows the developer to remove previously added custom items from the context menu.
 * @param {String[]} contexts An array of constants defining which contexts this new item should appear.
 * @param {String} actionId An id that uniquely defines the action to be removed from the context menu.
 * @BB10X
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *
 * function addMyItem() {
 *     var myItem = {actionId: 'MyItem', label: 'My Item', icon:'http://mysite.com/icon.png'},
 *         contexts = [blackberry.ui.contextmenu.CONTEXT_IMAGE, blackberry.ui.contextmenu.CONTEXT_INPUT];
 *     blackberry.ui.contextmenu.addItem(contexts, myItem);
 * }
 *
 * function removeMyItem() {
 *     var myItem = {actionId: 'MyItem', label: 'My Item', icon:'http://mysite.com/icon.png'},
 *         contexts = [blackberry.ui.contextmenu.CONTEXT_IMAGE, blackberry.ui.contextmenu.CONTEXT_INPUT];
 *     blackberry.ui.contextmenu.removeItem(contexts, myItem.actionId);
 * }
 *
 * </script>
 *
 */
removeItem: function (){},

 /**
 * @description Allows the developer to define a custom context.
 * @param {String} context A String representing the custom context.
 * @param {Object} options An Object that contains the various options to set for the custom context.
 * @BB10X
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *
 * function defineCustomContext() {
 *     var options = {
 *         includeContextItems: [blackberry.ui.contextmenu.CONTEXT_IMAGE],//Includes custom items added for CONTEXT_IMAGE
 *         includePlatformItems: true,
 *         includeMenuServiceItems: true
 *     };
 *
 *     blackberry.ui.contextmenu.defineCustomContext("myContext", options)
 * }
 * </script>
 *
 */
defineCustomContext: function (){},

/**
 * Constant denoting all contexts.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_ALL: "CONTEXT_ALL",

 /**
 * Constant denoting the context of links.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_LINK: "CONTEXT_LINK",

 /**
 * Constant denoting the context of images.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_IMAGE: "CONTEXT_IMAGE",

 /**
 * Constant denoting the context of image links.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_IMAGE_LINK: "CONTEXT_IMAGE_LINK",

 /**
 * Constant denoting the context of input fields.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_INPUT: "CONTEXT_INPUT",

 /**
 * Constant denoting the context of text.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_TEXT: "CONTEXT_TEXT",

 /**
 * Constant denoting the actionId of cancel
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_CANCEL: "Cancel",

 /**
 * Constant denoting the actionId of clear field.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_CLEAR_FIELD: "ClearField",

 /**
 * Constant denoting the actionId of copy.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_COPY: "Copy",

 /**
 * Constant denoting the actionId of copy image link.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_COPY_IMAGE_LINK: "CopyImageLink",

 /**
 * Constant denoting the actionId of copy link.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_COPY_LINK: "CopyLink",

 /**
 * Constant denoting the actionId of cut.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_CUT: "Cut",

 /**
 * Constant denoting the actionId of inspect element
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 INSPECT_ELEMENT: "InspectElement",

 /**
 * Constant denoting the actionId of open link.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_OPEN_LINK: "OpenLink",

 /**
 * Constant denoting the actionId of paste.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_PASTE: "Paste",

 /**
 * Constant denoting the actionId of save image.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTIONE_SAVE_IMAGE: "SaveImage",

 /**
 * Constant denoting the actionId of save link as.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_SAVE_LINK_AS: "SaveLinkAs",

 /**
 * Constant denoting the actionId of select.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_SELECT: "Select",

 /**
 * Constant denoting the actionId of view image.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 ACTION_VIEW_IMAGE: "ViewImage",

};
<commit_msg>Revert "Adding constants + examples for overriding system context menu actions"<commit_after>/*
* Copyright 2010-2012 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
 * @toc {User Interface} Context Menu
 * @featureID blackberry.ui.contextmenu
 * @BB10X
 * @RIPPLE
 * @namespace The contextmenu namespace provides the facility to interact with the context menu api to control whether context menus are enabled, listen to events, add items to appear based on the context, and set the theme of the context menu.
 *
 *
Context Menu

 *
Webworks applications can choose to use an in app contextmenu as opposed to the default operating system menu. The
 * contextmenu provides several facilities to developers to allow them to control the elements that appear in the menu, as
 * well as listen to specific events related to the context menu being triggered and displayed.
 *

 *
 *
Enabling

 *
The contextmenu can be enabled by calling the blackberry.ui.contextmenu.enabled property. When set to true, the
 * contextmenu will capture the context menu events, and pass any events that the user has registered for. When set to false
 * the contextmenu will default to the system, and the developer will have no access to the events described below.
 *

 *
 */
blackberry.ui.contextmenu = {

/**
 * @description Context Menu enabled allows the developer to enabled and disable crosscut context menus for their application.
 * @param {boolean} enabled property that sets the contextmenu to enabled or disabled
 * @type boolean
 * @example
 * <script type="text/javascript">
 *
 * function disabledContextMenu() {
 *     blackberry.ui.contextmenu.enabled = false;
 * }
 *
 * if(!blackberry.ui.contextmenu.enabled){
 *     console.log("context menu is currently disabled");
 *     }
 * </script>
 *
 */
 enabled : Boolean,

 /**
 * @description Allows the developer to add custom items to the context menu. The items will be appended to the end of the list
 * of operating system defined functions. Developers must provide the following parameters to successfully add items to the context
 * menu.
 * @param {String[]} contexts An array of constants defining which contexts this new item should appear.
 * @param {Object} action An object which defines the menu item to be added.
 * @param {String} action.actionId A property that uniquely defines the action to be added to the context menu.
 * @param {String} action.label A string that will be displayed to the user describing the custom context to be performed. ie: Edit
 * @param {String} action.icon A path to the an image to display in the context menu
 * @callback {Function} callback A function which runs when the menu item action is executed
 * @BB10X
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *
 * function addMyItem() {
 *     var myItem = {actionId: 'MyItem', label: 'My Item', icon:'http://mysite.com/icon.png'},
 *         contexts = [blackberry.ui.contextmenu.CONTEXT_IMAGE, blackberry.ui.contextmenu.CONTEXT_INPUT];
 *     blackberry.ui.contextmenu.addItem(contexts, myItem, function() { console.log('hi') });
 * }
 * </script>
 *
 */
 addItem : function (){},

 /**
 * @description Allows the developer to remove previously added custom items from the context menu.
 * @param {String[]} contexts An array of constants defining which contexts this new item should appear.
 * @param {String} actionId An id that uniquely defines the action to be removed from the context menu.
 * @BB10X
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *
 * function addMyItem() {
 *     var myItem = {actionId: 'MyItem', label: 'My Item', icon:'http://mysite.com/icon.png'},
 *         contexts = [blackberry.ui.contextmenu.CONTEXT_IMAGE, blackberry.ui.contextmenu.CONTEXT_INPUT];
 *     blackberry.ui.contextmenu.addItem(contexts, myItem);
 * }
 *
 * function removeMyItem() {
 *     var myItem = {actionId: 'MyItem', label: 'My Item', icon:'http://mysite.com/icon.png'},
 *         contexts = [blackberry.ui.contextmenu.CONTEXT_IMAGE, blackberry.ui.contextmenu.CONTEXT_INPUT];
 *     blackberry.ui.contextmenu.removeItem(contexts, myItem.actionId);
 * }
 *
 * </script>
 *
 */
removeItem: function (){},

 /**
 * @description Allows the developer to define a custom context.
 * @param {String} context A String representing the custom context.
 * @param {Object} options An Object that contains the various options to set for the custom context.
 * @BB10X
 * @RIPPLE
 * @example
 * <script type="text/javascript">
 *
 * function defineCustomContext() {
 *     var options = {
 *         includeContextItems: [blackberry.ui.contextmenu.CONTEXT_IMAGE],//Includes custom items added for CONTEXT_IMAGE
 *         includePlatformItems: true,
 *         includeMenuServiceItems: true
 *     };
 *
 *     blackberry.ui.contextmenu.defineCustomContext("myContext", options)
 * }
 * </script>
 *
 */
defineCustomContext: function (){},

/**
 * Constant denoting all contexts.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_ALL: "CONTEXT_ALL",

 /**
 * Constant denoting the context of links.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_LINK: "CONTEXT_LINK",

 /**
 * Constant denoting the context of images.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_IMAGE: "CONTEXT_IMAGE",

 /**
 * Constant denoting the context of image links.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_IMAGE_LINK: "CONTEXT_IMAGE_LINK",

 /**
 * Constant denoting the context of input fields.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_INPUT: "CONTEXT_INPUT",

 /**
 * Constant denoting the context of text.
 * @type String
 * @constant
 * @BB10X
 * @RIPPLE
 */
 CONTEXT_TEXT: "CONTEXT_TEXT"
};
<|endoftext|>