import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import debug from 'debug';
import Button from '@material-ui/core/Button';
import { withStyles } from '@material-ui/core/styles';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import isEqual from 'lodash/isEqual';
import { mq, updateSpans, HorizontalKeypad } from '@pie-lib/math-input';
import { InputContainer, color } from '@pie-lib/render-ui';
import IconButton from '@material-ui/core/IconButton';
import require$$3 from '@material-ui/core/SvgIcon';

function _extends() {
  _extends = Object.assign || function (target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];

      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }

    return target;
  };

  return _extends.apply(this, arguments);
}

const markFractionBaseSuperscripts = () => {
  document.querySelectorAll('.mq-supsub.mq-sup-only').forEach(supsub => {
    const prev = supsub.previousElementSibling;

    if (prev && prev.classList.contains('mq-non-leaf') && prev.querySelector('.mq-fraction')) {
      supsub.classList.add('mq-after-fraction-group');
    } else {
      supsub.classList.remove('mq-after-fraction-group');
    }
  });
};

const {
  commonMqFontStyles: commonMqFontStyles$1,
  commonMqKeyboardStyles,
  longdivStyles: longdivStyles$1,
  supsubStyles: supsubStyles$1
} = mq.CommonMqStyles;
const log$1 = debug('@pie-lib:math-toolbar:editor-and-pad');
const decimalRegex = /\.|,/g;

const toNodeData = data => {
  if (!data) {
    return;
  }

  const {
    type,
    value
  } = data;

  if (type === 'command' || type === 'cursor') {
    return data;
  } else if (type === 'answer') {
    return _extends({
      type: 'answer'
    }, data);
  } else if (value === 'clear') {
    return {
      type: 'clear'
    };
  } else {
    return {
      type: 'write',
      value
    };
  }
};

