<commit_before>/**
 * @copyright 2015+, Prometheus Research, LLC
 * @flow
 */

import React, {PropTypes} from 'react';
import {create} from 'react-dom-stylesheet';

type SizeUnit = string | number;

function choose(a?: SizeUnit, b?: SizeUnit, c?: SizeUnit): SizeUnit | void {
  if (a != null) {
    return a;
  } else if (b != null) {
    return b;
  } else if (c != null) {
    return c;
  } else {
    return undefined;
  }
}

/**
 * Flexbox layout primitive.
 *
 * See https://css-tricks.com/snippets/css/a-guide-to-flexbox/ for docs.
 */
export default class Box extends React.Component {

  static stylesheet = create({
    boxSizing: 'border-box',
    position: 'relative',

    margin: 0,
    padding: 0,

    display: 'flex',
    alignItems: 'stretch',
    flexBasis: 'auto',
    flexShrink: 0,

    minHeight: 0,
    minWidth: 0
  }, 'Box');

  static propTypes = {
    /**
     * Sets `align-content` style property.
     *
     * See https://css-tricks.com/almanac/properties/a/align-content/ for docs.
     */
    alignContent: PropTypes.oneOf([
      'flex-start',
      'flex-end',
      'center',
      'space-between',
      'space-around',
      'stretch'
    ]),

    /**
     * Sets `align-items` style property.
     *
     * See https://css-tricks.com/almanac/properties/a/align-items/ for docs.
     */
    alignItems: PropTypes.oneOf([
      'flex-start',
      'flex-end',
      'center',
      'baseline',
      'stretch'
    ]),

    /**
     * Sets `align-self` style property.
     *
     * See https://css-tricks.com/almanac/properties/a/align-self/ for docs.
     */
    alignSelf: PropTypes.oneOf([
      'auto',
      'flex-start',
      'flex-end',
      'center',
      'baseline',
      'stretch'
    ]),

    /**
     * Sets `flex` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex/ for docs.
     */
    flex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     *
     * Sets `flex-basis` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-basis/ for docs.
     */
    basis: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `flex-direction` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-direction/ for docs.
     */
    direction: PropTypes.oneOf([
      'row',
      'row-reverse',
      'column',
      'column-reverse'
    ]),

    /**
     * Sets `flex-flow` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-flow/ for docs.
     */
    flow: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `flex-grow` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-grow/ for docs.
     */
    grow: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `flex-shrink` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-shrink/ for docs.
     */
    shrink: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `flex-wrap` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-wrap/ for docs.
     */
    wrap: PropTypes.oneOf([
      'nowrap',
      'wrap',
      'wrap-reverse'
    ]),

    /**
     * Sets `justify-content` style property.
     *
     * See https://css-tricks.com/almanac/properties/j/justify-content/ for docs.
     */
    justifyContent: PropTypes.oneOf([
      'flex-start',
      'flex-end',
      'center',
      'space-between',
      'space-around'
    ]),

    /**
     * Sets `order` style property.
     *
     * See https://css-tricks.com/almanac/properties/o/order/ for docs.
     */
    order: PropTypes.number,

    /**
     * Sets `overflow` style property.
     */
    overflow: PropTypes.oneOf([
      'auto',
      'scroll',
      'visible',
      'hidden',
    ]),

    /**
     * Sets `top` style property.
     *
     * See https://css-tricks.com/almanac/properties/t/top/ for docs.
     */
    top: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `left` style property.
     *
     * See https://css-tricks.com/almanac/properties/l/left/ for docs.
     */
    left: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `bottom` style property.
     *
     * See https://css-tricks.com/almanac/properties/b/bottom/ for docs.
     */
    bottom: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `right` style property.
     *
     * See https://css-tricks.com/almanac/properties/r/right/ for docs.
     */
    right: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `height` style property.
     *
     * See https://css-tricks.com/almanac/properties/h/height/ for docs.
     */
    height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `width` style property.
     *
     * See https://css-tricks.com/almanac/properties/w/width/ for docs.
     */
    width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `min-width` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/min-width/ for docs.
     */
    minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `min-height` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/min-height/ for docs.
     */
    minHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `max-width` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/max-width/ for docs.
     */
    maxWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `max-height` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/max-height/ for docs.
     */
    maxHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin/ for docs.
     */
    margin: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-right` and `margin-left` style properties.
     */
    marginH: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-top` and `margin-bottom` style properties.
     */
    marginV: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-right` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin-right/ for docs.
     */
    marginRight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-left` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin-left/ for docs.
     */
    marginLeft: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-top` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin-top/ for docs.
     */
    marginTop: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-bottom` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin-bottom/ for docs.
     */
    marginBottom: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding/ for docs.
     */
    padding: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-right` and `padding-left` style properties.
     */
    paddingH: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-top` and `padding-bottom` style properties.
     */
    paddingV: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-right` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding-right/ for docs.
     */
    paddingRight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-left` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding-left/ for docs.
     */
    paddingLeft: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-top` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding-top/ for docs.
     */
    paddingTop: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-bottom` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding-bottom/ for docs.
     */
    paddingBottom: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Extra CSS style properties.
     */
    style: PropTypes.object,

    /**
     * Styleable variant.
     */
    variant: PropTypes.object,

    /**
     * Component to render.
     */
    Component: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
  };

  static defaultProps = {
    Component: 'div'
  };

  render() {
    let {
      alignContent,
      alignItems,
      alignSelf,
      flex,
      basis: flexBasis,
      direction: flexDirection,
      flow: flexFlow,
      grow: flexGrow,
      shrink: flexShrink,
      wrap: flexWrap,
      justifyContent,
      order,
      overflow,
      style,
      variant,
      Component,
      top, left, bottom, right,
      height, width,
      minWidth, minHeight,
      maxWidth, maxHeight,
      margin,
      marginH, marginV,
      marginRight, marginLeft, marginTop, marginBottom,
      padding,
      paddingH, paddingV,
      paddingRight, paddingLeft, paddingTop, paddingBottom,
      ...props
    } = this.props;
    style = {

      alignContent,
      alignItems,
      alignSelf,
      flex,
      flexBasis,
      flexDirection,
      flexFlow,
      flexGrow,
      flexShrink,
      flexWrap,
      justifyContent,
      order,

      overflow,

      top,
      left,
      bottom,
      right,

      height, width,

      minWidth, minHeight,
      maxWidth, maxHeight,

      marginLeft: choose(marginLeft, marginH, margin),
      marginRight: choose(marginRight, marginH, margin),
      marginTop: choose(marginTop, marginV, margin),
      marginBottom: choose(marginBottom, marginV, margin),

      paddingLeft: choose(paddingLeft, paddingH, padding),
      paddingRight: choose(paddingRight, paddingH, padding),
      paddingTop: choose(paddingTop, paddingV, padding),
      paddingBottom: choose(paddingBottom, paddingV, padding),

      ...style,
    };
    let className = this.constructor.stylesheet.asClassName(variant);
    return <Component className={className} {...props} style={style} />;
  }

  componentDidMount() {
    this.constructor.stylesheet.use();
  }

  componentWillUnmount() {
    this.constructor.stylesheet.dispose();
  }

  static style(stylesheet, displayName = this.displayName) {
    return class extends Box {
      static displayName = displayName;
      static stylesheet = this.stylesheet.override(stylesheet);
    };
  }
}
<commit_msg>fix: flex shorthand for React 15<commit_after>/**
 * @copyright 2015+, Prometheus Research, LLC
 * @flow
 */

import React, {PropTypes} from 'react';
import {create} from 'react-dom-stylesheet';

type SizeUnit = string | number;

