<commit_before>import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import htmlToElement from './htmlToElement';
import {Linking, StyleSheet, View} from 'react-native';

const boldStyle = {fontWeight: '500'};
const italicStyle = {fontStyle: 'italic'};
const underlineStyle = {textDecorationLine: 'underline'};
const codeStyle = {fontFamily: 'Menlo'};

const baseStyles = StyleSheet.create({
  b: boldStyle,
  strong: boldStyle,
  i: italicStyle,
  em: italicStyle,
  u: underlineStyle,
  pre: codeStyle,
  code: codeStyle,
  a: {
    fontWeight: '500',
    color: '#007AFF',
  },
  h1: {fontWeight: '500', fontSize: 36},
  h2: {fontWeight: '500', fontSize: 30},
  h3: {fontWeight: '500', fontSize: 24},
  h4: {fontWeight: '500', fontSize: 18},
  h5: {fontWeight: '500', fontSize: 14},
  h6: {fontWeight: '500', fontSize: 12},
});

const htmlToElementOptKeys = [
  'lineBreak',
  'paragraphBreak',
  'bullet',
  'TextComponent',
  'textComponentProps',
  'NodeComponent',
  'nodeComponentProps',
];

class HtmlView extends PureComponent {
  constructor() {
    super();
    this.state = {
      element: null,
    };
  }

  componentDidMount() {
    this.mounted = true;
    this.startHtmlRender(this.props.value);
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.value !== nextProps.value || this.props.stylesheet !== nextProps.stylesheet) {
      this.startHtmlRender(nextProps.value, nextProps.stylesheet);
    }
  }

  componentWillUnmount() {
    this.mounted = false;
  }

  startHtmlRender(value, style) {
    const {
      addLineBreaks,
      onLinkPress,
      onLinkLongPress,
      stylesheet,
      renderNode,
      onError,
    } = this.props;

    if (!value) {
      this.setState({element: null});
    }

    const opts = {
      addLineBreaks,
      linkHandler: onLinkPress,
      linkLongPressHandler: onLinkLongPress,
      styles: {...baseStyles, ...stylesheet, ...style},
      customRenderer: renderNode,
    };

    htmlToElementOptKeys.forEach(key => {
      if (typeof this.props[key] !== 'undefined') {
        opts[key] = this.props[key];
      }
    });

    htmlToElement(value, opts, (err, element) => {
      if (err) {
        onError(err);
      }

      if (this.mounted) {
        this.setState({element});
      }
    });
  }

  render() {
    const {RootComponent, style} = this.props;
    const {element} = this.state;
    if (element) {
      return (
        <RootComponent
          {...this.props.rootComponentProps}
          style={style}
        >
          {element}
        </RootComponent>
      );
    }
    return (
      <RootComponent
        {...this.props.rootComponentProps}
        style={style}
      />
    );
  }
}

HtmlView.propTypes = {
  addLineBreaks: PropTypes.bool,
  bullet: PropTypes.string,
  lineBreak: PropTypes.string,
  NodeComponent: PropTypes.func,
  nodeComponentProps: PropTypes.object,
  onError: PropTypes.func,
  onLinkPress: PropTypes.func,
  onLinkLongPress: PropTypes.func,
  paragraphBreak: PropTypes.string,
  renderNode: PropTypes.func,
  RootComponent: PropTypes.func,
  rootComponentProps: PropTypes.object,
  style: View.propTypes.style,
  stylesheet: PropTypes.object,
  TextComponent: PropTypes.func,
  textComponentProps: PropTypes.object,
  value: PropTypes.string,
};

HtmlView.defaultProps = {
  addLineBreaks: true,
  onLinkPress: url => Linking.openURL(url),
  onLinkLongPress: null,
  onError: console.error.bind(console),
  RootComponent: View,
};

export default HtmlView;
<commit_msg>Use monospace font for pre on Android<commit_after>import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import htmlToElement from './htmlToElement';
import {Linking, Platform, StyleSheet, View} from 'react-native';

const boldStyle = {fontWeight: '500'};
const italicStyle = {fontStyle: 'italic'};
const underlineStyle = {textDecorationLine: 'underline'};
const codeStyle = {fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace' };

const baseStyles = StyleSheet.create({
  b: boldStyle,
  strong: boldStyle,
  i: italicStyle,
  em: italicStyle,
  u: underlineStyle,
  pre: codeStyle,
  code: codeStyle,
  a: {
    fontWeight: '500',
    color: '#007AFF',
  },
  h1: {fontWeight: '500', fontSize: 36},
  h2: {fontWeight: '500', fontSize: 30},
  h3: {fontWeight: '500', fontSize: 24},
  h4: {fontWeight: '500', fontSize: 18},
  h5: {fontWeight: '500', fontSize: 14},
  h6: {fontWeight: '500', fontSize: 12},
});

const htmlToElementOptKeys = [
  'lineBreak',
  'paragraphBreak',
  'bullet',
  'TextComponent',
  'textComponentProps',
  'NodeComponent',
  'nodeComponentProps',
];

class HtmlView extends PureComponent {
  constructor() {
    super();
    this.state = {
      element: null,
    };
  }

  componentDidMount() {
    this.mounted = true;
    this.startHtmlRender(this.props.value);
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.value !== nextProps.value || this.props.stylesheet !== nextProps.stylesheet) {
      this.startHtmlRender(nextProps.value, nextProps.stylesheet);
    }
  }

  componentWillUnmount() {
    this.mounted = false;
  }

  startHtmlRender(value, style) {
    const {
      addLineBreaks,
      onLinkPress,
      onLinkLongPress,
      stylesheet,
      renderNode,
      onError,
    } = this.props;

    if (!value) {
      this.setState({element: null});
    }

    const opts = {
      addLineBreaks,
      linkHandler: onLinkPress,
      linkLongPressHandler: onLinkLongPress,
      styles: {...baseStyles, ...stylesheet, ...style},
      customRenderer: renderNode,
    };

    htmlToElementOptKeys.forEach(key => {
      if (typeof this.props[key] !== 'undefined') {
        opts[key] = this.props[key];
      }
    });

    htmlToElement(value, opts, (err, element) => {
      if (err) {
        onError(err);
      }

      if (this.mounted) {
        this.setState({element});
      }
    });
  }

  render() {
    const {RootComponent, style} = this.props;
    const {element} = this.state;
    if (element) {
      return (
        <RootComponent
          {...this.props.rootComponentProps}
          style={style}
        >
          {element}
        </RootComponent>
      );
    }
    return (
      <RootComponent
        {...this.props.rootComponentProps}
        style={style}
      />
    );
  }
}

HtmlView.propTypes = {
  addLineBreaks: PropTypes.bool,
  bullet: PropTypes.string,
  lineBreak: PropTypes.string,
  NodeComponent: PropTypes.func,
  nodeComponentProps: PropTypes.object,
  onError: PropTypes.func,
  onLinkPress: PropTypes.func,
  onLinkLongPress: PropTypes.func,
  paragraphBreak: PropTypes.string,
  renderNode: PropTypes.func,
  RootComponent: PropTypes.func,
  rootComponentProps: PropTypes.object,
  style: View.propTypes.style,
  stylesheet: PropTypes.object,
  TextComponent: PropTypes.func,
  textComponentProps: PropTypes.object,
  value: PropTypes.string,
};

HtmlView.defaultProps = {
  addLineBreaks: true,
  onLinkPress: url => Linking.openURL(url),
  onLinkLongPress: null,
  onError: console.error.bind(console),
  RootComponent: View,
};

export default HtmlView;
<|endoftext|>