class EditorAndPad extends React.Component {
  constructor(props) {
    super(props);

    this.onClick = data => {
      const {
        noDecimal,
        noLatexHandling,
        onChange
      } = this.props;
      const c = toNodeData(data);
      log$1('mathChange: ', c);

      if (noLatexHandling) {
        onChange(c.value);
        return;
      } // if decimals are not allowed for this response, we discard the input


      if (noDecimal && (c.value === '.' || c.value === ',')) {
        return;
      }

      if (!c) {
        return;
      }

      if (c.type === 'clear') {
        log$1('call clear...');
        this.input.clear();
      } else if (c.type === 'command') {
        this.input.command(c.value);
      } else if (c.type === 'cursor') {
        this.input.keystroke(c.value);
      } else if (c.type === 'answer') {
        this.input.write('%response%');
      } else {
        this.input.write(c.value);
      }
    };

    this.updateDisable = isEdit => {
      const {
        maxResponseAreas
      } = this.props;

      if (maxResponseAreas) {
        const shouldDisable = this.checkResponseAreasNumber(maxResponseAreas, isEdit);
        this.setState({
          addDisabled: shouldDisable
        });
      }
    };

    this.onAnswerBlockClick = () => {
      this.props.onAnswerBlockAdd();
      this.onClick({
        type: 'answer'
      });
      this.updateDisable(true);
    };

    this.onEditorChange = latex => {
      const {
        onChange,
        noDecimal
      } = this.props;
      updateSpans();
      markFractionBaseSuperscripts();
      this.updateDisable(true); // if no decimals are allowed and the last change is a decimal dot, discard the change

      if (noDecimal && (latex.indexOf('.') !== -1 || latex.indexOf(',') !== -1) && this.input) {
        this.input.clear();
        this.input.write(latex.replace(decimalRegex, ''));
        return;
      } // eslint-disable-next-line no-useless-escape


      const regexMatch = latex.match(/[0-9]\\ \\frac\{[^\{]*\}\{ \}/);

      if (this.input && regexMatch && regexMatch != null && regexMatch.length) {
        try {
          this.input.mathField.__controller.cursor.insLeftOf(this.input.mathField.__controller.cursor.parent[-1].parent);

          this.input.mathField.el().dispatchEvent(new KeyboardEvent('keydown', {
            keyCode: 8
          }));
        } catch (e) {
          // eslint-disable-next-line no-console
          console.error(e.toString());
        }

        return;
      }

      onChange(latex);
    };

    this.onEditorTypeChange = evt => {
      this.setState({
        equationEditor: evt.target.value
      });
    };

    this.checkResponseAreasNumber = (maxResponseAreas, isEdit) => {
      const {
        latex
      } = this.input && this.input.props || {};

      if (latex) {
        const count = (latex.match(/answerBlock/g) || []).length;
        return isEdit ? count === maxResponseAreas - 1 : count === maxResponseAreas;
      }

      return false;
    };

    this.state = {
      equationEditor: 'item-authoring',
      addDisabled: false
    };
  }

  componentDidMount() {
    if (this.input && this.props.autoFocus) {
      this.input.focus();
    }
  }

  /** Only render if the mathquill instance's latex is different
   * or the keypad state changed from one state to the other (shown / hidden) */
  shouldComponentUpdate(nextProps, nextState) {
    const inputIsDifferent = this.input.mathField.latex() !== nextProps.latex;
    log$1('[shouldComponentUpdate] ', 'inputIsDifferent: ', inputIsDifferent);

    if (!isEqual(this.props.error, nextProps.error)) {
      return true;
    }

    if (!inputIsDifferent && this.props.keypadMode !== nextProps.keypadMode) {
      return true;
    }

    if (!inputIsDifferent && this.props.noDecimal !== nextProps.noDecimal) {
      return true;
    }

    if (!inputIsDifferent && this.state.equationEditor !== nextState.equationEditor) {
      return true;
    }

    if (!inputIsDifferent && this.props.controlledKeypad) {
      return this.props.showKeypad !== nextProps.showKeypad;
    }

    return inputIsDifferent;
  }

  render() {
    const {
      classNames,
      keypadMode,
      allowAnswerBlock,
      additionalKeys,
      controlledKeypad,
      controlledKeypadMode,
      showKeypad,
      setKeypadInteraction,
      noDecimal,
      hideInput,
      layoutForKeyPad,
      latex,
      onFocus,
      onBlur,
      classes,
      error
    } = this.props;
    const shouldShowKeypad = !controlledKeypad || controlledKeypad && showKeypad;
    const {
      addDisabled
    } = this.state;
    log$1('[render]', latex);
    return /*#__PURE__*/React.createElement("div", {
      className: cx(classes.mathToolbar, classNames.mathToolbar)
    }, /*#__PURE__*/React.createElement("div", {
      className: cx(classes.inputAndTypeContainer, {
        [classes.hide]: hideInput
      })
    }, controlledKeypadMode && /*#__PURE__*/React.createElement(InputContainer, {
      label: "Equation Editor",
      className: classes.selectContainer
    }, /*#__PURE__*/React.createElement(Select, {
      className: classes.select,
      onChange: this.onEditorTypeChange,
      value: this.state.equationEditor
    }, /*#__PURE__*/React.createElement(MenuItem, {
      value: "non-negative-integers"
    }, "Numeric - Non-Negative Integers"), /*#__PURE__*/React.createElement(MenuItem, {
      value: "integers"
    }, "Numeric - Integers"), /*#__PURE__*/React.createElement(MenuItem, {
      value: "decimals"
    }, "Numeric - Decimals"), /*#__PURE__*/React.createElement(MenuItem, {
      value: "fractions"
    }, "Numeric - Fractions"), /*#__PURE__*/React.createElement(MenuItem, {
      value: 1
    }, "Grade 1 - 2"), /*#__PURE__*/React.createElement(MenuItem, {
      value: 3
    }, "Grade 3 - 5"), /*#__PURE__*/React.createElement(MenuItem, {
      value: 6
    }, "Grade 6 - 7"), /*#__PURE__*/React.createElement(MenuItem, {
      value: 8
    }, "Grade 8 - HS"), /*#__PURE__*/React.createElement(MenuItem, {
      value: 'geometry'
    }, "Geometry"), /*#__PURE__*/React.createElement(MenuItem, {
      value: 'advanced-algebra'
    }, "Advanced Algebra"), /*#__PURE__*/React.createElement(MenuItem, {
      value: 'statistics'
    }, "Statistics"), /*#__PURE__*/React.createElement(MenuItem, {
      value: 'item-authoring'
    }, "Item Authoring"))), /*#__PURE__*/React.createElement("div", {
      className: cx(classes.inputContainer, error ? classes.error : '')
    }, /*#__PURE__*/React.createElement(mq.Input, {
      onFocus: () => {
        onFocus && onFocus();
        this.updateDisable(false);
      },
      onBlur: event => {
        this.updateDisable(false);
        onBlur && onBlur(event);
      },
      className: cx(classes.mathEditor, classNames.editor, !controlledKeypadMode ? classes.longMathEditor : ''),
      innerRef: r => this.input = r,
      latex: latex,
      onChange: this.onEditorChange
    }))), allowAnswerBlock && /*#__PURE__*/React.createElement(Button, {
      className: classes.addAnswerBlockButton,
      type: "primary",
      style: {
        bottom: shouldShowKeypad ? '320px' : '20px'
      },
      onClick: this.onAnswerBlockClick,
      disabled: addDisabled
    }, "+ Response Area"), /*#__PURE__*/React.createElement("hr", {
      className: classes.hr
    }), shouldShowKeypad && /*#__PURE__*/React.createElement(HorizontalKeypad, {
      className: cx(classes[keypadMode], classes.keyboard),
      controlledKeypadMode: controlledKeypadMode,
      layoutForKeyPad: layoutForKeyPad,
      additionalKeys: additionalKeys,
      mode: controlledKeypadMode ? this.state.equationEditor : keypadMode,
      onClick: this.onClick,
      noDecimal: noDecimal,
      setKeypadInteraction: setKeypadInteraction
    }));
  }

}
EditorAndPad.propTypes = {
  classNames: PropTypes.object,
  keypadMode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  autoFocus: PropTypes.bool,
  allowAnswerBlock: PropTypes.bool,
  showKeypad: PropTypes.bool,
  controlledKeypad: PropTypes.bool,
  controlledKeypadMode: PropTypes.bool,
  error: PropTypes.string,
  noDecimal: PropTypes.bool,
  hideInput: PropTypes.bool,
  noLatexHandling: PropTypes.bool,
  layoutForKeyPad: PropTypes.object,
  maxResponseAreas: PropTypes.number,
  additionalKeys: PropTypes.array,
  latex: PropTypes.string.isRequired,
  onAnswerBlockAdd: PropTypes.func,
  onFocus: PropTypes.func,
  onBlur: PropTypes.func,
  onChange: PropTypes.func.isRequired,
  classes: PropTypes.object,
  setKeypadInteraction: PropTypes.func
};

const styles$2 = theme => ({
  inputAndTypeContainer: {
    display: 'flex',
    alignItems: 'center',
    '& .mq-editable-field .mq-cursor': {
      top: '-4px'
    },
    '& .mq-math-mode .mq-selection, .mq-editable-field .mq-selection': {
      paddingTop: '18px'
    },
    '& .mq-math-mode .mq-overarrow': {
      fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important'
    },
    '& .mq-math-mode .mq-overline .mq-overline-inner': {
      paddingTop: '0.4em !important'
    },
    '& .mq-overarrow.mq-arrow-both': {
      minWidth: '1.23em',
      '& *': {
        lineHeight: '1 !important'
      },
      '&:before': {
        top: '-0.45em',
        left: '-1px'
      },
      '&:after': {
        position: 'absolute !important',
        top: '0px !important',
        right: '-2px'
      },
      '&.mq-empty:after': {
        top: '-0.45em'
      }
    },
    '& .mq-overarrow.mq-arrow-right': {
      '&:before': {
        top: '-0.4em',
        right: '-1px'
      }
    },
    '& *': _extends({}, commonMqFontStyles$1, supsubStyles$1, longdivStyles$1, {
      '& .mq-math-mode .mq-sqrt-prefix': {
        verticalAlign: 'baseline !important',
        top: '1px !important',
        left: '-0.1em !important'
      },
      '& .mq-math-mode .mq-overarc ': {
        paddingTop: '0.45em !important'
      },
      '& .mq-math-mode .mq-empty': {
        padding: '9px 1px !important'
      },
      '& .mq-math-mode .mq-root-block': {
        paddingTop: '10px'
      },
      '& .mq-scaled .mq-sqrt-prefix': {
        top: '0 !important'
      },
      '& .mq-math-mode .mq-longdiv .mq-longdiv-inner': {
        marginLeft: '4px !important',
        paddingTop: '6px !important',
        paddingLeft: '6px !important'
      },
      '& .mq-math-mode .mq-paren': {
        verticalAlign: 'top !important',
        padding: '1px 0.1em !important'
      },
      '& .mq-math-mode .mq-sqrt-stem': {
        borderTop: '0.07em solid',
        marginLeft: '-1.5px',
        marginTop: '-2px !important',
        paddingTop: '5px !important'
      },
      '& .mq-math-mode .mq-denominator': {
        marginTop: '-5px !important',
        padding: '0.5em 0.1em 0.1em !important'
      },
      '& .mq-math-mode .mq-numerator, .mq-math-mode .mq-over': {
        padding: '0 0.1em !important',
        paddingBottom: '0 !important',
        marginBottom: '-2px'
      }
    }),
    '& span[data-prime="true"]': {
      fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important'
    }
  },
  hide: {
    display: 'none'
  },
  selectContainer: {
    flex: 'initial',
    width: '25%',
    minWidth: '100px',
    marginLeft: '15px',
    marginTop: '5px',
    marginBottom: '5px',
    marginRight: '5px',
    '& label': {
      fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important'
    },
    '& div': {
      fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important'
    }
  },
  mathEditor: {
    maxWidth: '400px',
    color: color.text(),
    backgroundColor: color.background(),
    padding: '2px'
  },
  longMathEditor: {
    maxWidth: '500px'
  },
  addAnswerBlockButton: {
    position: 'absolute',
    right: '12px',
    border: '1px solid lightgrey'
  },
  hr: {
    padding: 0,
    margin: 0,
    height: '1px',
    border: 'none',
    borderBottom: `solid 1px ${theme.palette.primary.main}`
  },
  mathToolbar: {
    zIndex: 9,
    position: 'relative',
    textAlign: 'center',
    width: 'auto',
    '& > .mq-math-mode': {
      border: 'solid 1px lightgrey'
    },
    '& > .mq-focused': {
      outline: 'none',
      boxShadow: 'none',
      border: `dotted 1px ${theme.palette.primary.main}`,
      borderRadius: '0px'
    },
    '& .mq-overarrow-inner': {
      border: 'none !important',
      paddingTop: '0 !important'
    },
    '& .mq-overarrow-inner-right': {
      display: 'none !important'
    },
    '& .mq-overarrow-inner-left': {
      display: 'none !important'
    },
    '& .mq-longdiv-inner': {
      borderTop: '1px solid !important',
      paddingTop: '1.5px !important'
    },
    '& .mq-overarrow.mq-arrow-both': {
      top: '7.8px',
      marginTop: '0px',
      minWidth: '1.23em'
    },
    '& .mq-parallelogram': {
      lineHeight: 0.85
    }
  },
  inputContainer: {
    minWidth: '500px',
    maxWidth: '900px',
    minHeight: '30px',
    width: '100%',
    display: 'flex',
    marginTop: theme.spacing.unit,
    marginBottom: theme.spacing.unit,
    '& .mq-sqrt-prefix .mq-scaled': {
      verticalAlign: 'middle !important'
    }
  },
  error: {
    border: '2px solid red'
  },
  keyboard: commonMqKeyboardStyles,
  language: {
    '& *': {
      fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important'
    }
  }
});

var EditorAndPad$1 = withStyles(styles$2)(EditorAndPad);

function getDefaultExportFromCjs (x) {
	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}

var Check$1 = {};

var interopRequireDefault = {exports: {}};

var hasRequiredInteropRequireDefault;

function requireInteropRequireDefault () {
	if (hasRequiredInteropRequireDefault) return interopRequireDefault.exports;
	hasRequiredInteropRequireDefault = 1;
	(function (module) {
		function _interopRequireDefault(obj) {
		  return obj && obj.__esModule ? obj : {
		    "default": obj
		  };
		}

		module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports; 
	} (interopRequireDefault));
	return interopRequireDefault.exports;
}

var createSvgIcon = {};

var pure = {};

var shouldUpdate = {};

var inheritsLoose = {exports: {}};

var setPrototypeOf = {exports: {}};

var hasRequiredSetPrototypeOf;

function requireSetPrototypeOf () {
	if (hasRequiredSetPrototypeOf) return setPrototypeOf.exports;
	hasRequiredSetPrototypeOf = 1;
	(function (module) {
		function _setPrototypeOf(o, p) {
		  module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
		    o.__proto__ = p;
		    return o;
		  }, module.exports.__esModule = true, module.exports["default"] = module.exports;
		  return _setPrototypeOf(o, p);
		}

		module.exports = _setPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports; 
	} (setPrototypeOf));
	return setPrototypeOf.exports;
}