function choose(a?: SizeUnit, b?: SizeUnit, c?: SizeUnit): SizeUnit | void {
  if (a != null) {
    return a;
  } else if (b != null) {
    return b;
  } else if (c != null) {
    return c;
  } else {
    return undefined;
  }
}

/**
 * Flexbox layout primitive.
 *
 * See https://css-tricks.com/snippets/css/a-guide-to-flexbox/ for docs.
 */
export default class Box extends React.Component {

  static stylesheet = create({
    boxSizing: 'border-box',
    position: 'relative',

    margin: 0,
    padding: 0,

    display: 'flex',
    alignItems: 'stretch',
    flexBasis: 'auto',
    flexShrink: 0,

    minHeight: 0,
    minWidth: 0
  }, 'Box');

  static propTypes = {
    /**
     * Sets `align-content` style property.
     *
     * See https://css-tricks.com/almanac/properties/a/align-content/ for docs.
     */
    alignContent: PropTypes.oneOf([
      'flex-start',
      'flex-end',
      'center',
      'space-between',
      'space-around',
      'stretch'
    ]),

    /**
     * Sets `align-items` style property.
     *
     * See https://css-tricks.com/almanac/properties/a/align-items/ for docs.
     */
    alignItems: PropTypes.oneOf([
      'flex-start',
      'flex-end',
      'center',
      'baseline',
      'stretch'
    ]),

    /**
     * Sets `align-self` style property.
     *
     * See https://css-tricks.com/almanac/properties/a/align-self/ for docs.
     */
    alignSelf: PropTypes.oneOf([
      'auto',
      'flex-start',
      'flex-end',
      'center',
      'baseline',
      'stretch'
    ]),

    /**
     * Sets `flex` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex/ for docs.
     */
    flex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     *
     * Sets `flex-basis` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-basis/ for docs.
     */
    basis: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `flex-direction` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-direction/ for docs.
     */
    direction: PropTypes.oneOf([
      'row',
      'row-reverse',
      'column',
      'column-reverse'
    ]),

    /**
     * Sets `flex-flow` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-flow/ for docs.
     */
    flow: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `flex-grow` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-grow/ for docs.
     */
    grow: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `flex-shrink` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-shrink/ for docs.
     */
    shrink: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `flex-wrap` style property.
     *
     * See https://css-tricks.com/almanac/properties/f/flex-wrap/ for docs.
     */
    wrap: PropTypes.oneOf([
      'nowrap',
      'wrap',
      'wrap-reverse'
    ]),

    /**
     * Sets `justify-content` style property.
     *
     * See https://css-tricks.com/almanac/properties/j/justify-content/ for docs.
     */
    justifyContent: PropTypes.oneOf([
      'flex-start',
      'flex-end',
      'center',
      'space-between',
      'space-around'
    ]),

    /**
     * Sets `order` style property.
     *
     * See https://css-tricks.com/almanac/properties/o/order/ for docs.
     */
    order: PropTypes.number,

    /**
     * Sets `overflow` style property.
     */
    overflow: PropTypes.oneOf([
      'auto',
      'scroll',
      'visible',
      'hidden',
    ]),

    /**
     * Sets `top` style property.
     *
     * See https://css-tricks.com/almanac/properties/t/top/ for docs.
     */
    top: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `left` style property.
     *
     * See https://css-tricks.com/almanac/properties/l/left/ for docs.
     */
    left: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `bottom` style property.
     *
     * See https://css-tricks.com/almanac/properties/b/bottom/ for docs.
     */
    bottom: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `right` style property.
     *
     * See https://css-tricks.com/almanac/properties/r/right/ for docs.
     */
    right: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `height` style property.
     *
     * See https://css-tricks.com/almanac/properties/h/height/ for docs.
     */
    height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `width` style property.
     *
     * See https://css-tricks.com/almanac/properties/w/width/ for docs.
     */
    width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `min-width` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/min-width/ for docs.
     */
    minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `min-height` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/min-height/ for docs.
     */
    minHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `max-width` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/max-width/ for docs.
     */
    maxWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `max-height` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/max-height/ for docs.
     */
    maxHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin/ for docs.
     */
    margin: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-right` and `margin-left` style properties.
     */
    marginH: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-top` and `margin-bottom` style properties.
     */
    marginV: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-right` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin-right/ for docs.
     */
    marginRight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-left` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin-left/ for docs.
     */
    marginLeft: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-top` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin-top/ for docs.
     */
    marginTop: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `margin-bottom` style property.
     *
     * See https://css-tricks.com/almanac/properties/m/margin-bottom/ for docs.
     */
    marginBottom: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding/ for docs.
     */
    padding: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-right` and `padding-left` style properties.
     */
    paddingH: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-top` and `padding-bottom` style properties.
     */
    paddingV: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-right` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding-right/ for docs.
     */
    paddingRight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-left` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding-left/ for docs.
     */
    paddingLeft: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-top` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding-top/ for docs.
     */
    paddingTop: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Sets `padding-bottom` style property.
     *
     * See https://css-tricks.com/almanac/properties/p/padding-bottom/ for docs.
     */
    paddingBottom: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    /**
     * Extra CSS style properties.
     */
    style: PropTypes.object,

    /**
     * Styleable variant.
     */
    variant: PropTypes.object,

    /**
     * Component to render.
     */
    Component: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
  };

  static defaultProps = {
    Component: 'div'
  };

  render() {
    let {
      alignContent,
      alignItems,
      alignSelf,
      flex,
      basis: flexBasis,
      direction: flexDirection,
      flow: flexFlow,
      grow: flexGrow,
      shrink: flexShrink,
      wrap: flexWrap,
      justifyContent,
      order,
      overflow,
      style,
      variant,
      Component,
      top, left, bottom, right,
      height, width,
      minWidth, minHeight,
      maxWidth, maxHeight,
      margin,
      marginH, marginV,
      marginRight, marginLeft, marginTop, marginBottom,
      padding,
      paddingH, paddingV,
      paddingRight, paddingLeft, paddingTop, paddingBottom,
      ...props
    } = this.props;
    style = {

      alignContent,
      alignItems,
      alignSelf,
      flexBasis: choose(typeof flex !== 'number' ? flex : null, flexBasis),
      flexDirection,
      flexFlow,
      flexGrow: choose(typeof flex === 'number' ? flex : null, flexGrow),
      flexShrink,
      flexWrap,
      justifyContent,
      order,

      overflow,

      top,
      left,
      bottom,
      right,

      height, width,

      minWidth, minHeight,
      maxWidth, maxHeight,

      marginLeft: choose(marginLeft, marginH, margin),
      marginRight: choose(marginRight, marginH, margin),
      marginTop: choose(marginTop, marginV, margin),
      marginBottom: choose(marginBottom, marginV, margin),

      paddingLeft: choose(paddingLeft, paddingH, padding),
      paddingRight: choose(paddingRight, paddingH, padding),
      paddingTop: choose(paddingTop, paddingV, padding),
      paddingBottom: choose(paddingBottom, paddingV, padding),

      ...style,
    };
    let className = this.constructor.stylesheet.asClassName(variant);
    return <Component className={className} {...props} style={style} />;
  }

  componentDidMount() {
    this.constructor.stylesheet.use();
  }

  componentWillUnmount() {
    this.constructor.stylesheet.dispose();
  }

  static style(stylesheet, displayName = this.displayName) {
    return class extends Box {
      static displayName = displayName;
      static stylesheet = this.stylesheet.override(stylesheet);
    };
  }
}
<|endoftext|>