<commit_before>define({
	// should add a way to recursivley call eloquent when verification passes
	define : {
		allow   : "*",
		require : [
			"morph",
			"transistor",
			"event_master"
		],
	},

	make : function ( define ) {

		var shumput_body, event_circle

		shumput_body = this.library.transistor.make(
			this.define_body( define )
		)
		event_circle = this.library.event_master.make({
			state  : this.define_state( define ),
			events : this.define_event({
				body : shumput_body,
				with : define.with
			})
		})
		event_circle.add_listener(
			this.define_listener( define )
		)

		return this.define_interface({
			body         : shumput_body,
			event_master : event_circle
		})
	},

	define_interface : function ( define ) {
		return {
			body      : define.body.body,
			append    : define.body.append,
			get_state : function () {
				return define.event_master.get_state()
			},
			reset     : function () {
				define.event_master.stage_event({
					called : "reset",
					as     : function ( state ) {
						return {
							event : {
								target : define.body.body
							},
							state : state
						}
					}
				})
			},
		}
	},

	define_state : function ( define ) {
		var default_value
		default_value = define.with.value || ""
		return {
			value          : default_value,
			original_value : default_value,
			valid          : ( !define.with.verify ),
			verify         : define.with.verify || {}
		}
	},

	define_event : function ( define ) {
		return [
			{
				called : "reset"
			},
			{
				called       : "shumput input type",
				that_happens : [
					{
						on : define.body.body,
						is : [ "keyup" ]
					}
				],
				only_if      : function ( heard ) {
					return heard.event.target.hasAttribute("data-shumput")
				}
			}
		]
	},

	define_listener : function ( define ) {
		var self = this
		return [
			{
				for       : "reset",
				that_does : function ( heard ) {

					var input_node, option_state

					input_node         = heard.event.target.firstChild
					option_state       = heard.state
					option_state.value = option_state.original_value
					input_node.value   = option_state.original_value
					input_node.setAttribute("value", option_state.original_value )

					if ( option_state.verify && option_state.verify.when ) {

						var verification, text_body

						text_body = input_node.nextSibling

						if ( option_state.verify.when( input_node.value ) ) {

							verification            = option_state.verify.with( input_node.value )
							option_state.valid      = verification.is_valid
							text_body.textContent   = verification.text
							text_body.style.display = "block"

						} else {
							text_body.style.display = "none"
						}
					}

					return heard
				}
			},
			{
				for       : "shumput input type",
				that_does : function ( heard ) {

					var input_node, option_state

					input_node   = heard.event.target
					option_state = heard.state

					if ( option_state.verify && option_state.verify.when ) {

						var verification, text_body

						text_body = input_node.nextSibling

						if ( option_state.verify.when( input_node.value ) ) {

							verification            = option_state.verify.with( input_node.value )
							option_state.valid      = verification.is_valid
							option_state.value      = input_node.value
							text_body.textContent   = verification.text
							text_body.style.display = "block"

							if ( option_state.valid ) {
								text_body.setAttribute( "class", define.class_name.text_valid )
							} else {
								text_body.setAttribute( "class", define.class_name.text_invalid )
							}

						} else {
							text_body.style.display = "none"
						}

					}

					return heard
				}
			}
		]
	},

	define_body : function ( define ) {
		return {
			"class" : define.class_name.wrap,
			"child" : [
				( define.with.size === "large" ?
					this.define_large( define ) :
					this.define_small( define )
				)
			].concat(
				( define.with.verify ?
					this.define_text( define ) :
					[]
				)
			)
		}
	},

	define_text : function ( define ) {

		var verification, default_value, to_be_shown

		default_value = define.with.value || ""
		to_be_shown   = define.with.verify.when( default_value )
		verification  = {
			is_valud : false,
			text     : ""
		}

		if ( to_be_shown ) {
			verification = define.with.verify.with( default_value )
		}

		return {
			"class"   : (
				verification.is_valid ?
					define.class_name.text_valid :
					define.class_name.text_invalid
			),
			"text"    : verification.text,
			"display" : ( to_be_shown ? "block" : "none" )
		}
	},

	define_small : function ( define ) {

		var definition

		definition = {
			"type"         : "input",
			"class"        : define.class_name.small,
			"value"        : define.with.value || "",
			"data-shumput" : "true"
		}

		if ( define.with.placeholder ) {
			definition.placeholder = define.with.placeholder
		}

		return definition
	},

	define_large : function ( define ) {

		var definition

		definition = {
			"type"         : "textarea",
			"data-shumput" : "true",
			"class"        : define.class_name.large,
			"text"         : define.with.value || ""
		}

		if ( define.with.placeholder ) {
			definition.placeholder = define.with.placeholder
		}

		return definition
	},
})<commit_msg>Some small changes<commit_after>define({
	// should add a way to recursivley call eloquent when verification passes
	define : {
		allow   : "*",
		require : [
			"morph",
			"transistor",
			"event_master"
		],
	},

	make : function ( define ) {

		var shumput_body, event_circle

		shumput_body = this.library.transistor.make(
			this.define_body( define )
		)
		event_circle = this.library.event_master.make({
			state  : this.define_state( define ),
			events : this.define_event({
				body : shumput_body,
				with : define.with
			})
		})
		event_circle.add_listener(
			this.define_listener( define )
		)

		return this.define_interface({
			body         : shumput_body,
			event_master : event_circle
		})
	},

	define_interface : function ( define ) {
		return {
			body      : define.body.body,
			append    : define.body.append,
			get_state : function () {
				return define.event_master.get_state()
			},
			reset     : function () {
				define.event_master.stage_event({
					called : "reset",
					as     : function ( state ) {
						return {
							event : {
								target : define.body.body
							},
							state : state
						}
					}
				})
			},
		}
	},

	define_state : function ( define ) {
		var default_value
		default_value = define.with.value || ""
		return {
			value          : default_value,
			original_value : default_value,
			valid          : ( !define.with.verify ),
			verify         : define.with.verify || {}
		}
	},

	define_event : function ( define ) {
		return [
			{
				called : "reset"
			},
			{
				called       : "shumput input type",
				that_happens : [
					{
						on : define.body.body,
						is : [ "keyup" ]
					}
				],
				only_if      : function ( heard ) {
					return heard.event.target.hasAttribute("data-shumput")
				}
			}
		]
	},

	define_listener : function ( define ) {
		var self = this
		return [
			{
				for       : "reset",
				that_does : function ( heard ) {

					var input_node, option_state

					input_node         = heard.event.target.firstChild
					option_state       = heard.state
					option_state.value = option_state.original_value
					input_node.value   = option_state.original_value
					input_node.setAttribute("value", option_state.original_value )

					if ( option_state.verify && option_state.verify.when ) {

						var verification, text_body

						text_body = input_node.nextSibling

						if ( option_state.verify.when( input_node.value ) ) {

							verification            = option_state.verify.with( input_node.value )
							option_state.valid      = verification.is_valid
							text_body.textContent   = verification.text
							text_body.style.display = "block"

						} else {
							text_body.style.display = "none"
						}
					}

					return heard
				}
			},
			{
				for       : "shumput input type",
				that_does : function ( heard ) {

					var input_node, option_state
					input_node         = heard.event.target
					option_state       = heard.state
					option_state.value = input_node.value

					if ( option_state.verify && option_state.verify.when ) {

						var verification, text_body

						text_body = input_node.nextSibling

						if ( option_state.verify.when( input_node.value ) ) {

							verification            = option_state.verify.with( input_node.value )
							option_state.valid      = verification.is_valid
							text_body.textContent   = verification.text
							text_body.style.display = "block"

							if ( option_state.valid ) {
								text_body.setAttribute( "class", define.class_name.text_valid )
							} else {
								text_body.setAttribute( "class", define.class_name.text_invalid )
							}

						} else {
							text_body.style.display = "none"
						}

					}

					return heard
				}
			}
		]
	},

	define_body : function ( define ) {
		return {
			"class" : define.class_name.wrap,
			"child" : [
				( define.with.size === "large" ?
					this.define_large( define ) :
					this.define_small( define )
				)
			].concat(
				( define.with.verify ?
					this.define_text( define ) :
					[]
				)
			)
		}
	},

	define_text : function ( define ) {

		var verification, default_value, to_be_shown

		default_value = define.with.value || ""
		to_be_shown   = define.with.verify.when( default_value )
		verification  = {
			is_valud : false,
			text     : ""
		}

		if ( to_be_shown ) {
			verification = define.with.verify.with( default_value )
		}

		return {
			"class"   : (
				verification.is_valid ?
					define.class_name.text_valid :
					define.class_name.text_invalid
			),
			"text"    : verification.text,
			"display" : ( to_be_shown ? "block" : "none" )
		}
	},

	define_small : function ( define ) {

		var definition

		definition = {
			"type"         : "input",
			"class"        : define.class_name.small,
			"value"        : define.with.value || "",
			"data-shumput" : "true"
		}

		if ( define.with.placeholder ) {
			definition.placeholder = define.with.placeholder
		}

		return definition
	},

	define_large : function ( define ) {

		var definition

		definition = {
			"type"         : "textarea",
			"data-shumput" : "true",
			"class"        : define.class_name.large,
			"text"         : define.with.value || ""
		}

		if ( define.with.placeholder ) {
			definition.placeholder = define.with.placeholder
		}

		return definition
	},
})<|endoftext|>