var hasRequiredInheritsLoose;

function requireInheritsLoose () {
	if (hasRequiredInheritsLoose) return inheritsLoose.exports;
	hasRequiredInheritsLoose = 1;
	(function (module) {
		var setPrototypeOf = requireSetPrototypeOf();

		function _inheritsLoose(subClass, superClass) {
		  subClass.prototype = Object.create(superClass.prototype);
		  subClass.prototype.constructor = subClass;
		  setPrototypeOf(subClass, superClass);
		}

		module.exports = _inheritsLoose, module.exports.__esModule = true, module.exports["default"] = module.exports; 
	} (inheritsLoose));
	return inheritsLoose.exports;
}

var setDisplayName = {};

var setStatic = {};

var hasRequiredSetStatic;

function requireSetStatic () {
	if (hasRequiredSetStatic) return setStatic;
	hasRequiredSetStatic = 1;

	setStatic.__esModule = true;
	setStatic.default = void 0;

	var setStatic$1 = function setStatic(key, value) {
	  return function (BaseComponent) {
	    /* eslint-disable no-param-reassign */
	    BaseComponent[key] = value;
	    /* eslint-enable no-param-reassign */

	    return BaseComponent;
	  };
	};

	var _default = setStatic$1;
	setStatic.default = _default;
	return setStatic;
}