<commit_before>(function () {
    "use strict";
    // Initialise Vue variable
    var gallery;

    gallery = new Vue({
        // Attach the Vue object to the master parent called #gallery
        // Gallery will include all the photos and the photo gallery itself
        el: "#gallery",

        data: {
            // Toggle photo gallery visibility
            isVisible: false,
            // Current photo title
            title: '',
            // Current image src
            image: '',
            // Next and Previous object
            // from the current photo selected
            next: null,
            previous: null
        },

        methods: {
            // When click on an anchor of image this will triggered
            viewImage: function () {
                // TODO: This seems utter bullshit, refactor this pls
                this.next = event.target.parentNode.nextElementSibling;
                this.previous = event.target.parentNode.previousElementSibling;
                this.title = event.target.parentNode.getAttribute("data-title");
                this.image = event.target.parentNode.getAttribute("data-original");
                // Show the gallery itself
                this.isVisible = !this.isVisible;
                event.preventDefault();
            },
            // Close the gallery
            closeGallery: function (event) {
                this.isVisible = false;
                this.title = '';
                this.image = '';
                this.counter = 0;
                event.preventDefault();
            },
            // Next photo anchor
            nextPhoto: function () {
                if(this.next !== null && this.next.nodeName === "FIGURE"){
                    this.title = this.next.getAttribute("data-title");
                    this.image = this.next.getAttribute("data-original");
                    this.next = this.next.nextElementSibling;
                    if(this.next !== null){
                        this.previous = this.next.previousElementSibling;
                    }
                }

                event.preventDefault();
            },
            // Previous photo anchor
            previousPhoto: function () {
                if(this.previous !== null && this.previous.nodeName === "FIGURE"){
                    this.title = this.previous.getAttribute("data-title");
                    this.image = this.previous.getAttribute("data-original");
                    this.next = this.previous.nextElementSibling;
                    this.previous = this.previous.previousElementSibling;
                }

                event.preventDefault();
            }
        }
    });
})();<commit_msg>Fixed firefox bug<commit_after>(function () {
    "use strict";
    // Initialise Vue variable
    var gallery;

    gallery = new Vue({
        // Attach the Vue object to the master parent called #gallery
        // Gallery will include all the photos and the photo gallery itself
        el: "#gallery",

        data: {
            // Toggle photo gallery visibility
            isVisible: false,
            // Current photo title
            title: '',
            // Current image src
            image: '',
            // Next and Previous object
            // from the current photo selected
            next: null,
            previous: null
        },

        methods: {
            // When click on an anchor of image this will triggered
            viewImage: function (event) {
                // TODO: This seems utter bullshit, refactor this pls
                this.next = event.target.parentNode.nextElementSibling;
                this.previous = event.target.parentNode.previousElementSibling;
                this.title = event.target.parentNode.getAttribute("data-title");
                this.image = event.target.parentNode.getAttribute("data-original");
                // Show the gallery itself
                this.isVisible = !this.isVisible;
                event.preventDefault();
            },
            // Close the gallery
            closeGallery: function (event) {
                this.isVisible = false;
                this.title = '';
                this.image = '';
                this.counter = 0;
                event.preventDefault();
            },
            // Next photo anchor
            nextPhoto: function () {
                if(this.next !== null && this.next.nodeName === "FIGURE"){
                    this.title = this.next.getAttribute("data-title");
                    this.image = this.next.getAttribute("data-original");
                    this.next = this.next.nextElementSibling;
                    if(this.next !== null){
                        this.previous = this.next.previousElementSibling;
                    }
                }

                event.preventDefault();
            },
            // Previous photo anchor
            previousPhoto: function () {
                if(this.previous !== null && this.previous.nodeName === "FIGURE"){
                    this.title = this.previous.getAttribute("data-title");
                    this.image = this.previous.getAttribute("data-original");
                    this.next = this.previous.nextElementSibling;
                    this.previous = this.previous.previousElementSibling;
                }

                event.preventDefault();
            }
        }
    });
})();
<|endoftext|>


<commit_before>$(function() {
    $("#new-questions").on("click", ".up_vote", function(event) {
        event.preventDefault();
        var question = $(this);
        $.ajax({
            type: "GET",
            url: $(this).attr("href"),
            success: function(data) {
                var d = $.parseJSON(data);
                $("#question-" + d.success).hide();
            },
            error: function(data, error) {
                alert(data);
                alert(error);
            }
        });
        return false;
    });
});

function subscribeClassRoomChannel(channel, username) {
    pubnub = getPubNubConn();
    pubnub.subscribe({
        channel: channel,
        restore: false,

        callback: function(message) {
            // determine which type of message
            // and handle accordingly
            switch (message.type) {
            case "student_connected":
                incrementStudentCount();
                console.log(message.name + " connected");
                break;
            case "new_question":
                addQuestion(message.question);
                break;
            default:
                console.log(message.type);
                break;
            }
        },
        disconnect: function() {
            $('#conn_status').html('Closed');
	    $('#conn_status').attr("class", "label label-warning");
        },

        reconnect: function() {
            $('#conn_status').html('Connected');
	    $('#conn_status').attr("class", "label label-success");
        },

        connect: function() {
            $('#conn_status').html('Connected');
	    $('#conn_status').attr("class", "label label-success");
            pubnub.publish({
                channel: channel,
                message: {"type": "student_connected", "name": username}
            });
        }
    });
}

function incrementStudentCount() {
    // get student count element
    // grab the value increment by 1
    // set value
}

function addQuestion(question) {
    // question added to asked list
    q = "
 \

 \
         \
           \
         \
        " + question.subject + " \

 \

 \

" + question.content + "
 \
         " + question.student  + " \

 \

";
    $("#new-questions").prepend(q);
    // if asked list greater then set #
    // remove older questions
    if ($("#new-questions li").length > parseInt($("#max_new_question_count").text())) {
        $("#new-questions li:last").remove();
    }
}
<commit_msg>sorted out increment status count js function<commit_after>$(function() {
    $("#new-questions").on("click", ".up_vote", function(event) {
        event.preventDefault();
        var question = $(this);
        $.ajax({
            type: "GET",
            url: $(this).attr("href"),
            success: function(data) {
                var d = $.parseJSON(data);
                $("#question-" + d.success).hide();
            },
            error: function(data, error) {
                alert(data);
                alert(error);
            }
        });
        return false;
    });
});

function subscribeClassRoomChannel(channel, username) {
    pubnub = getPubNubConn();
    pubnub.subscribe({
        channel: channel,
        restore: false,

        callback: function(message) {
            // determine which type of message
            // and handle accordingly
            switch (message.type) {
            case "student_connected":
                incrementStudentCount();
                console.log(message.name + " connected");
                break;
            case "new_question":
                addQuestion(message.question);
                break;
            default:
                console.log(message.type);
                break;
            }
        },
        disconnect: function() {
            $('#conn_status').html('Closed');
	    $('#conn_status').attr("class", "label label-warning");
        },

        reconnect: function() {
            $('#conn_status').html('Connected');
	    $('#conn_status').attr("class", "label label-success");
        },

        connect: function() {
            $('#conn_status').html('Connected');
	    $('#conn_status').attr("class", "label label-success");
            pubnub.publish({
                channel: channel,
                message: {"type": "student_connected", "name": username}
            });
        }
    });
}

function incrementStudentCount() {
    // get student count element
    // grab the value increment by 1
    // set value
    var count = parseInt($("#student_count").text());
    count += 1;
    $("#student_count").text(count);
}

function addQuestion(question) {
    // question added to asked list
    q = "
 \

 \
         \
           \
         \
        " + question.subject + " \

 \

 \

" + question.content + "
 \
         " + question.student  + " \

 \

";
    $("#new-questions").prepend(q);
    // if asked list greater then set #
    // remove older questions
    if ($("#new-questions li").length > parseInt($("#max_new_question_count").text())) {
        $("#new-questions li:last").remove();
    }
}
<|endoftext|>