<commit_before>import Color from "color";
import classnames from "classnames";
import withHover from "../../helperComponents/withHover";
import getAnnotationNameAndStartStopString from "../../utils/getAnnotationNameAndStartStopString";

import React from "react";
import { doesLabelFitInAnnotation } from "../utils";
import { noop } from "lodash";
import getAnnotationClassnames from "../../utils/getAnnotationClassnames";

class PointedAnnotation extends React.PureComponent {
  render() {
    let {
      className,
      widthInBps,
      charWidth,
      height,
      rangeType,
      forward,
      name = "",
      type,
      onMouseLeave,
      onMouseOver,
      isProtein,
      id,
      hideName,
      pointiness = 8,
      color = "orange",
      fill,
      stroke,
      opacity,
      onClick,
      onDoubleClick = noop,
      textColor,
      onRightClick,
      gapsInside,
      gapsBefore,
      annotation,
      externalLabels,
      onlyShowLabelsThatDoNotFit
    } = this.props;

    const classNames = getAnnotationClassnames(annotation, {
      isProtein,
      type,
      viewName: "RowView"
    });

    let width = (widthInBps + gapsInside) * charWidth;
    let charWN = charWidth; //charWN is normalized
    if (charWidth < 15) {
      //allow the arrow width to adapt
      if (width > 15) {
        charWN = 15; //tnr: replace 15 here with a non-hardcoded number..
      } else {
        charWN = width;
      }
    }
    let widthMinusOne = width - charWN;
    let path;
    let hasAPoint = false;
    const endLine = annotation.doesOverlapSelf
      ? `L 0,${height / 2}
    L -10,${height / 2}
    L 0,${height / 2} `
      : "";
    const arrowLine = annotation.doesOverlapSelf
      ? `L ${width + 10},${height / 2}
    L ${width},${height / 2} `
      : "";
    // starting from the top left of the annotation
    if (rangeType === "middle") {
      //draw a rectangle
      path = `
          M 0,0
          L ${width - pointiness / 2},0
          Q ${width + pointiness / 2},${height / 2} ${
        width - pointiness / 2
      },${height}
          L ${0},${height}
          Q ${pointiness},${height / 2} ${0},${0}
          z`;
    } else if (rangeType === "start") {
      path = `
          M 0,0
          L ${width - pointiness / 2},0
          Q ${width + pointiness / 2},${height / 2} ${
        width - pointiness / 2
      },${height}
          L 0,${height}
          ${endLine}
          z`;
    } else if (rangeType === "beginningAndEnd") {
      hasAPoint = true;
      path = `
          M 0,0
          L ${widthMinusOne},0
          L ${width},${height / 2}
          ${arrowLine}
          L ${widthMinusOne},${height}
          L 0,${height}
          ${endLine}
          z`;
    } else {
      hasAPoint = true;
      path = `
        M 0,0
        L ${widthMinusOne},0
        L ${width},${height / 2}
        ${arrowLine}
        L ${widthMinusOne},${height}
        L 0,${height}
        Q ${pointiness},${height / 2} ${0},${0}
        z`;
    }
    let nameToDisplay = name;
    let textOffset =
      width / 2 -
      (name.length * 5) / 2 -
      (hasAPoint ? (pointiness / 2) * (forward ? 1 : -1) : 0);
    if (
      !doesLabelFitInAnnotation(name, { width }, charWidth) ||
      (externalLabels &&
        !onlyShowLabelsThatDoNotFit &&
        ["parts", "features"].includes(annotation.annotationTypePlural))
    ) {
      textOffset = 0;
      nameToDisplay = "";
    }

    return (
      <g
        {...{ onMouseLeave, onMouseOver }}
        className={` clickable ${className} ${classNames}`}
        data-id={id}
        onClick={function (event) {
          onClick({ annotation, event, gapsBefore, gapsInside });
        }}
        onDoubleClick={function (event) {
          onDoubleClick &&
            onDoubleClick({ annotation, event, gapsBefore, gapsInside });
        }}
        onContextMenu={function (event) {
          onRightClick({ annotation, event, gapsBefore, gapsInside });
        }}
      >
        <title>
          {getAnnotationNameAndStartStopString(annotation, { isProtein })}
        </title>
        <path
          strokeWidth="1"
          stroke={stroke || "black"}
          opacity={opacity}
          fill={fill || color}
          transform={forward ? null : "translate(" + width + ",0) scale(-1,1) "}
          d={path}
        />
        {!hideName && nameToDisplay && (
          <text
            className={classnames(
              "veLabelText ve-monospace-font",
              annotation.labelClassName
            )}
            style={{
              fontSize: ".9em",
              fill: textColor || (Color(color).isDark() ? "white" : "black")
            }}
            transform={`translate(${textOffset},${height - 2})`}
          >
            {nameToDisplay}
          </text>
        )}
      </g>
    );
  }
}

export default withHover(PointedAnnotation);
<commit_msg>fix feature click error in preview mode<commit_after>import Color from "color";
import classnames from "classnames";
import withHover from "../../helperComponents/withHover";
import getAnnotationNameAndStartStopString from "../../utils/getAnnotationNameAndStartStopString";

import React from "react";
import { doesLabelFitInAnnotation } from "../utils";
import { noop } from "lodash";
import getAnnotationClassnames from "../../utils/getAnnotationClassnames";

class PointedAnnotation extends React.PureComponent {
  render() {
    let {
      className,
      widthInBps,
      charWidth,
      height,
      rangeType,
      forward,
      name = "",
      type,
      onMouseLeave,
      onMouseOver,
      isProtein,
      id,
      hideName,
      pointiness = 8,
      color = "orange",
      fill,
      stroke,
      opacity,
      onClick = noop,
      onDoubleClick = noop,
      textColor,
      onRightClick = noop,
      gapsInside,
      gapsBefore,
      annotation,
      externalLabels,
      onlyShowLabelsThatDoNotFit
    } = this.props;

    const classNames = getAnnotationClassnames(annotation, {
      isProtein,
      type,
      viewName: "RowView"
    });

    let width = (widthInBps + gapsInside) * charWidth;
    let charWN = charWidth; //charWN is normalized
    if (charWidth < 15) {
      //allow the arrow width to adapt
      if (width > 15) {
        charWN = 15; //tnr: replace 15 here with a non-hardcoded number..
      } else {
        charWN = width;
      }
    }
    let widthMinusOne = width - charWN;
    let path;
    let hasAPoint = false;
    const endLine = annotation.doesOverlapSelf
      ? `L 0,${height / 2}
    L -10,${height / 2}
    L 0,${height / 2} `
      : "";
    const arrowLine = annotation.doesOverlapSelf
      ? `L ${width + 10},${height / 2}
    L ${width},${height / 2} `
      : "";
    // starting from the top left of the annotation
    if (rangeType === "middle") {
      //draw a rectangle
      path = `
          M 0,0
          L ${width - pointiness / 2},0
          Q ${width + pointiness / 2},${height / 2} ${
        width - pointiness / 2
      },${height}
          L ${0},${height}
          Q ${pointiness},${height / 2} ${0},${0}
          z`;
    } else if (rangeType === "start") {
      path = `
          M 0,0
          L ${width - pointiness / 2},0
          Q ${width + pointiness / 2},${height / 2} ${
        width - pointiness / 2
      },${height}
          L 0,${height}
          ${endLine}
          z`;
    } else if (rangeType === "beginningAndEnd") {
      hasAPoint = true;
      path = `
          M 0,0
          L ${widthMinusOne},0
          L ${width},${height / 2}
          ${arrowLine}
          L ${widthMinusOne},${height}
          L 0,${height}
          ${endLine}
          z`;
    } else {
      hasAPoint = true;
      path = `
        M 0,0
        L ${widthMinusOne},0
        L ${width},${height / 2}
        ${arrowLine}
        L ${widthMinusOne},${height}
        L 0,${height}
        Q ${pointiness},${height / 2} ${0},${0}
        z`;
    }
    let nameToDisplay = name;
    let textOffset =
      width / 2 -
      (name.length * 5) / 2 -
      (hasAPoint ? (pointiness / 2) * (forward ? 1 : -1) : 0);
    if (
      !doesLabelFitInAnnotation(name, { width }, charWidth) ||
      (externalLabels &&
        !onlyShowLabelsThatDoNotFit &&
        ["parts", "features"].includes(annotation.annotationTypePlural))
    ) {
      textOffset = 0;
      nameToDisplay = "";
    }

    return (
      <g
        {...{ onMouseLeave, onMouseOver }}
        className={` clickable ${className} ${classNames}`}
        data-id={id}
        onClick={function (event) {
          onClick({ annotation, event, gapsBefore, gapsInside });
        }}
        onDoubleClick={function (event) {
          onDoubleClick &&
            onDoubleClick({ annotation, event, gapsBefore, gapsInside });
        }}
        onContextMenu={function (event) {
          onRightClick({ annotation, event, gapsBefore, gapsInside });
        }}
      >
        <title>
          {getAnnotationNameAndStartStopString(annotation, { isProtein })}
        </title>
        <path
          strokeWidth="1"
          stroke={stroke || "black"}
          opacity={opacity}
          fill={fill || color}
          transform={forward ? null : "translate(" + width + ",0) scale(-1,1) "}
          d={path}
        />
        {!hideName && nameToDisplay && (
          <text
            className={classnames(
              "veLabelText ve-monospace-font",
              annotation.labelClassName
            )}
            style={{
              fontSize: ".9em",
              fill: textColor || (Color(color).isDark() ? "white" : "black")
            }}
            transform={`translate(${textOffset},${height - 2})`}
          >
            {nameToDisplay}
          </text>
        )}
      </g>
    );
  }
}