var hasRequiredSetDisplayName;

function requireSetDisplayName () {
	if (hasRequiredSetDisplayName) return setDisplayName;
	hasRequiredSetDisplayName = 1;

	var _interopRequireDefault = requireInteropRequireDefault();

	setDisplayName.__esModule = true;
	setDisplayName.default = void 0;

	var _setStatic = _interopRequireDefault(requireSetStatic());

	var setDisplayName$1 = function setDisplayName(displayName) {
	  return (0, _setStatic.default)('displayName', displayName);
	};

	var _default = setDisplayName$1;
	setDisplayName.default = _default;
	return setDisplayName;
}

var wrapDisplayName = {};

var getDisplayName = {};

var hasRequiredGetDisplayName;

function requireGetDisplayName () {
	if (hasRequiredGetDisplayName) return getDisplayName;
	hasRequiredGetDisplayName = 1;

	getDisplayName.__esModule = true;
	getDisplayName.default = void 0;

	var getDisplayName$1 = function getDisplayName(Component) {
	  if (typeof Component === 'string') {
	    return Component;
	  }

	  if (!Component) {
	    return undefined;
	  }

	  return Component.displayName || Component.name || 'Component';
	};

	var _default = getDisplayName$1;
	getDisplayName.default = _default;
	return getDisplayName;
}

var hasRequiredWrapDisplayName;