<commit_before>/*global jQuery, google */

(function ($, g) {
    'use strict';

    g.load('visualization', '1', {
        packages: ['corechart'],
        callback: function () {
            function percentageFormatter(number) {
                return (number * 100).toFixed(2) * 1;
            }

            function handleLatestPtfRender(e, data) {
                var options = {
                        backgroundColor: 'transparent',
                        title: 'Graph based on the latest 100 portfolios',
                        hAxis: {title: 'Risk %'},
                        vAxis: {title: 'Return %'},
                        legend: 'none'
                    },
                    dataArray = [],
                    dataTable = new google.visualization.DataTable(),
                    chart = new g.visualization.ScatterChart(
                        $('#efficient-frontier').get()[0]);

                dataTable.addColumn('number', 'Risk');
                dataTable.addColumn('number', 'Return');
                dataTable.addColumn({type: 'string', role: 'tooltip'});

                data.rows.forEach(function (ptf) {
                    var risk = percentageFormatter(parseFloat(ptf.value.risk)),
                        ret = percentageFormatter(parseFloat(ptf.value.ret)),
                        perf = percentageFormatter(parseFloat(ptf.value.perf)),
                        assets = '';

                    ptf.value.assets.forEach(function (asset, index) {
                        assets += asset + ': ' +
                            percentageFormatter(ptf.value.weights[index]) +
                            '%\n';
                    });

                    dataArray.push([risk, ret,
                        'Risk: ' + risk + '%\n' +
                        'Return: ' + ret + '%\n' +
                        'Perf.: ' + (perf ? perf + '%' : 'n.a.') + '\n' +
                        assets +
                        ptf.value.ref
                    ]);
                });
                dataTable.addRows(dataArray);

                chart.draw(dataTable, options);
            }

            function handlePieChartRender(e, selector, assets, weights) {
                var options = {
                        backgroundColor: 'transparent',
                        pieSliceText: 'label',
                        pieHole: 0.2,
                        legend: 'none'
                    },
                    dataArray = [],
                    dataTable = new g.visualization.DataTable(),
                    chart = new g.visualization.PieChart($(selector).get()[0]);

                assets.forEach(function (asset, index) {
                    dataArray.push([asset, weights[index]]);
                });

                dataTable.addColumn('string', 'Asset');
                dataTable.addColumn('number', 'Weight');

                dataTable.addRows(dataArray);

                chart.draw(dataTable, options);
            }

            function handlePerfChartRender(e, selector, performances) {
                var options = {
                        backgroundColor: 'transparent',
                        legend: 'none'
                    },
                    dataArray = [],
                    dataTable = new g.visualization.DataTable(),
                    chart = new g.visualization.ColumnChart(
                        $(selector).get()[0]);

                performances.forEach(function (performance, index) {
                    dataArray.push([index, performance,
                        'Perf: ' + percentageFormatter(performance) + '%'
                    ]);
                });

                dataTable.addColumn('number', 'Week');
                dataTable.addColumn('number', 'Performance');
                dataTable.addColumn({type: 'string', role: 'tooltip'});

                dataTable.addRows(dataArray);

                chart.draw(dataTable, options);
            }

            $.subscribe('render.latestptfschart.conpa', handleLatestPtfRender);
            $.subscribe('render.piechart.conpa', handlePieChartRender);
            $.subscribe('render.perfchart.conpa', handlePerfChartRender);
        }
    });

}(jQuery, google));
<commit_msg>Fix eslint errors.<commit_after>/*global jQuery, google */

(function ($, g) {
    "use strict";

    g.load("visualization", "1", {
        packages: ["corechart"],
        callback: function () {
            function percentageFormatter(number) {
                return (number * 100).toFixed(2) * 1;
            }

            function handleLatestPtfRender(e, data) {
                var options = {
                        backgroundColor: "transparent",
                        title: "Graph based on the latest 100 portfolios",
                        hAxis: {title: "Risk %"},
                        vAxis: {title: "Return %"},
                        legend: "none"
                    },
                    dataArray = [],
                    dataTable = new google.visualization.DataTable(),
                    chart = new g.visualization.ScatterChart(
                        $("#efficient-frontier").get()[0]);

                dataTable.addColumn("number", "Risk");
                dataTable.addColumn("number", "Return");
                dataTable.addColumn({type: "string", role: "tooltip"});

                data.rows.forEach(function (ptf) {
                    var risk = percentageFormatter(parseFloat(ptf.value.risk)),
                        ret = percentageFormatter(parseFloat(ptf.value.ret)),
                        perf = percentageFormatter(parseFloat(ptf.value.perf)),
                        assets = "";

                    ptf.value.assets.forEach(function (asset, index) {
                        assets += asset + ": " +
                            percentageFormatter(ptf.value.weights[index]) +
                            "%\n";
                    });

                    dataArray.push([risk, ret,
                        "Risk: " + risk + "%\n" +
                        "Return: " + ret + "%\n" +
                        "Perf.: " + (perf ? perf + "%" : "n.a.") + "\n" +
                        assets +
                        ptf.value.ref]);
                });
                dataTable.addRows(dataArray);

                chart.draw(dataTable, options);
            }

            function handlePieChartRender(e, selector, assets, weights) {
                var options = {
                        backgroundColor: "transparent",
                        pieSliceText: "label",
                        pieHole: 0.2,
                        legend: "none"
                    },
                    dataArray = [],
                    dataTable = new g.visualization.DataTable(),
                    chart = new g.visualization.PieChart($(selector).get()[0]);

                assets.forEach(function (asset, index) {
                    dataArray.push([asset, weights[index]]);
                });

                dataTable.addColumn("string", "Asset");
                dataTable.addColumn("number", "Weight");

                dataTable.addRows(dataArray);

                chart.draw(dataTable, options);
            }

            function handlePerfChartRender(e, selector, performances) {
                var options = {
                        backgroundColor: "transparent",
                        legend: "none"
                    },
                    dataArray = [],
                    dataTable = new g.visualization.DataTable(),
                    chart = new g.visualization.ColumnChart(
                        $(selector).get()[0]);

                performances.forEach(function (performance, index) {
                    dataArray.push([index, performance,
                        "Perf: " + percentageFormatter(performance) + "%"]);
                });

                dataTable.addColumn("number", "Week");
                dataTable.addColumn("number", "Performance");
                dataTable.addColumn({type: "string", role: "tooltip"});

                dataTable.addRows(dataArray);

                chart.draw(dataTable, options);
            }

            $.subscribe("render.latestptfschart.conpa", handleLatestPtfRender);
            $.subscribe("render.piechart.conpa", handlePieChartRender);
            $.subscribe("render.perfchart.conpa", handlePerfChartRender);
        }
    });

}(jQuery, google));
<|endoftext|>


<commit_before>import keys from '../util/keys'
import platform from '../util/platform'
import Component from './Component'

class AbstractIsolatedNodeComponent extends Component {
  constructor (...args) {
    super(...args)

    this.name = this.props.node.id
    this._state = { selectionFragment: null }

    this.handleAction('escape', this.escape)
    this.ContentClass = this._getContentClass(this.props.node)

    // NOTE: FF does not allow to navigate contenteditable isles
    let useBlocker = platform.isFF || !this.ContentClass.noBlocker
    this.blockingMode = useBlocker ? 'closed' : 'open'
  }

  getInitialState () {
    let selState = this.context.editorSession.getSelectionState()
    return this._deriveStateFromSelectionState(selState)
  }

  getChildContext () {
    return {
      parentSurfaceId: this.getId(),
      isolatedNodeComponent: this,
      // TODO: we should clear 'surface' here
      // so that we know that we are not controlled by a surface
      surface: undefined
    }
  }

