Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

input autoFocus causes focus to be emitted before ref #7769

Open
syranide opened this issue Sep 19, 2016 · 14 comments
Open

input autoFocus causes focus to be emitted before ref #7769

syranide opened this issue Sep 19, 2016 · 14 comments

Comments

@syranide
Copy link
Contributor

syranide commented Sep 19, 2016

https://jsfiddle.net/nnwd2c34/

Can reproduce on Chrome, but not in IE11.

@LeZuse
Copy link

LeZuse commented Oct 4, 2016

Also came here to report this. Prevents a very usual usecase for focus/select:

<input
  autoFocus
  type="text"
  ref="valueInput"
  onFocus={this.onFocus}
/>

// this.onFocus:
this.refs.valueInput.select();
      ^ refs are not available yet

Using a workaround now:

// this.onFocus:
ReactDOM.findDOMNode(this).children[0]

@syranide
Copy link
Contributor Author

syranide commented Oct 4, 2016

@LeZuse You can just use event.target as a simpler workaround FYI.

@LeZuse
Copy link

LeZuse commented Oct 5, 2016

@syranide ha, true! Thanks!

@gaearon
Copy link
Collaborator

gaearon commented Oct 4, 2017

Still happens on 16.

@oliviertassinari
Copy link
Contributor

@syranide The event.target workaround works great. For everybody else, you might need event.currentTarget, be aware of the difference, and pick the one that fit your needs.

@gaearon
Copy link
Collaborator

gaearon commented Jan 5, 2018

Not sure what the right fix would be. Tagging as good first issue for somebody to investigate.

@RichieAHB
Copy link

RichieAHB commented Jan 18, 2018

The issue here seems to be that Ref effects are called after Update effects below (the latter being the effect to do the mounting). Although, if this is the issue, I'm not sure why it would work in IE11 🤔 ...

function commitAllLifeCycles() {
while (nextEffect !== null) {
const effectTag = nextEffect.effectTag;
if (effectTag & (Update | Callback)) {
recordEffect();
const current = nextEffect.alternate;
commitLifeCycles(current, nextEffect);
}
if (effectTag & Ref) {
recordEffect();
commitAttachRef(nextEffect);
}
if (effectTag & Err) {
recordEffect();
commitErrorHandling(nextEffect);
}
const next = nextEffect.nextEffect;
// Ensure that we clean these up so that we don't accidentally keep them.
// I'm not actually sure this matters because we can't reset firstEffect
// and lastEffect since they're on every node, not just the effectful
// ones. So we have to clean everything as we reuse nodes anyway.
nextEffect.nextEffect = null;
// Ensure that we reset the effectTag here so that we can rely on effect
// tags to reason about the current life-cycle.
nextEffect = next;
}
}

I'm assuming this is to ensure that all refs are guaranteed to be mounted, which seems to make sense. On the off-chance that this isn't a guarantee that React provides then we could just flip the order of effects processing (although this breaks two tests around refs being called at the correct time, suggesting this is a hard constraint). Otherwise, it seems autofocussing would need to be broken away from the mounting process to solve this issue, which seems like an odd thing to do for other reasons.

Edit:
To be clear: the update gets marked here if finalizeInitialChildren returns true (which it does only if the host component needs an autofocus).

// Certain renderers require commit-time effects for initial mount.
// (eg DOM renderer supports auto-focus for certain elements).
// Make sure such renderers get scheduled for later work.
if (
finalizeInitialChildren(
instance,
type,
newProps,
rootContainerInstance,
currentHostContext,
)
) {
markUpdate(workInProgress);
}

That then gets fired on commitMount in the reconciler, which again, makes sense.

@moe091
Copy link

moe091 commented Feb 4, 2018

Nobody else has picked up this issue? I'd love to give it a try if not

@RichieAHB
Copy link

I had a look at this but I feel like it would mean a relatively big change and could probably do with a bit of feedback from @gaearon before pushing on.

@moe091
Copy link

moe091 commented Feb 4, 2018

Yeah good point, it looks like this would require changing the order in which different effects are applied to elements when they are created/updated, and changing that would obviously have a lot of side-effects.

I'll leave this be and find something else to work on for now

@RichieAHB
Copy link

RichieAHB commented Feb 4, 2018 via email

betmakh referenced this issue in betmakh/trailersService Jul 8, 2018
TODO: cache
diff --git a/package.json b/package.json
index 2883d09..b31f02d 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
   },
   "dependencies": {
     "@material-ui/core": "1.2.3",
+    "@material-ui/icons": "^1.1.0",
     "babel-core": "^6.26.3",
     "babel-loader": "^7.1.5",
     "babel-preset-es2015": "^6.24.1",
@@ -26,10 +27,10 @@
     "webpack": "^4.15.1"
   },
   "devDependencies": {
-    "nodemon": "^1.17.5",
     "debug": "~2.6.9",
     "eslint": "^5.0.1",
     "eslint-plugin-react": "^7.10.0",
+    "nodemon": "^1.17.5",
     "webpack-cli": "^3.0.8"
   }
 }
diff --git a/public/javascripts/dist/app.js b/public/javascripts/dist/app.js
index 557727e..00fcc64 100644
--- a/public/javascripts/dist/app.js
+++ b/public/javascripts/dist/app.js
@@ -297,6 +297,102 @@ eval("\n\nvar _interopRequireDefault = __webpack_require__(/*! @babel/runtime/he

 /***/ }),