function requireWrapDisplayName () {
	if (hasRequiredWrapDisplayName) return wrapDisplayName;
	hasRequiredWrapDisplayName = 1;

	var _interopRequireDefault = requireInteropRequireDefault();

	wrapDisplayName.__esModule = true;
	wrapDisplayName.default = void 0;

	var _getDisplayName = _interopRequireDefault(requireGetDisplayName());

	var wrapDisplayName$1 = function wrapDisplayName(BaseComponent, hocName) {
	  return hocName + "(" + (0, _getDisplayName.default)(BaseComponent) + ")";
	};

	var _default = wrapDisplayName$1;
	wrapDisplayName.default = _default;
	return wrapDisplayName;
}

var hasRequiredShouldUpdate;

function requireShouldUpdate () {
	if (hasRequiredShouldUpdate) return shouldUpdate;
	hasRequiredShouldUpdate = 1;

	var _interopRequireDefault = requireInteropRequireDefault();

	shouldUpdate.__esModule = true;
	shouldUpdate.default = void 0;

	var _inheritsLoose2 = _interopRequireDefault(requireInheritsLoose());

	var _react = React;

	var _setDisplayName = _interopRequireDefault(requireSetDisplayName());

	var _wrapDisplayName = _interopRequireDefault(requireWrapDisplayName());

	var shouldUpdate$1 = function shouldUpdate(test) {
	  return function (BaseComponent) {
	    var factory = (0, _react.createFactory)(BaseComponent);

	    var ShouldUpdate =
	    /*#__PURE__*/
	    function (_Component) {
	      (0, _inheritsLoose2.default)(ShouldUpdate, _Component);

	      function ShouldUpdate() {
	        return _Component.apply(this, arguments) || this;
	      }

	      var _proto = ShouldUpdate.prototype;

	      _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps) {
	        return test(this.props, nextProps);
	      };

	      _proto.render = function render() {
	        return factory(this.props);
	      };

	      return ShouldUpdate;
	    }(_react.Component);

	    if (process.env.NODE_ENV !== 'production') {
	      return (0, _setDisplayName.default)((0, _wrapDisplayName.default)(BaseComponent, 'shouldUpdate'))(ShouldUpdate);
	    }

	    return ShouldUpdate;
	  };
	};

	var _default = shouldUpdate$1;
	shouldUpdate.default = _default;
	return shouldUpdate;
}

var shallowEqual = {};

/**
 * Copyright (c) 2013-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @typechecks
 * 
 */

var shallowEqual_1;
var hasRequiredShallowEqual$1;

function requireShallowEqual$1 () {
	if (hasRequiredShallowEqual$1) return shallowEqual_1;
	hasRequiredShallowEqual$1 = 1;

	var hasOwnProperty = Object.prototype.hasOwnProperty;

	/**
	 * inlined Object.is polyfill to avoid requiring consumers ship their own
	 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
	 */
	function is(x, y) {
	  // SameValue algorithm
	  if (x === y) {
	    // Steps 1-5, 7-10
	    // Steps 6.b-6.e: +0 != -0
	    // Added the nonzero y check to make Flow happy, but it is redundant
	    return x !== 0 || y !== 0 || 1 / x === 1 / y;
	  } else {
	    // Step 6.a: NaN == NaN
	    return x !== x && y !== y;
	  }
	}

	/**
	 * Performs equality by iterating through keys on an object and returning false
	 * when any key has values which are not strictly equal between the arguments.
	 * Returns true when the values of all keys are strictly equal.
	 */
	function shallowEqual(objA, objB) {
	  if (is(objA, objB)) {
	    return true;
	  }

	  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
	    return false;
	  }

	  var keysA = Object.keys(objA);
	  var keysB = Object.keys(objB);

	  if (keysA.length !== keysB.length) {
	    return false;
	  }

	  // Test for A's keys different from B.
	  for (var i = 0; i < keysA.length; i++) {
	    if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
	      return false;
	    }
	  }

	  return true;
	}

	shallowEqual_1 = shallowEqual;
	return shallowEqual_1;
}

var hasRequiredShallowEqual;

function requireShallowEqual () {
	if (hasRequiredShallowEqual) return shallowEqual;
	hasRequiredShallowEqual = 1;

	var _interopRequireDefault = requireInteropRequireDefault();

	shallowEqual.__esModule = true;
	shallowEqual.default = void 0;

	var _shallowEqual = _interopRequireDefault(requireShallowEqual$1());

	var _default = _shallowEqual.default;
	shallowEqual.default = _default;
	return shallowEqual;
}

var hasRequiredPure;

function requirePure () {
	if (hasRequiredPure) return pure;
	hasRequiredPure = 1;

	var _interopRequireDefault = requireInteropRequireDefault();

	pure.__esModule = true;
	pure.default = void 0;

	var _shouldUpdate = _interopRequireDefault(requireShouldUpdate());

	var _shallowEqual = _interopRequireDefault(requireShallowEqual());

	var _setDisplayName = _interopRequireDefault(requireSetDisplayName());

	var _wrapDisplayName = _interopRequireDefault(requireWrapDisplayName());

	var pure$1 = function pure(BaseComponent) {
	  var hoc = (0, _shouldUpdate.default)(function (props, nextProps) {
	    return !(0, _shallowEqual.default)(props, nextProps);
	  });

	  if (process.env.NODE_ENV !== 'production') {
	    return (0, _setDisplayName.default)((0, _wrapDisplayName.default)(BaseComponent, 'pure'))(hoc(BaseComponent));
	  }

	  return hoc(BaseComponent);
	};

	var _default = pure$1;
	pure.default = _default;
	return pure;
}