  didMount () {
    super.didMount()

    let editorSession = this.context.editorSession
    editorSession.onRender('selection', this._onSelectionChanged, this)
  }

  dispose () {
    super.dispose.call(this)

    let editorSession = this.context.editorSession
    editorSession.off(this)
  }

  renderContent ($$, node, options = {}) {
    let ComponentClass = this.ContentClass
    if (!ComponentClass) {
      console.error('Could not resolve a component for type: ' + node.type)
      return $$(this.__elementTag)
    } else {
      let props = Object.assign({
        disabled: this.props.disabled,
        node: node,
        isolatedNodeState: this.state.mode,
        focused: (this.state.mode === 'focused')
      }, options)
      return $$(ComponentClass, props)
    }
  }

  getId () {
    // HACK: doing this lazily here instead of in the constructor.
    // This is because `getInitialState()` already needs this information
    if (!this._id) {
      this._id = this.context.parentSurfaceId + '/' + this.name
    }
    return this._id
  }

  get id () { return this.getId() }

  getMode () {
    return this.state.mode
  }

  isOpen () {
    return this.blockingMode === 'open'
  }

  isClosed () {
    return this.blockingMode === 'closed'
  }

  isNotSelected () {
    return !this.state.mode
  }

  isSelected () {
    return this.state.mode === 'selected'
  }

  isCoSelected () {
    return this.state.mode === 'co-selected'
  }

  isFocused () {
    return this.state.mode === 'focused'
  }

  isCoFocused () {
    return this.state.mode === 'co-focused'
  }

  getParentSurface () {
    return this.context.surface
  }

  escape () {
    // console.log('Escaping from IsolatedNode', this.id)
    this.selectNode()
  }

  _onSelectionChanged () {
    let editorSession = this.context.editorSession
    let newState = this._deriveStateFromSelectionState(editorSession.getSelectionState())
    if (!newState && this.state.mode) {
      this.extendState({ mode: null })
    } else if (newState && newState.mode !== this.state.mode) {
      this.extendState(newState)
    }
  }

  onKeydown (event) {
    // console.log('####', event.keyCode, event.metaKey, event.ctrlKey, event.shiftKey);
    // TODO: while this works when we have an isolated node with input or CE,
    // there is no built-in way of receiving key events in other cases
    // We need a global event listener for keyboard events which dispatches to the current isolated node
    if (event.keyCode === keys.ESCAPE && this.state.mode === 'focused') {
      event.stopPropagation()
      event.preventDefault()
      this.escape()
    }
  }

  _getContentClass (node) {
    let ComponentClass
    // first try to get the component registered for this node
    ComponentClass = this.getComponent(node.type, true)
    // otherwise just use an empty Component
    if (!ComponentClass) {
      ComponentClass = Component
    }
    return ComponentClass
  }

  _getSurface (selState) {
    let surface = selState.get('surface')
    if (surface === undefined) {
      let sel = selState.getSelection()
      if (sel && sel.surfaceId) {
        let surfaceManager = this.context.surfaceManager
        surface = surfaceManager.getSurface(sel.surfaceId)
      } else {
        surface = null
      }
      selState.set('surface', surface)
    }
    return surface
  }

  // compute the list of surfaces and isolated nodes
  // for the given selection
  _getIsolatedNodes (selState) {
    let isolatedNodes = selState.get('isolatedNodes')
    if (!isolatedNodes) {
      let sel = selState.getSelection()
      isolatedNodes = []
      if (sel && sel.surfaceId) {
        let surfaceManager = this.context.surfaceManager
        let surface = surfaceManager.getSurface(sel.surfaceId)
        if (surface) {
          isolatedNodes = surface.getComponentPath().filter(comp => comp._isAbstractIsolatedNodeComponent)
        }
      }
      selState.set('isolatedNodes', isolatedNodes)
    }
    return isolatedNodes
  }

  _shouldConsumeEvent (event) {
    let comp = Component.unwrap(event.target)
    let isolatedNodeComponent = this._getIsolatedNode(comp)
    return (isolatedNodeComponent === this)
  }

  _getIsolatedNode (comp) {
    if (comp._isAbstractIsolatedNodeComponent) {
      return this
    } else if (comp.context.isolatedNodeComponent) {
      return comp.context.isolatedNodeComponent
    } else if (comp.context.surface) {
      return comp.context.surface.context.isolatedNodeComponent
    }
  }
}

AbstractIsolatedNodeComponent.prototype._isAbstractIsolatedNodeComponent = true

export default AbstractIsolatedNodeComponent
<commit_msg>Introduce AbstratIsolatedNodeComponent._getContentProps()<commit_after>import keys from '../util/keys'
import platform from '../util/platform'
import Component from './Component'

class AbstractIsolatedNodeComponent extends Component {
  constructor (...args) {
    super(...args)

    this.name = this.props.node.id
    this._state = { selectionFragment: null }

    this.handleAction('escape', this.escape)
    this.ContentClass = this._getContentClass(this.props.node)

    // NOTE: FF does not allow to navigate contenteditable isles
    let useBlocker = platform.isFF || !this.ContentClass.noBlocker
    this.blockingMode = useBlocker ? 'closed' : 'open'
  }

  getInitialState () {
    let selState = this.context.editorSession.getSelectionState()
    return this._deriveStateFromSelectionState(selState)
  }

  getChildContext () {
    return {
      parentSurfaceId: this.getId(),
      isolatedNodeComponent: this,
      // TODO: we should clear 'surface' here
      // so that we know that we are not controlled by a surface
      surface: undefined
    }
  }

  didMount () {
    super.didMount()

    let editorSession = this.context.editorSession
    editorSession.onRender('selection', this._onSelectionChanged, this)
  }

  dispose () {
    super.dispose.call(this)

    let editorSession = this.context.editorSession
    editorSession.off(this)
  }

  renderContent ($$, node, options = {}) {
    let ComponentClass = this.ContentClass
    if (!ComponentClass) {
      console.error('Could not resolve a component for type: ' + node.type)
      return $$(this.__elementTag)
    } else {
      let props = Object.assign(this._getContentProps(), options)
      return $$(ComponentClass, props)
    }
  }

  getId () {
    // HACK: doing this lazily here instead of in the constructor.
    // This is because `getInitialState()` already needs this information
    if (!this._id) {
      this._id = this.context.parentSurfaceId + '/' + this.name
    }
    return this._id
  }

  get id () { return this.getId() }

  getMode () {
    return this.state.mode
  }

  isOpen () {
    return this.blockingMode === 'open'
  }

  isClosed () {
    return this.blockingMode === 'closed'
  }

  isNotSelected () {
    return !this.state.mode
  }

  isSelected () {
    return this.state.mode === 'selected'
  }

  isCoSelected () {
    return this.state.mode === 'co-selected'
  }

  isFocused () {
    return this.state.mode === 'focused'
  }

  isCoFocused () {
    return this.state.mode === 'co-focused'
  }

  getParentSurface () {
    return this.context.surface
  }

  escape () {
    // console.log('Escaping from IsolatedNode', this.id)
    this.selectNode()
  }

  _onSelectionChanged () {
    let editorSession = this.context.editorSession
    let newState = this._deriveStateFromSelectionState(editorSession.getSelectionState())
    if (!newState && this.state.mode) {
      this.extendState({ mode: null })
    } else if (newState && newState.mode !== this.state.mode) {
      this.extendState(newState)
    }
  }