export default withHover(PointedAnnotation);
<|endoftext|>


<commit_before>var loggedInUser = {
		      "_id":"56be5ae3f3289a31645ef276",
		      "name":"John Mon Calamari",
		      "type":"player",
		      "phoneNumber":"0729003605",
		      "hasPets":true,
		      "allergies":[
		         "squids",
		         "octopus",
		         "oysters",
		         "calamares"
		      ],
		      "__v":0,
		      "awards":[

		      ],
		      "challenges":{
		         "published":[

		         ],
		         "active":[

		         ],
		         "completed":[

		         ]
		      },
		      "location":{
		         "address":"Valhallavägen 21",
		         "geojson":{
		            "type":"Point",
		            "coordinates":[
		               -105.01621,
		               39.57422
		            ]
		         }
		      }
			}

angular.module('app',[
	'ngRoute',
	'app.homeModule',
	'app.createChallengeModule',
	'app.challengeListModule',
	'app.challengeViewModule',
	'app.leaderBoardModule',
	'app.achievementListModule',
	'app.profileViewModule',
	'app.challengeHistoryModule',
	'app.headerModule',
	'app.footerModule'
	])
.controller('mainController', function($scope, $http) {
		 $http.get("http://kommoncare.davidmr.es/api/users")
	    .then(function(response) {
	       alert(response);
	    });
	});<commit_msg>server user loading<commit_after>var loggedInUser;

angular.module('app',[
	'ngRoute',
	'app.homeModule',
	'app.createChallengeModule',
	'app.challengeListModule',
	'app.challengeViewModule',
	'app.leaderBoardModule',
	'app.achievementListModule',
	'app.profileViewModule',
	'app.challengeHistoryModule',
	'app.headerModule',
	'app.footerModule'
	])
.controller('mainController', function($scope, $http) {
		id = "56be644c2c73f39864399e60";
		$http.get("http://kommoncare.davidmr.es/api/users/" +id)
	    .then(function(response) {
	    	loggedInUser = response;
	    });
	});<|endoftext|>


<commit_before>(function () {
    'use strict';

    var React = require('react');

    module.exports = React.createClass({
        render: function () {
            return React.DOM.div({className: 'period-of-stay-input'}, this.topRow());
        },

        topRow: function () {
            var m = this.props.model,
                e = this.props.environment,

                result = [
                    React.DOM.label(
                        {className: 'period-of-stay-check-in', key: 0},
                        'Check-in day',
                        React.DOM.input({type: 'date', ref: 'checkIn', value: m.checkInDate})
                    ),

                    React.DOM.label(
                        {className: 'period-of-stay-check-out', key: 1},
                        'Check-out day',
                        React.DOM.input({type: 'date', ref: 'checkOut', value: m.checkOutDate})
                    ),

                    React.DOM.label(
                        {className: 'period-of-stay-nights', key: 2},
                        'Nights',

                        React.DOM.input({
                            type: 'number',
                            min: 1,
                            step: 1,
                            max: 27,
                            ref: 'nights',
                            value: m.nightsCount()
                        })
                    )
                ];

            if (e.zeroNightsAllowed) {
                if (m.nightsCount() === 0) {
                    result.push(
                        React.DOM.a(
                            {className: 'period-of-stay-overnight', href: '', key: 3},
                            'Overnight stay'
                        )
                    );
                }
                else {
                    result.push(
                        React.DOM.a(
                            {className: 'period-of-stay-one-day', href: '', key: 3},
                            '1-day stay'
                        )
                    );
                }
            }

            return result;
        }
    });
}());
<commit_msg>Extract valueInputs() and addModeLinks()<commit_after>(function () {
    'use strict';

    var React = require('react');

    module.exports = React.createClass({
        render: function () {
            return React.DOM.div(
                {className: 'period-of-stay-input'}, this.addModeLinks(this.valueInputs()));
        },

        valueInputs: function () {
            var m = this.props.model;

            return [
                React.DOM.label(
                    {className: 'period-of-stay-check-in', key: 0},
                    'Check-in day',
                    React.DOM.input({type: 'date', ref: 'checkIn', value: m.checkInDate})
                ),

                React.DOM.label(
                    {className: 'period-of-stay-check-out', key: 1},
                    'Check-out day',
                    React.DOM.input({type: 'date', ref: 'checkOut', value: m.checkOutDate})
                ),

                React.DOM.label(
                    {className: 'period-of-stay-nights', key: 2},
                    'Nights',

                    React.DOM.input({
                        type: 'number',
                        min: 1,
                        step: 1,
                        max: 27,
                        ref: 'nights',
                        value: m.nightsCount()
                    })
                )
            ];
        },

        addModeLinks: function (componentsArray) {
            var m = this.props.model,
                e = this.props.environment,
                result = componentsArray.slice();

            if (e.zeroNightsAllowed) {
                if (m.nightsCount() === 0) {
                    result.push(
                        React.DOM.a(
                            {className: 'period-of-stay-overnight', href: '', key: 3},
                            'Overnight stay'
                        )
                    );
                }
                else {
                    result.push(
                        React.DOM.a(
                            {className: 'period-of-stay-one-day', href: '', key: 3},
                            '1-day stay'
                        )
                    );
                }
            }

            return result;
        }
    });
}());
<|endoftext|>