var hasRequiredCreateSvgIcon;

function requireCreateSvgIcon () {
	if (hasRequiredCreateSvgIcon) return createSvgIcon;
	hasRequiredCreateSvgIcon = 1;

	var _interopRequireDefault = requireInteropRequireDefault();

	Object.defineProperty(createSvgIcon, "__esModule", {
	  value: true
	});
	createSvgIcon.default = void 0;

	var _react = _interopRequireDefault(React);

	var _pure = _interopRequireDefault(requirePure());

	var _SvgIcon = _interopRequireDefault(require$$3);

	function createSvgIcon$1(path, displayName) {
	  var Icon = function Icon(props) {
	    return _react.default.createElement(_SvgIcon.default, props, path);
	  };

	  Icon.displayName = "".concat(displayName, "Icon");
	  Icon = (0, _pure.default)(Icon);
	  Icon.muiName = 'SvgIcon';
	  return Icon;
	}
	var _default = createSvgIcon$1;
	createSvgIcon.default = _default;
	return createSvgIcon;
}

var hasRequiredCheck;

function requireCheck () {
	if (hasRequiredCheck) return Check$1;
	hasRequiredCheck = 1;

	var _interopRequireDefault = requireInteropRequireDefault();

	Object.defineProperty(Check$1, "__esModule", {
	  value: true
	});
	Check$1.default = void 0;

	var _react = _interopRequireDefault(React);

	var _createSvgIcon = _interopRequireDefault(/*@__PURE__*/ requireCreateSvgIcon());

	var _default = (0, _createSvgIcon.default)(_react.default.createElement(_react.default.Fragment, null, _react.default.createElement("path", {
	  fill: "none",
	  d: "M0 0h24v24H0z"
	}), _react.default.createElement("path", {
	  d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"
	})), 'Check');

	Check$1.default = _default;
	return Check$1;
}

var CheckExports = /*@__PURE__*/ requireCheck();
var Check = /*@__PURE__*/getDefaultExportFromCjs(CheckExports);

const RawDoneButton = ({
  classes,
  onClick,
  hideBackground
}) => /*#__PURE__*/React.createElement(IconButton, {
  "aria-label": "Done",
  className: classes.iconRoot,
  onClick: onClick,
  classes: {
    label: classes.label,
    root: cx(classes.iconRoot, {
      [classes.hideBackground]: hideBackground
    })
  }
}, /*#__PURE__*/React.createElement(Check, null));
RawDoneButton.propTypes = {
  classes: PropTypes.object.isRequired,
  onClick: PropTypes.func
};

const styles$1 = theme => ({
  iconRoot: {
    verticalAlign: 'top',
    width: '28px',
    height: '28px',
    color: '#00bb00'
  },
  hideBackground: {
    backgroundColor: theme.palette.common.white,
    '&:hover': {
      backgroundColor: theme.palette.grey[200]
    }
  },
  label: {
    position: 'absolute',
    top: '2px'
  }
});

const DoneButton = withStyles(styles$1)(RawDoneButton);

const {
  commonMqFontStyles,
  longdivStyles,
  supsubStyles
} = mq.CommonMqStyles;
const log = debug('@pie-lib:math-toolbar:math-preview');
class RawMathPreview extends React.Component {
  componentDidMount() {
    markFractionBaseSuperscripts();
  }

  componentDidUpdate(prevProps) {
    // Re-run only if LaTeX changed
    if (this.props.node.data.get('latex') !== prevProps.node.data.get('latex')) {
      markFractionBaseSuperscripts();
    }
  }

  render() {
    log('[render] data: ', this.props.node.data);
    const latex = this.props.node.data.get('latex');
    const {
      classes,
      isSelected,
      onFocus,
      onBlur
    } = this.props;
    return /*#__PURE__*/React.createElement("div", {
      className: cx(classes.root, isSelected && classes.selected)
    }, ' ', /*#__PURE__*/React.createElement("span", {
      className: classes.insideOverlay
    }), /*#__PURE__*/React.createElement(mq.Static, {
      latex: latex,
      onFocus: onFocus,
      onBlur: onBlur
    }));
  }

}
RawMathPreview.propTypes = {
  latex: PropTypes.string,
  node: PropTypes.object,
  classes: PropTypes.object,
  isSelected: PropTypes.bool,
  onFocus: PropTypes.func,
  onBlur: PropTypes.func
};