  onKeydown (event) {
    // console.log('####', event.keyCode, event.metaKey, event.ctrlKey, event.shiftKey);
    // TODO: while this works when we have an isolated node with input or CE,
    // there is no built-in way of receiving key events in other cases
    // We need a global event listener for keyboard events which dispatches to the current isolated node
    if (event.keyCode === keys.ESCAPE && this.state.mode === 'focused') {
      event.stopPropagation()
      event.preventDefault()
      this.escape()
    }
  }

  _getContentClass (node) {
    let ComponentClass
    // first try to get the component registered for this node
    ComponentClass = this.getComponent(node.type, true)
    // otherwise just use an empty Component
    if (!ComponentClass) {
      ComponentClass = Component
    }
    return ComponentClass
  }

  _getContentProps () {
    return {
      disabled: this.props.disabled,
      node: this.props.node,
      isolatedNodeState: this.state.mode,
      focused: (this.state.mode === 'focused')
    }
  }

  _getSurface (selState) {
    let surface = selState.get('surface')
    if (surface === undefined) {
      let sel = selState.getSelection()
      if (sel && sel.surfaceId) {
        let surfaceManager = this.context.surfaceManager
        surface = surfaceManager.getSurface(sel.surfaceId)
      } else {
        surface = null
      }
      selState.set('surface', surface)
    }
    return surface
  }

  // compute the list of surfaces and isolated nodes
  // for the given selection
  _getIsolatedNodes (selState) {
    let isolatedNodes = selState.get('isolatedNodes')
    if (!isolatedNodes) {
      let sel = selState.getSelection()
      isolatedNodes = []
      if (sel && sel.surfaceId) {
        let surfaceManager = this.context.surfaceManager
        let surface = surfaceManager.getSurface(sel.surfaceId)
        if (surface) {
          isolatedNodes = surface.getComponentPath().filter(comp => comp._isAbstractIsolatedNodeComponent)
        }
      }
      selState.set('isolatedNodes', isolatedNodes)
    }
    return isolatedNodes
  }

  _shouldConsumeEvent (event) {
    let comp = Component.unwrap(event.target)
    let isolatedNodeComponent = this._getIsolatedNode(comp)
    return (isolatedNodeComponent === this)
  }

  _getIsolatedNode (comp) {
    if (comp._isAbstractIsolatedNodeComponent) {
      return this
    } else if (comp.context.isolatedNodeComponent) {
      return comp.context.isolatedNodeComponent
    } else if (comp.context.surface) {
      return comp.context.surface.context.isolatedNodeComponent
    }
  }
}

AbstractIsolatedNodeComponent.prototype._isAbstractIsolatedNodeComponent = true

export default AbstractIsolatedNodeComponent
<|endoftext|>


<commit_before>/*global _:true */
(function() {
  "use strict";

}());<commit_msg>backed out previous<commit_after><|endoftext|>


<commit_before> /**************************************************************************
  * This file is part of median-cut.js                                     *
  *                                                                        *
  * median-cut.js is free software: you can redistribute it and/or modify  *
  * it under the terms of the GNU General Public License as published by   *
  * the Free Software Foundation, either version 3 of the License, or      *
  * (at your option) any later version.                                    *
  *                                                                        *
  * median-cut.js is distributed in the hope that it will be useful,       *
  * but WITHOUT ANY WARRANTY; without even the implied warranty of         *
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
  * GNU General Public License for more details.                           *
  *                                                                        *
  * You should have received a copy of the GNU General Public License      *
  * along with median-cut.js.  If not, see <http://www.gnu.org/licenses/>. *
  **************************************************************************/

//  This is the median-cut algorithm.
//
//  1. Find the smallest box which contains all the colors in the image.
//
//  2. Sort the enclosed colors along the longest axis of the box.
//
//  3. Split the box into 2 regions at median of the sorted list.
//
//  4. Repeat the above process until the original color space has been divided into N regions
//     where N is the number of colors you want.

var MedianCut = function() {

    var boxes,

    init = function( _data ) {

        var box1 = Box();
        box1.init( _data );

        boxes = [ box1 ];

    },

    get_longest_box_index = function() {

        // find the box with the longest axis of them all...
        var longest_box_index = 0;

        for( var box_index = boxes.length - 1; box_index >= 0; --box_index ) {
            if( boxes[ box_index ] > longest_box_index ) {
                longest_box_index = boxes[ box_index ];
            }
        }

        return longest_box_index;

    },

    get_boxes = function() {
        return boxes;
    },

    get_dynamic_size_palette = function( _threshold ) {

        // threshold is a value in (0,1] that influences how many colors
        // will be in the resulting palette.  lower values of threshold
        // will result in a smaller palette size.

        var values = [],
            i,
            longest_box_index = get_longest_box_index(),
            longest_axis      = boxes[ longest_box_index ].get_longest_axis(),
            max_box_length    = longest_axis.length * ( 1 - _threshold );

        do {

            // remove the longest box and split it
            var box_to_split = boxes.splice( longest_box_index, 1 )[0];
            var split_boxes = box_to_split.split();
            var box1 = split_boxes[0];
            var box2 = split_boxes[1];

            // then push the resulting boxes into the boxes array
            boxes.push( box1 );
            boxes.push( box2 );

            longest_box_index = get_longest_box_index()
            longest_axis      = boxes[ longest_box_index ].get_longest_axis();

        }
        while( longest_axis.length > max_box_length );

        // palette is complete.  get the average colors from each box
        // and push them into the values array, then return.
        for( var i = boxes.length - 1; i >= 0; --i ) {
            values.push( boxes[i].average() );
        }

        return values;

    },

    get_fixed_size_palette = function( _number ) {

        var values = [];

        for( var i = _number - 1; i >= 0; --i ) {

            longest_box_index = get_longest_box_index();

            // remove the longest box and split it
            var box_to_split = boxes.splice( longest_box_index, 1 )[0];
            var split_boxes = box_to_split.split();
            var box1 = split_boxes[0];
            var box2 = split_boxes[1];

            // then push the resulting boxes into the boxes array
            boxes.push( box1 );
            boxes.push( box2 );
        }

        // palette is complete.  get the average colors from each box
        // and push them into the values array, then return.
        for( var i = _number - 1; i >= 0; --i ) {
            values.push( boxes[i].average() );
        }

        return values;

    };

    return {
        // This is a private function (listed here in case it needs to be made public easily :)
        //get_boxes                : get_boxes

        // These are exposed (public) functions
        init                     : init,
        get_fixed_size_palette   : get_fixed_size_palette,
        get_dynamic_size_palette : get_dynamic_size_palette,
    };
};