+/***/ "./node_modules/@material-ui/core/Button/Button.js":
+/*!*********************************************************!*\
+  !*** ./node_modules/@material-ui/core/Button/Button.js ***!
+  \*********************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\nvar _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/builtin/interopRequireDefault */ \"./node_modules/@babel/runtime/helpers/builtin/interopRequireDefault.js\");\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/extends */ \"./node_modules/@babel/runtime/helpers/builtin/extends.js\"));\n\nvar _defineProperty2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/defineProperty */ \"./node_modules/@babel/runtime/helpers/builtin/defineProperty.js\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/objectWithoutProperties */ \"./node_modules/@babel/runtime/helpers/builtin/objectWithoutProperties.js\"));\n\nvar _objectSpread2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/objectSpread */ \"./node_modules/@babel/runtime/helpers/builtin/objectSpread.js\"));\n\nvar _react = _interopRequireDefault(__webpack_require__(/*! react */ \"./node_modules/react/index.js\"));\n\nvar _propTypes = _interopRequireDefault(__webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\"));\n\nvar _classnames = _interopRequireDefault(__webpack_require__(/*! classnames */ \"./node_modules/classnames/index.js\"));\n\nvar _withStyles = _interopRequireDefault(__webpack_require__(/*! ../styles/withStyles */ \"./node_modules/@material-ui/core/styles/withStyles.js\"));\n\nvar _colorManipulator = __webpack_require__(/*! ../styles/colorManipulator */ \"./node_modules/@material-ui/core/styles/colorManipulator.js\");\n\nvar _ButtonBase = _interopRequireDefault(__webpack_require__(/*! ../ButtonBase */ \"./node_modules/@material-ui/core/ButtonBase/index.js\"));\n\nvar _helpers = __webpack_require__(/*! ../utils/helpers */ \"./node_modules/@material-ui/core/utils/helpers.js\");\n\n// @inheritedComponent ButtonBase\nvar styles = function styles(theme) {\n  return {\n    root: (0, _objectSpread2.default)({}, theme.typography.button, {\n      lineHeight: '1.4em',\n      // Improve readability for multiline button.\n      boxSizing: 'border-box',\n      minWidth: theme.spacing.unit * 11,\n      minHeight: 36,\n      padding: \"\".concat(theme.spacing.unit, \"px \").concat(theme.spacing.unit * 2, \"px\"),\n      borderRadius: 4,\n      color: theme.palette.text.primary,\n      transition: theme.transitions.create(['background-color', 'box-shadow'], {\n        duration: theme.transitions.duration.short\n      }),\n      '&:hover': {\n        textDecoration: 'none',\n        backgroundColor: (0, _colorManipulator.fade)(theme.palette.text.primary, theme.palette.action.hoverOpacity),\n        // Reset on touch devices, it doesn't add specificity\n        '@media (hover: none)': {\n          backgroundColor: 'transparent'\n        },\n        '&$disabled': {\n          backgroundColor: 'transparent'\n        }\n      },\n      '&$disabled': {\n        color: theme.palette.action.disabled\n      }\n    }),\n    label: {\n      width: '100%',\n      display: 'inherit',\n      alignItems: 'inherit',\n      justifyContent: 'inherit'\n    },\n    textPrimary: {\n      color: theme.palette.primary.main,\n      '&:hover': {\n        backgroundColor: (0, _colorManipulator.fade)(theme.palette.primary.main, theme.palette.action.hoverOpacity),\n        // Reset on touch devices, it doesn't add specificity\n        '@media (hover: none)': {\n          backgroundColor: 'transparent'\n        }\n      }\n    },\n    textSecondary: {\n      color: theme.palette.secondary.main,\n      '&:hover': {\n        backgroundColor: (0, _colorManipulator.fade)(theme.palette.secondary.main, theme.palette.action.hoverOpacity),\n        // Reset on touch devices, it doesn't add specificity\n        '@media (hover: none)': {\n          backgroundColor: 'transparent'\n        }\n      }\n    },\n    flat: {},\n    flatPrimary: {},\n    flatSecondary: {},\n    outlined: {\n      border: \"1px solid \".concat(theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)')\n    },\n    colorInherit: {\n      color: 'inherit'\n    },\n    contained: {\n      color: theme.palette.getContrastText(theme.palette.grey[300]),\n      backgroundColor: theme.palette.grey[300],\n      boxShadow: theme.shadows[2],\n      '&$focusVisible': {\n        boxShadow: theme.shadows[6]\n      },\n      '&:active': {\n        boxShadow: theme.shadows[8]\n      },\n      '&$disabled': {\n        color: theme.palette.action.disabled,\n        boxShadow: theme.shadows[0],\n        backgroundColor: theme.palette.action.disabledBackground\n      },\n      '&:hover': {\n        backgroundColor: theme.palette.grey.A100,\n        // Reset on touch devices, it doesn't add specificity\n        '@media (hover: none)': {\n          backgroundColor: theme.palette.grey[300]\n        },\n        '&$disabled': {\n          backgroundColor: theme.palette.action.disabledBackground\n        }\n      }\n    },\n    containedPrimary: {\n      color: theme.palette.primary.contrastText,\n      backgroundColor: theme.palette.primary.main,\n      '&:hover': {\n        backgroundColor: theme.palette.primary.dark,\n        // Reset on touch devices, it doesn't add specificity\n        '@media (hover: none)': {\n          backgroundColor: theme.palette.primary.main\n        }\n      }\n    },\n    containedSecondary: {\n      color: theme.palette.secondary.contrastText,\n      backgroundColor: theme.palette.secondary.main,\n      '&:hover': {\n        backgroundColor: theme.palette.secondary.dark,\n        // Reset on touch devices, it doesn't add specificity\n        '@media (hover: none)': {\n          backgroundColor: theme.palette.secondary.main\n        }\n      }\n    },\n    raised: {},\n    raisedPrimary: {},\n    raisedSecondary: {},\n    focusVisible: {},\n    disabled: {},\n    fab: {\n      borderRadius: '50%',\n      padding: 0,\n      minWidth: 0,\n      width: 56,\n      fontSize: 24,\n      height: 56,\n      boxShadow: theme.shadows[6],\n      '&:active': {\n        boxShadow: theme.shadows[12]\n      }\n    },\n    mini: {\n      width: 40,\n      height: 40\n    },\n    sizeSmall: {\n      padding: \"\".concat(theme.spacing.unit - 1, \"px \").concat(theme.spacing.unit, \"px\"),\n      minWidth: theme.spacing.unit * 8,\n      minHeight: 32,\n      fontSize: theme.typography.pxToRem(13)\n    },\n    sizeLarge: {\n      padding: \"\".concat(theme.spacing.unit, \"px \").concat(theme.spacing.unit * 3, \"px\"),\n      minWidth: theme.spacing.unit * 14,\n      minHeight: 40,\n      fontSize: theme.typography.pxToRem(15)\n    },\n    fullWidth: {\n      width: '100%'\n    }\n  };\n};\n\nexports.styles = styles;\n\nfunction Button(props) {\n  var _classNames;\n\n  var children = props.children,\n      classes = props.classes,\n      classNameProp = props.className,\n      color = props.color,\n      disabled = props.disabled,\n      disableFocusRipple = props.disableFocusRipple,\n      fullWidth = props.fullWidth,\n      focusVisibleClassName = props.focusVisibleClassName,\n      mini = props.mini,\n      size = props.size,\n      variant = props.variant,\n      other = (0, _objectWithoutProperties2.default)(props, [\"children\", \"classes\", \"className\", \"color\", \"disabled\", \"disableFocusRipple\", \"fullWidth\", \"focusVisibleClassName\", \"mini\", \"size\", \"variant\"]);\n  var fab = variant === 'fab';\n  var contained = variant === 'contained' || variant === 'raised';\n  var text = !contained && !fab;\n  var className = (0, _classnames.default)(classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.contained, contained || fab), (0, _defineProperty2.default)(_classNames, classes.fab, fab), (0, _defineProperty2.default)(_classNames, classes.mini, fab && mini), (0, _defineProperty2.default)(_classNames, classes.colorInherit, color === 'inherit'), (0, _defineProperty2.default)(_classNames, classes.textPrimary, text && color === 'primary'), (0, _defineProperty2.default)(_classNames, classes.textSecondary, text && color === 'secondary'), (0, _defineProperty2.default)(_classNames, classes.flat, text), (0, _defineProperty2.default)(_classNames, classes.flatPrimary, text && color === 'primary'), (0, _defineProperty2.default)(_classNames, classes.flatSecondary, text && color === 'secondary'), (0, _defineProperty2.default)(_classNames, classes.containedPrimary, !text && color === 'primary'), (0, _defineProperty2.default)(_classNames, classes.containedSecondary, !text && color === 'secondary'), (0, _defineProperty2.default)(_classNames, classes.raised, contained || fab), (0, _defineProperty2.default)(_classNames, classes.raisedPrimary, (contained || fab) && color === 'primary'), (0, _defineProperty2.default)(_classNames, classes.raisedSecondary, (contained || fab) && color === 'secondary'), (0, _defineProperty2.default)(_classNames, classes.text, variant === 'text'), (0, _defineProperty2.default)(_classNames, classes.outlined, variant === 'outlined'), (0, _defineProperty2.default)(_classNames, classes[\"size\".concat((0, _helpers.capitalize)(size))], size !== 'medium'), (0, _defineProperty2.default)(_classNames, classes.disabled, disabled), (0, _defineProperty2.default)(_classNames, classes.fullWidth, fullWidth), _classNames), classNameProp);\n  return _react.default.createElement(_ButtonBase.default, (0, _extends2.default)({\n    className: className,\n    disabled: disabled,\n    focusRipple: !disableFocusRipple,\n    focusVisibleClassName: (0, _classnames.default)(classes.focusVisible, focusVisibleClassName)\n  }, other), _react.default.createElement(\"span\", {\n    className: classes.label\n  }, children));\n}\n\nButton.propTypes =  true ? {\n  /**\n   * The content of the button.\n   */\n  children: _propTypes.default.node.isRequired,\n\n  /**\n   * Override or extend the styles applied to the component.\n   * See [CSS API](#css-api) below for more details.\n   */\n  classes: _propTypes.default.object.isRequired,\n\n  /**\n   * @ignore\n   */\n  className: _propTypes.default.string,\n\n  /**\n   * The color of the component. It supports those theme colors that make sense for this component.\n   */\n  color: _propTypes.default.oneOf(['default', 'inherit', 'primary', 'secondary']),\n\n  /**\n   * The component used for the root node.\n   * Either a string to use a DOM element or a component.\n   */\n  component: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func, _propTypes.default.object]),\n\n  /**\n   * If `true`, the button will be disabled.\n   */\n  disabled: _propTypes.default.bool,\n\n  /**\n   * If `true`, the  keyboard focus ripple will be disabled.\n   * `disableRipple` must also be true.\n   */\n  disableFocusRipple: _propTypes.default.bool,\n\n  /**\n   * If `true`, the ripple effect will be disabled.\n   */\n  disableRipple: _propTypes.default.bool,\n\n  /**\n   * @ignore\n   */\n  focusVisibleClassName: _propTypes.default.string,\n\n  /**\n   * If `true`, the button will take up the full width of its container.\n   */\n  fullWidth: _propTypes.default.bool,\n\n  /**\n   * The URL to link to when the button is clicked.\n   * If defined, an `a` element will be used as the root node.\n   */\n  href: _propTypes.default.string,\n\n  /**\n   * If `true`, and `variant` is `'fab'`, will use mini floating action button styling.\n   */\n  mini: _propTypes.default.bool,\n\n  /**\n   * The size of the button.\n   * `small` is equivalent to the dense button styling.\n   */\n  size: _propTypes.default.oneOf(['small', 'medium', 'large']),\n\n  /**\n   * @ignore\n   */\n  type: _propTypes.default.string,\n\n  /**\n   * The type of button.\n   */\n  variant: _propTypes.default.oneOf(['text', 'flat', 'outlined', 'contained', 'raised', 'fab'])\n} : undefined;\nButton.defaultProps = {\n  color: 'default',\n  component: 'button',\n  disabled: false,\n  disableFocusRipple: false,\n  fullWidth: false,\n  mini: false,\n  size: 'medium',\n  type: 'button',\n  variant: 'text'\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n  name: 'MuiButton'\n})(Button);\n\nexports.default = _default;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsLXVpL2NvcmUvQnV0dG9uL0J1dHRvbi5qcz80ZDk5Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxZQUFZO0FBQ1osbUJBQW1CO0FBQ25CLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxjQUFjO0FBQ2QscUJBQXFCO0FBQ3JCLHVCQUF1QjtBQUN2QixvQkFBb0I7QUFDcEIsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEVBQTBFO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsImZpbGUiOiIuL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwtdWkvY29yZS9CdXR0b24vQnV0dG9uLmpzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYnVpbHRpbi9pbnRlcm9wUmVxdWlyZURlZmF1bHRcIik7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLnN0eWxlcyA9IHZvaWQgMDtcblxudmFyIF9leHRlbmRzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYnVpbHRpbi9leHRlbmRzXCIpKTtcblxudmFyIF9kZWZpbmVQcm9wZXJ0eTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2J1aWx0aW4vZGVmaW5lUHJvcGVydHlcIikpO1xuXG52YXIgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYnVpbHRpbi9vYmplY3RXaXRob3V0UHJvcGVydGllc1wiKSk7XG5cbnZhciBfb2JqZWN0U3ByZWFkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYnVpbHRpbi9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX3JlYWN0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwicmVhY3RcIikpO1xuXG52YXIgX3Byb3BUeXBlcyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcInByb3AtdHlwZXNcIikpO1xuXG52YXIgX2NsYXNzbmFtZXMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJjbGFzc25hbWVzXCIpKTtcblxudmFyIF93aXRoU3R5bGVzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi4vc3R5bGVzL3dpdGhTdHlsZXNcIikpO1xuXG52YXIgX2NvbG9yTWFuaXB1bGF0b3IgPSByZXF1aXJlKFwiLi4vc3R5bGVzL2NvbG9yTWFuaXB1bGF0b3JcIik7XG5cbnZhciBfQnV0dG9uQmFzZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4uL0J1dHRvbkJhc2VcIikpO1xuXG52YXIgX2hlbHBlcnMgPSByZXF1aXJlKFwiLi4vdXRpbHMvaGVscGVyc1wiKTtcblxuLy8gQGluaGVyaXRlZENvbXBvbmVudCBCdXR0b25CYXNlXG52YXIgc3R5bGVzID0gZnVuY3Rpb24gc3R5bGVzKHRoZW1lKSB7XG4gIHJldHVybiB7XG4gICAgcm9vdDogKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCB0aGVtZS50eXBvZ3JhcGh5LmJ1dHRvbiwge1xuICAgICAgbGluZUhlaWdodDogJzEuNGVtJyxcbiAgICAgIC8vIEltcHJvdmUgcmVhZGFiaWxpdHkgZm9yIG11bHRpbGluZSBidXR0b24uXG4gICAgICBib3hTaXppbmc6ICdib3JkZXItYm94JyxcbiAgICAgIG1pbldpZHRoOiB0aGVtZS5zcGFjaW5nLnVuaXQgKiAxMSxcbiAgICAgIG1pbkhlaWdodDogMzYsXG4gICAgICBwYWRkaW5nOiBcIlwiLmNvbmNhdCh0aGVtZS5zcGFjaW5nLnVuaXQsIFwicHggXCIpLmNvbmNhdCh0aGVtZS5zcGFjaW5nLnVuaXQgKiAyLCBcInB4XCIpLFxuICAgICAgYm9yZGVyUmFkaXVzOiA0LFxuICAgICAgY29sb3I6IHRoZW1lLnBhbGV0dGUudGV4dC5wcmltYXJ5LFxuICAgICAgdHJhbnNpdGlvbjogdGhlbWUudHJhbnNpdGlvbnMuY3JlYXRlKFsnYmFja2dyb3VuZC1jb2xvcicsICdib3gtc2hhZG93J10sIHtcbiAgICAgICAgZHVyYXRpb246IHRoZW1lLnRyYW5zaXRpb25zLmR1cmF0aW9uLnNob3J0XG4gICAgICB9KSxcbiAgICAgICcmOmhvdmVyJzoge1xuICAgICAgICB0ZXh0RGVjb3JhdGlvbjogJ25vbmUnLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICgwLCBfY29sb3JNYW5pcHVsYXRvci5mYWRlKSh0aGVtZS5wYWxldHRlLnRleHQucHJpbWFyeSwgdGhlbWUucGFsZXR0ZS5hY3Rpb24uaG92ZXJPcGFjaXR5KSxcbiAgICAgICAgLy8gUmVzZXQgb24gdG91Y2ggZGV2aWNlcywgaXQgZG9lc24ndCBhZGQgc3BlY2lmaWNpdHlcbiAgICAgICAgJ0BtZWRpYSAoaG92ZXI6IG5vbmUpJzoge1xuICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3RyYW5zcGFyZW50J1xuICAgICAgICB9LFxuICAgICAgICAnJiRkaXNhYmxlZCc6IHtcbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd0cmFuc3BhcmVudCdcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgICcmJGRpc2FibGVkJzoge1xuICAgICAgICBjb2xvcjogdGhlbWUucGFsZXR0ZS5hY3Rpb24uZGlzYWJsZWRcbiAgICAgIH1cbiAgICB9KSxcbiAgICBsYWJlbDoge1xuICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgIGRpc3BsYXk6ICdpbmhlcml0JyxcbiAgICAgIGFsaWduSXRlbXM6ICdpbmhlcml0JyxcbiAgICAgIGp1c3RpZnlDb250ZW50OiAnaW5oZXJpdCdcbiAgICB9LFxuICAgIHRleHRQcmltYXJ5OiB7XG4gICAgICBjb2xvcjogdGhlbWUucGFsZXR0ZS5wcmltYXJ5Lm1haW4sXG4gICAgICAnJjpob3Zlcic6IHtcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiAoMCwgX2NvbG9yTWFuaXB1bGF0b3IuZmFkZSkodGhlbWUucGFsZXR0ZS5wcmltYXJ5Lm1haW4sIHRoZW1lLnBhbGV0dGUuYWN0aW9uLmhvdmVyT3BhY2l0eSksXG4gICAgICAgIC8vIFJlc2V0IG9uIHRvdWNoIGRldmljZXMsIGl0IGRvZXNuJ3QgYWRkIHNwZWNpZmljaXR5XG4gICAgICAgICdAbWVkaWEgKGhvdmVyOiBub25lKSc6IHtcbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd0cmFuc3BhcmVudCdcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgdGV4dFNlY29uZGFyeToge1xuICAgICAgY29sb3I6IHRoZW1lLnBhbGV0dGUuc2Vjb25kYXJ5Lm1haW4sXG4gICAgICAnJjpob3Zlcic6IHtcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiAoMCwgX2NvbG9yTWFuaXB1bGF0b3IuZmFkZSkodGhlbWUucGFsZXR0ZS5zZWNvbmRhcnkubWFpbiwgdGhlbWUucGFsZXR0ZS5hY3Rpb24uaG92ZXJPcGFjaXR5KSxcbiAgICAgICAgLy8gUmVzZXQgb24gdG91Y2ggZGV2aWNlcywgaXQgZG9lc24ndCBhZGQgc3BlY2lmaWNpdHlcbiAgICAgICAgJ0BtZWRpYSAoaG92ZXI6IG5vbmUpJzoge1xuICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3RyYW5zcGFyZW50J1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBmbGF0OiB7fSxcbiAgICBmbGF0UHJpbWFyeToge30sXG4gICAgZmxhdFNlY29uZGFyeToge30sXG4gICAgb3V0bGluZWQ6IHtcbiAgICAgIGJvcmRlcjogXCIxcHggc29saWQgXCIuY29uY2F0KHRoZW1lLnBhbGV0dGUudHlwZSA9PT0gJ2xpZ2h0JyA/ICdyZ2JhKDAsIDAsIDAsIDAuMjMpJyA6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMjMpJylcbiAgICB9LFxuICAgIGNvbG9ySW5oZXJpdDoge1xuICAgICAgY29sb3I6ICdpbmhlcml0J1xuICAgIH0sXG4gICAgY29udGFpbmVkOiB7XG4gICAgICBjb2xvcjogdGhlbWUucGFsZXR0ZS5nZXRDb250cmFzdFRleHQodGhlbWUucGFsZXR0ZS5ncmV5WzMwMF0pLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5wYWxldHRlLmdyZXlbMzAwXSxcbiAgICAgIGJveFNoYWRvdzogdGhlbWUuc2hhZG93c1syXSxcbiAgICAgICcmJGZvY3VzVmlzaWJsZSc6IHtcbiAgICAgICAgYm94U2hhZG93OiB0aGVtZS5zaGFkb3dzWzZdXG4gICAgICB9LFxuICAgICAgJyY6YWN0aXZlJzoge1xuICAgICAgICBib3hTaGFkb3c6IHRoZW1lLnNoYWRvd3NbOF1cbiAgICAgIH0sXG4gICAgICAnJiRkaXNhYmxlZCc6IHtcbiAgICAgICAgY29sb3I6IHRoZW1lLnBhbGV0dGUuYWN0aW9uLmRpc2FibGVkLFxuICAgICAgICBib3hTaGFkb3c6IHRoZW1lLnNoYWRvd3NbMF0sXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUucGFsZXR0ZS5hY3Rpb24uZGlzYWJsZWRCYWNrZ3JvdW5kXG4gICAgICB9LFxuICAgICAgJyY6aG92ZXInOiB7XG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUucGFsZXR0ZS5ncmV5LkExMDAsXG4gICAgICAgIC8vIFJlc2V0IG9uIHRvdWNoIGRldmljZXMsIGl0IGRvZXNuJ3QgYWRkIHNwZWNpZmljaXR5XG4gICAgICAgICdAbWVkaWEgKGhvdmVyOiBub25lKSc6IHtcbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLnBhbGV0dGUuZ3JleVszMDBdXG4gICAgICAgIH0sXG4gICAgICAgICcmJGRpc2FibGVkJzoge1xuICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUucGFsZXR0ZS5hY3Rpb24uZGlzYWJsZWRCYWNrZ3JvdW5kXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIGNvbnRhaW5lZFByaW1hcnk6IHtcbiAgICAgIGNvbG9yOiB0aGVtZS5wYWxldHRlLnByaW1hcnkuY29udHJhc3RUZXh0LFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5wYWxldHRlLnByaW1hcnkubWFpbixcbiAgICAgICcmOmhvdmVyJzoge1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLnBhbGV0dGUucHJpbWFyeS5kYXJrLFxuICAgICAgICAvLyBSZXNldCBvbiB0b3VjaCBkZXZpY2VzLCBpdCBkb2Vzbid0IGFkZCBzcGVjaWZpY2l0eVxuICAgICAgICAnQG1lZGlhIChob3Zlcjogbm9uZSknOiB7XG4gICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5wYWxldHRlLnByaW1hcnkubWFpblxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBjb250YWluZWRTZWNvbmRhcnk6IHtcbiAgICAgIGNvbG9yOiB0aGVtZS5wYWxldHRlLnNlY29uZGFyeS5jb250cmFzdFRleHQsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoZW1lLnBhbGV0dGUuc2Vjb25kYXJ5Lm1haW4sXG4gICAgICAnJjpob3Zlcic6IHtcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5wYWxldHRlLnNlY29uZGFyeS5kYXJrLFxuICAgICAgICAvLyBSZXNldCBvbiB0b3VjaCBkZXZpY2VzLCBpdCBkb2Vzbid0IGFkZCBzcGVjaWZpY2l0eVxuICAgICAgICAnQG1lZGlhIChob3Zlcjogbm9uZSknOiB7XG4gICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGVtZS5wYWxldHRlLnNlY29uZGFyeS5tYWluXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIHJhaXNlZDoge30sXG4gICAgcmFpc2VkUHJpbWFyeToge30sXG4gICAgcmFpc2VkU2Vjb25kYXJ5OiB7fSxcbiAgICBmb2N1c1Zpc2libGU6IHt9LFxuICAgIGRpc2FibGVkOiB7fSxcbiAgICBmYWI6IHtcbiAgICAgIGJvcmRlclJhZGl1czogJzUwJScsXG4gICAgICBwYWRkaW5nOiAwLFxuICAgICAgbWluV2lkdGg6IDAsXG4gICAgICB3aWR0aDogNTYsXG4gICAgICBmb250U2l6ZTogMjQsXG4gICAgICBoZWlnaHQ6IDU2LFxuICAgICAgYm94U2hhZG93OiB0aGVtZS5zaGFkb3dzWzZdLFxuICAgICAgJyY6YWN0aXZlJzoge1xuICAgICAgICBib3hTaGFkb3c6IHRoZW1lLnNoYWRvd3NbMTJdXG4gICAgICB9XG4gICAgfSxcbiAgICBtaW5pOiB7XG4gICAgICB3aWR0aDogNDAsXG4gICAgICBoZWlnaHQ6IDQwXG4gICAgfSxcbiAgICBzaXplU21hbGw6IHtcbiAgICAgIHBhZGRpbmc6IFwiXCIuY29uY2F0KHRoZW1lLnNwYWNpbmcudW5pdCAtIDEsIFwicHggXCIpLmNvbmNhdCh0aGVtZS5zcGFjaW5nLnVuaXQsIFwicHhcIiksXG4gICAgICBtaW5XaWR0aDogdGhlbWUuc3BhY2luZy51bml0ICogOCxcbiAgICAgIG1pbkhlaWdodDogMzIsXG4gICAgICBmb250U2l6ZTogdGhlbWUudHlwb2dyYXBoeS5weFRvUmVtKDEzKVxuICAgIH0sXG4gICAgc2l6ZUxhcmdlOiB7XG4gICAgICBwYWRkaW5nOiBcIlwiLmNvbmNhdCh0aGVtZS5zcGFjaW5nLnVuaXQsIFwicHggXCIpLmNvbmNhdCh0aGVtZS5zcGFjaW5nLnVuaXQgKiAzLCBcInB4XCIpLFxuICAgICAgbWluV2lkdGg6IHRoZW1lLnNwYWNpbmcudW5pdCAqIDE0LFxuICAgICAgbWluSGVpZ2h0OiA0MCxcbiAgICAgIGZvbnRTaXplOiB0aGVtZS50eXBvZ3JhcGh5LnB4VG9SZW0oMTUpXG4gICAgfSxcbiAgICBmdWxsV2lkdGg6IHtcbiAgICAgIHdpZHRoOiAnMTAwJSdcbiAgICB9XG4gIH07XG59O1xuXG5leHBvcnRzLnN0eWxlcyA9IHN0eWxlcztcblxuZnVuY3Rpb24gQnV0dG9uKHByb3BzKSB7XG4gIHZhciBfY2xhc3NOYW1lcztcblxuICB2YXIgY2hpbGRyZW4gPSBwcm9wcy5jaGlsZHJlbixcbiAgICAgIGNsYXNzZXMgPSBwcm9wcy5jbGFzc2VzLFxuICAgICAgY2xhc3NOYW1lUHJvcCA9IHByb3BzLmNsYXNzTmFtZSxcbiAgICAgIGNvbG9yID0gcHJvcHMuY29sb3IsXG4gICAgICBkaXNhYmxlZCA9IHByb3BzLmRpc2FibGVkLFxuICAgICAgZGlzYWJsZUZvY3VzUmlwcGxlID0gcHJvcHMuZGlzYWJsZUZvY3VzUmlwcGxlLFxuICAgICAgZnVsbFdpZHRoID0gcHJvcHMuZnVsbFdpZHRoLFxuICAgICAgZm9jdXNWaXNpYmxlQ2xhc3NOYW1lID0gcHJvcHMuZm9jdXNWaXNpYmxlQ2xhc3NOYW1lLFxuICAgICAgbWluaSA9IHByb3BzLm1pbmksXG4gICAgICBzaXplID0gcHJvcHMuc2l6ZSxcbiAgICAgIHZhcmlhbnQgPSBwcm9wcy52YXJpYW50LFxuICAgICAgb3RoZXIgPSAoMCwgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzMi5kZWZhdWx0KShwcm9wcywgW1wiY2hpbGRyZW5cIiwgXCJjbGFzc2VzXCIsIFwiY2xhc3NOYW1lXCIsIFwiY29sb3JcIiwgXCJkaXNhYmxlZFwiLCBcImRpc2FibGVGb2N1c1JpcHBsZVwiLCBcImZ1bGxXaWR0aFwiLCBcImZvY3VzVmlzaWJsZUNsYXNzTmFtZVwiLCBcIm1pbmlcIiwgXCJzaXplXCIsIFwidmFyaWFudFwiXSk7XG4gIHZhciBmYWIgPSB2YXJpYW50ID09PSAnZmFiJztcbiAgdmFyIGNvbnRhaW5lZCA9IHZhcmlhbnQgPT09ICdjb250YWluZWQnIHx8IHZhcmlhbnQgPT09ICdyYWlzZWQnO1xuICB2YXIgdGV4dCA9ICFjb250YWluZWQgJiYgIWZhYjtcbiAgdmFyIGNsYXNzTmFtZSA9ICgwLCBfY2xhc3NuYW1lcy5kZWZhdWx0KShjbGFzc2VzLnJvb3QsIChfY2xhc3NOYW1lcyA9IHt9LCAoMCwgX2RlZmluZVByb3BlcnR5Mi5kZWZhdWx0KShfY2xhc3NOYW1lcywgY2xhc3Nlcy5jb250YWluZWQsIGNvbnRhaW5lZCB8fCBmYWIpLCAoMCwgX2RlZmluZVByb3BlcnR5Mi5kZWZhdWx0KShfY2xhc3NOYW1lcywgY2xhc3Nlcy5mYWIsIGZhYiksICgwLCBfZGVmaW5lUHJvcGVydHkyLmRlZmF1bHQpKF9jbGFzc05hbWVzLCBjbGFzc2VzLm1pbmksIGZhYiAmJiBtaW5pKSwgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkoX2NsYXNzTmFtZXMsIGNsYXNzZXMuY29sb3JJbmhlcml0LCBjb2xvciA9PT0gJ2luaGVyaXQnKSwgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkoX2NsYXNzTmFtZXMsIGNsYXNzZXMudGV4dFByaW1hcnksIHRleHQgJiYgY29sb3IgPT09ICdwcmltYXJ5JyksICgwLCBfZGVmaW5lUHJvcGVydHkyLmRlZmF1bHQpKF9jbGFzc05hbWVzLCBjbGFzc2VzLnRleHRTZWNvbmRhcnksIHRleHQgJiYgY29sb3IgPT09ICdzZWNvbmRhcnknKSwgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkoX2NsYXNzTmFtZXMsIGNsYXNzZXMuZmxhdCwgdGV4dCksICgwLCBfZGVmaW5lUHJvcGVydHkyLmRlZmF1bHQpKF9jbGFzc05hbWVzLCBjbGFzc2VzLmZsYXRQcmltYXJ5LCB0ZXh0ICYmIGNvbG9yID09PSAncHJpbWFyeScpLCAoMCwgX2RlZmluZVByb3BlcnR5Mi5kZWZhdWx0KShfY2xhc3NOYW1lcywgY2xhc3Nlcy5mbGF0U2Vjb25kYXJ5LCB0ZXh0ICYmIGNvbG9yID09PSAnc2Vjb25kYXJ5JyksICgwLCBfZGVmaW5lUHJvcGVydHkyLmRlZmF1bHQpKF9jbGFzc05hbWVzLCBjbGFzc2VzLmNvbnRhaW5lZFByaW1hcnksICF0ZXh0ICYmIGNvbG9yID09PSAncHJpbWFyeScpLCAoMCwgX2RlZmluZVByb3BlcnR5Mi5kZWZhdWx0KShfY2xhc3NOYW1lcywgY2xhc3Nlcy5jb250YWluZWRTZWNvbmRhcnksICF0ZXh0ICYmIGNvbG9yID09PSAnc2Vjb25kYXJ5JyksICgwLCBfZGVmaW5lUHJvcGVydHkyLmRlZmF1bHQpKF9jbGFzc05hbWVzLCBjbGFzc2VzLnJhaXNlZCwgY29udGFpbmVkIHx8IGZhYiksICgwLCBfZGVmaW5lUHJvcGVydHkyLmRlZmF1bHQpKF9jbGFzc05hbWVzLCBjbGFzc2VzLnJhaXNlZFByaW1hcnksIChjb250YWluZWQgfHwgZmFiKSAmJiBjb2xvciA9PT0gJ3ByaW1hcnknKSwgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkoX2NsYXNzTmFtZXMsIGNsYXNzZXMucmFpc2VkU2Vjb25kYXJ5LCAoY29udGFpbmVkIHx8IGZhYikgJiYgY29sb3IgPT09ICdzZWNvbmRhcnknKSwgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkoX2NsYXNzTmFtZXMsIGNsYXNzZXMudGV4dCwgdmFyaWFudCA9PT0gJ3RleHQnKSwgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkoX2NsYXNzTmFtZXMsIGNsYXNzZXMub3V0bGluZWQsIHZhcmlhbnQgPT09ICdvdXRsaW5lZCcpLCAoMCwgX2RlZmluZVByb3BlcnR5Mi5kZWZhdWx0KShfY2xhc3NOYW1lcywgY2xhc3Nlc1tcInNpemVcIi5jb25jYXQoKDAsIF9oZWxwZXJzLmNhcGl0YWxpemUpKHNpemUpKV0sIHNpemUgIT09ICdtZWRpdW0nKSwgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkoX2NsYXNzTmFtZXMsIGNsYXNzZXMuZGlzYWJsZWQsIGRpc2FibGVkKSwgKDAsIF9kZWZpbmVQcm9wZXJ0eTIuZGVmYXVsdCkoX2NsYXNzTmFtZXMsIGNsYXNzZXMuZnVsbFdpZHRoLCBmdWxsV2lkdGgpLCBfY2xhc3NOYW1lcyksIGNsYXNzTmFtZVByb3ApO1xuICByZXR1cm4gX3JlYWN0LmRlZmF1bHQuY3JlYXRlRWxlbWVudChfQnV0dG9uQmFzZS5kZWZhdWx0LCAoMCwgX2V4dGVuZHMyLmRlZmF1bHQpKHtcbiAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICBkaXNhYmxlZDogZGlzYWJsZWQsXG4gICAgZm9jdXNSaXBwbGU6ICFkaXNhYmxlRm9jdXNSaXBwbGUsXG4gICAgZm9jdXNWaXNpYmxlQ2xhc3NOYW1lOiAoMCwgX2NsYXNzbmFtZXMuZGVmYXVsdCkoY2xhc3Nlcy5mb2N1c1Zpc2libGUsIGZvY3VzVmlzaWJsZUNsYXNzTmFtZSlcbiAgfSwgb3RoZXIpLCBfcmVhY3QuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwic3BhblwiLCB7XG4gICAgY2xhc3NOYW1lOiBjbGFzc2VzLmxhYmVsXG4gIH0sIGNoaWxkcmVuKSk7XG59XG5cbkJ1dHRvbi5wcm9wVHlwZXMgPSBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIgPyB7XG4gIC8qKlxuICAgKiBUaGUgY29udGVudCBvZiB0aGUgYnV0dG9uLlxuICAgKi9cbiAgY2hpbGRyZW46IF9wcm9wVHlwZXMuZGVmYXVsdC5ub2RlLmlzUmVxdWlyZWQsXG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIG9yIGV4dGVuZCB0aGUgc3R5bGVzIGFwcGxpZWQgdG8gdGhlIGNvbXBvbmVudC5cbiAgICogU2VlIFtDU1MgQVBJXSgjY3NzLWFwaSkgYmVsb3cgZm9yIG1vcmUgZGV0YWlscy5cbiAgICovXG4gIGNsYXNzZXM6IF9wcm9wVHlwZXMuZGVmYXVsdC5vYmplY3QuaXNSZXF1aXJlZCxcblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgY2xhc3NOYW1lOiBfcHJvcFR5cGVzLmRlZmF1bHQuc3RyaW5nLFxuXG4gIC8qKlxuICAgKiBUaGUgY29sb3Igb2YgdGhlIGNvbXBvbmVudC4gSXQgc3VwcG9ydHMgdGhvc2UgdGhlbWUgY29sb3JzIHRoYXQgbWFrZSBzZW5zZSBmb3IgdGhpcyBjb21wb25lbnQuXG4gICAqL1xuICBjb2xvcjogX3Byb3BUeXBlcy5kZWZhdWx0Lm9uZU9mKFsnZGVmYXVsdCcsICdpbmhlcml0JywgJ3ByaW1hcnknLCAnc2Vjb25kYXJ5J10pLFxuXG4gIC8qKlxuICAgKiBUaGUgY29tcG9uZW50IHVzZWQgZm9yIHRoZSByb290IG5vZGUuXG4gICAqIEVpdGhlciBhIHN0cmluZyB0byB1c2UgYSBET00gZWxlbWVudCBvciBhIGNvbXBvbmVudC5cbiAgICovXG4gIGNvbXBvbmVudDogX3Byb3BUeXBlcy5kZWZhdWx0Lm9uZU9mVHlwZShbX3Byb3BUeXBlcy5kZWZhdWx0LnN0cmluZywgX3Byb3BUeXBlcy5kZWZhdWx0LmZ1bmMsIF9wcm9wVHlwZXMuZGVmYXVsdC5vYmplY3RdKSxcblxuICAvKipcbiAgICogSWYgYHRydWVgLCB0aGUgYnV0dG9uIHdpbGwgYmUgZGlzYWJsZWQuXG4gICAqL1xuICBkaXNhYmxlZDogX3Byb3BUeXBlcy5kZWZhdWx0LmJvb2wsXG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgdGhlICBrZXlib2FyZCBmb2N1cyByaXBwbGUgd2lsbCBiZSBkaXNhYmxlZC5cbiAgICogYGRpc2FibGVSaXBwbGVgIG11c3QgYWxzbyBiZSB0cnVlLlxuICAgKi9cbiAgZGlzYWJsZUZvY3VzUmlwcGxlOiBfcHJvcFR5cGVzLmRlZmF1bHQuYm9vbCxcblxuICAvKipcbiAgICogSWYgYHRydWVgLCB0aGUgcmlwcGxlIGVmZmVjdCB3aWxsIGJlIGRpc2FibGVkLlxuICAgKi9cbiAgZGlzYWJsZVJpcHBsZTogX3Byb3BUeXBlcy5kZWZhdWx0LmJvb2wsXG5cbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGZvY3VzVmlzaWJsZUNsYXNzTmFtZTogX3Byb3BUeXBlcy5kZWZhdWx0LnN0cmluZyxcblxuICAvKipcbiAgICogSWYgYHRydWVgLCB0aGUgYnV0dG9uIHdpbGwgdGFrZSB1cCB0aGUgZnVsbCB3aWR0aCBvZiBpdHMgY29udGFpbmVyLlxuICAgKi9cbiAgZnVsbFdpZHRoOiBfcHJvcFR5cGVzLmRlZmF1bHQuYm9vbCxcblxuICAvKipcbiAgICogVGhlIFVSTCB0byBsaW5rIHRvIHdoZW4gdGhlIGJ1dHRvbiBpcyBjbGlja2VkLlxuICAgKiBJZiBkZWZpbmVkLCBhbiBgYWAgZWxlbWVudCB3aWxsIGJlIHVzZWQgYXMgdGhlIHJvb3Qgbm9kZS5cbiAgICovXG4gIGhyZWY6IF9wcm9wVHlwZXMuZGVmYXVsdC5zdHJpbmcsXG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgYW5kIGB2YXJpYW50YCBpcyBgJ2ZhYidgLCB3aWxsIHVzZSBtaW5pIGZsb2F0aW5nIGFjdGlvbiBidXR0b24gc3R5bGluZy5cbiAgICovXG4gIG1pbmk6IF9wcm9wVHlwZXMuZGVmYXVsdC5ib29sLFxuXG4gIC8qKlxuICAgKiBUaGUgc2l6ZSBvZiB0aGUgYnV0dG9uLlxuICAgKiBgc21hbGxgIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGRlbnNlIGJ1dHRvbiBzdHlsaW5nLlxuICAgKi9cbiAgc2l6ZTogX3Byb3BUeXBlcy5kZWZhdWx0Lm9uZU9mKFsnc21hbGwnLCAnbWVkaXVtJywgJ2xhcmdlJ10pLFxuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICB0eXBlOiBfcHJvcFR5cGVzLmRlZmF1bHQuc3RyaW5nLFxuXG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiBidXR0b24uXG4gICAqL1xuICB2YXJpYW50OiBfcHJvcFR5cGVzLmRlZmF1bHQub25lT2YoWyd0ZXh0JywgJ2ZsYXQnLCAnb3V0bGluZWQnLCAnY29udGFpbmVkJywgJ3JhaXNlZCcsICdmYWInXSlcbn0gOiB7fTtcbkJ1dHRvbi5kZWZhdWx0UHJvcHMgPSB7XG4gIGNvbG9yOiAnZGVmYXVsdCcsXG4gIGNvbXBvbmVudDogJ2J1dHRvbicsXG4gIGRpc2FibGVkOiBmYWxzZSxcbiAgZGlzYWJsZUZvY3VzUmlwcGxlOiBmYWxzZSxcbiAgZnVsbFdpZHRoOiBmYWxzZSxcbiAgbWluaTogZmFsc2UsXG4gIHNpemU6ICdtZWRpdW0nLFxuICB0eXBlOiAnYnV0dG9uJyxcbiAgdmFyaWFudDogJ3RleHQnXG59O1xuXG52YXIgX2RlZmF1bHQgPSAoMCwgX3dpdGhTdHlsZXMuZGVmYXVsdCkoc3R5bGVzLCB7XG4gIG5hbWU6ICdNdWlCdXR0b24nXG59KShCdXR0b24pO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/@material-ui/core/Button/Button.js\n");
+
+/***/ }),
+
+/***/ "./node_modules/@material-ui/core/Button/index.js":
+/*!********************************************************!*\
+  !*** ./node_modules/@material-ui/core/Button/index.js ***!
+  \********************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\nvar _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/builtin/interopRequireDefault */ \"./node_modules/@babel/runtime/helpers/builtin/interopRequireDefault.js\");\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nObject.defineProperty(exports, \"default\", {\n  enumerable: true,\n  get: function get() {\n    return _Button.default;\n  }\n});\n\nvar _Button = _interopRequireDefault(__webpack_require__(/*! ./Button */ \"./node_modules/@material-ui/core/Button/Button.js\"));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsLXVpL2NvcmUvQnV0dG9uL2luZGV4LmpzP2Q0ZTYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsImZpbGUiOiIuL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwtdWkvY29yZS9CdXR0b24vaW5kZXguanMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9idWlsdGluL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImRlZmF1bHRcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX0J1dHRvbi5kZWZhdWx0O1xuICB9XG59KTtcblxudmFyIF9CdXR0b24gPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL0J1dHRvblwiKSk7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/@material-ui/core/Button/index.js\n");
+
+/***/ }),
+
+/***/ "./node_modules/@material-ui/core/ButtonBase/ButtonBase.js":
+/*!*****************************************************************!*\
+  !*** ./node_modules/@material-ui/core/ButtonBase/ButtonBase.js ***!
+  \*****************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\nvar _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/builtin/interopRequireDefault */ \"./node_modules/@babel/runtime/helpers/builtin/interopRequireDefault.js\");\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = exports.styles = void 0;\n\nvar _extends2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/extends */ \"./node_modules/@babel/runtime/helpers/builtin/extends.js\"));\n\nvar _defineProperty2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/defineProperty */ \"./node_modules/@babel/runtime/helpers/builtin/defineProperty.js\"));\n\nvar _objectWithoutProperties2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/objectWithoutProperties */ \"./node_modules/@babel/runtime/helpers/builtin/objectWithoutProperties.js\"));\n\nvar _classCallCheck2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/classCallCheck */ \"./node_modules/@babel/runtime/helpers/builtin/classCallCheck.js\"));\n\nvar _createClass2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/createClass */ \"./node_modules/@babel/runtime/helpers/builtin/createClass.js\"));\n\nvar _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/possibleConstructorReturn */ \"./node_modules/@babel/runtime/helpers/builtin/possibleConstructorReturn.js\"));\n\nvar _inherits2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/inherits */ \"./node_modules/@babel/runtime/helpers/builtin/inherits.js\"));\n\nvar _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(/*! @babel/runtime/helpers/builtin/assertThisInitialized */ \"./node_modules/@babel/runtime/helpers/builtin/assertThisInitialized.js\"));\n\nvar _react = _interopRequireDefault(__webpack_require__(/*! react */ \"./node_modules/react/index.js\"));\n\nvar _propTypes = _interopRequireDefault(__webpack_require__(/*! prop-types */ \"./node_modules/prop-types/index.js\"));\n\nvar _reactDom = _interopRequireDefault(__webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\"));\n\nvar _classnames = _interopRequireDefault(__webpack_require__(/*! classnames */ \"./node_modules/classnames/index.js\"));\n\nvar _keycode = _interopRequireDefault(__webpack_require__(/*! keycode */ \"./node_modules/keycode/index.js\"));\n\nvar _ownerWindow = _interopRequireDefault(__webpack_require__(/*! ../utils/ownerWindow */ \"./node_modules/@material-ui/core/utils/ownerWindow.js\"));\n\nvar _withStyles = _interopRequireDefault(__webpack_require__(/*! ../styles/withStyles */ \"./node_modules/@material-ui/core/styles/withStyles.js\"));\n\nvar _focusVisible = __webpack_require__(/*! ./focusVisible */ \"./node_modules/@material-ui/core/ButtonBase/focusVisible.js\");\n\nvar _TouchRipple = _interopRequireDefault(__webpack_require__(/*! ./TouchRipple */ \"./node_modules/@material-ui/core/ButtonBase/TouchRipple.js\"));\n\nvar _createRippleHandler = _interopRequireDefault(__webpack_require__(/*! ./createRippleHandler */ \"./node_modules/@material-ui/core/ButtonBase/createRippleHandler.js\"));\n\nvar styles = {\n  root: {\n    display: 'inline-flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n    position: 'relative',\n    // Remove grey highlight\n    WebkitTapHighlightColor: 'transparent',\n    backgroundColor: 'transparent',\n    // Reset default value\n    // We disable the focus ring for mouse, touch and keyboard users.\n    outline: 'none',\n    border: 0,\n    margin: 0,\n    // Remove the margin in Safari\n    borderRadius: 0,\n    padding: 0,\n    // Remove the padding in Firefox\n    cursor: 'pointer',\n    userSelect: 'none',\n    verticalAlign: 'middle',\n    '-moz-appearance': 'none',\n    // Reset\n    '-webkit-appearance': 'none',\n    // Reset\n    textDecoration: 'none',\n    // So we take precedent over the style of a native <a /> element.\n    color: 'inherit',\n    '&::-moz-focus-inner': {\n      borderStyle: 'none' // Remove Firefox dotted outline.\n\n    },\n    '&$disabled': {\n      pointerEvents: 'none',\n      // Disable link interactions\n      cursor: 'default'\n    }\n  },\n  disabled: {},\n  focusVisible: {}\n};\n/* istanbul ignore if */\n\nexports.styles = styles;\n\nif (\"development\" !== 'production' && !_react.default.createContext) {\n  throw new Error('Material-UI: react@16.3.0 or greater is required.');\n}\n/**\n * `ButtonBase` contains as few styles as possible.\n * It aims to be a simple building block for creating a button.\n * It contains a load of style reset and some focus/ripple logic.\n */\n\n\nvar ButtonBase =\n/*#__PURE__*/\nfunction (_React$Component) {\n  (0, _inherits2.default)(ButtonBase, _React$Component);\n\n  function ButtonBase() {\n    var _ref;\n\n    var _temp, _this;\n\n    (0, _classCallCheck2.default)(this, ButtonBase);\n\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    return (0, _possibleConstructorReturn2.default)(_this, (_temp = _this = (0, _possibleConstructorReturn2.default)(this, (_ref = ButtonBase.__proto__ || Object.getPrototypeOf(ButtonBase)).call.apply(_ref, [this].concat(args))), _this.state = {}, _this.onFocusVisibleHandler = function (event) {\n      _this.keyDown = false;\n\n      _this.setState({\n        focusVisible: true\n      });\n\n      if (_this.props.onFocusVisible) {\n        _this.props.onFocusVisible(event);\n      }\n    }, _this.onRippleRef = function (node) {\n      _this.ripple = node;\n    }, _this.ripple = null, _this.keyDown = false, _this.button = null, _this.focusVisibleTimeout = null, _this.focusVisibleCheckTime = 50, _this.focusVisibleMaxCheckTimes = 5, _this.handleKeyDown = function (event) {\n      var _this$props = _this.props,\n          component = _this$props.component,\n          focusRipple = _this$props.focusRipple,\n          onKeyDown = _this$props.onKeyDown,\n          onClick = _this$props.onClick;\n      var key = (0, _keycode.default)(event); // Check if key is already down to avoid repeats being counted as multiple activations\n\n      if (focusRipple && !_this.keyDown && _this.state.focusVisible && _this.ripple && key === 'space') {\n        _this.keyDown = true;\n        event.persist();\n\n        _this.ripple.stop(event, function () {\n          _this.ripple.start(event);\n        });\n      }\n\n      if (onKeyDown) {\n        onKeyDown(event);\n      } // Keyboard accessibility for non interactive elements\n\n\n      if (event.target === event.currentTarget && component && component !== 'button' && (key === 'space' || key === 'enter') && !(_this.button.tagName === 'A' && _this.button.href)) {\n        event.preventDefault();\n\n        if (onClick) {\n          onClick(event);\n        }\n      }\n    }, _this.handleKeyUp = function (event) {\n      if (_this.props.focusRipple && (0, _keycode.default)(event) === 'space' && _this.ripple && _this.state.focusVisible) {\n        _this.keyDown = false;\n        event.persist();\n\n        _this.ripple.stop(event, function () {\n          _this.ripple.pulsate(event);\n        });\n      }\n\n      if (_this.props.onKeyUp) {\n        _this.props.onKeyUp(event);\n      }\n    }, _this.handleMouseDown = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'MouseDown', 'start', function () {\n      clearTimeout(_this.focusVisibleTimeout);\n\n      if (_this.state.focusVisible) {\n        _this.setState({\n          focusVisible: false\n        });\n      }\n    }), _this.handleMouseUp = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'MouseUp', 'stop'), _this.handleMouseLeave = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'MouseLeave', 'stop', function (event) {\n      if (_this.state.focusVisible) {\n        event.preventDefault();\n      }\n    }), _this.handleTouchStart = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'TouchStart', 'start'), _this.handleTouchEnd = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'TouchEnd', 'stop'), _this.handleTouchMove = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'TouchMove', 'stop'), _this.handleBlur = (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'Blur', 'stop', function () {\n      clearTimeout(_this.focusVisibleTimeout);\n\n      if (_this.state.focusVisible) {\n        _this.setState({\n          focusVisible: false\n        });\n      }\n    }), _this.handleFocus = function (event) {\n      if (_this.props.disabled) {\n        return;\n      } // Fix for https://github.com/facebook/react/issues/7769\n\n\n      if (!_this.button) {\n        _this.button = event.currentTarget;\n      }\n\n      event.persist();\n      (0, _focusVisible.detectFocusVisible)((0, _assertThisInitialized2.default)(_this), _this.button, function () {\n        _this.onFocusVisibleHandler(event);\n      });\n\n      if (_this.props.onFocus) {\n        _this.props.onFocus(event);\n      }\n    }, _temp));\n  }\n\n  (0, _createClass2.default)(ButtonBase, [{\n    key: \"componentDidMount\",\n    value: function componentDidMount() {\n      var _this2 = this;\n\n      this.button = _reactDom.default.findDOMNode(this);\n      (0, _focusVisible.listenForFocusKeys)((0, _ownerWindow.default)(this.button));\n\n      if (this.props.action) {\n        this.props.action({\n          focusVisible: function focusVisible() {\n            _this2.setState({\n              focusVisible: true\n            });\n\n            _this2.button.focus();\n          }\n        });\n      }\n    }\n  }, {\n    key: \"componentDidUpdate\",\n    value: function componentDidUpdate(prevProps, prevState) {\n      if (this.props.focusRipple && !this.props.disableRipple && !prevState.focusVisible && this.state.focusVisible) {\n        this.ripple.pulsate();\n      }\n    }\n  }, {\n    key: \"componentWillUnmount\",\n    value: function componentWillUnmount() {\n      this.button = null;\n      clearTimeout(this.focusVisibleTimeout);\n    }\n  }, {\n    key: \"render\",\n    value: function render() {\n      var _classNames;\n\n      var _props = this.props,\n          action = _props.action,\n          buttonRef = _props.buttonRef,\n          centerRipple = _props.centerRipple,\n          children = _props.children,\n          classes = _props.classes,\n          classNameProp = _props.className,\n          component = _props.component,\n          disabled = _props.disabled,\n          disableRipple = _props.disableRipple,\n          disableTouchRipple = _props.disableTouchRipple,\n          focusRipple = _props.focusRipple,\n          focusVisibleClassName = _props.focusVisibleClassName,\n          onBlur = _props.onBlur,\n          onFocus = _props.onFocus,\n          onFocusVisible = _props.onFocusVisible,\n          onKeyDown = _props.onKeyDown,\n          onKeyUp = _props.onKeyUp,\n          onMouseDown = _props.onMouseDown,\n          onMouseLeave = _props.onMouseLeave,\n          onMouseUp = _props.onMouseUp,\n          onTouchEnd = _props.onTouchEnd,\n          onTouchMove = _props.onTouchMove,\n          onTouchStart = _props.onTouchStart,\n          tabIndex = _props.tabIndex,\n          TouchRippleProps = _props.TouchRippleProps,\n          type = _props.type,\n          other = (0, _objectWithoutProperties2.default)(_props, [\"action\", \"buttonRef\", \"centerRipple\", \"children\", \"classes\", \"className\", \"component\", \"disabled\", \"disableRipple\", \"disableTouchRipple\", \"focusRipple\", \"focusVisibleClassName\", \"onBlur\", \"onFocus\", \"onFocusVisible\", \"onKeyDown\", \"onKeyUp\", \"onMouseDown\", \"onMouseLeave\", \"onMouseUp\", \"onTouchEnd\", \"onTouchMove\", \"onTouchStart\", \"tabIndex\", \"TouchRippleProps\", \"type\"]);\n      var className = (0, _classnames.default)(classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.disabled, disabled), (0, _defineProperty2.default)(_classNames, classes.focusVisible, this.state.focusVisible), (0, _defineProperty2.default)(_classNames, focusVisibleClassName, this.state.focusVisible), _classNames), classNameProp);\n      var buttonProps = {};\n      var ComponentProp = component;\n\n      if (ComponentProp === 'button' && other.href) {\n        ComponentProp = 'a';\n      }\n\n      if (ComponentProp === 'button') {\n        buttonProps.type = type || 'button';\n        buttonProps.disabled = disabled;\n      } else {\n        buttonProps.role = 'button';\n      }\n\n      return _react.default.createElement(ComponentProp, (0, _extends2.default)({\n        onBlur: this.handleBlur,\n        onFocus: this.handleFocus,\n        onKeyDown: this.handleKeyDown,\n        onKeyUp: this.handleKeyUp,\n        onMouseDown: this.handleMouseDown,\n        onMouseLeave: this.handleMouseLeave,\n        onMouseUp: this.handleMouseUp,\n        onTouchEnd: this.handleTouchEnd,\n        onTouchMove: this.handleTouchMove,\n        onTouchStart: this.handleTouchStart,\n        tabIndex: disabled ? '-1' : tabIndex,\n        className: className,\n        ref: buttonRef\n      }, buttonProps, other), children, !disableRipple && !disabled ? _react.default.createElement(_TouchRipple.default, (0, _extends2.default)({\n        innerRef: this.onRippleRef,\n        center: centerRipple\n      }, TouchRippleProps)) : null);\n    }\n  }], [{\n    key: \"getDerivedStateFromProps\",\n    value: function getDerivedStateFromProps(nextProps, prevState) {\n      if (typeof prevState.focusVisible === 'undefined') {\n        return {\n          focusVisible: false,\n          lastDisabled: nextProps.disabled\n        };\n      } // The blur won't fire when the disabled state is set on a focused input.\n      // We need to book keep the focused state manually.\n\n\n      if (!prevState.prevState && nextProps.disabled && prevState.focusVisible) {\n        return {\n          focusVisible: false,\n          lastDisabled: nextProps.disabled\n        };\n      }\n\n      return {\n        lastDisabled: nextProps.disabled\n      };\n    }\n  }]);\n  return ButtonBase;\n}(_react.default.Component);\n\nButtonBase.propTypes =  true ? {\n  /**\n   * Callback fired when the component mounts.\n   * This is useful when you want to trigger an action programmatically.\n   * It currently only supports `focusVisible()` action.\n   *\n   * @param {object} actions This object contains all possible actions\n   * that can be triggered programmatically.\n   */\n  action: _propTypes.default.func,\n\n  /**\n   * Use that property to pass a ref callback to the native button component.\n   */\n  buttonRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]),\n\n  /**\n   * If `true`, the ripples will be centered.\n   * They won't start at the cursor interaction position.\n   */\n  centerRipple: _propTypes.default.bool,\n\n  /**\n   * The content of the component.\n   */\n  children: _propTypes.default.node,\n\n  /**\n   * Override or extend the styles applied to the component.\n   * See [CSS API](#css-api) below for more details.\n   */\n  classes: _propTypes.default.object.isRequired,\n\n  /**\n   * @ignore\n   */\n  className: _propTypes.default.string,\n\n  /**\n   * The component used for the root node.\n   * Either a string to use a DOM element or a component.\n   */\n  component: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func, _propTypes.default.object]),\n\n  /**\n   * If `true`, the base button will be disabled.\n   */\n  disabled: _propTypes.default.bool,\n\n  /**\n   * If `true`, the ripple effect will be disabled.\n   */\n  disableRipple: _propTypes.default.bool,\n\n  /**\n   * If `true`, the touch ripple effect will be disabled.\n   */\n  disableTouchRipple: _propTypes.default.bool,\n\n  /**\n   * If `true`, the base button will have a keyboard focus ripple.\n   * `disableRipple` must also be `false`.\n   */\n  focusRipple: _propTypes.default.bool,\n\n  /**\n   * This property can help a person know which element has the keyboard focus.\n   * The class name will be applied when the element gain the focus throught a keyboard interaction.\n   * It's a polyfill for the [CSS :focus-visible feature](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo).\n   * The rational for using this feature [is explain here](https://github.com/WICG/focus-visible/blob/master/explainer.md).\n   */\n  focusVisibleClassName: _propTypes.default.string,\n\n  /**\n   * @ignore\n   */\n  onBlur: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onClick: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onFocus: _propTypes.default.func,\n\n  /**\n   * Callback fired when the component is focused with a keyboard.\n   * We trigger a `onFocus` callback too.\n   */\n  onFocusVisible: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onKeyDown: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onKeyUp: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onMouseDown: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onMouseLeave: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onMouseUp: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onTouchEnd: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onTouchMove: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  onTouchStart: _propTypes.default.func,\n\n  /**\n   * @ignore\n   */\n  role: _propTypes.default.string,\n\n  /**\n   * @ignore\n   */\n  tabIndex: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),\n\n  /**\n   * Properties applied to the `TouchRipple` element.\n   */\n  TouchRippleProps: _propTypes.default.object,\n\n  /**\n   * Used to control the button's purpose.\n   * This property passes the value to the `type` attribute of the native button component.\n   * Valid property values include `button`, `submit`, and `reset`.\n   */\n  type: _propTypes.default.string\n} : undefined;\nButtonBase.defaultProps = {\n  centerRipple: false,\n  component: 'button',\n  disableRipple: false,\n  disableTouchRipple: false,\n  focusRipple: false,\n  tabIndex: '0',\n  type: 'button'\n};\n\nvar _default = (0, _withStyles.default)(styles, {\n  name: 'MuiButtonBase'\n})(ButtonBase);\n\nexports.default = _default;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsLXVpL2NvcmUvQnV0dG9uQmFzZS9CdXR0b25CYXNlLmpzPzAzODYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsY0FBYztBQUNkO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLHVFQUF1RSxhQUFhO0FBQ3BGO0FBQ0E7O0FBRUEsc1BBQXNQO0FBQ3RQOztBQUVBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDOztBQUU3QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0EsT0FBTzs7O0FBR1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLE9BQU87OztBQUdQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4RUFBOEU7QUFDOUU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQiLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsLXVpL2NvcmUvQnV0dG9uQmFzZS9CdXR0b25CYXNlLmpzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYnVpbHRpbi9pbnRlcm9wUmVxdWlyZURlZmF1bHRcIik7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLnN0eWxlcyA9IHZvaWQgMDtcblxudmFyIF9leHRlbmRzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYnVpbHRpbi9leHRlbmRzXCIpKTtcblxudmFyIF9kZWZpbmVQcm9wZXJ0eTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2J1aWx0aW4vZGVmaW5lUHJvcGVydHlcIikpO1xuXG52YXIgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYnVpbHRpbi9vYmplY3RXaXRob3V0UHJvcGVydGllc1wiKSk7XG5cbnZhciBfY2xhc3NDYWxsQ2hlY2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9idWlsdGluL2NsYXNzQ2FsbENoZWNrXCIpKTtcblxudmFyIF9jcmVhdGVDbGFzczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2J1aWx0aW4vY3JlYXRlQ2xhc3NcIikpO1xuXG52YXIgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9idWlsdGluL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIikpO1xuXG52YXIgX2luaGVyaXRzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYnVpbHRpbi9pbmhlcml0c1wiKSk7XG5cbnZhciBfYXNzZXJ0VGhpc0luaXRpYWxpemVkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYnVpbHRpbi9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIikpO1xuXG52YXIgX3JlYWN0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwicmVhY3RcIikpO1xuXG52YXIgX3Byb3BUeXBlcyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcInByb3AtdHlwZXNcIikpO1xuXG52YXIgX3JlYWN0RG9tID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwicmVhY3QtZG9tXCIpKTtcblxudmFyIF9jbGFzc25hbWVzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiY2xhc3NuYW1lc1wiKSk7XG5cbnZhciBfa2V5Y29kZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcImtleWNvZGVcIikpO1xuXG52YXIgX293bmVyV2luZG93ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi4vdXRpbHMvb3duZXJXaW5kb3dcIikpO1xuXG52YXIgX3dpdGhTdHlsZXMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuLi9zdHlsZXMvd2l0aFN0eWxlc1wiKSk7XG5cbnZhciBfZm9jdXNWaXNpYmxlID0gcmVxdWlyZShcIi4vZm9jdXNWaXNpYmxlXCIpO1xuXG52YXIgX1RvdWNoUmlwcGxlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9Ub3VjaFJpcHBsZVwiKSk7XG5cbnZhciBfY3JlYXRlUmlwcGxlSGFuZGxlciA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vY3JlYXRlUmlwcGxlSGFuZGxlclwiKSk7XG5cbnZhciBzdHlsZXMgPSB7XG4gIHJvb3Q6IHtcbiAgICBkaXNwbGF5OiAnaW5saW5lLWZsZXgnLFxuICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgIGp1c3RpZnlDb250ZW50OiAnY2VudGVyJyxcbiAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJyxcbiAgICAvLyBSZW1vdmUgZ3JleSBoaWdobGlnaHRcbiAgICBXZWJraXRUYXBIaWdobGlnaHRDb2xvcjogJ3RyYW5zcGFyZW50JyxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6ICd0cmFuc3BhcmVudCcsXG4gICAgLy8gUmVzZXQgZGVmYXVsdCB2YWx1ZVxuICAgIC8vIFdlIGRpc2FibGUgdGhlIGZvY3VzIHJpbmcgZm9yIG1vdXNlLCB0b3VjaCBhbmQga2V5Ym9hcmQgdXNlcnMuXG4gICAgb3V0bGluZTogJ25vbmUnLFxuICAgIGJvcmRlcjogMCxcbiAgICBtYXJnaW46IDAsXG4gICAgLy8gUmVtb3ZlIHRoZSBtYXJnaW4gaW4gU2FmYXJpXG4gICAgYm9yZGVyUmFkaXVzOiAwLFxuICAgIHBhZGRpbmc6IDAsXG4gICAgLy8gUmVtb3ZlIHRoZSBwYWRkaW5nIGluIEZpcmVmb3hcbiAgICBjdXJzb3I6ICdwb2ludGVyJyxcbiAgICB1c2VyU2VsZWN0OiAnbm9uZScsXG4gICAgdmVydGljYWxBbGlnbjogJ21pZGRsZScsXG4gICAgJy1tb3otYXBwZWFyYW5jZSc6ICdub25lJyxcbiAgICAvLyBSZXNldFxuICAgICctd2Via2l0LWFwcGVhcmFuY2UnOiAnbm9uZScsXG4gICAgLy8gUmVzZXRcbiAgICB0ZXh0RGVjb3JhdGlvbjogJ25vbmUnLFxuICAgIC8vIFNvIHdlIHRha2UgcHJlY2VkZW50IG92ZXIgdGhlIHN0eWxlIG9mIGEgbmF0aXZlIDxhIC8+IGVsZW1lbnQuXG4gICAgY29sb3I6ICdpbmhlcml0JyxcbiAgICAnJjo6LW1vei1mb2N1cy1pbm5lcic6IHtcbiAgICAgIGJvcmRlclN0eWxlOiAnbm9uZScgLy8gUmVtb3ZlIEZpcmVmb3ggZG90dGVkIG91dGxpbmUuXG5cbiAgICB9LFxuICAgICcmJGRpc2FibGVkJzoge1xuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLFxuICAgICAgLy8gRGlzYWJsZSBsaW5rIGludGVyYWN0aW9uc1xuICAgICAgY3Vyc29yOiAnZGVmYXVsdCdcbiAgICB9XG4gIH0sXG4gIGRpc2FibGVkOiB7fSxcbiAgZm9jdXNWaXNpYmxlOiB7fVxufTtcbi8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuXG5leHBvcnRzLnN0eWxlcyA9IHN0eWxlcztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgIV9yZWFjdC5kZWZhdWx0LmNyZWF0ZUNvbnRleHQpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdNYXRlcmlhbC1VSTogcmVhY3RAMTYuMy4wIG9yIGdyZWF0ZXIgaXMgcmVxdWlyZWQuJyk7XG59XG4vKipcbiAqIGBCdXR0b25CYXNlYCBjb250YWlucyBhcyBmZXcgc3R5bGVzIGFzIHBvc3NpYmxlLlxuICogSXQgYWltcyB0byBiZSBhIHNpbXBsZSBidWlsZGluZyBibG9jayBmb3IgY3JlYXRpbmcgYSBidXR0b24uXG4gKiBJdCBjb250YWlucyBhIGxvYWQgb2Ygc3R5bGUgcmVzZXQgYW5kIHNvbWUgZm9jdXMvcmlwcGxlIGxvZ2ljLlxuICovXG5cblxudmFyIEJ1dHRvbkJhc2UgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgKDAsIF9pbmhlcml0czIuZGVmYXVsdCkoQnV0dG9uQmFzZSwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgZnVuY3Rpb24gQnV0dG9uQmFzZSgpIHtcbiAgICB2YXIgX3JlZjtcblxuICAgIHZhciBfdGVtcCwgX3RoaXM7XG5cbiAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMi5kZWZhdWx0KSh0aGlzLCBCdXR0b25CYXNlKTtcblxuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICByZXR1cm4gKDAsIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMi5kZWZhdWx0KShfdGhpcywgKF90ZW1wID0gX3RoaXMgPSAoMCwgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yLmRlZmF1bHQpKHRoaXMsIChfcmVmID0gQnV0dG9uQmFzZS5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKEJ1dHRvbkJhc2UpKS5jYWxsLmFwcGx5KF9yZWYsIFt0aGlzXS5jb25jYXQoYXJncykpKSwgX3RoaXMuc3RhdGUgPSB7fSwgX3RoaXMub25Gb2N1c1Zpc2libGVIYW5kbGVyID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICBfdGhpcy5rZXlEb3duID0gZmFsc2U7XG5cbiAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgZm9jdXNWaXNpYmxlOiB0cnVlXG4gICAgICB9KTtcblxuICAgICAgaWYgKF90aGlzLnByb3BzLm9uRm9jdXNWaXNpYmxlKSB7XG4gICAgICAgIF90aGlzLnByb3BzLm9uRm9jdXNWaXNpYmxlKGV2ZW50KTtcbiAgICAgIH1cbiAgICB9LCBfdGhpcy5vblJpcHBsZVJlZiA9IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICBfdGhpcy5yaXBwbGUgPSBub2RlO1xuICAgIH0sIF90aGlzLnJpcHBsZSA9IG51bGwsIF90aGlzLmtleURvd24gPSBmYWxzZSwgX3RoaXMuYnV0dG9uID0gbnVsbCwgX3RoaXMuZm9jdXNWaXNpYmxlVGltZW91dCA9IG51bGwsIF90aGlzLmZvY3VzVmlzaWJsZUNoZWNrVGltZSA9IDUwLCBfdGhpcy5mb2N1c1Zpc2libGVNYXhDaGVja1RpbWVzID0gNSwgX3RoaXMuaGFuZGxlS2V5RG93biA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgdmFyIF90aGlzJHByb3BzID0gX3RoaXMucHJvcHMsXG4gICAgICAgICAgY29tcG9uZW50ID0gX3RoaXMkcHJvcHMuY29tcG9uZW50LFxuICAgICAgICAgIGZvY3VzUmlwcGxlID0gX3RoaXMkcHJvcHMuZm9jdXNSaXBwbGUsXG4gICAgICAgICAgb25LZXlEb3duID0gX3RoaXMkcHJvcHMub25LZXlEb3duLFxuICAgICAgICAgIG9uQ2xpY2sgPSBfdGhpcyRwcm9wcy5vbkNsaWNrO1xuICAgICAgdmFyIGtleSA9ICgwLCBfa2V5Y29kZS5kZWZhdWx0KShldmVudCk7IC8vIENoZWNrIGlmIGtleSBpcyBhbHJlYWR5IGRvd24gdG8gYXZvaWQgcmVwZWF0cyBiZWluZyBjb3VudGVkIGFzIG11bHRpcGxlIGFjdGl2YXRpb25zXG5cbiAgICAgIGlmIChmb2N1c1JpcHBsZSAmJiAhX3RoaXMua2V5RG93biAmJiBfdGhpcy5zdGF0ZS5mb2N1c1Zpc2libGUgJiYgX3RoaXMucmlwcGxlICYmIGtleSA9PT0gJ3NwYWNlJykge1xuICAgICAgICBfdGhpcy5rZXlEb3duID0gdHJ1ZTtcbiAgICAgICAgZXZlbnQucGVyc2lzdCgpO1xuXG4gICAgICAgIF90aGlzLnJpcHBsZS5zdG9wKGV2ZW50LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgX3RoaXMucmlwcGxlLnN0YXJ0KGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvbktleURvd24pIHtcbiAgICAgICAgb25LZXlEb3duKGV2ZW50KTtcbiAgICAgIH0gLy8gS2V5Ym9hcmQgYWNjZXNzaWJpbGl0eSBmb3Igbm9uIGludGVyYWN0aXZlIGVsZW1lbnRzXG5cblxuICAgICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gZXZlbnQuY3VycmVudFRhcmdldCAmJiBjb21wb25lbnQgJiYgY29tcG9uZW50ICE9PSAnYnV0dG9uJyAmJiAoa2V5ID09PSAnc3BhY2UnIHx8IGtleSA9PT0gJ2VudGVyJykgJiYgIShfdGhpcy5idXR0b24udGFnTmFtZSA9PT0gJ0EnICYmIF90aGlzLmJ1dHRvbi5ocmVmKSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGlmIChvbkNsaWNrKSB7XG4gICAgICAgICAgb25DbGljayhldmVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCBfdGhpcy5oYW5kbGVLZXlVcCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgaWYgKF90aGlzLnByb3BzLmZvY3VzUmlwcGxlICYmICgwLCBfa2V5Y29kZS5kZWZhdWx0KShldmVudCkgPT09ICdzcGFjZScgJiYgX3RoaXMucmlwcGxlICYmIF90aGlzLnN0YXRlLmZvY3VzVmlzaWJsZSkge1xuICAgICAgICBfdGhpcy5rZXlEb3duID0gZmFsc2U7XG4gICAgICAgIGV2ZW50LnBlcnNpc3QoKTtcblxuICAgICAgICBfdGhpcy5yaXBwbGUuc3RvcChldmVudCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIF90aGlzLnJpcHBsZS5wdWxzYXRlKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChfdGhpcy5wcm9wcy5vbktleVVwKSB7XG4gICAgICAgIF90aGlzLnByb3BzLm9uS2V5VXAoZXZlbnQpO1xuICAgICAgfVxuICAgIH0sIF90aGlzLmhhbmRsZU1vdXNlRG93biA9ICgwLCBfY3JlYXRlUmlwcGxlSGFuZGxlci5kZWZhdWx0KSgoMCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZDIuZGVmYXVsdCkoX3RoaXMpLCAnTW91c2VEb3duJywgJ3N0YXJ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY2xlYXJUaW1lb3V0KF90aGlzLmZvY3VzVmlzaWJsZVRpbWVvdXQpO1xuXG4gICAgICBpZiAoX3RoaXMuc3RhdGUuZm9jdXNWaXNpYmxlKSB7XG4gICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBmb2N1c1Zpc2libGU6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pLCBfdGhpcy5oYW5kbGVNb3VzZVVwID0gKDAsIF9jcmVhdGVSaXBwbGVIYW5kbGVyLmRlZmF1bHQpKCgwLCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkMi5kZWZhdWx0KShfdGhpcyksICdNb3VzZVVwJywgJ3N0b3AnKSwgX3RoaXMuaGFuZGxlTW91c2VMZWF2ZSA9ICgwLCBfY3JlYXRlUmlwcGxlSGFuZGxlci5kZWZhdWx0KSgoMCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZDIuZGVmYXVsdCkoX3RoaXMpLCAnTW91c2VMZWF2ZScsICdzdG9wJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICBpZiAoX3RoaXMuc3RhdGUuZm9jdXNWaXNpYmxlKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgfSksIF90aGlzLmhhbmRsZVRvdWNoU3RhcnQgPSAoMCwgX2NyZWF0ZVJpcHBsZUhhbmRsZXIuZGVmYXVsdCkoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKF90aGlzKSwgJ1RvdWNoU3RhcnQnLCAnc3RhcnQnKSwgX3RoaXMuaGFuZGxlVG91Y2hFbmQgPSAoMCwgX2NyZWF0ZVJpcHBsZUhhbmRsZXIuZGVmYXVsdCkoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKF90aGlzKSwgJ1RvdWNoRW5kJywgJ3N0b3AnKSwgX3RoaXMuaGFuZGxlVG91Y2hNb3ZlID0gKDAsIF9jcmVhdGVSaXBwbGVIYW5kbGVyLmRlZmF1bHQpKCgwLCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkMi5kZWZhdWx0KShfdGhpcyksICdUb3VjaE1vdmUnLCAnc3RvcCcpLCBfdGhpcy5oYW5kbGVCbHVyID0gKDAsIF9jcmVhdGVSaXBwbGVIYW5kbGVyLmRlZmF1bHQpKCgwLCBfYXNzZXJ0VGhpc0luaXRpYWxpe…
@eragon512
Copy link