const mp = theme => ({
  root: _extends({
    display: 'inline-flex',
    alignItems: 'center',
    position: 'relative',
    '& *': commonMqFontStyles
  }, supsubStyles, longdivStyles, {
    '& > .mq-math-mode': {
      border: 'solid 1px lightgrey'
    },
    '& > .mq-focused': {
      outline: 'none',
      boxShadow: 'none',
      border: 'solid 1px black',
      borderRadius: '0px'
    },
    '& > .mq-math-mode .mq-root-block': {
      paddingTop: '7px !important'
    },
    '& > .mq-math-mode .mq-overarc ': {
      paddingTop: '0.45em !important'
    },
    '& > .mq-math-mode .mq-sqrt-prefix': {
      verticalAlign: 'baseline !important',
      top: '1px !important',
      left: '-0.1em !important'
    },
    '& > .mq-math-mode .mq-denominator': {
      marginTop: '-5px !important',
      padding: '0.5em 0.1em 0.1em !important'
    },
    '& > .mq-math-mode .mq-numerator, .mq-math-mode .mq-over': {
      padding: '0 0.1em !important',
      paddingBottom: '0 !important',
      marginBottom: '-2px'
    },
    '& > .mq-math-mode .mq-longdiv .mq-longdiv-inner .mq-empty': {
      paddingTop: '6px !important',
      paddingLeft: '4px !important'
    },
    '& > .mq-math-mode .mq-longdiv .mq-longdiv-inner': {
      marginLeft: '0 !important'
    },
    '& > .mq-math-mode .mq-overarrow': {
      fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important'
    },
    '& > .mq-math-mode .mq-paren': {
      verticalAlign: 'top !important',
      padding: '1px 0.1em !important'
    },
    '& > .mq-math-mode .mq-sqrt-stem': {
      borderTop: '0.07em solid',
      marginLeft: '-1.5px',
      marginTop: '-2px !important',
      paddingTop: '5px !important'
    },
    '& .mq-overarrow-inner': {
      paddingTop: '0 !important',
      border: 'none !important'
    },
    '& .mq-editable-field .mq-cursor': {
      marginTop: '-15px !important'
    },
    '& .mq-overarrow.mq-arrow-both': {
      top: '7.5px',
      marginTop: '0px',
      minWidth: '1.23em',
      '& *': {
        lineHeight: '1 !important'
      },
      '&:before': {
        top: '-0.4em',
        left: '-1px'
      },
      // NOTE: This workaround adds `!important` to enforce the correct positioning and styling
      // of `.mq-overarrow.mq-arrow-both` elements in MathQuill. This ensures consistent display
      // regardless of the order in which MathQuill is initialized on our websites.
      //
      // In the future, investigate why MathQuill scripts and styles are being initialized
      // more than once and address the root cause to prevent potential conflicts and ensure
      // optimal performance.
      '&:after': {
        top: '0px !important',
        position: 'absolute !important',
        right: '-2px'
      },
      '&.mq-empty:after': {
        top: '-0.45em'
      }
    },
    '& .mq-overarrow.mq-arrow-right': {
      '&:before': {
        top: '-0.4em',
        right: '-1px'
      }
    },
    '& .mq-overarrow-inner-right': {
      display: 'none !important'
    },
    '& .mq-overarrow-inner-left': {
      display: 'none !important'
    },
    '& .mq-longdiv-inner': {
      borderTop: '1px solid !important',
      paddingTop: '1.5px !important'
    },
    '& .mq-parallelogram': {
      lineHeight: 0.85
    },
    '& span[data-prime="true"]': {
      fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important'
    }
  }),
  selected: {
    border: `solid 1px ${theme.palette.primary.main}`,
    '& > .mq-math-mode': {
      border: 'solid 0px lightgrey'
    }
  },
  insideOverlay: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
    top: 0
  }
});

var mathPreview = withStyles(mp)(RawMathPreview);

class MathToolbar extends React.Component {
  constructor(props) {
    super(props);

    this.done = () => {
      this.props.onDone(this.state.latex);
    };

    this.onChange = latex => {
      this.setState({
        latex
      });
      this.props.onChange(latex);
    };

    this.state = {
      latex: props.latex
    };
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    this.setState({
      latex: nextProps.latex
    });
  }

  render() {
    const {
      latex
    } = this.state;
    const {
      classNames,
      autoFocus,
      allowAnswerBlock,
      onAnswerBlockAdd,
      controlledKeypad,
      controlledKeypadMode,
      keypadMode,
      noDecimal,
      additionalKeys,
      showKeypad,
      onFocus,
      onBlur,
      hideDoneButton,
      error,
      keyPadCharacterRef,
      setKeypadInteraction,
      maxResponseAreas
    } = this.props;
    return /*#__PURE__*/React.createElement(PureToolbar, {
      autoFocus: autoFocus,
      classNames: classNames,
      onAnswerBlockAdd: onAnswerBlockAdd,
      allowAnswerBlock: allowAnswerBlock,
      latex: latex,
      additionalKeys: additionalKeys,
      noDecimal: noDecimal,
      keypadMode: keypadMode,
      keyPadCharacterRef: keyPadCharacterRef,
      setKeypadInteraction: setKeypadInteraction,
      onChange: this.onChange,
      onDone: this.done,
      onFocus: onFocus,
      onBlur: onBlur,
      showKeypad: showKeypad,
      controlledKeypad: controlledKeypad,
      controlledKeypadMode: controlledKeypadMode,
      hideDoneButton: hideDoneButton,
      error: error,
      maxResponseAreas: maxResponseAreas
    });
  }

}
MathToolbar.propTypes = {
  autoFocus: PropTypes.bool,
  allowAnswerBlock: PropTypes.bool,
  controlledKeypad: PropTypes.bool,
  controlledKeypadMode: PropTypes.bool,
  keypadMode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  classNames: PropTypes.object,
  error: PropTypes.string,
  maxResponseAreas: PropTypes.number,
  showKeypad: PropTypes.bool,
  noDecimal: PropTypes.bool,
  additionalKeys: PropTypes.array,
  latex: PropTypes.string.isRequired,
  onAnswerBlockAdd: PropTypes.func,
  onChange: PropTypes.func,
  onDone: PropTypes.func.isRequired,
  onFocus: PropTypes.func,
  onBlur: PropTypes.func,
  hideDoneButton: PropTypes.bool,
  keyPadCharacterRef: PropTypes.func,
  setKeypadInteraction: PropTypes.func
};
MathToolbar.defaultProps = {
  classNames: {},
  keypadMode: 'item-authoring',
  autoFocus: false,
  allowAnswerBlock: false,
  controlledKeypad: false,
  controlledKeypadMode: false,
  noDecimal: false,
  showKeypad: true,
  additionalKeys: [],
  onChange: () => {},
  onAnswerBlockAdd: () => {},
  onFocus: () => {},
  hideDoneButton: false
};
class RawPureToolbar extends React.Component {
  render() {
    const {
      classNames,
      autoFocus,
      allowAnswerBlock,
      onAnswerBlockAdd,
      controlledKeypad,
      controlledKeypadMode,
      additionalKeys,
      showKeypad,
      keypadMode,
      noDecimal,
      hideInput,
      noLatexHandling,
      layoutForKeyPad,
      keyPadCharacterRef,
      setKeypadInteraction,
      latex,
      onChange,
      onDone,
      onFocus,
      onBlur,
      hideDoneButton,
      hideDoneButtonBackground,
      classes,
      error,
      maxResponseAreas
    } = this.props;
    return /*#__PURE__*/React.createElement("div", {
      className: cx(classes.pureToolbar, (classNames || {}).toolbar),
      ref: keyPadCharacterRef
    }, /*#__PURE__*/React.createElement("div", null), /*#__PURE__*/React.createElement(EditorAndPad$1, {
      autoFocus: autoFocus,
      keypadMode: keypadMode,
      classNames: classNames || {},
      controlledKeypad: controlledKeypad,
      controlledKeypadMode: controlledKeypadMode,
      noDecimal: noDecimal,
      hideInput: hideInput,
      noLatexHandling: noLatexHandling,
      layoutForKeyPad: layoutForKeyPad,
      showKeypad: showKeypad,
      additionalKeys: additionalKeys,
      allowAnswerBlock: allowAnswerBlock,
      onAnswerBlockAdd: onAnswerBlockAdd,
      latex: latex,
      onChange: onChange,
      onFocus: onFocus,
      onBlur: onBlur,
      error: error,
      maxResponseAreas: maxResponseAreas,
      setKeypadInteraction: setKeypadInteraction
    }), (!controlledKeypad || controlledKeypad && showKeypad) && !hideDoneButton && /*#__PURE__*/React.createElement(DoneButton, {
      hideBackground: hideDoneButtonBackground,
      onClick: onDone
    }));
  }

}
RawPureToolbar.propTypes = {
  classNames: PropTypes.object,
  latex: PropTypes.string.isRequired,
  keypadMode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  hideInput: PropTypes.bool,
  noLatexHandling: PropTypes.bool,
  layoutForKeyPad: PropTypes.object,
  onChange: PropTypes.func.isRequired,
  onDone: PropTypes.func.isRequired,
  onBlur: PropTypes.func,
  onAnswerBlockAdd: PropTypes.func,
  additionalKeys: PropTypes.array,
  onFocus: PropTypes.func,
  classes: PropTypes.object.isRequired,
  autoFocus: PropTypes.bool,
  noDecimal: PropTypes.bool,
  allowAnswerBlock: PropTypes.bool,
  controlledKeypad: PropTypes.bool,
  controlledKeypadMode: PropTypes.bool,
  showKeypad: PropTypes.bool,
  hideDoneButton: PropTypes.bool,
  hideDoneButtonBackground: PropTypes.bool,
  error: PropTypes.any,
  maxResponseAreas: PropTypes.number,
  keyPadCharacterRef: PropTypes.object,
  setKeypadInteraction: PropTypes.func
};
RawPureToolbar.defaultProps = {
  classNames: {},
  hideDoneButtonBackground: false
};

const styles = () => ({
  pureToolbar: {
    display: 'flex',
    width: '100%',
    zIndex: 8,
    alignItems: 'center'
  }
});

const PureToolbar = withStyles(styles)(RawPureToolbar);

export { mathPreview as MathPreview, MathToolbar, PureToolbar, RawPureToolbar };
//# sourceMappingURL=index.js.map