var Box = function() {

    var data, // it's all about the data
        box,  // the bounding box of the data
        dim,  // number of dimensions in the data

    init = function( _data ) {

        // Initializes the data values, number of dimensions in the data
        // (currently fixed to 3 to handle RGB, but may be genericized in
        // the future), and the bounding box of the data.

        data = _data;
        dim  = 3; // lock this to 3 (RGB pixels) for now.
        box  = calculate_bounding_box();

    },

    get_data = function() {

        // Getter for data

        return data;

    },

    sort = function() {

        // Sorts all the elements in this box based on their values on the
        // longest axis.

        var a           = get_longest_axis().axis;
        var sort_method = get_comparison_func( a );

        data.sort( sort_method );

        return data;

    },

    get_comparison_func = function( _i ) {

        // Return a comparison function based on a given index (for median-cut,
        // sort on the longest axis) ie: sort ONLY on a single axis.
        // get_comparison_func( 1 ) would return a sorting function that sorts
        // the data according to each item's Green value.

        var sort_method = function( a, b ) {
            return a[_i] - b[_i];
        };

        return sort_method;

    },

    split = function() {

        // Splits this box in two and returns two box objects. This function
        // represents steps 2 and 3 of the algorithm, as written at the top
        // of this file.

        if( data.length <  0 ) console.error( "can't split; box is screwed up. (box has less than 0 length)" );
        if( data.length == 0 ) console.error( "can't split; box is empty!" );
        if( data.length == 1 ) console.error( "can't split; box has one element!" );

        sort();

        var med   = median_pos();

        var data1 = data.slice( 0, med );   // elements 0 through med
        var data2 = data.slice( med );      // elements med through end

        var box1  = Box();
        var box2  = Box();

        box1.init( data1 );
        box2.init( data2 );

        return [ box1, box2 ];

    },

    average = function() {

        // Returns the average value of the data in this box

        var avg_r = 0;
        var avg_g = 0;
        var avg_b = 0;

        for( var i = data.length - 1; i >= 0; --i ) {
            avg_r += data[i][0];
            avg_g += data[i][1];
            avg_b += data[i][2];
        }

        avg_r /= data.length;
        avg_g /= data.length;
        avg_b /= data.length;

        return [ parseInt( avg_r ),
                 parseInt( avg_g ),
                 parseInt( avg_b ) ];

    },

    median_pos = function() {

        // Returns the position of the median value of the data in
        // this box.  The position number is rounded down, to deal
        // with cases when the data has an odd number of elements.

        return Math.floor( data.length / 2 );

    },

    get_bounding_box = function() {
        // Getter for the bounding box
        return box;
    },

    calculate_bounding_box = function() {

        // keeps running tally of the min and max values on each dimension
        // initialize the min value to the highest number possible, and the
        // max value to the lowest number possible

        var minmax = [ { min: Number.MAX_VALUE, max: Number.MIN_VALUE },
                       { min: Number.MAX_VALUE, max: Number.MIN_VALUE },
                       { min: Number.MAX_VALUE, max: Number.MIN_VALUE } ];

        for( var i = data.length - 1; i >= 0; --i ) {

            minmax[0].min = ( data[i][0] < minmax[0].min ) ? data[i][0] : minmax[0].min; // r
            minmax[1].min = ( data[i][1] < minmax[1].min ) ? data[i][1] : minmax[1].min; // g
            minmax[2].min = ( data[i][2] < minmax[2].min ) ? data[i][2] : minmax[2].min; // b

            minmax[0].max = ( data[i][0] > minmax[0].max ) ? data[i][0] : minmax[0].max; // r
            minmax[1].max = ( data[i][1] > minmax[1].max ) ? data[i][1] : minmax[1].max; // g
            minmax[2].max = ( data[i][2] > minmax[2].max ) ? data[i][2] : minmax[2].max; // b
        }

        return minmax;

    },

    get_longest_axis = function() {

        // Returns the longest (aka "widest") axis of the data in this box.

        var longest_axis = 0,
            longest_axis_size = 0;

        for( var i = dim - 1; i >= 0; --i ) {
            var axis_size = box[i].max - box[i].min;
            if( axis_size > longest_axis_size ) {
                longest_axis      = i;
                longest_axis_size = axis_size;
            }
        }

        return { axis   : longest_axis,
                 length : longest_axis_size };
    };

    return {

        /**/ // these are private functions
        //get_data               : get_data,
        //median_pos             : median_pos,
        //get_bounding_box       : get_bounding_box,
        //calculate_bounding_box : calculate_bounding_box,
        //sort                   : sort,
        //get_comparison_func    : get_comparison_func,
        /**/

        // These are exposed (public) functions
        split            : split,
        get_longest_axis : get_longest_axis,
        average          : average,
        init             : init
    };
};
<commit_msg>restrict line length to 79 characters<commit_after> /**************************************************************************
  * This file is part of median-cut.js                                     *
  *                                                                        *
  * median-cut.js is free software: you can redistribute it and/or modify  *
  * it under the terms of the GNU General Public License as published by   *
  * the Free Software Foundation, either version 3 of the License, or      *
  * (at your option) any later version.                                    *
  *                                                                        *
  * median-cut.js is distributed in the hope that it will be useful,       *
  * but WITHOUT ANY WARRANTY; without even the implied warranty of         *
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
  * GNU General Public License for more details.                           *
  *                                                                        *
  * You should have received a copy of the GNU General Public License      *
  * along with median-cut.js.  If not, see <http://www.gnu.org/licenses/>. *
  **************************************************************************/

//  This is the median-cut algorithm.
//
//  1. Find the smallest box which contains all the colors in the image.
//
//  2. Sort the enclosed colors along the longest axis of the box.
//
//  3. Split the box into 2 regions at median of the sorted list.
//
//  4. Repeat the above process until the original color space has been divided
//     into N regions where N is the number of colors you want.

var MedianCut = function() {

    var boxes,

    init = function( _data ) {

        var box1 = Box();
        box1.init( _data );

        boxes = [ box1 ];

    },

    get_longest_box_index = function() {

        // find the box with the longest axis of them all...
        var longest_box_index = 0;

        for( var box_index = boxes.length - 1; box_index >= 0; --box_index ) {
            if( boxes[ box_index ] > longest_box_index ) {
                longest_box_index = boxes[ box_index ];
            }
        }

        return longest_box_index;

    },

    get_boxes = function() {
        return boxes;
    },

    get_dynamic_size_palette = function( _threshold ) {

        // threshold is a value in (0,1] that influences how many colors
        // will be in the resulting palette.  lower values of threshold
        // will result in a smaller palette size.

        var values = [],
            i,
            longest_box_index = get_longest_box_index(),
            longest_axis      = boxes[ longest_box_index ].get_longest_axis(),
            max_box_length    = longest_axis.length * ( 1 - _threshold );

        do {

            // remove the longest box and split it
            var box_to_split = boxes.splice( longest_box_index, 1 )[0];
            var split_boxes = box_to_split.split();
            var box1 = split_boxes[0];
            var box2 = split_boxes[1];

            // then push the resulting boxes into the boxes array
            boxes.push( box1 );
            boxes.push( box2 );

            longest_box_index = get_longest_box_index()
            longest_axis      = boxes[ longest_box_index ].get_longest_axis();

        }
        while( longest_axis.length > max_box_length );

        // palette is complete.  get the average colors from each box
        // and push them into the values array, then return.
        for( var i = boxes.length - 1; i >= 0; --i ) {
            values.push( boxes[i].average() );
        }

        return values;

    },

    get_fixed_size_palette = function( _number ) {

        var values = [];

        for( var i = _number - 1; i >= 0; --i ) {

            longest_box_index = get_longest_box_index();

            // remove the longest box and split it
            var box_to_split = boxes.splice( longest_box_index, 1 )[0];
            var split_boxes = box_to_split.split();
            var box1 = split_boxes[0];
            var box2 = split_boxes[1];

            // then push the resulting boxes into the boxes array
            boxes.push( box1 );
            boxes.push( box2 );
        }

        // palette is complete.  get the average colors from each box
        // and push them into the values array, then return.
        for( var i = _number - 1; i >= 0; --i ) {
            values.push( boxes[i].average() );
        }

        return values;

    };

    return {
        // This is a private function (listed here in case it needs to be made
        // public easily :)

        //get_boxes                : get_boxes

        // These are exposed (public) functions
        init                     : init,
        get_fixed_size_palette   : get_fixed_size_palette,
        get_dynamic_size_palette : get_dynamic_size_palette,
    };
};

var Box = function() {

    var data, // it's all about the data
        box,  // the bounding box of the data
        dim,  // number of dimensions in the data

    init = function( _data ) {

        // Initializes the data values, number of dimensions in the data
        // (currently fixed to 3 to handle RGB, but may be genericized in
        // the future), and the bounding box of the data.

        data = _data;
        dim  = 3; // lock this to 3 (RGB pixels) for now.
        box  = calculate_bounding_box();

    },

    get_data = function() {

        // Getter for data

        return data;

    },

    sort = function() {

        // Sorts all the elements in this box based on their values on the
        // longest axis.

        var a           = get_longest_axis().axis;
        var sort_method = get_comparison_func( a );

        data.sort( sort_method );

        return data;

    },

    get_comparison_func = function( _i ) {

        // Return a comparison function based on a given index (for median-cut,
        // sort on the longest axis) ie: sort ONLY on a single axis.
        // get_comparison_func( 1 ) would return a sorting function that sorts
        // the data according to each item's Green value.

        var sort_method = function( a, b ) {
            return a[_i] - b[_i];
        };

        return sort_method;

    },

    split = function() {

        // Splits this box in two and returns two box objects. This function
        // represents steps 2 and 3 of the algorithm, as written at the top
        // of this file.

        sort();

        var med   = median_pos();

        var data1 = data.slice( 0, med );   // elements 0 through med
        var data2 = data.slice( med );      // elements med through end

        var box1  = Box();
        var box2  = Box();

        box1.init( data1 );
        box2.init( data2 );

        return [ box1, box2 ];

    },

    average = function() {

        // Returns the average value of the data in this box

        var avg_r = 0;
        var avg_g = 0;
        var avg_b = 0;

        for( var i = data.length - 1; i >= 0; --i ) {
            avg_r += data[i][0];
            avg_g += data[i][1];
            avg_b += data[i][2];
        }

        avg_r /= data.length;
        avg_g /= data.length;
        avg_b /= data.length;

        return [ parseInt( avg_r ),
                 parseInt( avg_g ),
                 parseInt( avg_b ) ];

    },

    median_pos = function() {

        // Returns the position of the median value of the data in
        // this box.  The position number is rounded down, to deal
        // with cases when the data has an odd number of elements.

        return Math.floor( data.length / 2 );

    },

    get_bounding_box = function() {
        // Getter for the bounding box
        return box;
    },

    calculate_bounding_box = function() {

        // keeps running tally of the min and max values on each dimension
        // initialize the min value to the highest number possible, and the
        // max value to the lowest number possible

        var minmax = [ { min: Number.MAX_VALUE, max: Number.MIN_VALUE },
                       { min: Number.MAX_VALUE, max: Number.MIN_VALUE },
                       { min: Number.MAX_VALUE, max: Number.MIN_VALUE } ];

        for( var i = data.length - 1; i >= 0; --i ) {

            minmax[0].min = ( data[i][0] < minmax[0].min ) ?
                              data[i][0] : minmax[0].min; // r
            minmax[1].min = ( data[i][1] < minmax[1].min ) ?
                              data[i][1] : minmax[1].min; // g
            minmax[2].min = ( data[i][2] < minmax[2].min ) ?
                              data[i][2] : minmax[2].min; // b

            minmax[0].max = ( data[i][0] > minmax[0].max ) ?
                              data[i][0] : minmax[0].max; // r
            minmax[1].max = ( data[i][1] > minmax[1].max ) ?
                              data[i][1] : minmax[1].max; // g
            minmax[2].max = ( data[i][2] > minmax[2].max ) ?
                              data[i][2] : minmax[2].max; // b
        }

        return minmax;

    },

    get_longest_axis = function() {

        // Returns the longest (aka "widest") axis of the data in this box.

        var longest_axis = 0,
            longest_axis_size = 0;

        for( var i = dim - 1; i >= 0; --i ) {
            var axis_size = box[i].max - box[i].min;
            if( axis_size > longest_axis_size ) {
                longest_axis      = i;
                longest_axis_size = axis_size;
            }
        }

        return { axis   : longest_axis,
                 length : longest_axis_size };
    };

    return {

        /**/ // these are private functions
        //get_data               : get_data,
        //median_pos             : median_pos,
        //get_bounding_box       : get_bounding_box,
        //calculate_bounding_box : calculate_bounding_box,
        //sort                   : sort,
        //get_comparison_func    : get_comparison_func,
        /**/

        // These are exposed (public) functions
        split            : split,
        get_longest_axis : get_longest_axis,
        average          : average,
        init             : init
    };
};
<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var Promise = require('bluebird');

module.exports = function (MR) {

	var user = MR.userModel({name: String, age: Number});
	var fighter = MR.model('fighter', {
			name: String,
			health: Number,
			born: Date,
			death: { type: Date, permissions: {R: 4, W: 20}},
			owner: { type: mongoose.Schema.Types.ObjectId, ref: 'user', required: true }
		}, {
			schemaInit: function (schema) {
				// if you want to call any methods on schema before model is created, you can do so in schemaInit
				schema.index({ owner: 1, name: 1 }, { unique: true, dropDups: true });
			},
			permissions: {
				C: 20,
				R: 0,
				U: 50,
				D: 50
			}
//            checkPermission: function () {    //for overriding permission check
//                return false;
//            }
		}
	);

	fighter.model.on('preupdate', function (doc, evName, previous) {
		console.log("special preupdate callback triggered " + doc.isModified()); // a good place to put custom save logic
		console.dir(doc);
		console.dir(previous);
	});

	var battleM = MR.model('battle', {
		name: String,
		year: Number,
		fighters: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Fighter' }]
	});

    var cleaningPromises = [fighter, user].map(function (mrModel) {
        var dfd = Promise.defer();

        mrModel.model.remove({}, function(err) {
            if (err) {
                dfd.reject();
            }
            dfd.resolve();
        });
        return dfd.promise;

    });

    Promise.all(cleaningPromises).then(function () {
        console.log("all collections should be clean");

        user.model.create({
            name: 'admin', privilige_level: 50
        }).then(function () {
            console.log("admin created");
        });

        user.model.create({
            name: 'testUser', privilige_level: 10
        }).then(function () {
            console.log("testUser created");
        });

    });

};<commit_msg>just nicer formatting<commit_after>var mongoose = require('mongoose');
var Promise = require('bluebird');

module.exports = function (MR) {

	var user = MR.userModel({name: String, age: Number});
	var fighter = MR.model('fighter', {
		name: String,
		health: Number,
		born: Date,
		death: {type: Date, permissions: {R: 4, W: 20}}
	}, {
		schemaInit: function(schema) {
			// if you want to call any methods on schema before model is created, you can do so in schemaInit
			schema.index({owner: 1, name: 1}, {unique: true, dropDups: true});
			// you may notice that we index here field owner even though we did not specify such field in the schema. It is because owner field is added to every model schema
		},
		permissions: {
			C: 20,
			R: 0,
			U: 50,
			D: 50
		}
//            checkPermission: function () {    //for overriding permission check
//                return false;
//            }
	});

	fighter.model.on('preupdate', function (doc, evName, previous) {
		console.log("special preupdate callback triggered " + doc.isModified()); // a good place to put custom save logic
		console.dir(doc);
		console.dir(previous);
	});

	var battleM = MR.model('battle', {
		name: String,
		year: Number,
		fighters: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Fighter' }]
	});

    var cleaningPromises = [fighter, user].map(function (mrModel) {
        var dfd = Promise.defer();

        mrModel.model.remove({}, function(err) {
            if (err) {
                dfd.reject();
            }
            dfd.resolve();
        });
        return dfd.promise;

    });

    Promise.all(cleaningPromises).then(function () {
        console.log("all collections should be clean");

        user.model.create({
            name: 'admin', privilige_level: 50
        }).then(function () {
            console.log("admin created");
        });

        user.model.create({
            name: 'testUser', privilige_level: 10
        }).then(function () {
            console.log("testUser created");
        });

    });

};<|endoftext|>