<commit_before>$(function() {
  /* "list all" functions */
  $.ajax({
    type: 'GET'
    , url: 'http://' + window.location.hostname + '/api/show'
    , cache: false
    , success: function(data) {
      // Clear placeholder
      $('.dotted-list').html('');
      // Populate
 with host
's
      data.forEach(function(host) {
        $('.dotted-list').append('
' + host.ip + ' ' + host.host + '
');
      });
    }
  });

  /* "add host" functions */
  $('.modal-open#add-button').on('click', function() {
    // Show modal
    $('.modal#add').addClass('modal--active');

    // Check if text areas are not empty
    $('.btn--submit').attr('disabled', true);
    $('.modal#add input').on('keyup',function() {
      if ($('.modal#add #ip-input').val() && $('.modal#add #host-input').val()) {
        $('.modal#add .btn--submit').attr('disabled', false);
      } else {
        $('.modal#add .btn--submit').attr('disabled', true);
      }
    });

    // Save host
    $('.modal#add .modal-save').on('click', function() {
      // Close modal
      $('.modal#add').removeClass('modal--active');
      // Show saving overlay
      $('.modal#add').addClass('modal--saving');

      // Create POST object
      var postObject = {
        'host': $('.modal#add #host-input').val()
        , 'ip': $('.modal#add #ip-input').val()
      };

      // Send POST request to API
      $.ajax({
        type: 'POST'
        , url: 'http://' + window.location.hostname + '/api/add'
        , data: postObject
        , dataType: 'json'
        , success: function(data) {
          if (!data.success && data.errors.name) {
            // Log errors
            console.log(data.errors.name);
          } else {
            // Remove saving class
            $('.modal#add').removeClass('modal--saving');
            // Reload page
            location.reload();
          }
        }
      });
    });
  });

  /* "edit host" functions */
  // @TODO - is this below performant?
  $(document).on('click', 'li#host', function() {
    // Show modal
    $('.modal#edit').addClass('modal--active');

    // Get current host details
    var hostId = $(this).data('host')
        , hostName = $('span#host', this).html()
        , hostIp = $('span#ip', this).html();

    // Fill host and ip inputs
    $('.modal#edit #id-input').val(hostId);
    $('.modal#edit #host-input').val(hostName);
    $('.modal#edit #ip-input').val(hostIp);

    // Check if text areas are not empty
    $('.modal#edit input').on('keyup',function() {
      if ($('.modal#edit #ip-input').val() && $('.modal#edit #host-input').val()) {
        $('.modal#edit .btn--submit').attr('disabled', false);
      } else {
        $('.modal#edit .btn--submit').attr('disabled', true);
      }
    });

    // Save edited host
    $('.modal#edit .modal-save').on('click', function() {
      // Close modal
      $('.modal#edit').removeClass('modal--active');
      // Show saving overlay
      $('.modal#edit').addClass('modal--saving');

      // Create POST object
      var postObject = {
        'host': $('.modal#edit #host-input').val()
        , 'ip': $('.modal#edit #ip-input').val()
      };

      // Send PUT request to API
      $.ajax({
        type: 'PUT'
        , url: 'http://' + window.location.hostname + '/api/edit/' + hostId
        , data: postObject
        , success: function(data) {
          if (!data.success && data.errors.name) {
            // Log errors
            console.log(data.errors.name);
          } else {
            // Remove saving class
            $('.modal#edit').removeClass('modal--saving');
            // Reload page
            location.reload();
          }
        }
      });
    });
  });

  /* "delete host" functions */
  $('.modal-delete').on('click', function() {
    // Get current host details
    var hostId = $('.modal#edit #id-input').val();
    console.log(hostId);
    // Close modal
    $('.modal#edit').removeClass('modal--active');
    // Show saving overlay
    $('.modal#edit').addClass('modal--saving');

    // Send DELETE request to API
    $.ajax({
      type: 'DELETE'
      , url: 'http://' + window.location.hostname + '/api/delete/' + hostId
      , success: function(data) {
        if (!data.success && data.errors.name) {
          // Log errors
          console.log(data.errors.name);
        } else {
          // Remove saving class
          $('.modal#edit').removeClass('modal--saving');
          // Reload page
          location.reload();
        }
      }
    });
  });

  // Close modals on click on close button
  $('.modal button.modal-close').on('click', function() {
    // Close modal
    $('.modal').removeClass('modal--active');
    // Remove saving class
    $('.modal').removeClass('modal--saving');
  });
});
<commit_msg>Reload list without page refresh<commit_after>$(function() {
  /* "list all" functions */
  var appendHostList = function() {
    $.ajax({
      type: 'GET'
      , url: 'http://' + window.location.hostname + '/api/show'
      , cache: false
      , success: function(data) {
        // Clear placeholder
        $('.dotted-list').html('');
        // Populate
 with host
's
        data.forEach(function(host) {
          $('.dotted-list').append('
' + host.ip + ' ' + host.host + '
');
        });
      }
    });
  };

  appendHostList();

  /* "add host" functions */
  $('.modal-open#add-button').on('click', function() {
    // Show modal
    $('.modal#add').addClass('modal--active');

    // Check if text areas are not empty
    $('.btn--submit').attr('disabled', true);
    $('.modal#add input').on('keyup',function() {
      if ($('.modal#add #ip-input').val() && $('.modal#add #host-input').val()) {
        $('.modal#add .btn--submit').attr('disabled', false);
      } else {
        $('.modal#add .btn--submit').attr('disabled', true);
      }
    });

    // Save host
    $('.modal#add .modal-save').on('click', function() {
      // Close modal
      $('.modal#add').removeClass('modal--active');
      // Show saving overlay
      $('.modal#add').addClass('modal--saving');

      // Create POST object
      var postObject = {
        'host': $('.modal#add #host-input').val()
        , 'ip': $('.modal#add #ip-input').val()
      };

      // Send POST request to API
      $.ajax({
        type: 'POST'
        , url: 'http://' + window.location.hostname + '/api/add'
        , data: postObject
        , dataType: 'json'
        , success: function(data) {
          if (!data.success && data.errors.name) {
            // Log errors
            console.log(data.errors.name);
          } else {
            // Remove saving class
            setTimeout(function() {
              $('.modal#add').removeClass('modal--saving');
            }, 800);
            // Reload page
            appendHostList();
          }
        }
      });
    });
  });

  /* "edit host" functions */
  // @TODO - is this below performant?
  $(document).on('click', 'li#host', function() {
    // Show modal
    $('.modal#edit').addClass('modal--active');

    // Get current host details
    var hostId = $(this).data('host')
        , hostName = $('span#host', this).html()
        , hostIp = $('span#ip', this).html();

    // Fill host and ip inputs
    $('.modal#edit #id-input').val(hostId);
    $('.modal#edit #host-input').val(hostName);
    $('.modal#edit #ip-input').val(hostIp);

    // Check if text areas are not empty
    $('.modal#edit input').on('keyup',function() {
      if ($('.modal#edit #ip-input').val() && $('.modal#edit #host-input').val()) {
        $('.modal#edit .btn--submit').attr('disabled', false);
      } else {
        $('.modal#edit .btn--submit').attr('disabled', true);
      }
    });

    // Save edited host
    $('.modal#edit .modal-save').on('click', function() {
      // Close modal
      $('.modal#edit').removeClass('modal--active');
      // Show saving overlay
      $('.modal#edit').addClass('modal--saving');

      // Create POST object
      var postObject = {
        'host': $('.modal#edit #host-input').val()
        , 'ip': $('.modal#edit #ip-input').val()
      };

      // Send PUT request to API
      $.ajax({
        type: 'PUT'
        , url: 'http://' + window.location.hostname + '/api/edit/' + hostId
        , data: postObject
        , success: function(data) {
          if (!data.success && data.errors.name) {
            // Log errors
            console.log(data.errors.name);
          } else {
            // Remove saving class
            setTimeout(function() {
              $('.modal#edit').removeClass('modal--saving');
            }, 800);
            // Reload page
            appendHostList();
          }
        }
      });
    });
  });

  /* "delete host" functions */
  $('.modal-delete').on('click', function() {
    // Get current host details
    var hostId = $('.modal#edit #id-input').val();
    console.log(hostId);
    // Close modal
    $('.modal#edit').removeClass('modal--active');
    // Show saving overlay
    $('.modal#edit').addClass('modal--saving');

    // Send DELETE request to API
    $.ajax({
      type: 'DELETE'
      , url: 'http://' + window.location.hostname + '/api/delete/' + hostId
      , success: function(data) {
        if (!data.success && data.errors.name) {
          // Log errors
          console.log(data.errors.name);
        } else {
          // Remove saving class
          setTimeout(function() {
            $('.modal#edit').removeClass('modal--saving');
          }, 800);
          // Reload page
          appendHostList();
        }
      }
    });
  });

  // Close modals on click on close button
  $('.modal button.modal-close').on('click', function() {
    // Close modal
    $('.modal').removeClass('modal--active');
    // Remove saving class
    $('.modal').removeClass('modal--saving');
  });
});
<|endoftext|>


<commit_before>
raw.charts.binning = function(){

	return {

		title : 'Hexagonal binning',

		description : "",

		model : raw.models.points(),

		options : {

			width : {
				title : 'Width',
				type : 'number',
				position : 1,
				description : 'Width is whatever',
				value : 800
			},

			height : {
				title : 'Height',
				type : 'number',
				position : 1,
				description : 'Width is whatever',
				value : 500
			},

			radius : {
				title : 'Cell radius',
				type : 'number',
				position : 1,
				description : 'Radius',
				value : 20
			},

			grid : {
				title : 'Grid',
				type : 'boolean',
				position : 2,
				description : '',
				value : true
			},

			color : {
				title : 'Color',
				type : 'color',
				position : 2,
				description : 'Color sucks!',
				value : raw.diverging()
			}
		},

		render : function(data, target) {

			var model = this.model,
					options = this.options,
					format = d3.format(",d");

			var points = model.applyOn(data);

			console.log(points)

			// let's calculate margins
			var marginLeft = !options.grid.value ? 0 : d3.max(points, function(d){ return (Math.log(d.y) / 2.302585092994046) + 1; }) * 9,
				marginBottom = !options.grid.value ? 0 : 20,
				width = options.width.value - marginLeft -2,
				height = options.height.value - marginBottom-1;

			var color = d3.scale.linear()
			    .domain([0, 20])
			    .range(["white", "steelblue"])
			    .interpolate(d3.interpolateLab);

			var hexbin = d3.hexbin()
			    .size([width, height])
			    .x(function(d){ return xScale(d.x); })
			    .y(function(d){ return yScale(d.y); })
			    .radius(this.options.radius.value);

			var	xScale = d3.scale.linear().range([marginLeft,this.options.width.value-1]).domain([ d3.min(points, function(d){ return d.x; }), d3.max(points, function(d){ return d.x; }) ]),
					yScale = d3.scale.linear().range([height, 0]).domain([ d3.min(points, function(d){ return d.y; }), d3.max(points, function(d){ return d.y; }) ])

			var xAxis = d3.svg.axis()
			    .scale(xScale)
			    .orient("bottom")
			    .tickSize(6, -height);

			var yAxis = d3.svg.axis()
			    .scale(yScale)
			    .orient("left")
			    .tickSize(6, -width);

			svg = target.append("svg:svg")
			    .attr("width", parseInt(options.width.value))
			    .attr("height", parseInt(options.height.value))
			  	.append("svg:g")
			    .attr("transform", "translate(0,0)");

			svg.append("clipPath")
			    .attr("id", "clip")
			  .append("rect")
			    .attr("class", "mesh")
			    .attr("width", width)
			    .attr("height", height)
			    .attr("transform", "translate(" + marginLeft + ",1)");

			    console.log(hexbin(points))

			svg.append("g")
			    .attr("clip-path", "url(#clip)")
			  .selectAll(".hexagon")
			    .data(hexbin(points))
			  .enter().append("path")
			    .attr("class", "hexagon")
			    .attr("d", hexbin.hexagon())
			    .attr("transform", function(d) { console.log(d); return "translate(" + d.x + "," + d.y + ")"; })
			    .style("fill", function(d) { return color(d.length); })
			    .attr("stroke","#000")
			    .attr("stroke-width",".5px")

			svg.append("g")
			    .attr("class", "y axis")
			    .attr("transform", "translate(" + marginLeft + ",0)")
			    .call(yAxis);

			svg.append("g")
			    .attr("class", "x axis")
			    .attr("transform", "translate(0," + height + ")")
			    .call(xAxis);

			svg.selectAll(".axis")
				.selectAll("text")
				.style("font","10px sans-serif")

			svg.selectAll(".axis")
				.selectAll("path")
				.style("fill","none")
				.style("stroke","#000000")
				.style("shape-rendering","crispEdges")

			svg.selectAll(".axis")
				.selectAll("line")
				.style("fill","none")
				.style("stroke","#000000")
				.style("shape-rendering","crispEdges")

			return this;
		}

	}
};<commit_msg>added description & changed the name<commit_after>raw.charts.binning = function(){

	return {

		title : 'Binned scatterplot',

		description : 'Visually clusters the most populated areas on a scatterplot. Useful to make more readable a scatterplot when plotting hundreds of points.
Based on http://bl.ocks.org/mbostock/4248145',

		model : raw.models.points(),

		options : {

			width : {
				title : 'Width',
				type : 'number',
				position : 1,
				description : 'Width is whatever',
				value : 800
			},

			height : {
				title : 'Height',
				type : 'number',
				position : 1,
				description : 'Width is whatever',
				value : 500
			},

			radius : {
				title : 'Cell radius',
				type : 'number',
				position : 1,
				description : 'Radius',
				value : 20
			},

			grid : {
				title : 'Grid',
				type : 'boolean',
				position : 2,
				description : '',
				value : true
			},

			color : {
				title : 'Color',
				type : 'color',
				position : 2,
				description : 'Color sucks!',
				value : raw.diverging()
			}
		},

		render : function(data, target) {

			var model = this.model,
					options = this.options,
					format = d3.format(",d");

			var points = model.applyOn(data);

			console.log(points)

			// let's calculate margins
			var marginLeft = !options.grid.value ? 0 : d3.max(points, function(d){ return (Math.log(d.y) / 2.302585092994046) + 1; }) * 9,
				marginBottom = !options.grid.value ? 0 : 20,
				width = options.width.value - marginLeft -2,
				height = options.height.value - marginBottom-1;

			var color = d3.scale.linear()
			    .domain([0, 20])
			    .range(["white", "steelblue"])
			    .interpolate(d3.interpolateLab);

			var hexbin = d3.hexbin()
			    .size([width, height])
			    .x(function(d){ return xScale(d.x); })
			    .y(function(d){ return yScale(d.y); })
			    .radius(this.options.radius.value);

			var	xScale = d3.scale.linear().range([marginLeft,this.options.width.value-1]).domain([ d3.min(points, function(d){ return d.x; }), d3.max(points, function(d){ return d.x; }) ]),
					yScale = d3.scale.linear().range([height, 0]).domain([ d3.min(points, function(d){ return d.y; }), d3.max(points, function(d){ return d.y; }) ])

			var xAxis = d3.svg.axis()
			    .scale(xScale)
			    .orient("bottom")
			    .tickSize(6, -height);

			var yAxis = d3.svg.axis()
			    .scale(yScale)
			    .orient("left")
			    .tickSize(6, -width);

			svg = target.append("svg:svg")
			    .attr("width", parseInt(options.width.value))
			    .attr("height", parseInt(options.height.value))
			  	.append("svg:g")
			    .attr("transform", "translate(0,0)");

			svg.append("clipPath")
			    .attr("id", "clip")
			  .append("rect")
			    .attr("class", "mesh")
			    .attr("width", width)
			    .attr("height", height)
			    .attr("transform", "translate(" + marginLeft + ",1)");

			    console.log(hexbin(points))

			svg.append("g")
			    .attr("clip-path", "url(#clip)")
			  .selectAll(".hexagon")
			    .data(hexbin(points))
			  .enter().append("path")
			    .attr("class", "hexagon")
			    .attr("d", hexbin.hexagon())
			    .attr("transform", function(d) { console.log(d); return "translate(" + d.x + "," + d.y + ")"; })
			    .style("fill", function(d) { return color(d.length); })
			    .attr("stroke","#000")
			    .attr("stroke-width",".5px")

			svg.append("g")
			    .attr("class", "y axis")
			    .attr("transform", "translate(" + marginLeft + ",0)")
			    .call(yAxis);

			svg.append("g")
			    .attr("class", "x axis")
			    .attr("transform", "translate(0," + height + ")")
			    .call(xAxis);

			svg.selectAll(".axis")
				.selectAll("text")
				.style("font","10px sans-serif")

			svg.selectAll(".axis")
				.selectAll("path")
				.style("fill","none")
				.style("stroke","#000000")
				.style("shape-rendering","crispEdges")

			svg.selectAll(".axis")
				.selectAll("line")
				.style("fill","none")
				.style("stroke","#000000")
				.style("shape-rendering","crispEdges")

			return this;
		}

	}
};
<|endoftext|>


<commit_before>import detectIt from 'detect-it';
import objectAssign from 'object-assign';
import PropTypes from 'prop-types';
import React from 'react';
import ReactCursorPosition from 'react-cursor-position';

import EnlargedImage from './EnlargedImage';
import ShadedLens from './shaded-lens';
import DisplayUntilActive from './hint/DisplayUntilActive';
import Hint from './hint/DefaultHint';

import { getLensCursorOffset } from './lib/lens';
import {
    getEnlargedImageContainerDimension,
    getDefaultEnlargedImageContainerDimensions
} from './lib/dimensions';
import {
    getContainerStyle,
    getSmallImageStyle
} from './lib/styles';
import {
    LargeImageShape,
    SmallImageShape
} from './prop-types/Image';
import {
    EnlargedImagePosition,
    EnlargedImageContainerDimensions
} from './prop-types/EnlargedImage';
import { noop } from './utils';
import {
    INPUT_TYPE,
    ENLARGED_IMAGE_POSITION
} from './constants';

class ReactImageMagnify extends React.Component {

    constructor(props) {
        super(props);

        const { primaryInput } = detectIt;
        const {
            mouse: MOUSE,
            touch: TOUCH
        } = INPUT_TYPE;

        this.state = {
            smallImageWidth: 0,
            smallImageHeight: 0,
            detectedInputType: {
                isMouseDeteced: (primaryInput === MOUSE),
                isTouchDetected: (primaryInput === TOUCH)
            }
        }

        this.onSmallImageLoad = this.onSmallImageLoad.bind(this);
        this.setSmallImageDimensionState = this.setSmallImageDimensionState.bind(this);
        this.onDetectedInputTypeChanged = this.onDetectedInputTypeChanged.bind(this);
    }

    static propTypes = {
        className: PropTypes.string,
        enlargedImageContainerClassName: PropTypes.string,
        enlargedImageContainerStyle: PropTypes.object,
        enlargedImageClassName: PropTypes.string,
        enlargedImageStyle: PropTypes.object,
        enlargedImageContainerDimensions: EnlargedImageContainerDimensions,
        fadeDurationInMs: PropTypes.number,
        hintComponent: PropTypes.func,
        shouldHideHintAfterFirstActivation: PropTypes.bool,
        isHintEnabled: PropTypes.bool,
        hintTextMouse: PropTypes.string,
        hintTextTouch: PropTypes.string,
        hoverDelayInMs: PropTypes.number,
        hoverOffDelayInMs: PropTypes.number,
        isActivatedOnTouch: PropTypes.bool,
        imageClassName: PropTypes.string,
        imageStyle: PropTypes.object,
        largeImage: LargeImageShape,
        lensStyle: PropTypes.object,
        pressDuration: PropTypes.number,
        pressMoveThreshold: PropTypes.number,
        smallImage: SmallImageShape,
        style: PropTypes.object,
        enlargedImagePosition: EnlargedImagePosition
    };

    static defaultProps = {
        enlargedImageContainerDimensions: {
            width: '100%',
            height: '100%'
        },
        fadeDurationInMs: 300,
        hintComponent: Hint,
        shouldHideHintAfterFirstActivation: true,
        isHintEnabled: false,
        hintTextMouse: 'Hover to Zoom',
        hintTextTouch: 'Long-Touch to Zoom',
        hoverDelayInMs: 250,
        hoverOffDelayInMs: 150
    };

    componentDidMount() {
        const {
            smallImage: {
                isFluidWidth
            }
        } = this.props;

        if (!isFluidWidth) {
            return;
        }

        this.setSmallImageDimensionState();
        window.addEventListener('resize', this.setSmallImageDimensionState);
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.setSmallImageDimensionState);
    }

    onSmallImageLoad(e) {
        const {
            smallImage: {
                onLoad = noop
            }
        } = this.props;

        onLoad(e);

        if (!this.props.smallImage.isFluidWidth) {
            return;
        }

        this.setSmallImageDimensionState();
    }

    onDetectedInputTypeChanged(detectedInputType) {
        this.setState({
            detectedInputType
        });
    }

    setSmallImageDimensionState() {
        const {
            offsetWidth: smallImageWidth,
            offsetHeight: smallImageHeight
        } = this.smallImageEl;

        this.setState({
            smallImageWidth,
            smallImageHeight
        });
    }

    get smallImage() {
        const {
            smallImage,
            smallImage: {
                isFluidWidth: isSmallImageFluidWidth
            },
        } = this.props;
        const {
            smallImageWidth,
            smallImageHeight
        } = this.state;

        const fluidWidthSmallImage = objectAssign(
            {},
            smallImage,
            {
                width: smallImageWidth,
                height: smallImageHeight
            }
        );
        const fixedWidthSmallImage = smallImage;

        return isSmallImageFluidWidth
            ? fluidWidthSmallImage
            : fixedWidthSmallImage
    }

    get enlargedImagePlacement() {
        const {
            enlargedImagePosition: userDefinedEnlargedImagePosition
        } = this.props;

        const {
            detectedInputType: {
                isTouchDetected
            }
        } = this.state;

        const computedEnlargedImagePosition = (
            isTouchDetected
                ? ENLARGED_IMAGE_POSITION.over
                : ENLARGED_IMAGE_POSITION.beside
        );

        return userDefinedEnlargedImagePosition || computedEnlargedImagePosition;
    }

    get isInPlaceMode() {
        return this.enlargedImagePlacement === ENLARGED_IMAGE_POSITION.over;
    }

    get enlargedImageContainerDimensions() {
        const {
            enlargedImageContainerDimensions: {
                width: containerWidth,
                height: containerHeight
            }
        } = this.props;
        const {
            width: smallImageWidth,
            height: smallImageHeight
        } = this.smallImage;

        if (this.isInPlaceMode) {
            return getDefaultEnlargedImageContainerDimensions(this.smallImage);
        }

        return {
            width: getEnlargedImageContainerDimension({
                containerDimension: containerWidth,
                smallImageDimension: smallImageWidth
            }),
            height: getEnlargedImageContainerDimension({
                containerDimension: containerHeight,
                smallImageDimension: smallImageHeight
            })
        };
    }

    get shouldShowLens() {
        const {
            detectedInputType: {
                isTouchDetected
            }
        } = this.state;

        const enlargeImagePlacement = this.enlargedImagePlacement;

        return (
            enlargeImagePlacement !== ENLARGED_IMAGE_POSITION.over &&
            !isTouchDetected
        );

    }

    render() {
        const {
            className,
            enlargedImageContainerClassName,
            enlargedImageContainerStyle,
            enlargedImageClassName,
            enlargedImageStyle,
            fadeDurationInMs,
            hintComponent: HintComponent,
            shouldHideHintAfterFirstActivation,
            isHintEnabled,
            hintTextMouse,
            hintTextTouch,
            hoverDelayInMs,
            hoverOffDelayInMs,
            isActivatedOnTouch,
            imageClassName,
            imageStyle,
            largeImage,
            lensStyle,
            pressDuration,
            pressMoveThreshold,
            smallImage: {
                onError = noop
            },
            style,
        } = this.props;

        const smallImage = this.smallImage;

        const {
            detectedInputType: {
                isTouchDetected
            }
        } = this.state;

        const cursorOffset = getLensCursorOffset(
            smallImage,
            largeImage,
            this.enlargedImageContainerDimensions
        );

        return (
            <ReactCursorPosition { ...{
                className,
                hoverDelayInMs,
                hoverOffDelayInMs,
                isActivatedOnTouch,
                onDetectedInputTypeChanged: this.onDetectedInputTypeChanged,
                pressDuration,
                pressMoveThreshold,
                shouldStopTouchMovePropagation: true,
                style: getContainerStyle(smallImage, style)
            }}>
                <img { ...{
                    src: smallImage.src,
                    srcSet: smallImage.srcSet,
                    sizes: smallImage.sizes,
                    alt: smallImage.alt,
                    className: imageClassName,
                    style: getSmallImageStyle(smallImage, imageStyle),
                    ref: (el) => this.smallImageEl = el,
                    onLoad: this.onSmallImageLoad,
                    onError
                }} />
                {isHintEnabled &&
                    <DisplayUntilActive {...{
                        shouldHideAfterFirstActivation: shouldHideHintAfterFirstActivation
                    }}>
                        <HintComponent {...{
                            isTouchDetected,
                            hintTextMouse,
                            hintTextTouch
                        }}/>
                    </DisplayUntilActive>
                }
                {this.shouldShowLens &&
                    <ShadedLens {...{
                        cursorOffset,
                        fadeDurationInMs,
                        enlargedImageContainerDimensions: this.enlargedImageContainerDimensions,
                        smallImage,
                        style: lensStyle
                    }} />
                }
                <EnlargedImage { ...{
                    containerClassName: enlargedImageContainerClassName,
                    containerDimensions: this.enlargedImageContainerDimensions,
                    containerStyle: enlargedImageContainerStyle,
                    cursorOffset,
                    fadeDurationInMs,
                    imageClassName: enlargedImageClassName,
                    imageStyle: enlargedImageStyle,
                    imagePosition: this.enlargedImagePlacement,
                    largeImage,
                    smallImage
                }}/>
            </ReactCursorPosition>
        );
    }
}

export default ReactImageMagnify;
<commit_msg>Reorder Public PropTypes<commit_after>import detectIt from 'detect-it';
import objectAssign from 'object-assign';
import PropTypes from 'prop-types';
import React from 'react';
import ReactCursorPosition from 'react-cursor-position';

import EnlargedImage from './EnlargedImage';
import ShadedLens from './shaded-lens';
import DisplayUntilActive from './hint/DisplayUntilActive';
import Hint from './hint/DefaultHint';

import { getLensCursorOffset } from './lib/lens';
import {
    getEnlargedImageContainerDimension,
    getDefaultEnlargedImageContainerDimensions
} from './lib/dimensions';
import {
    getContainerStyle,
    getSmallImageStyle
} from './lib/styles';
import {
    LargeImageShape,
    SmallImageShape
} from './prop-types/Image';
import {
    EnlargedImagePosition,
    EnlargedImageContainerDimensions
} from './prop-types/EnlargedImage';
import { noop } from './utils';
import {
    INPUT_TYPE,
    ENLARGED_IMAGE_POSITION
} from './constants';

class ReactImageMagnify extends React.Component {

    constructor(props) {
        super(props);

        const { primaryInput } = detectIt;
        const {
            mouse: MOUSE,
            touch: TOUCH
        } = INPUT_TYPE;

        this.state = {
            smallImageWidth: 0,
            smallImageHeight: 0,
            detectedInputType: {
                isMouseDeteced: (primaryInput === MOUSE),
                isTouchDetected: (primaryInput === TOUCH)
            }
        }

        this.onSmallImageLoad = this.onSmallImageLoad.bind(this);
        this.setSmallImageDimensionState = this.setSmallImageDimensionState.bind(this);
        this.onDetectedInputTypeChanged = this.onDetectedInputTypeChanged.bind(this);
    }

    static propTypes = {
        className: PropTypes.string,
        style: PropTypes.object,
        hoverDelayInMs: PropTypes.number,
        hoverOffDelayInMs: PropTypes.number,
        fadeDurationInMs: PropTypes.number,
        pressDuration: PropTypes.number,
        pressMoveThreshold: PropTypes.number,
        isActivatedOnTouch: PropTypes.bool,
        imageClassName: PropTypes.string,
        imageStyle: PropTypes.object,
        lensStyle: PropTypes.object,
        smallImage: SmallImageShape,
        largeImage: LargeImageShape,
        enlargedImageContainerClassName: PropTypes.string,
        enlargedImageContainerStyle: PropTypes.object,
        enlargedImageClassName: PropTypes.string,
        enlargedImageStyle: PropTypes.object,
        enlargedImageContainerDimensions: EnlargedImageContainerDimensions,
        enlargedImagePosition: EnlargedImagePosition,
        hintComponent: PropTypes.func,
        hintTextMouse: PropTypes.string,
        hintTextTouch: PropTypes.string,
        isHintEnabled: PropTypes.bool,
        shouldHideHintAfterFirstActivation: PropTypes.bool
    };

    static defaultProps = {
        enlargedImageContainerDimensions: {
            width: '100%',
            height: '100%'
        },
        fadeDurationInMs: 300,
        hintComponent: Hint,
        shouldHideHintAfterFirstActivation: true,
        isHintEnabled: false,
        hintTextMouse: 'Hover to Zoom',
        hintTextTouch: 'Long-Touch to Zoom',
        hoverDelayInMs: 250,
        hoverOffDelayInMs: 150
    };

    componentDidMount() {
        const {
            smallImage: {
                isFluidWidth
            }
        } = this.props;

        if (!isFluidWidth) {
            return;
        }

        this.setSmallImageDimensionState();
        window.addEventListener('resize', this.setSmallImageDimensionState);
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.setSmallImageDimensionState);
    }

    onSmallImageLoad(e) {
        const {
            smallImage: {
                onLoad = noop
            }
        } = this.props;

        onLoad(e);

        if (!this.props.smallImage.isFluidWidth) {
            return;
        }

        this.setSmallImageDimensionState();
    }

    onDetectedInputTypeChanged(detectedInputType) {
        this.setState({
            detectedInputType
        });
    }

    setSmallImageDimensionState() {
        const {
            offsetWidth: smallImageWidth,
            offsetHeight: smallImageHeight
        } = this.smallImageEl;

        this.setState({
            smallImageWidth,
            smallImageHeight
        });
    }

    get smallImage() {
        const {
            smallImage,
            smallImage: {
                isFluidWidth: isSmallImageFluidWidth
            },
        } = this.props;
        const {
            smallImageWidth,
            smallImageHeight
        } = this.state;

        const fluidWidthSmallImage = objectAssign(
            {},
            smallImage,
            {
                width: smallImageWidth,
                height: smallImageHeight
            }
        );
        const fixedWidthSmallImage = smallImage;

        return isSmallImageFluidWidth
            ? fluidWidthSmallImage
            : fixedWidthSmallImage
    }

    get enlargedImagePlacement() {
        const {
            enlargedImagePosition: userDefinedEnlargedImagePosition
        } = this.props;

        const {
            detectedInputType: {
                isTouchDetected
            }
        } = this.state;

        const computedEnlargedImagePosition = (
            isTouchDetected
                ? ENLARGED_IMAGE_POSITION.over
                : ENLARGED_IMAGE_POSITION.beside
        );

        return userDefinedEnlargedImagePosition || computedEnlargedImagePosition;
    }

    get isInPlaceMode() {
        return this.enlargedImagePlacement === ENLARGED_IMAGE_POSITION.over;
    }

    get enlargedImageContainerDimensions() {
        const {
            enlargedImageContainerDimensions: {
                width: containerWidth,
                height: containerHeight
            }
        } = this.props;
        const {
            width: smallImageWidth,
            height: smallImageHeight
        } = this.smallImage;

        if (this.isInPlaceMode) {
            return getDefaultEnlargedImageContainerDimensions(this.smallImage);
        }

        return {
            width: getEnlargedImageContainerDimension({
                containerDimension: containerWidth,
                smallImageDimension: smallImageWidth
            }),
            height: getEnlargedImageContainerDimension({
                containerDimension: containerHeight,
                smallImageDimension: smallImageHeight
            })
        };
    }

    get shouldShowLens() {
        const {
            detectedInputType: {
                isTouchDetected
            }
        } = this.state;

        const enlargeImagePlacement = this.enlargedImagePlacement;

        return (
            enlargeImagePlacement !== ENLARGED_IMAGE_POSITION.over &&
            !isTouchDetected
        );

    }

    render() {
        const {
            className,
            enlargedImageContainerClassName,
            enlargedImageContainerStyle,
            enlargedImageClassName,
            enlargedImageStyle,
            fadeDurationInMs,
            hintComponent: HintComponent,
            shouldHideHintAfterFirstActivation,
            isHintEnabled,
            hintTextMouse,
            hintTextTouch,
            hoverDelayInMs,
            hoverOffDelayInMs,
            isActivatedOnTouch,
            imageClassName,
            imageStyle,
            largeImage,
            lensStyle,
            pressDuration,
            pressMoveThreshold,
            smallImage: {
                onError = noop
            },
            style,
        } = this.props;

        const smallImage = this.smallImage;

        const {
            detectedInputType: {
                isTouchDetected
            }
        } = this.state;

        const cursorOffset = getLensCursorOffset(
            smallImage,
            largeImage,
            this.enlargedImageContainerDimensions
        );

        return (
            <ReactCursorPosition { ...{
                className,
                hoverDelayInMs,
                hoverOffDelayInMs,
                isActivatedOnTouch,
                onDetectedInputTypeChanged: this.onDetectedInputTypeChanged,
                pressDuration,
                pressMoveThreshold,
                shouldStopTouchMovePropagation: true,
                style: getContainerStyle(smallImage, style)
            }}>
                <img { ...{
                    src: smallImage.src,
                    srcSet: smallImage.srcSet,
                    sizes: smallImage.sizes,
                    alt: smallImage.alt,
                    className: imageClassName,
                    style: getSmallImageStyle(smallImage, imageStyle),
                    ref: (el) => this.smallImageEl = el,
                    onLoad: this.onSmallImageLoad,
                    onError
                }} />
                {isHintEnabled &&
                    <DisplayUntilActive {...{
                        shouldHideAfterFirstActivation: shouldHideHintAfterFirstActivation
                    }}>
                        <HintComponent {...{
                            isTouchDetected,
                            hintTextMouse,
                            hintTextTouch
                        }}/>
                    </DisplayUntilActive>
                }
                {this.shouldShowLens &&
                    <ShadedLens {...{
                        cursorOffset,
                        fadeDurationInMs,
                        enlargedImageContainerDimensions: this.enlargedImageContainerDimensions,
                        smallImage,
                        style: lensStyle
                    }} />
                }
                <EnlargedImage { ...{
                    containerClassName: enlargedImageContainerClassName,
                    containerDimensions: this.enlargedImageContainerDimensions,
                    containerStyle: enlargedImageContainerStyle,
                    cursorOffset,
                    fadeDurationInMs,
                    imageClassName: enlargedImageClassName,
                    imageStyle: enlargedImageStyle,
                    imagePosition: this.enlargedImagePlacement,
                    largeImage,
                    smallImage
                }}/>
            </ReactCursorPosition>
        );
    }
}

export default ReactImageMagnify;
<|endoftext|>