hey guys, I'd like to take up this issue if its available

@RichieAHB
Copy link

Another broad idea to fix this (a few years on) is to swap the order of Ref and Update but delay hooks until the Ref effects have run. No idea how feasible this would be.

@eps1lon
Copy link
Collaborator

eps1lon commented Jun 18, 2019

Encountered this issue when using useImperativeHandle. The issue is that refs can be set with useImperativeHandle after useLayoutEffects run. This can become an issue if we execute callbacks in useLayoutEffect that use the ref set by useImperativeHandle e.g.

https://codesandbox.io/s/dank-darkness-podtr

const Child = React.forwardRef(({ callback }, ref) => {
  React.useLayoutEffect(callback);
  React.useImperativeHandle(ref, () => () =>
    console.log("handled me imperatively")
  );

  return null;
});

function Parent() {
  const childRef = React.useRef(null);
  // crash unless order of effects in Child is swapped
  return <Child callback={() => childRef.current()} ref={childRef} />;
}

Tried @RichieAHB proposed fix which resulted in 2 test failures which are desired IMO:

diff --git a/packages/react-dom/src/__tests__/ReactComponent-test.js b/packages/react-dom/src/__tests__/ReactComponent-test.js
index d3c5cbc1f..450f053e5 100644
--- a/packages/react-dom/src/__tests__/ReactComponent-test.js
+++ b/packages/react-dom/src/__tests__/ReactComponent-test.js
@@ -356,10 +356,10 @@ describe('ReactComponent', () => {
       'start mount',
       'inner 1 render',
       'inner 2 render',
-      'inner 1 componentDidMount',
       'ref 1 got instance 1',
-      'inner 2 componentDidMount',
+      'inner 1 componentDidMount',
       'ref 2 got instance 2',
+      'inner 2 componentDidMount',
       'outer componentDidMount',
       'start update',
       // Previous (equivalent) refs get cleared
@@ -368,10 +368,10 @@ describe('ReactComponent', () => {
       'inner 2 render',
       'ref 1 got null',
       'ref 2 got null',
-      'inner 1 componentDidUpdate',
       'ref 1 got instance 1',
-      'inner 2 componentDidUpdate',
+      'inner 1 componentDidUpdate',
       'ref 2 got instance 2',
+      'inner 2 componentDidUpdate',
       'outer componentDidUpdate',
       'start unmount',
       'outer componentWillUnmount',
diff --git a/packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js b/packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
index fd286f1e6..355112e0b 100644
--- a/packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
+++ b/packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
@@ -1046,12 +1046,12 @@ describe('ReactComponentLifeCycle', () => {
     expect(log).toEqual([
       'will mount',
       'render',
-      'did mount',
       'ref',
+      'did mount',
 
       'render',
-      'did update',
       'ref',
+      'did update',
     ]);
   });

Basically: Refs are called before didUpdate/didMount which should make more sense. If the component already did mount and did update then I should already have the updated refs and not was is currently after-didUpdate.

The issue becomes more apparent with forwardRef. If I pass forwarded refs to host components then those are set before layout effects run. But if I manually handle them with useImperativeHandle and not carefully check that I place this at the top of my render function I get a slightly different behavior.

Is this something the core team would be interested in or should this be re-opened when a breaking change is scheduled?

lossir added a commit to skbkontur/retail-ui that referenced this issue Jul 9, 2019
lossir added a commit to skbkontur/retail-ui that referenced this issue Jul 11, 2019
* fix(Input): add calling 'selectAll' via 'setTimeout'

facebook/react#7769

Fix #1413

* test(Input): add delay(0) when testing 'selectAllOnFocus'

* refactor(Input): use 'raf' instead of 'setTimeout'

* test(Input): raise the delay time due to 'raf'

* refactor(Input): return partially previous implementation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants