[
  {
    "path": ".browserlistrc",
    "content": "ie >= 11\nlast 1 Edge version\nlast 1 Firefox version\nlast 1 Chrome version\nlast 1 Safari version\nlast 1 iOS version\nlast 1 Android version\nlast 1 ChromeAndroid version\n"
  },
  {
    "path": ".circleci/config.yml",
    "content": "version: 2\njobs:\n  install:\n    docker:\n      - image: circleci/node:10.24.0-browsers\n    working_directory: ~/repo\n    steps:\n      # Fetch Code\n      - checkout\n\n      - restore_cache:\n          keys:\n            # Restore cached node_modules\n            - v12-dependencies-{{ checksum \"yarn.lock\" }}\n            # fallback to using the latest cache if no exact match is found\n            - v12-dependencies-\n\n      - run:\n          name: Add CI global modules\n          command: yarn global add greenkeeper-lockfile@1\n\n      - run:\n          name: Install Dependencies\n          command: yarn\n\n      - run:\n          name: Update Lockfile\n          command: $(yarn global bin)/greenkeeper-lockfile-update\n\n      - run:\n          name: Upload Lockfile\n          command: $(yarn global bin)/greenkeeper-lockfile-upload\n\n      - run:\n          name: Validate Yarn Lock File\n          command: |\n            if [[ \"$(git status -s)\" != \"\" ]] && [[ \"$CIRCLE_BRANCH\" != greenkeeper/* ]]; then\n              echo \"Your yarn.lock was modified during install, please check in any changes to the yarn.lock file\"\n              exit 1\n            fi\n\n      # Save the node_modules cache\n      - save_cache:\n          paths:\n            - node_modules\n          key: v12-dependencies-{{ checksum \"yarn.lock\" }}\n  validate:\n    docker:\n      - image: circleci/node:10.24.0-browsers\n    working_directory: ~/repo\n    steps:\n      - checkout\n\n      - restore_cache:\n          keys:\n            - v12-dependencies-{{ checksum \"yarn.lock\" }}\n\n      - run:\n          # PR's from forks cannot use the dependency cache for performance reasons\n          name: 'Forked PR dependency install'\n          command: yarn\n\n      - run:\n          name: Lint + Typecheck\n          command: yarn validate\n  test-unit:\n    docker:\n      - image: circleci/node:10.24.0-browsers\n    working_directory: ~/repo\n    steps:\n      - checkout\n\n      - restore_cache:\n          keys:\n            - v12-dependencies-{{ checksum \"yarn.lock\" }}\n\n      - run:\n          # PR's from forks cannot use the dependency cache for performance reasons\n          name: 'Forked PR dependency install'\n          command: yarn\n\n      - run:\n          name: Jest Suite\n          command: yarn test:ci\n          environment:\n            JEST_JUNIT_OUTPUT: 'test-reports/junit/js-test-results.xml'\n\n      - store_test_results:\n          path: test-reports/junit\n  test-bundle:\n    docker:\n      - image: circleci/node:10.24.0-browsers\n    working_directory: ~/repo\n    steps:\n      - checkout\n\n      - restore_cache:\n          keys:\n            - v12-dependencies-{{ checksum \"yarn.lock\" }}\n\n      # PR's from forks cannot use the dependency cache for performance reasons\n      - run:\n          name: 'Forked PR dependency install'\n          command: yarn\n\n      - run:\n          name: Check Bundle Size\n          command: yarn run bundle-size:check\n  test-browser:\n    docker:\n      # Single Docker container with Node 10 and Cypress dependencies\n      # https://github.com/cypress-io/circleci-orb/blob/master/src/orb.yml\n      - image: cypress/base:10.22.0\n    working_directory: ~/repo\n    steps:\n      - checkout\n\n      - restore_cache:\n          keys:\n            - v12-dependencies-{{ checksum \"yarn.lock\" }}\n\n      # PR's from forks cannot use the dependency cache for performance reasons\n      - run:\n          name: 'Forked PR dependency install'\n          command: yarn\n\n      - run:\n          name: 'Run cypress'\n          command: node browser-test-harness.js yarn test:browser:ci\n\n      # store videos and screenshots (if any) as CI artifacts\n      - store_artifacts:\n          path: cypress/videos\n      - store_artifacts:\n          path: cypress/screenshots\n  test-a11y:\n    docker:\n      - image: circleci/node:10.24.0-browsers\n    working_directory: ~/repo\n    steps:\n      - checkout\n\n      - restore_cache:\n          keys:\n            - v12-dependencies-{{ checksum \"yarn.lock\" }}\n\n      # PR's from forks cannot use the dependency cache for performance reasons\n      - run:\n          name: 'Forked PR dependency install'\n          command: yarn\n\n      - run:\n          name: Accessibility Audit\n          command: node browser-test-harness.js yarn test:accessibility\n\n      - store_artifacts:\n          path: test-reports/lighthouse\n\n      - store_test_results:\n          path: test-reports/lighthouse\nworkflows:\n  version: 2\n  build:\n    jobs:\n      - install\n      - validate:\n          requires:\n            - install\n      - test-unit:\n          requires:\n            - install\n      - test-bundle:\n          requires:\n            - install\n      - test-browser:\n          requires:\n            - install\n# disabling ally test due to issue with lighthouse\n# not sure why lighthouse starting breaking, but could\n# be worth looking into upgrading browsers (docker) + lighthouse\n#     - test-a11y:\n#         requires:\n#           - install\n"
  },
  {
    "path": ".eslintignore",
    "content": "# Generated files\ndist/\nflow-typed/\nsite/\ncoverage/\nbabel.config.js\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  extends: [\n    'prettier',\n    'airbnb',\n    'plugin:flowtype/recommended',\n    'prettier/react',\n    'prettier/flowtype',\n    'plugin:jest/recommended',\n    'plugin:prettier/recommended',\n  ],\n  parser: 'babel-eslint',\n  plugins: [\n    'prettier',\n    'flowtype',\n    'emotion',\n    'react',\n    'react-hooks',\n    'import',\n    'jest',\n    'es5',\n  ],\n  env: {\n    es6: true,\n    browser: true,\n    node: true,\n    'jest/globals': true,\n  },\n  globals: {\n    // flow globals\n    TimeoutID: true,\n    IntervalID: true,\n    AnimationFrameID: true,\n  },\n  rules: {\n    // Error on prettier violations\n    'prettier/prettier': 'error',\n\n    // New eslint style rules that is not disabled by prettier:\n    'lines-between-class-members': 'off',\n\n    // Allowing warning and error console logging\n    // use `invariant` and `warning`\n    'no-console': ['error'],\n\n    // Opting out of prefer destructuring (nicer with flow in lots of cases)\n    'prefer-destructuring': 'off',\n\n    // Disallowing the use of variables starting with `_` unless it called on `this`.\n    // Allowed: `this._secret = Symbol()`\n    // Not allowed: `const _secret = Symbol()`\n    'no-underscore-dangle': ['error', { allowAfterThis: true }],\n\n    // Cannot reassign function parameters but allowing modification\n    'no-param-reassign': ['error', { props: false }],\n\n    // Named exports are kewl\n    'import/prefer-default-export': 'off',\n\n    // Don't tell me what to do!\n    'max-classes-per-file': 'off',\n\n    // Allowing ++ on numbers\n    'no-plusplus': 'off',\n\n    // Always enforcing the use of curly braces for if statements\n    curly: ['error', 'all'],\n\n    'no-restricted-syntax': [\n      // Nicer booleans #1\n      // Disabling the use of !! to cast to boolean\n      'error',\n      {\n        selector:\n          'UnaryExpression[operator=\"!\"] > UnaryExpression[operator=\"!\"]',\n        message:\n          '!! to cast to boolean relies on a double negative. Use Boolean() instead',\n      },\n      // Nicer booleans #2\n      // Avoiding accidental `new Boolean()` calls\n      // (also covered by `no-new-wrappers` but i am having fun)\n      {\n        selector: 'NewExpression[callee.name=\"Boolean\"]',\n        message:\n          'Avoid using constructor: `new Boolean(value)` as it creates a Boolean object. Did you mean `Boolean(value)`?',\n      },\n      // We are using a useLayoutEffect / useEffect switch to avoid SSR warnings for useLayoutEffect\n      // We want to ensure we use `import useEffect from '*use-isomorphic-layout-effect'`\n      // to ensure we still get the benefits of `eslint-plugin-react-hooks`\n      {\n        selector:\n          'ImportDeclaration[source.value=/use-isomorphic-layout-effect/] > ImportDefaultSpecifier[local.name!=\"useLayoutEffect\"]',\n        message:\n          'Must use `useLayoutEffect` as the name of the import from `*use-isomorphic-layout-effect` to leverage `eslint-plugin-react-hooks`',\n      },\n\n      // No Array.from as it pulls in a large amount of babel helpers\n      {\n        selector: 'MemberExpression[object.name=\"Array\"][property.name=\"from\"]',\n        message:\n          'Not allowing using of Array.from to save kbs. Please use native-with-fallback/from',\n      },\n\n      // No usage of `tiny-invariant`. Must use our own invariant for error flow\n      {\n        selector: 'ImportDeclaration[source.value=\"tiny-invariant\"]',\n        message:\n          'Please use our own invariant function (src/invariant.js) to ensure correct error flow',\n      },\n\n      // Must use invariant to throw\n      {\n        selector: 'ThrowStatement',\n        message:\n          'Please use invariant (src/invariant.js) for throwing. This is to ensure correct error flows',\n      },\n    ],\n\n    // Allowing Math.pow rather than forcing `**`\n    'no-restricted-properties': [\n      'off',\n      {\n        object: 'Math',\n        property: 'pow',\n      },\n    ],\n\n    'no-restricted-imports': [\n      'error',\n      {\n        paths: [\n          // Forcing use of useMemoOne\n          {\n            name: 'react',\n            importNames: ['useMemo', 'useCallback'],\n            message:\n              '`useMemo` and `useCallback` are subject to cache busting. Please use `useMemoOne`',\n          },\n          // Forcing use aliased imports from useMemoOne\n          {\n            name: 'use-memo-one',\n            importNames: ['useMemoOne', 'useCallbackOne'],\n            message:\n              'use-memo-one exports `useMemo` and `useCallback` which work nicer with `eslint-plugin-react-hooks`',\n          },\n          // Disabling using of useLayoutEffect from react\n          {\n            name: 'react',\n            importNames: ['useLayoutEffect'],\n            message:\n              '`useLayoutEffect` causes a warning in SSR. Use `useIsomorphicLayoutEffect`',\n          },\n        ],\n      },\n    ],\n\n    // Allowing jsx in files with any file extension (old components have jsx but not the extension)\n    'react/jsx-filename-extension': 'off',\n\n    // Not requiring default prop declarations all the time\n    'react/require-default-props': 'off',\n\n    // Opt out of preferring stateless functions\n    'react/prefer-stateless-function': 'off',\n\n    // Allowing files to have multiple components in it\n    'react/no-multi-comp': 'off',\n\n    // Sometimes we use the PropTypes.object PropType for simplicity\n    'react/forbid-prop-types': 'off',\n\n    // Allowing the non function setState approach\n    'react/no-access-state-in-setstate': 'off',\n\n    // Opting out of this\n    'react/destructuring-assignment': 'off',\n\n    // Adding 'skipShapeProps' as the rule has issues with correctly handling PropTypes.shape\n    'react/no-unused-prop-types': ['error', { skipShapeProps: true }],\n\n    // Having issues with this rule not working correctly\n    'react/default-props-match-prop-types': 'off',\n\n    // Allowing functions to be passed as props\n    'react/jsx-no-bind': 'off',\n\n    // Require // @flow at the top of files\n    'flowtype/require-valid-file-annotation': [\n      'error',\n      'always',\n      { annotationStyle: 'line' },\n    ],\n\n    // Allowing importing from dev deps (for stories and tests)\n    'import/no-extraneous-dependencies': 'off',\n\n    // Enforce rules of hooks\n    'react-hooks/rules-of-hooks': 'error',\n    // Second argument to hook functions\n    'react-hooks/exhaustive-deps': 'error',\n\n    'react/jsx-props-no-spreading': 'off',\n\n    // using <React.Fragment> is fine\n    'react/jsx-fragments': 'off',\n\n    // all good to declare static class members in the class\n    'react/static-property-placement': 'off',\n\n    // don't need to initialize state in a constructor\n    'react/state-in-constructor': 'off',\n\n    'jest/expect-expect': [\n      'error',\n      {\n        assertFunctionNames: [\n          'expect',\n          // these functions will run expect internally\n          'withWarn',\n          'withError',\n          'withoutError',\n          'withoutWarn',\n        ],\n      },\n    ],\n  },\n  overrides: [\n    // Forbid using not es5 methods\n    {\n      files: 'src/**/*.js',\n      rules: {\n        'es5/no-es6-methods': 'error',\n        'es5/no-es6-static-methods': [\n          'error',\n          { exceptMethods: ['Object.assign'] },\n        ],\n      },\n    },\n  ],\n};\n"
  },
  {
    "path": ".flowconfig",
    "content": "[untyped]\n# Issue with atlaskit/theme typing\n.*/node_modules/@atlaskit/theme\n\n[ignore]\n# Creating lots of invalid files\n.*/node_modules/jsonlint-mod/.*\n\n[libs]\n./flow-typed/custom/\n\n[options]\n\n# Provides a way to suppress flow errors in the following line.\n# Example: // $FlowFixMe: This following line is borked because of reasons.\n# Example: // $ExpectError: This following line is correctly ignored by flow.\nsuppress_comment= \\\\(.\\\\|\\n\\\\)*\\\\$FlowFixMe\nsuppress_comment= \\\\(.\\\\|\\n\\\\)*\\\\$ExpectError\ninclude_warnings=true\n# Fixing issue with CircleCI where flow would hang\n# I suspect this is caused by incorrect advertisement of virtual cores\nserver.max_workers=1\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.md",
    "content": "---\nname: 🐛 Bug Report\nabout: Bugs, missing documentation, or unexpected behavior 🤔.\nlabels: \"unconfirmed-bug, untriaged\"\n---\n\n<!--\n## Common issues setup guide\n\nWe have created a common setup issues guide to help you troubleshoot common setup problems:\n\nhttps://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/common-setup-issues.md\n\n## Check your console\n\nIn development builds we log warnings to the console for common setup issues. Please have a look to see if it can give you information in overcoming your issue\n\n## Are you new to rbd?\nIf you are new to `react-beautiful-dnd` we recommend taking at look at our getting started course: https://egghead.io/courses/beautiful-and-accessible-drag-and-drop-with-react-beautiful-dnd\n\nIt will give you a good base understanding of how everything fits together. This can often be the best help in overcoming your issue.\n\n## Duplicates\n\nBefore raising a feature request or bug please search through our open and closed issues to see if there is something similar. If you do find one similar you can show it is important to you by adding a reaction (such as 👍) to the issue\n\nOpen and closed issues:\nhttps://github.com/atlassian/react-beautiful-dnd/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aclosed%20is%3Aissue%20\n-->\n\n### Expected behavior\n\n### Actual behavior\n\n### Steps to reproduce\n\n### Suggested solution?\n\n<!--\n  Do you have any ideas on how we could fix this?\n  It is okay if you have no idea!\n-->\n\n### What version of `React` are you using?\n\n<!--\n  Take a look at your package.json\n  Ensure that it satisfies our peer dependency version - see our package.json. (Currently it is \"^16.8.0\")\n-->\n\n### What version of `react-beautiful-dnd` are you running?\n\n<!--\n  We will only look into issues that are effecting the latest version. At this stage we are not releasing fixes for previous releases\n-->\n\n### What browser are you using?\n\n<!--\nKeep in mind our supported browser matrix https://confluence.atlassian.com/cloud/supported-browsers-744721663.html\nIf you raise a bug that is not in a supported version we will not be fixing it\n-->\n\n### Demo\n\n<!--\nPlease provide an example to show the issue. Here is a boilerplate to help you get started:\nhttps://codesandbox.io/s/k260nyxq9v\n\nIf you paste a big block of code it can be difficult to debug it.\n\nIf it is a visual bug, a video or a gif would be helpful also.\n\nIssues without demo's may not be investigated\n-->\n\n<!--\n## Note: stale issues will be removed\n\nWhen a maintainer asks a question about an issue and it is not responded to within a reasonable time frame then the issue will be closed. We don't want this to happen - but we also do not want to accumulate stale issues\n--->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.md",
    "content": "---\nname: 💡Feature request\nabout: Ideas and suggestions\nlabels: \"idea \\U0001F914, untriaged\"\n---\n\n<!--\n## Keep in mind: our scope\n\nThis is not a general purpose drag and drop library and is attempting to create an experience that is more physical than standard drag and drop interactions on the web.\n\nBefore raising a new feature please ensure that it falls within the philosophy of the library.\n\nhttps://github.com/atlassian/react-beautiful-dnd/blob/master/docs/about/design-principles.md#foundational-idea-physicality\n\nAll features need to have a clear and generally applicable keyboard interaction pattern in order for us to deliver on our core goal of being highly accessible.\n-->\n\n### Description\n\n<!-- What would you like to see added? -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/tree-issue.md",
    "content": "---\nname: 🌲@atlaskit/tree\nabout: Bugs and feature requests for @atlaskit/tree\nlabels: 'wontfix ☠️'\n---\n\nPlease head to the [`@atlaskit/tree` issue tracker](https://ecosystem.atlassian.net/servicedesk/customer/portal/24/create/236).\n\nWe do not track `@atlaskit/tree` issues in the `react-beautiful-dnd` project\n"
  },
  {
    "path": ".gitignore",
    "content": "# editors\n.idea\n.vscode\n\n# library\nnode_modules/\n\n# MacOS\n.DS_Store\n\n# generated files\ndist/\n\n# generated site\nsite/\n\n# coverage reports\ncoverage/\n\n# test reports\ntest-reports/\n\n# test outputs\ncypress/videos/\ncypress/screenshots/\n\n# storybook\n.storybook.out\n.cache/\n\n# logs\nyarn-error.log\nnpm-debug.log\nnpm-debug.log.*\n"
  },
  {
    "path": ".nvmrc",
    "content": "10.24.0"
  },
  {
    "path": ".prettierignore",
    "content": "/node_modules/*"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"trailingComma\": \"all\",\n  \"semi\": true,\n  \"tabWidth\": 2,\n  \"useTabs\": false,\n  \"singleQuote\": true\n}\n"
  },
  {
    "path": ".size-snapshot.json",
    "content": "{\n  \"dist/react-beautiful-dnd.js\": {\n    \"bundled\": 364998,\n    \"minified\": 133574,\n    \"gzipped\": 39437\n  },\n  \"dist/react-beautiful-dnd.min.js\": {\n    \"bundled\": 306810,\n    \"minified\": 108365,\n    \"gzipped\": 31340\n  },\n  \"dist/react-beautiful-dnd.esm.js\": {\n    \"bundled\": 240910,\n    \"minified\": 125371,\n    \"gzipped\": 32650,\n    \"treeshaked\": {\n      \"rollup\": {\n        \"code\": 21121,\n        \"import_statements\": 503\n      },\n      \"webpack\": {\n        \"code\": 24005\n      }\n    }\n  }\n}\n"
  },
  {
    "path": ".storybook/.babelrc",
    "content": "{\n  \"presets\": [\n    \"@babel/react\",\n    \"@babel/flow\",\n    [\"@babel/env\", { \"modules\": false, \"loose\": true }],\n    \"@emotion/babel-preset-css-prop\"\n  ],\n  \"plugins\": [\n    \"emotion\",\n    [\"@babel/proposal-class-properties\", { \"loose\": true }],\n    [\"@babel/proposal-object-rest-spread\", { \"loose\": true }]\n  ],\n  \"comments\": false\n}\n"
  },
  {
    "path": ".storybook/babel-setup.md",
    "content": "# Babel\n\nstorybook looks for a root `.babelrc` in the project for its babel config. However, we are using `.babelrc.js` which is not supported. Rather than putting effort into this we are just having a custom `.babelrc` in this folder which is the same as `.babelrc.js`. This is lame, but we are looking to move away from storybook in the short term anyway.\n\n- [Storybook babel docs](https://storybook.js.org/configurations/custom-babel-config/)\n- [Storybook issue for supporting `babelrc.js`](https://github.com/storybooks/storybook/issues/2582)\n"
  },
  {
    "path": ".storybook/config.js",
    "content": "import React from 'react';\nimport { addParameters, configure, addDecorator } from '@storybook/react';\nimport { create } from '@storybook/theming';\nimport { withPerformance } from 'storybook-addon-performance';\nimport GlobalStylesDecorator from './custom-decorators/global-styles';\n// adding css reset - storybook includes a css loader\nimport '@atlaskit/css-reset';\nimport { colors } from '@atlaskit/theme';\nimport logo from './compressed-logo-rbd.svg';\nimport { version } from '../package.json';\n\nconst theme = create({\n  brandImage: logo,\n  brandName: 'react-beautiful-dnd',\n  brandUrl: 'https://github.com/atlassian/react-beautiful-dnd',\n});\n\naddParameters({\n  options: {\n    // currently not using any addons\n    showPanel: false,\n    theme,\n  },\n});\n\n// Using theme would be good for this, but it looks like theme is just for the chrome around the story\naddDecorator(GlobalStylesDecorator);\naddDecorator(withPerformance);\n\n// automatically import all files ending in *.stories.js\nconst req = require.context('../stories/', true, /.stories.js$/);\n\nfunction loadStories() {\n  req.keys().forEach(filename => req(filename));\n}\n\nconfigure(loadStories, module);\n\n// Doing this more complex check as console.table || console.log makes CI cry\nconst table = Object.prototype.hasOwnProperty.call(console, 'table')\n  ? console.table\n  : console.log;\n\n// Generated by: http://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=rbd\nconsole.log(\n  `%c\n██████╗ ██████╗ ██████╗\n██╔══██╗██╔══██╗██╔══██╗\n██████╔╝██████╔╝██║  ██║\n██╔══██╗██╔══██╗██║  ██║\n██║  ██║██████╔╝██████╔╝\n╚═╝  ╚═╝╚═════╝ ╚═════╝\n\n%cBeautiful and accessible drag and drop\n`,\n  `color: ${colors.G200}; font-size: 1.2em; font-weight: bold;`,\n  `color: ${colors.P200}; font-size: 1.2em; font-weight: bold;`,\n);\n\ntable([\n  ['react-beautiful-dnd version', version],\n  ['react version', React.version],\n  ['process.env.NODE_ENV', process.env.NODE_ENV],\n]);\n"
  },
  {
    "path": ".storybook/custom-decorators/global-styles.jsx",
    "content": "// @flow\nimport React from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { grid } from '../../stories/src/constants';\n\n// $ExpectError - not sure why\nconst GlobalStyles = styled.div`\n  min-height: 100vh;\n  color: ${colors.N900};\n`;\n\nconst GlobalStylesDecorator = (storyFn: Function) => (\n  <GlobalStyles>{storyFn()}</GlobalStyles>\n);\n\nexport default GlobalStylesDecorator;\n"
  },
  {
    "path": ".storybook/main.js",
    "content": "module.exports = {\n  addons: ['storybook-addon-performance/register','@storybook/addon-storysource'],\n};\n"
  },
  {
    "path": ".storybook/preview-head.html",
    "content": "<!--\n\n  Used to ensure there is a lang set on the html attribute for storybook\n  This is important for accessibility scores\n\n-->\n<script>\n  document.documentElement.setAttribute('lang', 'en');\n</script>\n"
  },
  {
    "path": ".stylelintrc.json",
    "content": "{\n  \"processors\": [\n    [\n      \"stylelint-processor-styled-components\",\n      {\n        \"moduleName\": \"@emotion/styled\"\n      }\n    ]\n  ],\n  \"extends\": [\n    \"stylelint-config-standard\",\n    \"stylelint-config-styled-components\",\n    \"stylelint-config-prettier\"\n  ],\n  \"rules\": {\n    \"declaration-empty-line-before\": null,\n    \"comment-empty-line-before\": null,\n    \"block-no-empty\": null,\n    \"value-keyword-case\": null\n  }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nThis project adheres to [Semantic Versioning 2.0](http://semver.org/).\nAll release notes and upgrade notes can be found on our [Github Releases](https://github.com/atlassian/react-beautiful-dnd/releases) page.\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n- Using welcoming and inclusive language\n- Being respectful of differing viewpoints and experiences\n- Gracefully accepting constructive criticism\n- Focusing on what is best for the community\n- Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n- The use of sexualized language or imagery and unwelcome sexual attention or advances\n- Trolling, insulting/derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or electronic address, without explicit permission\n- Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at areardon@atlassian.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nThanks for considering contributing to `react-beautiful-dnd`! ❤️\n\nThere are a few categories of contribution so we'll go through them individually.\n\n## Documentation\n\nIf you think the docs could be improved - please feel free to raise a pull request!\n\n## Bug\n\nIf you spot a bug you are welcome to raise it on our issue page. You are also welcome to take a crack at fixing it if you like! When you create an issue you will be prompted with the details we would like you to provide.\n\n## Feature request\n\nIf you would like to see a feature added to the library, here is what you do:\n\n1.  Have a read of `README.md` to understand the motivations of this library. It is fairly opinionated and is not intended to be a universal drag and drop library. As such, it will not support every drag and drop interaction.\n2.  Have a search through the [open and closed issues](https://github.com/atlassian/react-beautiful-dnd/issues?utf8=%E2%9C%93&q=is%3Aissue) to see if the feature you are requesting as already been requested.\n3.  Have a clear and general purpose keyboard story for any feature request\n4.  Please [create an issue](https://github.com/atlassian/react-beautiful-dnd/issues/new) to discuss it.\n\n**Please do not raise a pull request directly**. There may be reasons why we will not add every feature to this library.\n\n## Large contributions\n\nIf you are interested in making a large contribution to this library there is some recommended reading / training we suggest. There is a large amount of different libraries, techniques and tools used in `react-beautiful-dnd` and we have created a list with resources about them. Not everything in the list will be applicable to everyone. But it is a great reference and starting point for those who do not know where to start.\n\nThe online courses listed are no free - feel free to seek out alternatives if you want to. We recommend the egghead.io courses because they are quite comprehensive.\n\n### General knowledge\n\n- [You Don't Know JS](https://github.com/getify/You-Dont-Know-JS): This is an amazing resource that I recommend all the time. It is great for having a deeper understanding of the JavaScript language.\n\n### Technologies\n\n#### `React`\n\nThis is a `React` project so getting familiar with `React` is a must!\n\n- [`react`](https://facebook.github.io/react/)\n- [An intro to using React](https://egghead.io/courses/start-using-react-to-build-web-applications)\n\n#### `Redux`\n\nThis project uses `redux` for its state management. If you have not used `redux` before it is worth getting familiar with it.\n\n- [`redux`](http://redux.js.org/docs/introduction/): the library itself has really great docs\n- [Getting Started with Redux](https://egghead.io/courses/getting-started-with-redux): the whole course\n- [Building React Applications with Idiomatic Redux](https://egghead.io/courses/building-react-applications-with-idiomatic-redux): no need to do the lessons on react router or data fetching\n- [`react-redux`](https://github.com/reactjs/react-redux): `react` bindings for `redux`\n- [`reselect`](https://github.com/reactjs/reselect): we use `reselect` heavily to ensure that state selectors are as fast as they can be. Please have a read of its main page, especially the [sharing Selectors with Props Across Multiple Components](https://github.com/reactjs/reselect#sharing-selectors-with-props-across-multiple-components) section.\n\n#### Testing\n\nWe test our application very thoroughly. Changes will not be accepted without tests\n\n- [`jest`](https://facebook.github.io/jest/): We use the jest test runner. It is worth getting familiar with it\n- [Test JavaScript with Jest](https://egghead.io/lessons/javascript-test-javascript-with-jest)\n- [React Testing Cookbook](https://egghead.io/courses/react-testing-cookbook)\n\n#### Performance\n\nPerformance is **critical** to this project. Please get familiar with React performance considerations. Changes that break core performance characteristics will not be accepted.\n\n- [Performance optimisations for React applications](https://medium.com/@alexandereardon/performance-optimisations-for-react-applications-b453c597b191)\n- [Performance optimisations for React applications round 2](https://medium.com/@alexandereardon/performance-optimisations-for-react-applications-round-2-2042e5c9af97)\n- [React performance tools](https://facebook.github.io/react/docs/perf.html)\n- [React performance documentation](https://facebook.github.io/react/docs/optimizing-performance.html)\n- [React is slow, React is fast](https://marmelab.com/blog/2017/02/06/react-is-slow-react-is-fast.html)\n\n#### Flow\n\nThis codebase is typed with [`flow`](https://flow.org/). Changes will not be merged without correct flow typing. If you are not sure about a particular use case let flow break the build and it can be discussed in the pull request.\n\n- [`flow`](https://flow.org/en/docs/getting-started/): the `flow` docs are great\n- [Up and Running with Facebook Flow for Typed JavaScript](https://egghead.io/lessons/javascript-up-and-running-with-facebook-flow-for-typed-javascript): a small primer for running flow\n\n### Drag and drop problem space\n\n#### HTML5 drag and drop\n\nHow this library performs dragging is an implementation detail. The api is what users interact with. That said, this library does not use the html5 drag and drop api. The main reason is that html5 drag and drop does not allow the level of control we need to create our powerful and beautiful experiences. I could go into detail but this is not the right forum.\n\nHere is some general reading about html5 drag and drop. It is worth having a read to get familiar with its ideas and api\n\n- [HTML5 drag and drop api](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)\n- [HTML5 Rocks - dnd basics](https://www.html5rocks.com/en/tutorials/dnd/basics/)\n- [The HTML5 drag and drop disaster](https://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html)\n- [HTML5 drag and drop browser inconsistencies](http://mereskin.github.io/dnd/)\n\n#### Prior work\n\nIt is worth looking at other libraries out there to see how they do drag and drop. Things to look at is their philosophy and api. `react-beautiful-dnd` is an opinionated, higher level abstraction than most drag and drop libraries. We do not need to support every use case. We need to find the right level of control while still maintaining a beautiful experience for the user, flexibility of use and a clean, powerful api.\n\n- [`react-dnd`](https://react-dnd.github.io/react-dnd/) - `react-beautiful-dnd` draws a fair amount of inspiration from `react-dnd`. Something to keep in mind is that `react-dnd` is designed to provide a set of drag and drop primitives which is a different set of goals to this project.\n- [`react-sortable-hoc`](https://github.com/clauderic/react-sortable-hoc/) - on the surface this library looks similar to `react-beautiful-dnd`. I created a [comparison blog](https://medium.com/@alexandereardon/thanks-for-reaching-out-dimitar-nestorov-8c0bf9abe19) that explains the differences\n- [`jQuery sortable`](http://jqueryui.com/sortable/) - the king of drag and drop for a long time\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright 2019 Atlassian Pty Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "## 🔒 Archived\n\nThis project is now [archived](https://docs.github.com/en/repositories/archiving-a-github-repository/archiving-repositories) and is [deprecated on `npm`](https://www.npmjs.com/package/react-beautiful-dnd). If you are still using `react-beautiful-dnd`, we have put together some [resources to help you move forward](https://github.com/atlassian/react-beautiful-dnd/issues/2672). To see our ongoing work in the drag and drop problem space, head to [Pragmatic drag and drop](https://github.com/atlassian/pragmatic-drag-and-drop).\n\nWe are so grateful to everybody who contributed in big and small ways to this project.\n\nCheers\n\n<br>\n\n---\n\n<p align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/2182637/53611918-54c1ff80-3c24-11e9-9917-66ac3cef513d.png\" alt=\"react beautiful dnd logo\" />\n</p>\n<h1 align=\"center\">react-beautiful-dnd <small><sup>(rbd)</sup></small></h1>\n\n<div align=\"center\">\n\n**Beautiful** and **accessible** drag and drop for lists with [`React`](https://facebook.github.io/react/)\n\n[![CircleCI branch](https://img.shields.io/circleci/project/github/atlassian/react-beautiful-dnd/master.svg)](https://circleci.com/gh/atlassian/react-beautiful-dnd/tree/master)\n[![npm](https://img.shields.io/npm/v/react-beautiful-dnd.svg)](https://www.npmjs.com/package/react-beautiful-dnd)\n\n![quote application example](https://user-images.githubusercontent.com/2182637/53614150-efbed780-3c2c-11e9-9204-a5d2e746faca.gif)\n\n[Play with this example if you want!](https://react-beautiful-dnd.netlify.app/iframe.html?selectedKind=board&selectedStory=simple)\n\n</div>\n\n## Core characteristics\n\n- Beautiful and [natural movement](/docs/about/animations.md) of items 💐\n- [Accessible](/docs/about/accessibility.md): powerful keyboard and screen reader support ♿️\n- [Extremely performant](/docs/support/media.md) 🚀\n- Clean and powerful api which is simple to get started with\n- Plays extremely well with standard browser interactions\n- [Unopinionated styling](/docs/guides/preset-styles.md)\n- No creation of additional wrapper dom nodes - flexbox and focus management friendly!\n\n## Get started 👩‍🏫\n\nWe have created [a free course on `egghead.io` 🥚](https://egghead.io/courses/beautiful-and-accessible-drag-and-drop-with-react-beautiful-dnd) to help you get started with `react-beautiful-dnd` as quickly as possible.\n\n[![course-logo](https://user-images.githubusercontent.com/2182637/43372837-8c72d3f8-93e8-11e8-9d92-a82adde7718f.png)](https://egghead.io/courses/beautiful-and-accessible-drag-and-drop-with-react-beautiful-dnd)\n\n## Currently supported feature set ✅\n\n- Vertical lists ↕\n- Horizontal lists ↔\n- Movement between lists (▤ ↔ ▤)\n- [Virtual list support 👾](/docs/patterns/virtual-lists.md) - unlocking 10,000 items @ 60fps\n- [Combining items](/docs/guides/combining.md)\n- Mouse 🐭, keyboard 🎹♿️ and touch 👉📱 (mobile, tablet and so on) support\n- [Multi drag support](/docs/patterns/multi-drag.md)\n- Incredible screen reader support ♿️ - we provide an amazing experience for english screen readers out of the box 📦. We also provide complete customisation control and internationalisation support for those who need it 💖\n- [Conditional dragging](/docs/api/draggable.md#optional-props) and [conditional dropping](/docs/api/droppable.md#conditionally-dropping)\n- Multiple independent lists on the one page\n- Flexible item sizes - the draggable items can have different heights (vertical lists) or widths (horizontal lists)\n- [Add and remove items during a drag](/docs/guides/changes-while-dragging.md)\n- Compatible with semantic `<table>` reordering - [table pattern](/docs/patterns/tables.md)\n- [Auto scrolling](/docs/guides/auto-scrolling.md) - automatically scroll containers and the window as required during a drag (even with keyboard 🔥)\n- Custom drag handles - you can drag a whole item by just a part of it\n- Able to move the dragging item to another element while dragging (clone, portal) - [Reparenting your `<Draggable />`](/docs/guides/reparenting.md)\n- [Create scripted drag and drop experiences 🎮](/docs/sensors/sensor-api.md)\n- Allows extensions to support for [any input type you like 🕹](/docs/sensors/sensor-api.md)\n- 🌲 Tree support through the [`@atlaskit/tree`](https://atlaskit.atlassian.com/packages/confluence/tree) package\n- A `<Droppable />` list can be a scroll container (without a scrollable parent) or be the child of a scroll container (that also does not have a scrollable parent)\n- Independent nested lists - a list can be a child of another list, but you cannot drag items from the parent list into a child list\n- Server side rendering (SSR) compatible - see [resetServerContext()](/docs/api/reset-server-context.md)\n- Plays well with [nested interactive elements](/docs/api/draggable.md#interactive-child-elements-within-a-draggable-) by default\n\n## Motivation 🤔\n\n`react-beautiful-dnd` exists to create beautiful drag and drop for lists that anyone can use - even people who cannot see. For a good overview of the history and motivations of the project you can take a look at these external resources:\n\n- 📖 [Rethinking drag and drop](https://medium.com/@alexandereardon/rethinking-drag-and-drop-d9f5770b4e6b)\n- 🎧 [React podcast: fast, accessible and beautiful drag and drop](https://reactpodcast.simplecast.fm/17)\n\n## Not for everyone ✌️\n\nThere are a lot of libraries out there that allow for drag and drop interactions within React. Most notable of these is the amazing [`react-dnd`](https://github.com/react-dnd/react-dnd). It does an incredible job at providing a great set of drag and drop primitives which work especially well with the [wildly inconsistent](https://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html) html5 drag and drop feature. `react-beautiful-dnd` is a higher level abstraction specifically built for lists (vertical, horizontal, movement between lists, nested lists and so on). Within that subset of functionality `react-beautiful-dnd` offers a powerful, natural and beautiful drag and drop experience. However, it does not provide the breadth of functionality offered by `react-dnd`. So `react-beautiful-dnd` might not be for you depending on what your use case is.\n\n## Documentation 📖\n\n### About 👋\n\n- [Installation](/docs/about/installation.md)\n- [Examples and samples](/docs/about/examples.md)\n- [Get started](https://egghead.io/courses/beautiful-and-accessible-drag-and-drop-with-react-beautiful-dnd)\n- [Design principles](/docs/about/design-principles.md)\n- [Animations](/docs/about/animations.md)\n- [Accessibility](/docs/about/accessibility.md)\n- [Browser support](/docs/about/browser-support.md)\n\n### Sensors 🔉\n\n> The ways in which somebody can start and control a drag\n\n- [Mouse dragging 🐭](/docs/sensors/mouse.md)\n- [Touch dragging 👉📱](/docs/sensors/touch.md)\n- [Keyboard dragging 🎹♿️](/docs/sensors/keyboard.md)\n- [Create your own sensor](/docs/sensors/sensor-api.md) (allows for any input type as well as scripted experiences)\n\n### API 🏋️‍\n\n![diagram](https://user-images.githubusercontent.com/2182637/53607406-c8f3a780-3c12-11e9-979c-7f3b5bd1bfbd.gif)\n\n- [`<DragDropContext />`](/docs/api/drag-drop-context.md) - _Wraps the part of your application you want to have drag and drop enabled for_\n- [`<Droppable />`](/docs/api/droppable.md) - _An area that can be dropped into. Contains `<Draggable />`s_\n- [`<Draggable />`](/docs/api/draggable.md) - _What can be dragged around_\n- [`resetServerContext()`](/docs/api/reset-server-context.md) - _Utility for server side rendering (SSR)_\n\n### Guides 🗺\n\n- [`<DragDropContext />` responders](/docs/guides/responders.md) - _`onDragStart`, `onDragUpdate`, `onDragEnd` and `onBeforeDragStart`_\n- [Combining `<Draggable />`s](/docs/guides/combining.md)\n- [Common setup issues](/docs/guides/common-setup-issues.md)\n- [Using `innerRef`](/docs/guides/using-inner-ref.md)\n- [Setup problem detection and error recovery](/docs/guides/setup-problem-detection-and-error-recovery.md)\n- [Rules for `draggableId` and `droppableId`s](/docs/guides/identifiers.md)\n- [Browser focus retention](/docs/guides/browser-focus.md)\n- [Customising or skipping the drop animation](/docs/guides/drop-animation.md)\n- [Auto scrolling](/docs/guides/auto-scrolling.md)\n- [Controlling the screen reader](/docs/guides/screen-reader.md)\n- [Use the html5 `doctype`](/docs/guides/doctype.md)\n- [`TypeScript` and `flow`: type information](/docs/guides/types.md)\n- [Dragging `<svg>`s](/docs/guides/dragging-svgs.md)\n- [Avoiding image flickering](/docs/guides/avoiding-image-flickering.md)\n- [Non-visible preset styles](/docs/guides/preset-styles.md)\n- [How we detect scroll containers](/docs/guides/how-we-detect-scroll-containers.md)\n- [How we use dom events](/docs/guides/how-we-use-dom-events.md) - _Useful if you need to build on top of `react-beautiful-dnd`_\n- [Adding `<Draggable />`s during a drag (11.x behaviour)](/docs/guides/changes-while-dragging.md) - _⚠️ Advanced_\n- [Setting up Content Security Policy](/docs/guides/content-security-policy.md)\n\n### Patterns 👷‍\n\n- [Virtual lists 👾](/docs/patterns/virtual-lists.md)\n- [Multi drag](/docs/patterns/multi-drag.md)\n- [Tables](/docs/patterns/tables.md)\n- [Reparenting a `<Draggable />`](/docs/guides/reparenting.md) - _Using our cloning API or your own portal_\n\n### Support 👩‍⚕️\n\n- [Engineering health](/docs/support/engineering-health.md)\n- [Community and addons](/docs/support/community-and-addons.md)\n- [Release notes and changelog](https://github.com/atlassian/react-beautiful-dnd/releases)\n- [Upgrading](/docs/support/upgrading.md)\n- [Road map](https://github.com/atlassian/react-beautiful-dnd/issues)\n- [Media](/docs/support/media.md)\n\n## Read this in other languages 🌎\n\n- [![kr](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/South-Korea.png) **한글/Korean**](https://github.com/LeeHyungGeun/react-beautiful-dnd-kr)\n- [![ru](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Russia.png) **На русском/Russian**](https://github.com/vtereshyn/react-beautiful-dnd-ru)\n- [![pt](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Brazil.png) **Português/Portuguese**](https://github.com/dudestein/react-beautiful-dnd-pt)\n- [![gr](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Greece.png) **Ελληνικά/Greek**](https://github.com/milvard/react-beautiful-dnd-gr)\n- [![ja](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Japan.png) **日本語/Japanese**](https://github.com/eltociear/react-beautiful-dnd-ja)\n\n## Creator ✍️\n\nAlex Reardon [@alexandereardon](https://x.com/alexandereardon)\n\n> Alex is no longer personally maintaining this project. The other wonderful maintainers are carrying this project forward.\n\n## Maintainers\n\n- [Daniel Del Core](https://x.com/danieldelcore)\n- Many other [@Atlassian](https://x.com/Atlassian)'s!\n\n## Collaborators 🤝\n\n- Bogdan Chadkin [@IAmTrySound](https://x.com/IAmTrySound)\n"
  },
  {
    "path": "a11y-audit-parse.js",
    "content": "/* eslint-disable flowtype/require-valid-file-annotation */\n/* eslint-disable import/no-unresolved */\n/* eslint-disable global-require */\n/* eslint-disable no-console */\ntry {\n  // I disabled flow for this file because of this line.\n  // Sometimes the file exists, sometimes it doesn't.\n  // It depends on if you have run the accessibility test or not.\n  // Given this conditional I thought it best to simply disable flow for the file\n  const a11yReport = require('./test-reports/lighthouse/a11y.report.json');\n  const a11yScore = a11yReport.categories.accessibility.score;\n  const a11yScoreFormatted = `${a11yScore ? a11yScore * 100 : 0}%`;\n\n  console.log('*************************');\n  console.log('Lighthouse accessibility score: ', a11yScoreFormatted);\n  console.log('*************************');\n\n  if (a11yScore === 1) {\n    // success!\n    process.exit(0);\n  } else {\n    // fail build\n    console.log(\n      '\\nNOTE: Lighthouse accessibility audit score must be 100% to pass this build step.\\n\\n',\n    );\n    process.exit(1);\n  }\n} catch (e) {\n  console.error(e);\n  process.exit(1);\n}\n"
  },
  {
    "path": "babel.config.js",
    "content": "module.exports = {\n  presets: ['@babel/react', '@babel/flow', ['@babel/env', { loose: true }]],\n  plugins: [\n    '@babel/transform-object-assign',\n    ['@babel/proposal-class-properties', { loose: true }],\n    // used for stripping out the `invariant` messages in production builds\n    'dev-expression',\n  ],\n  comments: false,\n};\n"
  },
  {
    "path": "browser-test-harness.js",
    "content": "// @flow\nconst childProcess = require('child_process');\nconst path = require('path');\nconst waitPort = require('wait-port');\nconst ports = require('./server-ports');\n\nconst storybook = childProcess.spawn(process.execPath, [\n  path.join('node_modules', '.bin', 'start-storybook'),\n  '-p',\n  `${ports.storybook}`,\n]);\n\nconst cspServer = childProcess.spawn(process.execPath, [\n  path.join('csp-server', 'start.sh'),\n  `${ports.cspServer}`,\n]);\n\nprocess.on('exit', () => {\n  storybook.kill();\n  cspServer.kill();\n});\n\nPromise.all([\n  waitPort({\n    host: 'localhost',\n    port: ports.storybook,\n    timeout: 60000,\n  }),\n  waitPort({\n    host: 'localhost',\n    port: ports.cspServer,\n    timeout: 60000,\n  }),\n])\n  .then(() => {\n    if (!process.argv[2]) {\n      // eslint-disable-next-line no-console\n      console.warn('Started servers but no command supplied to run after');\n      process.exit();\n    }\n\n    const child = childProcess.spawn(process.argv[2], process.argv.slice(3), {\n      stdio: 'inherit',\n    });\n    process.on('exit', () => {\n      child.kill();\n    });\n    child.on('exit', (code) => {\n      process.exit(code);\n    });\n  })\n  .catch((error) => {\n    // eslint-disable-next-line no-console\n    console.error('Unable to spin up standalone servers');\n    // eslint-disable-next-line no-console\n    console.error(error);\n    storybook.kill();\n    cspServer.kill();\n    process.exit(1);\n  });\n"
  },
  {
    "path": "csp-server/.eslintrc.js",
    "content": "module.exports = {\n  rules: {\n    // allowing console.warn / console.error\n    // this is because we often mock console.warn and console.error and adding this rul\n    // avoids needing to constantly be opting out of the rule\n    'no-console': ['error', { allow: ['warn', 'error'] }],\n\n    // allowing useMemo and useCallback in tests\n    'no-restricted-imports': 'off',\n\n    // Allowing Array.from\n    'no-restricted-syntax': 'off',\n  },\n};\n"
  },
  {
    "path": "csp-server/app.jsx",
    "content": "// disabling flowtype to keep this example super simple\n// It matches\n/* eslint-disable flowtype/require-valid-file-annotation */\n\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { DragDropContext, Droppable, Draggable } from '../src';\n\n// fake data generator\nconst getItems = (count) =>\n  Array.from({ length: count }, (v, k) => k).map((k) => ({\n    id: `item-${k}`,\n    content: `item ${k}`,\n  }));\n\n// a little function to help us with reordering the result\nconst reorder = (list, startIndex, endIndex) => {\n  const result = Array.from(list);\n  const [removed] = result.splice(startIndex, 1);\n  result.splice(endIndex, 0, removed);\n\n  return result;\n};\n\nexport default class App extends Component {\n  constructor(props, context) {\n    super(props, context);\n    this.state = {\n      items: getItems(10),\n      cspErrors: [],\n    };\n    this.onDragEnd = this.onDragEnd.bind(this);\n  }\n\n  componentDidMount() {\n    document.addEventListener(\n      'securitypolicyviolation',\n      this.onSecurityPolicyViolation,\n    );\n  }\n\n  componentWillUnmount() {\n    document.removeEventListener(\n      'securitypolicyviolation',\n      this.onSecurityPolicyViolation,\n    );\n  }\n\n  onDragEnd(result) {\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    const items = reorder(\n      this.state.items,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      items,\n    });\n  }\n\n  onSecurityPolicyViolation = (e) => {\n    this.setState((state) => {\n      return { cspErrors: [...state.cspErrors, e] };\n    });\n  };\n\n  // Normally you would want to split things out into separate components.\n  // But in this example everything is just done in one place for simplicity\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd} nonce={this.props.nonce}>\n        <h1>\n          Content-Security-Policy error count:{' '}\n          <b id=\"cspErrors\">{this.state.cspErrors.length}</b>\n        </h1>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided) => (\n            <div ref={droppableProvided.innerRef}>\n              {this.state.items.map((item, index) => (\n                <Draggable key={item.id} draggableId={item.id} index={index}>\n                  {(draggableProvided) => (\n                    <div\n                      ref={draggableProvided.innerRef}\n                      {...draggableProvided.draggableProps}\n                      {...draggableProvided.dragHandleProps}\n                    >\n                      {item.content}\n                    </div>\n                  )}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n\nApp.propTypes = {\n  nonce: PropTypes.string,\n};\n"
  },
  {
    "path": "csp-server/client.js",
    "content": "// @flow\n/* eslint-env browser */\n\nimport React from 'react';\nimport { hydrate } from 'react-dom';\nimport Sample from './app';\n\nconst root: Element | null = document.getElementById('root');\n\nlet nonce = null;\n\nconst cspEl = document.getElementById('csp-nonce');\nif (cspEl) {\n  nonce = cspEl.getAttribute('content');\n}\n\nif (root) {\n  hydrate(<Sample nonce={nonce} />, root);\n}\n"
  },
  {
    "path": "csp-server/main.js",
    "content": "/* eslint-disable id-length */\n// @flow\n\nconst webpack = require('webpack');\nconst requireFromString = require('require-from-string');\nconst MemoryFS = require('memory-fs');\nconst path = require('path');\nconst config = require('./webpack.config');\nconst ports = require('../server-ports');\n\nconst fs = new MemoryFS();\nconst compiler = webpack(config);\n\n// $ExpectError\ncompiler.outputFileSystem = fs;\n// $ExpectError\nconst outputPath = compiler.compilers.find((cfg) => cfg.name === 'client')\n  .outputPath;\n\ncompiler.run(() => {\n  const content = fs.readFileSync(path.resolve(outputPath, 'server.js'));\n  const server = requireFromString(content.toString()).default;\n  server(process.argv[2] || ports.cspServer, outputPath, fs);\n});\n"
  },
  {
    "path": "csp-server/server.js",
    "content": "// @flow\nimport express from 'express';\nimport React from 'react';\nimport { renderToString } from 'react-dom/server';\nimport { resolve } from 'path';\nimport App from './app';\nimport { resetServerContext } from '../src';\n\nlet count = 0;\nfunction getNonce(): string {\n  return `ThisShouldBeACryptographicallySecurePseudoRandomNumber-${count++}`;\n}\n\nfunction renderHtml(policy?: string, nonce?: string) {\n  resetServerContext();\n  let meta = '';\n  if (nonce) {\n    meta += `<meta id=\"csp-nonce\" property=\"csp-nonce\" content=\"${nonce}\" />`;\n  }\n  if (policy) {\n    meta += `<meta http-equiv=\"Content-Security-Policy\" content=\"${policy}\"></meta>`;\n  }\n  return `<!doctype html><head>${meta}<head><html><body><div id=\"root\">${renderToString(\n    <App nonce={nonce} />,\n  )}</div><script src=\"/client.js\"></script></body></html>`;\n}\n\nexport default (port: string, outputPath: string, fs: any) => {\n  const server = express();\n\n  server.get('/client.js', (req, res) => {\n    res.header('content-type', 'text/javascript');\n    res.end(fs.readFileSync(resolve(outputPath, 'client.js')));\n  });\n\n  function render(res: any, policy?: string, nonce?: string) {\n    if (policy) {\n      res.header('Content-Security-Policy', policy);\n    }\n    res.header('content-type', 'text/html');\n    res.end(renderHtml(policy, nonce));\n  }\n\n  server.get('/', (req, res) => {\n    render(res);\n  });\n\n  server.get('/unsafe-inline', (req, res) => {\n    render(res, \"style-src 'unsafe-inline'\");\n  });\n\n  server.get('/nonce', (req, res) => {\n    const nonce = getNonce();\n    render(res, `style-src 'nonce-${nonce}'`, nonce);\n  });\n\n  server.get('/wrong-nonce', (req, res) => {\n    const nonce = getNonce();\n    const wrongNonce = getNonce();\n    render(res, `style-src 'nonce-${nonce}'`, wrongNonce);\n  });\n\n  server.listen(port, () => {\n    // eslint-disable-next-line no-console\n    console.log('csp server listening on port', port);\n  });\n};\n"
  },
  {
    "path": "csp-server/start.sh",
    "content": "#!/usr/bin/env node\n\nrequire('./main');\n"
  },
  {
    "path": "csp-server/webpack.config.js",
    "content": "// @flow\nconst path = require('path');\n\nconst common = {\n  context: path.resolve(__dirname, '..'),\n  mode: 'development',\n  entry: path.resolve(__dirname, 'main.js'),\n  target: 'web',\n  output: {\n    filename: 'client.js',\n    path: path.resolve(__dirname, 'dist'),\n  },\n  resolve: {\n    extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs'],\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.(png|jpg|gif)$/i,\n        use: [\n          {\n            loader: 'url-loader',\n          },\n        ],\n      },\n      {\n        test: /jsx?$/,\n        exclude: [/node_modules/],\n        use: [\n          {\n            loader: 'babel-loader',\n          },\n        ],\n      },\n    ],\n  },\n  externals: [\n    {\n      express: 'express',\n      fs: 'fs',\n      'convert-source-map': 'convert-source-map',\n    },\n  ],\n};\n\nmodule.exports = [\n  { ...common, entry: path.resolve(__dirname, 'client.js'), name: 'client' },\n  {\n    ...common,\n    entry: path.resolve(__dirname, 'server.js'),\n    name: 'server',\n    target: 'node',\n    output: {\n      filename: 'server.js',\n      path: path.resolve(__dirname, 'dist'),\n      libraryTarget: 'commonjs2',\n    },\n  },\n];\n"
  },
  {
    "path": "cypress/.eslintrc.js",
    "content": "module.exports = {\n  plugins: ['cypress'],\n  env: {\n    'cypress/globals': true,\n  },\n  extends: ['plugin:cypress/recommended'],\n  rules: {\n    // Allowing Array.from\n    'no-restricted-syntax': 'off',\n\n    // not using jest expects\n    'jest/expect-expect': 'off',\n  },\n};\n"
  },
  {
    "path": "cypress/fixtures/.gitkeep",
    "content": ""
  },
  {
    "path": "cypress/integration/content-security-policy.spec.js",
    "content": "// @flow\nimport * as keyCodes from '../../src/view/key-codes';\nimport { timings } from '../../src/animation';\nimport { getHandleSelector } from './util';\nimport ports from '../../server-ports';\n\nfunction commonTest(url: string, cspTest: string) {\n  cy.visit(url);\n\n  cy.get(getHandleSelector()).eq(0).as('first').should('contain', 'item 0');\n  cy.get(getHandleSelector()).eq(1).should('contain', 'item 1');\n\n  // reorder operation\n  cy.get('@first')\n    .focus()\n    .trigger('keydown', { keyCode: keyCodes.space })\n    // need to re-query for a clone\n    .get('@first')\n    .trigger('keydown', { keyCode: keyCodes.arrowDown, force: true })\n    // finishing before the movement time is fine - but this looks nice\n    .wait(timings.outOfTheWay * 1000)\n    .trigger('keydown', { keyCode: keyCodes.space, force: true });\n\n  // order now 2, 1\n  // note: not using get aliases as they where returning incorrect results\n  cy.get(getHandleSelector()).eq(0).should('contain', 'item 1');\n\n  cy.get(getHandleSelector()).eq(1).should('contain', 'item 0');\n\n  // element should maintain focus post drag\n  cy.focused().should('contain', 'item 0');\n\n  cy.get('#cspErrors').should(cspTest, '0');\n}\n\ndescribe('content security policy', () => {\n  it('should reorder a list without a nonce', () => {\n    commonTest(`http://localhost:${ports.cspServer}`, 'contain');\n  });\n\n  it('should reorder a list with a nonce', () => {\n    commonTest(`http://localhost:${ports.cspServer}/nonce`, 'contain');\n  });\n\n  it('should reorder a list with a wrong nonce', () => {\n    commonTest(\n      `http://localhost:${ports.cspServer}/wrong-nonce`,\n      'not.contain',\n    );\n  });\n});\n"
  },
  {
    "path": "cypress/integration/focus.spec.js",
    "content": "// @flow\nimport * as keyCodes from '../../src/view/key-codes';\nimport { getHandleSelector, getDraggableSelector } from './util';\n\ndescribe('focus', () => {\n  it('should not steal focus if not already focused when lifting', () => {\n    cy.visit('/iframe.html?id=board--dragging-a-clone');\n    // focusing on another handle\n    cy.get(getHandleSelector('1')).focus();\n    cy.focused().should('contain', 'id:1');\n\n    cy.get(getHandleSelector('2'))\n      .as('id:2')\n      .trigger('mousedown', { button: 0 })\n      .trigger('mousemove', {\n        button: 0,\n        clientX: 200,\n        clientY: 300,\n        force: true,\n      });\n\n    // asserting id:2 is now dragging\n    cy.get(getHandleSelector('2')).should(\n      'have.attr',\n      'data-is-dragging',\n      'true',\n    );\n\n    // focus not stolen\n    cy.focused().should('contain', 'id:1');\n\n    cy.get(getHandleSelector('2'))\n      .trigger('mouseup', { force: true })\n      // clone will be unmounting during drop\n      .should('not.exist');\n\n    // getting post clone handle\n    cy.get(getHandleSelector('2')).should(\n      'have.attr',\n      'data-is-dragging',\n      'false',\n    );\n\n    // focus not stolen\n    cy.focused().should('contain', 'id:1');\n  });\n\n  it('should maintain focus if dragging a clone', () => {\n    cy.visit('/iframe.html?id=board--dragging-a-clone');\n    // focusing on another handle\n    cy.get(getHandleSelector('2')).focus();\n    cy.focused().should('contain', 'id:2');\n\n    cy.get(getHandleSelector('2')).trigger('keydown', {\n      keyCode: keyCodes.space,\n    });\n\n    // asserting id:2 is now dragging\n    cy.get(getHandleSelector('2')).should(\n      'have.attr',\n      'data-is-dragging',\n      'true',\n    );\n\n    // focus maintained\n    cy.focused().should('contain', 'id:2');\n\n    cy.get(getHandleSelector('2'))\n      .trigger('keydown', { keyCode: keyCodes.arrowRight, force: true })\n      .trigger('keydown', { keyCode: keyCodes.space, force: true })\n      // clone will be unmounting during drop\n      .should('not.exist');\n\n    // getting post clone handle\n    cy.get(getHandleSelector('2'))\n      // no longer dragging\n      .should('have.attr', 'data-is-dragging', 'false')\n      // is in the second column (normally would loose focus moving between lists)\n      .closest(getDraggableSelector('BMO'));\n\n    // focus maintained\n    cy.focused().should('contain', 'id:2');\n  });\n\n  it('should give focus to a combine target', () => {\n    cy.visit('/iframe.html?id=board--with-combining-and-cloning');\n    cy.get(getHandleSelector('2')).focus();\n    cy.focused().should('contain', 'id:2');\n\n    cy.get(getHandleSelector('2')).trigger('keydown', {\n      keyCode: keyCodes.space,\n    });\n\n    // asserting id:2 is now dragging\n    cy.get(getHandleSelector('2')).should(\n      'have.attr',\n      'data-is-dragging',\n      'true',\n    );\n\n    // focus maintained\n    cy.focused().should('contain', 'id:2');\n\n    cy.get(getHandleSelector('2'))\n      .trigger('keydown', { keyCode: keyCodes.arrowRight, force: true })\n      // combining with item:1\n      .trigger('keydown', { keyCode: keyCodes.arrowUp, force: true })\n      // dropping\n      .trigger('keydown', { keyCode: keyCodes.space, force: true })\n      // clone will be unmounting during drop\n      .should('not.exist');\n\n    // focus giving to item:1 the combine target\n    cy.focused().should('contain', 'id:1');\n  });\n\n  it('should not give focus to a combine target if source did not have focus at start of drag', () => {\n    cy.visit('/iframe.html?id=board--with-combining-and-cloning');\n    // focusing on something unrelated to the drag\n    cy.get(getHandleSelector('3')).focus();\n\n    cy.get(getHandleSelector('2')).trigger('keydown', {\n      keyCode: keyCodes.space,\n    });\n\n    // asserting id:2 is now dragging\n    cy.get(getHandleSelector('2')).should(\n      'have.attr',\n      'data-is-dragging',\n      'true',\n    );\n\n    // focus not stolen\n    cy.focused().should('contain', 'id:3');\n\n    cy.get(getHandleSelector('2'))\n      .trigger('keydown', { keyCode: keyCodes.arrowRight, force: true })\n      // combining with item:1\n      .trigger('keydown', { keyCode: keyCodes.arrowUp, force: true })\n      // dropping\n      .trigger('keydown', { keyCode: keyCodes.space, force: true })\n      // clone will be unmounting during drop\n      .should('not.exist');\n\n    // focus not given to the combine target\n    cy.focused().should('contain', 'id:3');\n  });\n});\n"
  },
  {
    "path": "cypress/integration/move-between-lists.spec.js",
    "content": "// @flow\nimport * as keyCodes from '../../src/view/key-codes';\nimport { timings } from '../../src/animation';\nimport { getDroppableSelector, getHandleSelector } from './util';\n\ndescribe('move between lists', () => {\n  beforeEach(() => {\n    cy.visit('/iframe.html?id=board--simple');\n  });\n\n  it('should move between lists', () => {\n    // first list has item with id:2\n    cy.get(getDroppableSelector())\n      .eq(1)\n      .as('first-list')\n      .should('contain', 'id:2');\n\n    // second list does not have item with id:2\n    cy.get(getDroppableSelector())\n      .eq(2)\n      .as('second-list')\n      .should('not.contain', 'id:2');\n\n    cy.get('@first-list')\n      .find(getHandleSelector())\n      .first()\n      .should('contain', 'id:2')\n      .focus()\n      .trigger('keydown', { keyCode: keyCodes.space })\n      .trigger('keydown', { keyCode: keyCodes.arrowRight, force: true })\n      // finishing before the movement time is fine - but this looks nice\n      .wait(timings.outOfTheWay * 1000)\n      .trigger('keydown', { keyCode: keyCodes.space, force: true });\n\n    // no longer in the first list\n    cy.get('@first-list').should('not.contain', 'id:2');\n\n    // now in the second list\n    cy.get('@second-list').should('contain', 'id:2');\n  });\n});\n"
  },
  {
    "path": "cypress/integration/reorder-lists.spec.js",
    "content": "// @flow\nimport * as keyCodes from '../../src/view/key-codes';\nimport { timings } from '../../src/animation';\nimport { getHandleSelector } from './util';\n\ndescribe('reorder lists', () => {\n  beforeEach(() => {\n    cy.visit('/iframe.html?id=board--simple');\n  });\n\n  it('should reorder lists', () => {\n    // order: Jake, BMO\n    cy.get('h4').eq(0).as('first').should('contain', 'Jake');\n\n    cy.get('h4').eq(1).should('contain', 'BMO');\n\n    // reorder operation\n    cy.get('@first')\n      .closest(getHandleSelector())\n      .focus()\n      .trigger('keydown', { keyCode: keyCodes.space })\n      .trigger('keydown', { keyCode: keyCodes.arrowRight, force: true })\n      // finishing before the movement time is fine - but this looks nice\n      .wait(timings.outOfTheWay * 1000)\n      .trigger('keydown', { keyCode: keyCodes.space, force: true });\n\n    // order now 2, 1\n    // note: not using get aliases as they where returning incorrect results\n    cy.get('h4').eq(0).should('contain', 'BMO');\n\n    // index of the drag handle has changed\n    cy.get('h4').eq(1).should('contain', 'Jake');\n  });\n});\n"
  },
  {
    "path": "cypress/integration/reorder-virtual.spec.js",
    "content": "// @flow\nimport * as keyCodes from '../../src/view/key-codes';\nimport { timings } from '../../src/animation';\nimport { getHandleSelector } from './util';\n\ndescribe('reorder: virtual', () => {\n  beforeEach(() => {\n    cy.visit('/iframe.html?id=virtual-react-window--list');\n  });\n\n  it('should reorder within a list', () => {\n    const movements: number = 12;\n\n    cy.get(getHandleSelector()).first().as('item');\n\n    cy.get('@item').invoke('attr', 'data-testid').as('item-id');\n\n    cy.get('@item')\n      .invoke('attr', 'data-index')\n      .as('item-index')\n      .should('equal', '0');\n\n    // lift\n    cy.get('@item')\n      .focus()\n      .trigger('keydown', { keyCode: keyCodes.space })\n      // need to re-query for a clone\n      .get('@item');\n\n    cy.wrap(Array.from({ length: movements })).each(() => {\n      cy.get('@item')\n        .trigger('keydown', { keyCode: keyCodes.arrowDown, force: true })\n        // finishing before the movement time is fine - but this looks nice\n        // waiting longer than we should (timings.outOfTheWay * 1000) as electron is being strange\n        .wait(timings.outOfTheWay * 1000 * 2);\n    });\n\n    // drop\n    cy.get('@item').trigger('keydown', {\n      keyCode: keyCodes.space,\n      force: true,\n    });\n\n    // This is setting up a chain of commands and this test will not wait\n    // for a 'promise' to resolve. Linting is getting confused by .then\n    // eslint-disable-next-line jest/valid-expect-in-promise\n    cy.get('@item-id').then((id) => {\n      cy.get(getHandleSelector(id))\n        .invoke('attr', 'data-index')\n        .should('equal', `${movements}`);\n    });\n  });\n});\n"
  },
  {
    "path": "cypress/integration/reorder.spec.js",
    "content": "// @flow\nimport * as keyCodes from '../../src/view/key-codes';\nimport { timings } from '../../src/animation';\nimport { getHandleSelector } from './util';\n\ndescribe('reorder', () => {\n  beforeEach(() => {\n    cy.visit('/iframe.html?id=single-vertical-list--basic');\n  });\n\n  it('should reorder within a list', () => {\n    // order: 1, 2\n    cy.get(getHandleSelector()).eq(0).as('first').should('contain', 'id:1');\n    cy.get(getHandleSelector()).eq(1).should('contain', 'id:2');\n\n    // reorder operation\n    cy.get('@first')\n      .focus()\n      .trigger('keydown', { keyCode: keyCodes.space })\n      // need to re-query for a clone\n      .get('@first')\n      .trigger('keydown', { keyCode: keyCodes.arrowDown, force: true })\n      // finishing before the movement time is fine - but this looks nice\n      .wait(timings.outOfTheWay * 1000)\n      .trigger('keydown', { keyCode: keyCodes.space, force: true });\n\n    // order now 2, 1\n    // note: not using get aliases as they where returning incorrect results\n    cy.get(getHandleSelector()).eq(0).should('contain', 'id:2');\n\n    cy.get(getHandleSelector()).eq(1).should('contain', 'id:1');\n\n    // element should maintain focus post drag\n    cy.focused().should('contain', 'id:1');\n  });\n});\n"
  },
  {
    "path": "cypress/integration/util.js",
    "content": "// @flow\nimport * as dataAttr from '../../src/view/data-attributes';\n\nexport function getDroppableSelector(droppableId?: string) {\n  if (droppableId) {\n    return `[${dataAttr.droppable.id}=\"${droppableId}\"]`;\n  }\n  return `[${dataAttr.droppable.id}]`;\n}\n\nexport function getHandleSelector(draggableId?: string) {\n  if (draggableId) {\n    return `[${dataAttr.dragHandle.draggableId}=\"${draggableId}\"]`;\n  }\n  return `[${dataAttr.dragHandle.draggableId}]`;\n}\n\nexport function getDraggableSelector(draggableId?: string) {\n  if (draggableId) {\n    return `[${dataAttr.draggable.id}=\"${draggableId}\"]`;\n  }\n  return `[${dataAttr.draggable.id}]`;\n}\n"
  },
  {
    "path": "cypress/plugins/index.js",
    "content": "/* eslint-disable no-unused-vars */\n/* eslint-disable flowtype/require-valid-file-annotation */\n// ***********************************************************\n// This example plugins/index.js can be used to load plugins\n//\n// You can change the location of this file or turn off loading\n// the plugins file with the 'pluginsFile' configuration option.\n//\n// You can read more here:\n// https://on.cypress.io/plugins-guide\n// ***********************************************************\n\n// This function is called when a project is opened or re-opened (e.g. due to\n// the project's config changing)\n\nmodule.exports = (on, config) => {\n  // `on` is used to hook into various events Cypress emits\n  // `config` is the resolved Cypress config\n};\n"
  },
  {
    "path": "cypress/support/commands.js",
    "content": "// @flow\n// ***********************************************\n// This example commands.js shows you how to\n// create various custom commands and overwrite\n// existing commands.\n//\n// For more comprehensive examples of custom\n// commands please read more here:\n// https://on.cypress.io/custom-commands\n// ***********************************************\n//\n//\n// -- This is a parent command --\n// Cypress.Commands.add(\"login\", (email, password) => { ... })\n//\n//\n// -- This is a child command --\n// Cypress.Commands.add(\"drag\", { prevSubject: 'element'}, (subject, options) => { ... })\n//\n//\n// -- This is a dual command --\n// Cypress.Commands.add(\"dismiss\", { prevSubject: 'optional'}, (subject, options) => { ... })\n//\n//\n// -- This is will overwrite an existing command --\n// Cypress.Commands.overwrite(\"visit\", (originalFn, url, options) => { ... })// @flow\n"
  },
  {
    "path": "cypress/support/index.js",
    "content": "// @flow\n// ***********************************************************\n// This example support/index.js is processed and\n// loaded automatically before your test files.\n//\n// This is a great place to put global configuration and\n// behavior that modifies Cypress.\n//\n// You can change the location of this file or turn off\n// automatically serving support files with the\n// 'supportFile' configuration option.\n//\n// You can read more here:\n// https://on.cypress.io/configuration\n// ***********************************************************\n\n// Import commands.js using ES2015 syntax:\nimport './commands';\n\n// Alternatively you can use CommonJS syntax:\n// require('./commands')\n"
  },
  {
    "path": "cypress.json",
    "content": "{\n  \"baseUrl\": \"http://localhost:9002\"\n}\n"
  },
  {
    "path": "docs/about/accessibility.md",
    "content": "# Accessibility ♿️\n\nTraditionally drag and drop interactions have been exclusively a mouse or touch interaction. This library has invested a huge amount of effort to ensure that everybody has access to drag and drop interactions\n\n## What we do to include everyone\n\n- [Full keyboard support](/docs/sensors/keyboard.md) (reordering, combining, moving between lists)\n- [Keyboard multi drag support](/docs/patterns/multi-drag.md)\n- Keyboard [auto scrolling](/docs/guides/auto-scrolling.md)\n- Fantastic [screen reader support](/docs/guides/screen-reader.md) - _We ship with english messaging out of the box 📦_\n- Smart management of [browser focus](/docs/guides/browser-focus.md)\n- A [Google lighthouse](https://developers.google.com/web/tools/lighthouse) automated build to ensure perfect accessibility scores (at least according to [Google](https://developers.google.com/web/tools/lighthouse/v3/scoring#a11y))\n\n![screen-reader-text](https://user-images.githubusercontent.com/2182637/36571009-d326d82a-1888-11e8-9a1d-e44f8b969c2f.gif)\n\n> Example screen reader announcement\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/about/animations.md",
    "content": "# Carefully designed animations\n\nWith things moving a lot it would be easy for the user to become distracted by the animations or for them to get in the way. We have tweaked the various animations to ensure the right balance of guidance, performance and interactivity.\n\n## Dropping\n\nWe have designed a drop animation that feels weighted and physical. It is based on a [`spring`](https://developer.android.com/guide/topics/graphics/spring-animation) and uses a CSS animation with a dynamic duration to achieve the effect.\n\n![result-curve](https://user-images.githubusercontent.com/2182637/48235467-1ce34200-e412-11e8-8c69-2060a0c2f61a.png)\n\n> Animation curve used when dropping. Duration is dynamic based on distance to travel\n\nYou can tweak the drop animation if you would like to. We have created a guide: [drop animation](/docs/guides/drop-animation.md)\n\n## Moving out of the way\n\nItems that are moving out of the way of a dragging item do so with a CSS transition rather than physics. This is to maximise performance by allowing the GPU to handle the movement. The CSS animation curve has been designed to communicate getting out of the way.\n\nHow it is composed:\n\n1.  A warm up period to mimic a natural response time\n2.  A small phase to quickly move out of the way\n3.  A long tail so that people can read any text that is being animated in the second half of the animation\n\n![animation curve](https://raw.githubusercontent.com/alexreardon/files/master/resources/dnd-ease-in-out-small.png?raw=true)\n\n> Animation curve used when moving out of the way\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/about/browser-support.md",
    "content": "# Browser support 🌍\n\nThis library supports the standard [Atlassian supported browsers](https://confluence.atlassian.com/cloud/supported-browsers-744721663.html) for desktop:\n\n| Desktop                              | Version                                              |\n| ------------------------------------ | ---------------------------------------------------- |\n| Microsoft Internet Explorer(Windows) | Version 11                                           |\n| Microsoft Edge                       | Latest stable version supported                      |\n| Mozilla Firefox (all platforms)      | Latest stable version supported                      |\n| Google Chrome (Windows and Mac)      | Latest stable version supported                      |\n| Safari (Mac)                         | Latest stable version on latest OS release supported |\n\n| Mobile                   | Version                                                   |\n| ------------------------ | --------------------------------------------------------- |\n| Chrome (Android and iOS) | Latest stable version supported                           |\n| Mobile Safari (iOS)      | Latest stable version supported                           |\n| Android (Android)        | The default browser on Android 4.0.3 (Ice Cream Sandwich) |\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/about/design-principles.md",
    "content": "# Design principles 📖\n\nThis page goes over the design and interaction thinking behind `react-beautiful-dnd`.\n\n## Foundational idea: physicality\n\nThe core design idea of `react-beautiful-dnd` is physicality: we want users to feel like they are moving physical objects around\n\n### Application 1: no instant movement (no snapping)\n\nIt is a fairly standard drag and drop pattern for things to disappear and reappear in response to the users drag. For a more natural drag we animate the movement of items as they need to move out of the way while dragging to more clearly show a drags effect. We also animate the drop of an item so that it animates into its new home position. At no point is an item instantly moved anywhere — regardless of whether it is dragging or not.\n\n### Application 2: knowing when to move\n\nIt is quite common for drag and drop interactions to be based on the position that user started the drag from.\n\nIn `react-beautiful-dnd` a dragging items impact is based on its centre of gravity — regardless of where a user grabs an item from. A dragging items impact follows similar rules to a set of scales ⚖️. Here are some rules that are followed to allow for a natural drag experience even with items of flexible height:\n\n- A list is _dragged over_ when the centre position of a dragging item goes over one of the boundaries of the list\n- A resting drag item will move out of the way of a dragging item when the centre position of the dragging item goes over the edge of the resting item. Put another way: once the centre position of an item (A) goes over the edge of another item (B), B moves out of the way.\n\n### Application 3: movement to communicate positioning\n\n> No support for drop shadows or line markings\n> _Drop shadow: putting a clone or 'shadow' of the dragging item in the drop location_\n\n`react-beautiful-dnd` relies on movement to communicate positioning. It is trying to create a system that is based on physical metaphores. Drop shadows, lines and other affordances are useful in drag and drop contexts where natural movement is not possible.\n\nDrop shadows pose a number of confusing design moments if combined with a natural movement system, including:\n\n- Where is the shadow when you are not over a list?\n- How should it move between items?\n- How should it appear as you enter a new list?\n\nThe answer to these is often: snapping (where something just appears in the right spot). We are trying hard to avoid any snapping as it breaks the physicality we are trying to model.\n\n### Application 4: maximise interactivity\n\n`react-beautiful-dnd` works really hard to avoid as many periods of non-interactivity as possible. The user should feel like they are in control of the interface and not waiting for an animation to finish before they can continue to interact with the interface. However, there is a balance that needs to be made between correctness and power in order to make everybody's lives more sane. Here are the only situations where some things are not interactive:\n\n1.  From when a user cancels a drag to when the drop animation completes. On cancel there are lots of things moving back to where they should be. If you grab an item in a location that is not its true home then the following drag will be incorrect.\n2.  Starting a drag on an item that is animating its own drop. For simplicity this is the case - it is actually quite hard to grab something while it is animating home. It could be coded around - but it seems like an edge case that would add a lot of complexity.\n\nKeep in mind that these periods of inactivity may not always exist.\n\n### Application 5: no drag axis locking\n\nFor now, the library does not support drag axis locking (aka drag rails). This is where the user is restricted to only dragging along one axis. The current thinking is this breaks the physical metaphor we are going for and sends a message to the user that they are interacting with a piece of software rather than moving physical objects around. It is possible to ensure that a user can only drop in a single list by using props `type` and `isDropDisabled`. You can also do some visual treatment to the list `onDragStart` to show the user that this is the only place they can interact with.\n\n### Application 6: natural cross list movement\n\nRather than using an index based approach for keyboard movement between lists, `react-beautiful-dnd` performs cross list movement based on **inertia, gravity and collisions**. You can find out more about how this works by reading the blog [\"Natural keyboard movement between lists\"](https://medium.com/@alexandereardon/friction-gravity-and-collisions-3adac3a94e19).\n\n![example](https://raw.githubusercontent.com/alexreardon/files/master/resources/collision.gif?raw=true)\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/about/examples.md",
    "content": "# Examples 🎉\n\nSee how beautiful it is for yourself!\n\n## Viewing on a desktop\n\n[All the examples!](https://react-beautiful-dnd.netlify.app)\n\n## Viewing on a mobile or tablet\n\n- [Simple list](https://react-beautiful-dnd.netlify.app/iframe.html?id=single-vertical-list--basic)\n- [Board](https://react-beautiful-dnd.netlify.app/iframe.html?id=board--simple) - best viewed in landscape\n\n> We provide different links for touch devices as [storybook](https://github.com/storybooks/storybook) runs examples in an iframe which can result in a strange auto scroll experience\n\n## Basic samples\n\nWe have created some basic examples on `codesandbox` for you to play with directly:\n\n- [Simple vertical list](https://codesandbox.io/s/k260nyxq9v)\n- [Simple horizontal list](https://codesandbox.io/s/mmrp44okvj)\n- [Using with function components](https://codesandbox.io/s/zqwz5n5p9x)\n- [Simple DnD between two lists](https://codesandbox.io/s/ql08j35j3q) - _Community made_\n- [Simple DnD between a dynamic number of lists (with function components) and ability to delete items](https://codesandbox.io/s/-w5szl) - _Community made_\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/about/installation.md",
    "content": "# Installation\n\n[![module formats: umd, cjs, and esm](https://img.shields.io/badge/module%20formats-umd%2c%20cjs%2c%20esm-green.svg?style=flat)](https://unpkg.com/react-beautiful-dnd/dist/)\n\n## General\n\n1. Add the `react-beautiful-dnd` package\n\n```bash\n# yarn\nyarn add react-beautiful-dnd\n\n# npm\nnpm install react-beautiful-dnd --save\n```\n\n2. Use the package\n\n```js\nimport { DragDropContext } from 'react-beautiful-dnd';\n```\n\n3. Profit 🕺\n\n## `React` environment\n\nIn order to use `react-beautiful-dnd` you will probably want to have a `React` environment set up.\n\n- [Add react to a website](https://reactjs.org/docs/add-react-to-a-website.html) - official `React` docs\n- [Setup a react environment with `create-react-app`](https://egghead.io/lessons/react-set-up-a-react-environment-with-create-react-app) - from our [free getting started course](https://egghead.io/courses/beautiful-and-accessible-drag-and-drop-with-react-beautiful-dnd)\n\n## Distribution bundle\n\nA [universal module definition](https://github.com/umdjs/umd) bundle is published on `npm` under the `/dist` folder for consumption . We publish the following files:\n\n- `dist/react-beautiful-dnd.js`\n- `dist/react-beautiful-dnd.min.js` (minified bundle)\n\nThese bundles list `react` as an external which needs to be provided. This is done to reduce the size of the bundle and prevent consumers from loading `react` multiple times. You can provide `react` through your module system or simply by having `react` on the `window`.\n\nYou can use the UMD to run `react-beautiful-dnd` directly in the browser.\n\n```html\n<!-- peer dependency -->\n<script src=\"https://unpkg.com/react@16.3.1/umd/react.development.js\"></script>\n<!-- lib (change x.x.x for the version you would like) -->\n<script src=\"https://unpkg.com/react-beautiful-dnd@x.x.x/dist/react-beautiful-dnd.js\"></script>\n<!-- needed to mount your react app -->\n<script src=\"https://unpkg.com/react-dom@16.3.1/umd/react-dom.development.js\"></script>\n\n<script>\n  const React = window.React;\n  const ReactDOM = window.ReactDOM;\n  const { DragDropContext, Draggable, Droppable } = window.ReactBeautifulDnd;\n\n  function App() {\n    // ...\n  }\n\n  // You can use JSX if your environment supports it\n  ReactDOM.render(React.createElement(App), document.getElementById('app'));\n</script>\n```\n\nThere is also an [example codepen](https://codepen.io/alexreardon/project/editor/ZyNMPo) you can use to play with this installation method.\n\n## [`ClojureScript`](https://clojurescript.org/)\n\nYou can consume `react-beautiful-dnd` from within `ClojureScript` using [CLJSJS](https://cljsjs.github.io/)!\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/api/drag-drop-context.md",
    "content": "# `<DragDropContext />`\n\nIn order to use drag and drop, you need to have the part of your `React` tree that you want to be able to use drag and drop in wrapped in a `<DragDropContext />`. It is advised to just wrap your entire application in a `<DragDropContext />`. Having nested `<DragDropContext />`'s is _not_ supported. You will be able to achieve your desired conditional dragging and dropping using the props of `<Droppable />` and `<Draggable />`. You can think of `<DragDropContext />` as having a similar purpose to the [react-redux Provider component](https://react-redux.js.org/api/provider). A content-security-protection nonce attribute is added to the injected style tags if provided.\n\n## Props\n\n```js\ntype Responders = {|\n  // optional\n  onBeforeCapture?: OnBeforeCaptureResponder\n  onBeforeDragStart?: OnBeforeDragStartResponder,\n  onDragStart?: OnDragStartResponder,\n  onDragUpdate?: OnDragUpdateResponder,\n  // required\n  onDragEnd: OnDragEndResponder,\n|};\n\nimport type { Node } from 'react';\n\ntype Props = {|\n  ...Responders,\n  // We do not technically need any children for this component\n  children: Node | null,\n  // Read out by screen readers when focusing on a drag handle\n  dragHandleUsageInstructions?: string,\n  // Used for strict content security policies\n  nonce?: string,\n  // Used for custom sensors\n  sensors?: Sensor[],\n  enableDefaultSensors?: ?boolean,\n|};\n```\n\n- `dragHandleUsageInstructions`: What is read out to screen reader users when a _drag handle_ is given browser focus. See our [screen reader guide](/docs/guides/screen-reader.md)\n- `nonce`: Used for strict content security policy setups. See our [content security policy guide](/docs/guides/content-security-policy.md)\n- `sensors`: Used to pass in your own `sensor`s for a `<DragDropContext />`. See our [sensor api documentation](/docs/sensors/sensor-api.md)\n- `enableDefaultSensors`: Whether or not the default sensors ([mouse](/docs/sensors/mouse.md), [keyboard](/docs/sensors/keyboard.md), and [touch](/docs/sensors/touch.md)) are enabled. You can also import them separately as `useMouseSensor`, `useKeyboardSensor`, or `useTouchSensor` and reuse just some of them via `sensors` prop. See our [sensor api documentation](/docs/sensors/sensor-api.md)\n\n> See our [type guide](/docs/guides/types.md) for more details\n\n## Basic usage\n\n### Using a `class` component\n\n```js\nimport React from 'react';\nimport { DragDropContext } from 'react-beautiful-dnd';\n\nclass App extends React.Component {\n  onBeforeCapture = () => {\n    /*...*/\n  };\n\n  onBeforeDragStart = () => {\n    /*...*/\n  };\n\n  onDragStart = () => {\n    /*...*/\n  };\n  onDragUpdate = () => {\n    /*...*/\n  };\n  onDragEnd = () => {\n    // the only one that is required\n  };\n\n  render() {\n    return (\n      <DragDropContext\n        onBeforeCapture={this.onBeforeCapture}\n        onBeforeDragStart={this.onBeforeDragStart}\n        onDragStart={this.onDragStart}\n        onDragUpdate={this.onDragUpdate}\n        onDragEnd={this.onDragEnd}\n      >\n        <div>Hello world</div>\n      </DragDropContext>\n    );\n  }\n}\n```\n\n### Using a `function` component\n\n```js\nimport React from 'react';\nimport { DragDropContext } from 'react-beautiful-dnd';\n\nfunction App() {\n  // using useCallback is optional\n  const onBeforeCapture = useCallback(() => {\n    /*...*/\n  }, []);\n  const onBeforeDragStart = useCallback(() => {\n    /*...*/\n  }, []);\n  const onDragStart = useCallback(() => {\n    /*...*/\n  }, []);\n  const onDragUpdate = useCallback(() => {\n    /*...*/\n  }, []);\n  const onDragEnd = useCallback(() => {\n    // the only one that is required\n  }, []);\n\n  return (\n    <DragDropContext\n      onBeforeCapture={onBeforeCapture}\n      onBeforeDragStart={onBeforeDragStart}\n      onDragStart={onDragStart}\n      onDragUpdate={onDragUpdate}\n      onDragEnd={onDragEnd}\n    >\n      <div>Hello world</div>\n    </DragDropContext>\n  );\n}\n```\n\n## `Responders`\n\n> `Responders` were previously known as `Hooks`\n\nResponders are top level application events that you can use to perform your own state updates, style updates, as well as to make screen reader announcements.\n\n[Please see our Responders guide](/docs/guides/responders.md) for detailed information about responders ❤️\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/api/draggable.md",
    "content": "# `<Draggable />`\n\n`<Draggable />` components can be dragged around and dropped onto `<Droppable />`s. A `<Draggable />` must always be contained within a `<Droppable />`. It is **possible** to reorder a `<Draggable />` within its home `<Droppable />` or move to another `<Droppable />`. It is **possible** because a `<Droppable />` is free to control what it allows to be dropped on it.\n\nEvery `<Draggable />` has a _drag handle_. A _drag handle_ is the element that the user interacts with in order to drag a `<Draggable />`. A _drag handle_ can be the `<Draggable />` element itself, or a child of the `<Draggable />`. Note that by default a _drag handle_ cannot be an interactive element, since [event handlers are blocked on nested interactive elements](#interactive-child-elements-within-a-draggable-). Proper semantics for accessibility are added to the _drag handle_ element. If you wish to use an interactive element, `disableInteractiveElementBlocking` must be set.\n\n```js\nimport { Draggable } from 'react-beautiful-dnd';\n\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => (\n    <div\n      ref={provided.innerRef}\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n    >\n      <h4>My draggable</h4>\n    </div>\n  )}\n</Draggable>;\n```\n\n## Draggable Props\n\n```js\nimport type { Node } from 'react';\n\ntype Props = {|\n  // required\n  draggableId: DraggableId,\n  index: number,\n  children: DraggableChildrenFn,\n  // optional\n  isDragDisabled: ?boolean,\n  disableInteractiveElementBlocking: ?boolean,\n  shouldRespectForcePress: ?boolean,\n|};\n```\n\n### Required props\n\n> `react-beautiful-dnd` will throw an error if a required prop is not provided\n\n- `draggableId`: A _required_ `DraggableId(string)`. See our [identifiers guide](/docs/guides/identifiers.md) for more information.\n- `index`: A _required_ `number` that matches the order of the `<Draggable />` in the `<Droppable />`. It is simply the index of the `<Draggable />` in the list.\n\n`index` rule:\n\n- Must be unique within a `<Droppable />` (no duplicates)\n- Must be consecutive. `[0, 1, 2]` and not `[1, 2, 8]`\n\nIndexes do not need to start from `0` (this is often the case in [virtual lists](/docs/patterns/virtual-lists.md)). In development mode we will log warnings to the `console` if any of these rules are violated. See [Setup problem detection and error recovery](/docs/guides/setup-problem-detection-and-error-recovery.md)\n\nTypically the `index` value will simply be the `index` provided by a `Array.prototype.map` function:\n\n```js\n{\n  this.props.items.map((item, index) => (\n    <Draggable draggableId={item.id} index={index}>\n      {(provided, snapshot) => (\n        <div\n          ref={provided.innerRef}\n          {...provided.draggableProps}\n          {...provided.dragHandleProps}\n        >\n          {item.content}\n        </div>\n      )}\n    </Draggable>\n  ));\n}\n```\n\n### Optional props\n\n- `isDragDisabled`: A flag to control whether or not the `<Draggable />` is permitted to drag. You can use this to implement your own conditional drag logic. It will default to `false`.\n- `disableInteractiveElementBlocking`: A flag to opt out of blocking a drag from interactive elements. For more information refer to the section _Interactive child elements within a `<Draggable />`_\n- `shouldRespectForcePress`: Whether or not the _drag handle_ should respect force press interactions. See [Force press](#force-press).\n\n## Children function (render props / function as child)\n\nThe `React` children of a `<Draggable />` must be a function that returns a `ReactNode`.\n\n```js\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => (\n    <div\n      ref={provided.innerRef}\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n    >\n      Drag me!\n    </div>\n  )}\n</Draggable>\n```\n\n```js\ntype DraggableChildrenFn = (\n  DraggableProvided,\n  DraggableStateSnapshot,\n  DraggableRubric,\n) => Node;\n```\n\nThe function is provided with three arguments:\n\n### 1. provided: (DraggableProvided)\n\n```js\ntype DraggableProvided = {|\n  innerRef: (HTMLElement) => void,\n  draggableProps: DraggableProps,\n  // will be null if the draggable is disabled\n  dragHandleProps: ?DragHandleProps,\n|};\n```\n\n> For more type information please see [our types guide](/docs/guides/types.md).\n\nEverything within the _provided_ object must be applied for the `<Draggable />` to function correctly.\n\n- `provided.innerRef (innerRef: (HTMLElement) => void)`: In order for the `<Draggable />` to function correctly, **you must** bind the `innerRef` function to the `ReactElement` that you want to be considered the `<Draggable />` node. We do this in order to avoid needing to use `ReactDOM` to look up your DOM node.\n\n> For more information on using `innerRef` see our [using `innerRef` guide](/docs/guides/using-inner-ref.md)\n\n#### `innerRef` Example\n\n```js\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => <div ref={provided.innerRef}>Drag me!</div>}\n</Draggable>\n\n// Note: this will not work directly as we are not applying draggableProps or dragHandleProps\n```\n\n- `provided.draggableProps (DraggableProps)`: This is an Object that contains a `data` attribute and an inline `style`. This Object needs to be applied to the same node that you apply `provided.innerRef` to. This controls the movement of the draggable when it is dragging and not dragging. You are welcome to add your own styles to `DraggableProps.style` – but please do not remove or replace any of the properties.\n\n#### `draggableProps` type information\n\n```js\n// Props that can be spread onto the element directly\nexport type DraggableProps = {|\n  // inline style\n  style: ?DraggableStyle,\n  // used for shared global styles\n  'data-rbd-draggable-context-id': string,\n  'data-rbd-draggable-id': string,\n  // used to know when a transition ends\n  onTransitionEnd: ?(event: TransitionEvent) => void,\n|};\n```\n\n> For more type information please see [our types guide](/docs/guides/types.md).\n\n#### `draggableProps` Example\n\n```js\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => (\n    <div ref={provided.innerRef} {...provided.draggableProps}>\n      Drag me!\n    </div>\n  )}\n</Draggable>\n\n// Note: this will not work directly as we are not applying dragHandleProps\n```\n\n#### `key`s for a list of `<Draggable />`\n\nIf you are rendering a list of `<Draggable />`s then it is important that you add a `key` prop to each `<Draggable />`.\n\n```js\nreturn items.map((item, index) => (\n  <Draggable\n    // adding a key is important!\n    key={item.id}\n    draggableId={item.id}\n    index={index}\n  >\n    {(provided, snapshot) => (\n      <div\n        ref={provided.innerRef}\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n      >\n        {item.content}\n      </div>\n    )}\n  </Draggable>\n));\n```\n\nRules:\n\n- Your `key` needs to be unique within the list\n- Your `key` should not include the `index` of the item\n\nUsually you will want to just use the `draggableId` as the `key`\n\n`React` will warn you if your list is missing `keys`. It will not warn you if you are using `index` as a part of your `key`.\n\nNot using `keys` correctly will cause really bad times 💥\n\n[`React` docs about `keys`](https://reactjs.org/docs/lists-and-keys.html)\n\n#### Positioning ownership\n\nIt is a contract of this library that it owns the positioning logic of the dragging element. This includes properties such as `top`, `right`, `bottom`, `left` and `transform`. The library may change how it positions things and which properties it uses without performing a major version bump. It is also recommended that you do not apply your own `transition` property to the dragging element.\n\n#### Warning: `position: fixed`\n\n`react-beautiful-dnd` uses `position: fixed` to position the dragging element. This is quite robust and allows for you to have `position: relative | absolute | fixed` parents. However, unfortunately `position:fixed` is [impacted by `transform`](http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/) (such as `transform: rotate(10deg);`). This means that if you have a `transform: *` on one of the parents of a `<Draggable />` then the positioning logic will be incorrect while dragging. Lame! For most consumers this will not be an issue.\n\nTo get around this you can [reparent your <Draggable />](/docs/guides/reparenting.md). We do not enable this functionality by default as it has performance problems.\n\n#### Force press\n\n> Safari only\n\nIn Safari, it is possible for a user to perform a force press action. This is possible with a touch device (`touchforcechange`) and with a mouse (`webkitmouseforcechanged`).\n\nWe have found that in order to give the most consistent drag and drop experience we need to _opt out_ of force press interactions on a _drag handle_. However, it is possible to have `react-beautiful-dnd` work while also respecting force press interactions. The trade off is that if we register a force press interaction a drag will be cancelled.\n\nIn order to control this behaviour you set the `shouldRespectForcePress` prop on a `<Draggable />`. By default we set this value to `false` to prevent heavy presses from cancelling a drag.\n\n##### Enabling `shouldRespectForcePress`\n\nIf you set `shouldRespectForcePress` to `true` then the following will occur:\n\n###### Touch dragging\n\nIf the user force presses on the element before they have moved the element (even if a drag has already started) then the drag is cancelled and the standard force press action occurs. For an anchor this is a website preview.\n\n###### Mouse dragging\n\nAny force press action will cancel an existing or pending drag\n\n#### Focus retention\n\nSee [our focus guide](/docs/guides/browser-focus.md)\n\n#### Extending `DraggableProps.style`\n\nIf you are using inline styles you are welcome to extend the `DraggableProps.style` object. You are also welcome to apply the `DraggableProps.style` object using inline styles and use your own styling solution for the component itself. You can use anything you like to style the `<Draggable />` such as\n\n- css-in-js such as [`styled-components`](https://www.styled-components.com) or [`emotion`](https://emotion.sh)\n- sass, less\n- vanilla css\n\nIf you are overriding inline styles be sure to do it after you spread the `provided.draggableProps` or the spread will override your inline style.\n\n```js\n<Draggable draggable=\"draggable-1\" index={0}>\n  {(provided, snapshot) => {\n    // extending the DraggableStyle with our own inline styles\n    const style = {\n      ...provided.draggableProps.style,\n      backgroundColor: snapshot.isDragging ? 'blue' : 'white',\n      fontSize: 18,\n    };\n    return (\n      <div ref={provided.innerRef} {...provided.draggableProps} style={style}>\n        Drag me!\n      </div>\n    );\n  }}\n</Draggable>\n```\n\n#### Unsupported `margin` setups\n\nAvoid margin collapsing between `<Draggable />`s. [margin collapsing](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing) is one of those really hard parts of CSS. For our purposes, if you have one `<Draggable />` with a `margin-bottom: 10px` and the next `<Draggable />` has a `margin-top: 12px` these margins will _collapse_ and the resulting space between the elements will be the greater of the two: `12px`. When we do our calculations we are currently not accounting for margin collapsing. If you do want to have a margin on the siblings, wrap them both in a `div` and apply the margin to the inner `div` so they are not direct siblings.\n\n#### `<Draggable />`s should be visible siblings\n\nIt is an assumption that `<Draggable />`s are _visible siblings_ of one another. There can be other elements in between, but these elements should not take up any additional space. You probably will not do this anyway, but just calling it out to be super clear.\n\n```js\n// Direct siblings ✅\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {() => {}}\n</Draggable>\n<Draggable draggableId=\"draggable-2\" index={1}>\n  {() => {}}\n</Draggable>\n\n// Not direct siblings, but are visible siblings ✅\n<div>\n  <Draggable draggableId=\"draggable-1\" index={0}>\n    {() => {}}\n  </Draggable>\n</div>\n<div>\n  <Draggable draggableId=\"draggable-2\" index={1}>\n    {() => {}}\n  </Draggable>\n</div>\n\n// Spacer elements ❌\n<Draggable draggableId=\"draggable-1\" index={0}>\n    {() => {}}\n</Draggable>\n<p>I will break things!</p>\n<Draggable draggableId=\"draggable-2\" index={1}>\n    {() => {}}\n</Draggable>\n\n// Spacing on non sibling wrappers ❌\n<div style={{padding: 10}}>\n  <Draggable draggableId=\"draggable-1\" index={0}>\n    {() => {}}\n  </Draggable>\n</div>\n<div style={{padding: 10}}>\n  <Draggable draggableId=\"draggable-2\" index={1}>\n    {() => {}}\n  </Draggable>\n</div>\n```\n\n- `provided.dragHandleProps (?DragHandleProps)` every `<Draggable />` has a _drag handle_. This is what is used to drag the whole `<Draggable />`. Often this will be the same node as the `<Draggable />`, but sometimes it can be a child of the `<Draggable />`. `DragHandleProps` need to be applied to the node that you want to be the drag handle. This is a number of props that need to be applied to the `<Draggable />` node. The simplest approach is to spread the props onto the draggable node (`{...provided.dragHandleProps}`). However, you are also welcome to [monkey patch](https://davidwalsh.name/monkey-patching) these props if you also need to respond to them. DragHandleProps will be `null` when `isDragDisabled` is set to `true`.\n\n#### `dragHandleProps` Type information\n\n```js\ntype DragHandleProps = {|\n  // what draggable the handle belongs to\n  'data-rbd-drag-handle-draggable-id': DraggableId,\n\n  // What DragDropContext the drag handle is in\n  'data-rbd-drag-handle-context-id': ContextId,\n\n  // Id of hidden element that contains the lift instruction (nicer screen reader text)\n  'aria-labelledby': ElementId,\n\n  // Allow tabbing to this element\n  tabIndex: number,\n\n  // Stop html5 drag and drop\n  draggable: boolean,\n  onDragStart: (event: DragEvent) => void,\n|};\n```\n\n#### `dragHandleProps` Example: standard\n\n```js\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => (\n    <div\n      ref={provided.innerRef}\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n    >\n      Drag me!\n    </div>\n  )}\n</Draggable>\n```\n\n#### `dragHandleProps` example: custom drag handle\n\nControlling a whole draggable by just a part of it\n\n```js\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => (\n    <div ref={provided.innerRef} {...provided.draggableProps}>\n      <h2>Hello there</h2>\n      <div {...provided.dragHandleProps}>Drag handle</div>\n    </div>\n  )}\n</Draggable>\n```\n\n### 2. Snapshot: (DraggableStateSnapshot)\n\n```js\ntype DraggableStateSnapshot = {|\n  // Set to true if a Draggable is being actively dragged, or if it is drop animating\n  // Both active dragging and the drop animation are considered part of the drag\n  // *Generally this is the only property you will be using*\n  isDragging: boolean,\n  // Set to true if a Draggable is drop animating. Not every drag and drop interaction\n  // as a drop animation. There is no drop animation when a Draggable is already in its final\n  // position when dropped. This is commonly the case when dragging with a keyboard\n  isDropAnimating: boolean,\n  // Information about a drop animation\n  dropAnimation: ?DropAnimation\n  // What Droppable (if any) the Draggable is currently over\n  draggingOver: ?DroppableId,\n  // the id of a draggable that you are combining with\n  combineWith: ?DraggableId,\n  // if something else is dragging and you are a combine target, then this is the id of the item that is dragging\n  combineTargetFor: ?DraggableId,\n  // There are two modes that a drag can be in\n  // 'FLUID': everything is done in response to highly granular input (eg mouse)\n  // 'SNAP': items snap between positions (eg keyboard);\n  mode: ?MovementMode,\n|};\n```\n\n> See our [type guide](/docs/guides/types.md) for more details\n\nThe `children` function is also provided with a small amount of state relating to the current drag state. This can be optionally used to enhance your component. A common use case is changing the appearance of a `<Draggable />` while it is being dragged. Note: if you want to change the cursor to something like `grab` you will need to add the style to the draggable. (See [Extending `DraggableProps.style`](#extending-draggableprops-style) above)\n\n```js\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => {\n    const style = {\n      backgroundColor: snapshot.isDragging ? 'blue' : 'grey',\n      ...provided.draggableProps.style,\n    };\n\n    return (\n      <div\n        ref={provided.innerRef}\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        style={style}\n      >\n        Drag me!\n      </div>\n    );\n  }}\n</Draggable>\n```\n\n### 3. rubric: (DraggableRubric)\n\n```js\ntype DraggableRubric = {|\n  draggableId: DraggableId,\n  type: TypeId,\n  source: DraggableLocation,\n|};\n```\n\n`rubric` represents all of the information associated with a `<Draggable />`. `rubric` is helpful for looking up the data associated with your `<Draggable />` when it is not available in the current scope. This is useful when using the `<Droppable /> | renderClone` API. The `rubric` is the same lookup information that is provided to the [`Responder`s](/docs/guides/responders.md).\n\n## Adding an `onClick` handler to a `<Draggable />` or a _drag handle_\n\nYou are welcome to add your own `onClick` handler to a `<Draggable />` or a _drag handle_ (which might be the same element). `onClick` events handlers will always be called if a click occurred. If we are preventing the click, then the `event.defaultPrevented` property will be set to `true`. We prevent click events from occurring when the user was dragging an item. See [sloppy clicks and click prevention](/docs/sensors/mouse.md#sloppy-clicks-and-click-prevention-) for more information.\n\n## Interactive child elements within a `<Draggable />`\n\nIt is possible for your `<Draggable />` to contain interactive elements. By default we block dragging on these elements. By doing this we allow those elements to function in the usual way. Here is the list of interactive elements that we block dragging from by default:\n\n- `input`\n- `button`\n- `textarea`\n- `select`\n- `option`\n- `optgroup`\n- `video`\n- `audio`\n- [`contenteditable`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable) (any elements that are `contenteditable` or are within a `contenteditable` container)\n\nYou can opt out of this behavior by adding the `disableInteractiveElementBlocking` prop to a `<Draggable />`. However, it is questionable as to whether you should be doing so because it will render the interactive element unusable. If you need to _conditionally_ block dragging from interactive elements you can add the `disableInteractiveElementBlocking` prop to opt out of the default blocking and monkey patch the `dragHandleProps (DragHandleProps)` event handlers to disable dragging as required.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/api/droppable.md",
    "content": "# `<Droppable />`\n\n`<Droppable />` components can be **dropped on by a `<Draggable />`**. They also **contain** `<Draggable />`s. A `<Draggable />` must be contained within a `<Droppable />`.\n\n```js\nimport { Droppable } from 'react-beautiful-dnd';\n\n<Droppable droppableId=\"droppable-1\" type=\"PERSON\">\n  {(provided, snapshot) => (\n    <div\n      ref={provided.innerRef}\n      style={{ backgroundColor: snapshot.isDraggingOver ? 'blue' : 'grey' }}\n      {...provided.droppableProps}\n    >\n      <h2>I am a droppable!</h2>\n      {provided.placeholder}\n    </div>\n  )}\n</Droppable>;\n```\n\n## Droppable props\n\n```js\nimport type { Node } from 'react';\n\ntype Props = {|\n  // required\n  droppableId: DroppableId,\n  // optional\n  type?: TypeId,\n  mode?: DroppableMode,\n  isDropDisabled?: boolean,\n  isCombineEnabled?: boolean,\n  direction?: Direction,\n  ignoreContainerClipping?: boolean,\n  renderClone?: DraggableChildrenFn,\n  getContainerForClone?: () => HTMLElement,\n  children: (DroppableProvided, DroppableStateSnapshot) => Node,\n|};\n\ntype DroppableMode = 'standard' | 'virtual';\ntype Direction = 'horizontal' | 'vertical';\n```\n\n### Required props\n\n> `react-beautiful-dnd` will throw an error if a required prop is not provided\n\n- `droppableId`: A _required_ `DroppableId(string)`. See our [identifiers guide](/docs/guides/identifiers.md) for more information.\n\n### Optional props\n\n- `type`: A `TypeId(string)` that can be used to simply accept only the specified class of `<Draggable />`. `<Draggable />`s always inherit type from the `<Droppable />` they are defined in. For example, if you use the type `PERSON` then it will only allow `<Draggable />`s of type `PERSON` to be dropped on itself. `<Draggable />`s of type `TASK` would not be able to be dropped on a `<Droppable />` with type `PERSON`. If no `type` is provided, it will be set to `'DEFAULT'`.\n- `isDropDisabled`: A flag to control whether or not dropping is currently allowed on the `<Droppable />`. You can use this to implement your own conditional dropping logic. It will default to `false`.\n- `isCombineEnabled`: A flag to control whether or not _all_ the `Draggables` in the list will be able to be **combined** with. It will default to `false`.\n- `direction`: The direction in which items flow in this droppable. Options are `vertical` (default) and `horizontal`.\n- `ignoreContainerClipping`: When a `<Droppable />` is inside a scrollable container its area is constrained so that you can only drop on the part of the `<Droppable />` that you can see. Setting this prop opts out of this behavior, allowing you to drop anywhere on a `<Droppable />` even if it's visually hidden by a scrollable parent. The default behavior is suitable for most cases so odds are you'll never need to use this prop, but it can be useful if you've got very long `<Draggable />`s inside a short scroll container. Keep in mind that it might cause some unexpected behavior if you have multiple `<Droppable />`s inside scroll containers on the same page.\n- `mode`: `standard` (default) or `virtual`. Used to designate a list as a virtual list. See our [virtual lists pattern](/docs/patterns/virtual-lists.md)\n- `renderClone`: used to render a clone (replacement) of the dragging `<Draggable />` while a drag is occurring. See our [reparenting guide](/docs/guides/reparenting.md) for usage details. **A clone must be used for [virtual lists](/docs/patterns/virtual-lists.md).** You can use a clone without using virtual lists\n- `getContainerForClone`: a function that returns the containing element (parent element) for a clone during a drag. See our [reparenting guide](/docs/guides/reparenting.md).\n\n## Children function\n\nThe `React` children of a `<Droppable />` must be a function that returns a [`ReactElement`](https://tylermcginnis.com/react-elements-vs-react-components/).\n\n```js\n<Droppable droppableId=\"droppable-1\">\n  {(provided, snapshot) => ({\n    /*...*/\n  })}\n</Droppable>\n```\n\nThe function is provided with two arguments:\n\n### 1. provided: (DroppableProvided)\n\n```js\nimport type { Node } from 'react';\n\ntype DroppableProvided = {|\n  innerRef: (?HTMLElement) => void,\n  droppableProps: DroppableProps,\n  placeholder: ?Node,\n|};\n\ntype DroppableProps = {|\n  // used for shared global styles\n  'data-rbd-droppable-context-id': ContextId,\n  // Used to lookup. Currently not used for drag and drop lifecycle\n  'data-rbd-droppable-id': DroppableId,\n|};\n```\n\n- `provided.innerRef`: In order for the droppable to function correctly, **you must** bind the `provided.innerRef` to the highest possible DOM node in the `ReactElement`. We do this in order to avoid needing to use `ReactDOM` to look up your DOM node.\n\n> For more information on using `innerRef` see our [using `innerRef` guide](/docs/guides/using-inner-ref.md)\n\n- `provided.placeholder`: This is used to create space in the `<Droppable />` as needed during a drag. This space is needed when a user is dragging over a list that is not the home list. Please be sure to put the placeholder inside of the component for which you have provided the ref. We need to increase the size of the `<Droppable />` itself.\n- `provided.droppableProps (DroppableProps)`: This is an Object that contains properties that need to be applied to a Droppable element. It needs to be applied to the same element that you apply `provided.innerRef` to. It currently contains `data` attributes that we use for styling and lookups.\n\n```js\n<Droppable droppableId=\"droppable-1\">\n  {(provided, snapshot) => (\n    <div ref={provided.innerRef} {...provided.droppableProps}>\n      Good to go\n      {provided.placeholder}\n    </div>\n  )}\n</Droppable>\n```\n\n### 2. snapshot: (DroppableStateSnapshot)\n\n```js\ntype DroppableStateSnapshot = {|\n  // Is the Droppable being dragged over?\n  isDraggingOver: boolean,\n  // What is the id of the draggable that is dragging over the Droppable?\n  draggingOverWith: ?DraggableId,\n  // What is the id of the draggable that is dragging from this list?\n  // Useful for styling the home list when not being dragged over\n  draggingFromThisWith: ?DraggableId,\n  // Whether or not the placeholder is actively being used.\n  // This is useful information when working with virtual lists\n  // (See our virtual list pattern)\n  isUsingPlaceholder: boolean,\n|};\n```\n\nThe `children` function is also provided with a small amount of state relating to the current drag state. This can be optionally used to enhance your component. A common use case is changing the appearance of a `<Droppable />` while it is being dragged over.\n\n```js\n<Droppable droppableId=\"droppable-1\">\n  {(provided, snapshot) => (\n    <div\n      ref={provided.innerRef}\n      style={{ backgroundColor: snapshot.isDraggingOver ? 'blue' : 'grey' }}\n      {...provided.droppableProps}\n    >\n      I am a droppable!\n      {provided.placeholder}\n    </div>\n  )}\n</Droppable>\n```\n\n## Combining\n\n`react-beautiful-dnd` supports the combining of `<Draggable />`s 🤩\n\n![combining](https://user-images.githubusercontent.com/2182637/48045145-318dc300-e1e3-11e8-83bd-22c9bd44c442.gif)\n\nYou can enable a _combining_ mode for a `<Droppable />` by setting `isCombineEnabled` to `true` on a `<Droppable />`. We have created a [combining guide](/docs/guides/combining.md) to help you implement combining in your lists.\n\n## Adding and removing `<Draggable />`s while dragging\n\nIt is possible to change the `<Draggable />`s in a `<Droppable />` for a limited set of circumstances. We have created a comprehensive [changes while dragging guide](/docs/guides/changes-while-dragging.md)\n\n## Conditionally dropping\n\n- `<Droppable />`s can only be dropped on by `<Draggable />`s who share the same `type`. This is a simple way of allowing conditional dropping. If you do not provide a `type` for the `<Droppable />`, then it will only accept `<Draggable />`s which also have the default type. `<Draggable />`s and `<Droppable />`s both will have their `types` set to `'DEFAULT'` when none is provided. There is currently no way to set multiple `types`, or a `type` wildcard that will accept `<Draggable />`s of multiple any types. This could be added if there is a valid use case.\n- Using the `isDropDisabled` prop you can conditionally allow dropping. This allows you to do arbitrarily complex conditional transitions. This will only be considered if the `type` of the `<Droppable />` matches the `type` of the currently dragging `<Draggable />`.\n- You can disable dropping on a `<Droppable />` altogether by always setting `isDropDisabled` to `true`. You can do this to create a list that is never able to be dropped on, but contains `<Draggable />`s.\n- Technically you do not need to use `type` and do all of your conditional drop logic with the `isDropDisabled` function. The `type` parameter is a convenient shortcut for a common use case.\n\n## Scroll containers\n\nThis library supports dragging within scroll containers (DOM elements that have `overflow: auto;` or `overflow: scroll;`). The **only** supported use cases are:\n\n1.  The `<Droppable />` can itself be a scroll container with **no scrollable parents**\n2.  The `<Droppable />` has **one scrollable parent**\n\nwhere a _scrollable parent_ refers to a scroll container that is not the window itself.\n\nFor more information see [how we detect scroll containers guide](/docs/guides/how-we-detect-scroll-containers.md)\n\n> We currently only support a single scroll parent. We plan on adding support for [nested scroll containers](https://github.com/atlassian/react-beautiful-dnd/issues/131)\n\n## Empty `<Droppable />`s\n\nIt is recommended that you put a `min-height` on a vertical `<Droppable />` or a `min-width` on a horizontal `<Droppable />`. Otherwise when the `<Droppable />` is empty there may not be enough of a target for `<Draggable />` being dragged with touch or mouse inputs to be _over_ the `<Droppable />`.\n\n## Fixed `<Droppable />`s\n\n`react-beautiful-dnd` has partial support for `<Droppable />` lists that use `position: fixed`. When you start a drag and _any_ list of the same type is `position:fixed` then auto window scrolling will be disabled. This is because our virtual model assumes that when the page scroll changes the position of a `<Droppable />` will shift too. If a manual window scroll is detected then the scroll will be aborted. Scroll container scroll is still allowed. We could improve this support, but it would just be a big effort. Please raise an issue if you would be keen to be a part of this effort ❤️\n\n## Recommended 🏠 home list styling\n\nWe recommend you style the home list when it is not being dragged over. This makes it easy for a user to see where an item is dragging from. You can use the `snapshot.draggingFromThisWith` value for this. This will be populated in the home list.\n\nIn this example we set the `background-color` of the home list to `pink` when we are dragging over the list. We set the `background-color` of the home list to `blue` when not dragging over the home list.\n\n![no-placeholder-when-over-no-list](https://user-images.githubusercontent.com/2182637/54155390-251ebd00-4498-11e9-8748-ab441795d19f.gif)\n\n```js\nconst getBackgroundColor = (snapshot: DroppableStateSnapshot): string => {\n  // Giving isDraggingOver preference\n  if (snapshot.isDraggingOver) {\n    return 'pink';\n  }\n\n  // If it is the home list but not dragging over\n  if (snapshot.draggingFromThisWith) {\n    return 'blue';\n  }\n\n  // Otherwise use our default background\n  return 'white';\n};\n```\n\n## Recommended `<Droppable />` performance optimisation\n\n> 📺 This optimisation is covered in a [free lesson of our getting started course](https://egghead.io/lessons/react-optimize-performance-in-react-beautiful-dnd-with-shouldcomponentupdate-and-purecomponent)\n\nWhen a user drags over, or stops dragging over, a `<Droppable />` we re-render the `<Droppable />` with an updated `DroppableStateSnapshot > isDraggingOver` value. This is useful for styling the `<Droppable />`. However, by default this will cause a render of all of the children of the `<Droppable />` - which might be 100's of `<Draggable />`s! This can result in a noticeable frame rate drop. To avoid this problem we recommend that you create a component that is the child of a `<Droppable />` whose responsibility it is to avoid rendering children if it is not required.\n\nHere is an example of how you could do this using `class` components:\n\n```js\nimport React, { Component } from 'react';\n\nclass Student extends Component<{ student: Person }> {\n  render() {\n    // Renders out a draggable student\n  }\n}\n\nclass InnerList extends Component<{ students: Person[] }> {\n  // do not re-render if the students list has not changed\n  shouldComponentUpdate(nextProps: Props) {\n    if (this.props.students === nextProps.students) {\n      return false;\n    }\n    return true;\n  }\n  // You could also not do your own shouldComponentUpdate check and just\n  // extend from React.PureComponent\n\n  render() {\n    return this.props.students.map((student: Person) => (\n      <Student student={student} />\n    ));\n  }\n}\n\nclass Students extends Component<{ students: Person[] }> {\n  render() {\n    return (\n      <Droppable droppableId=\"list\">\n        {(provided: DroppableProvided, snapshot: DroppableStateSnapshot) => (\n          <div\n            ref={provided.innerRef}\n            style={{\n              backgroundColor: snapshot.isDragging ? 'green' : 'lightblue',\n            }}\n            {...provided.droppableProps}\n          >\n            <InnerList students={this.props.students} />\n            {provided.placeholder}\n          </div>\n        )}\n      </Droppable>\n    );\n  }\n}\n```\n\nHere is an example of how you could do this using `function` components:\n\n```js\nimport React from 'react';\n\nfunction Student (props: { student: Person }) {\n  // Renders out a draggable student\n}\n\n// do not re-render if the students list reference has not changed\nconst InnerList = React.memo(function InnerList(props: students: Person[]) {\n  return props.students.map((student: Person) => (\n    <Student student={student} />\n  ));\n});\n\nfunction Students(props: { students: Person[] }) {\n  return (\n    <Droppable droppableId=\"list\">\n      {(provided: DroppableProvided, snapshot: DroppableStateSnapshot) => (\n        <div\n          ref={provided.innerRef}\n          style={{\n            backgroundColor: snapshot.isDragging ? 'green' : 'lightblue',\n          }}\n          {...provided.droppableProps}\n        >\n          {/* only re-render if the students array reference changes */}\n          <InnerList students={props.students} />\n          {provided.placeholder}\n        </div>\n      )}\n    </Droppable>\n  );\n}\n```\n\nBy using the approach you are able to make style changes to a `<Droppable />` when it is being dragged over, but you avoid re-rendering all of the children unnecessarily.\n\nWhen moving into a new list, the visible `Draggables` will have their `render` function called directly even with this optimisation. This is because we need to move those `Draggables` out of the way. The `InnerList` optimisation will prevent the `<Droppable />` from calling `render` on the whole list from the top down. This optimisation will prevent the non-visible `Draggables` from having their render function called.\n\nUnfortunately we are [unable to apply this optimisation for you](https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9). It is a byproduct of using the render-props pattern.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/api/reset-server-context.md",
    "content": "# `resetServerContext`\n\nThe `resetServerContext` function should be used when server side rendering (SSR). It ensures context state does not persist across multiple renders on the server which would result in client/server markup mismatches after multiple requests are rendered on the server.\n\nUse it before calling the server side render method:\n\n```js\nimport { resetServerContext } from 'react-beautiful-dnd';\nimport { renderToString } from 'react-dom/server';\n\n// ...\n\nresetServerContext();\nrenderToString(...);\n```\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/auto-scrolling.md",
    "content": "# Auto scrolling\n\nWhen a user drags a `<Draggable />` near the edge of a _container_ we automatically scroll the container as we are able to in order make room for the `<Draggable />`.\n\n> A _container_ is either a `<Droppable />` that is scrollable or has a scroll parent - or the `window`.\n\n| Mouse and touch                                                                                                           | Keyboard                                                                                                                     |\n| ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| ![auto-scroll-mouse](https://user-images.githubusercontent.com/2182637/36520373-c9e2cb7e-17e4-11e8-9e93-4d2389d51fa4.gif) | ![auto-scroll-keyboard](https://user-images.githubusercontent.com/2182637/36520375-cc1aa45c-17e4-11e8-842d-94aed694428a.gif) |\n\nIt also works in multi list configurations with all input types\n\n| Mouse and touch                                                                                                                 | Keyboard                                                                                                                           |\n| ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |\n| ![auto-scroll-board-mouse](https://user-images.githubusercontent.com/2182637/36520670-57752526-17e6-11e8-95b3-b5a3978a5312.gif) | ![auto-scroll-board-keyboard](https://user-images.githubusercontent.com/2182637/36520650-3d3638f8-17e6-11e8-9cba-1fb439070285.gif) |\n\n## For mouse and touch inputs 🐭📱\n\nWhen the center of a `<Draggable />` gets within a small distance from the edge of a container we start auto scrolling. As the user gets closer to the edge of the container we increase the speed of the auto scroll. This acceleration uses an easing function to exponentially increase the rate of acceleration the closer we move towards the edge. We reach a maximum rate of acceleration a small distance from the true edge of a container so that the user does not need to be extremely precise to obtain the maximum scroll speed. This logic applies for any edge that is scrollable.\n\nThe distances required for auto scrolling are based on a percentage of the height or width of the container for vertical and horizontal scrolling respectively. By using percentages rather than raw pixel values we are able to have a great experience regardless of the size and shape of your containers.\n\n### Mouse wheel and trackpads\n\nIn addition to auto scrolling we also allow users to scroll the window or a `<Droppable />` manually using their _mouse wheel_ or _trackpad_ 👌\n\n### A note about big `<Draggable />`s\n\nIf the `<Draggable />` is bigger than a container on the axis you are trying to scroll - we will not permit scrolling on that axis. For example, if you have a `<Draggable />` that is longer than the height of the window we will not auto scroll vertically. However, we will still permit scrolling to occur horizontally.\n\n### iOS auto scroll shake 📱🤕\n\nWhen auto scrolling on an iOS browser (webkit) the `<Draggable />` noticeably shakes. This is due to a [bug with webkit](https://bugs.webkit.org/show_bug.cgi?id=181954) that has no known work around. We tried for a long time to work around the issue! If you are interesting in seeing this improved please engage with the [webkit issue](https://bugs.webkit.org/show_bug.cgi?id=181954).\n\n## For keyboard dragging 🎹♿️\n\nWe also correctly update the scroll position as required when keyboard dragging. In order to move a `<Draggable />` into the correct position we can do a combination of a `<Droppable />` scroll, `window` scroll and manual movements to ensure the `<Draggable />` ends up in the correct position in response to user movement instructions. This is boss 🔥.\n\nThis is amazing for users with visual impairments as they can correctly move items around in big lists without needing to use mouse positioning.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/avoiding-image-flickering.md",
    "content": "# Avoiding image flickering\n\n> Often all you need to do is close your browsers dev tools! See 'HTTP cache headers below'\n\nIf your `<Draggable />` has a image inside of it, then you might notice that sometimes it flashes sometimes. Why is that?\n\nSome behaviours will cause a `<Draggable />` to be **recreated**. This is where the original DOM element is destroyed, and a new DOM element is created. When the new DOM element is inserted into the DOM then the browser will try to load the image from scratch. Image flashing is caused by the gap between the new element being inserted into the DOM and the image being loaded.\n\nThese are the actions that can cause a `<Draggable />` to be recreated:\n\n- [Reparenting](/docs/guides/reparenting.md) a `<Draggable />` (using the cloning api, or using your own portal)\n- Moving `<Draggable />` into a new list. React will not shift the original element. It will recreate one.\n\n## How can you prevent image flickering?\n\nThe big idea is you want to allow the browser to load the image **instantly** when it is recreated.\n\nHere are some ways you can do that:\n\n### HTTP cache headers\n\n> When you open devtools, it can disable HTTP caching. So simply closing devtools might make your image flickering go away! 🤘\n\nGenerally speaking, a browser will not request an image that it already has cached and it will load instantly. You can use the [HTTP cache headers](https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers) to tell a browser that an image can be cached. Ultimately the browser can decide to re-request the image if it wants to, but that would be an edge case.\n\nWe put together an [example on Glitch](https://glitch.com/~image-flickering) that shows off the impact of using HTTP cache headers.\n\n### Inline your images\n\n[Base64 encode](https://stackoverflow.com/questions/201479/what-is-base-64-encoding-used-for) your images and use that as the source. That way there is no need to talk to the server to get the source.\n\n```diff\n- <img src=\"/public/my-image.png\">\n\n+ <img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAA...\">\n```\n\nYou can use the [webpack `url-loader`](https://github.com/webpack-contrib/url-loader) to help.\n\n#### Drawbacks of this approach\n\n- If the same image is used in multiple places, they all need to be downloaded independently\n- The browser cannot defer image loading\n\nYou will want to keep your image sizes fairly small.\n\n### Really anything else!\n\nThe big idea is that you don't want to be calling the server to refetch an image that has already been fetched. So anything you can use to do client side caching of images is fine. You could even use [service workers](https://developers.google.com/web/ilt/pwa/caching-files-with-service-worker) if you want!\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/browser-focus.md",
    "content": "# Browser focus\n\n> \"You got to focus on what's real, man\" - [Jake from Adventure time](https://www.youtube.com/watch?v=TFGz6Qvg1CE)\n\n`react-beautiful-dnd` includes logic to maintain browser focus for _drag handles_. This especially important for [keyboard dragging](/docs/sensors/keyboard.md) which requires the dragging item to be focused.\n\n## Terminology reminder 📖\n\nA `<Draggable />` has a _drag handle_. A _drag handle_ is the part of the `<Draggable />` that controls the dragging of the whole `<Draggable />`. A _drag handle_ can be the same element as the `<Draggable />`\n\n## Drag handle not focused at drag start\n\nIf the _drag handle_ is not focused when a drag starts then **focus is not given** to the dragging item. This is a mirror of the native HTML5 drag and drop behaviour which does not give focus to an item just because it is dragging. You are welcome to call `HTMLElement.focus()` when a drag starts to give it focus, but that is up to you.\n\n## Drag handle is focused at drag start\n\nIf a _drag handle_ has browser focus when a drag starts then `rbd` will try to give focus to the _drag handle_ during a drag and just after a drag ends.\n\nHere is what is done:\n\n- Give focus to a _drag handle_ with a matching `DraggableId` after the drag starts. This might be a different element to the original _drag handle_ if you are [reparenting your `<Draggable />`](/docs/guides/reparenting.md).\n- Give focus to a _drag handle_ with a matching `DraggableId` after the drag ends. Sometimes the original _drag handle_ element is lost during a drag, such as when [reparenting your `<Draggable />`](/docs/guides/reparenting.md), or when moving a `<Draggable />` from one list to another as `React` will recreate the element.\n- If [combining](/docs/guides/combining.md) then focus is given to the combine target after a drag ends. This allows keyboard users to continue to engage with the application without needing to get the focus back to where they where the last interaction was\n\n## Browser testing\n\nFun fact: we test this behaviour using [`cypress.io`](http://cypress.io) to ensure that focus management behaves as we expect\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/changes-while-dragging.md",
    "content": "# Changes while dragging\n\n> For virtual list support see our [virtual list pattern](/docs/patterns/virtual-lists.md)\n\n> ❌ **This behaviour is only supported in `11.x`**. We do plan on supporting this type of behaviour again in a future `minor` release. We needed to cut this existing behaviour order to get `12.x` across the line. Going forward, tree behaviour will be supported on the latest version. We know this sucks, but we thought it better to move things forward.\n\n`react-beautiful-dnd` supports the addition and removal of `<Draggable />`s during a drag.\n\n## What behaviours does this unlock?\n\n### Lazy loading of list items\n\n> In this example we are adding more `<Draggable />`s to a list we scroll closer to the bottom of the list\n\n![lazy-loading 2018-11-01 17_01_21](https://user-images.githubusercontent.com/2182637/47835395-ec8b1a80-ddf7-11e8-88e6-848848ab4af1.gif)\n\n### Collapsing and expanding groups\n\n> We recommend you use the [`@atlaskit/tree`](https://atlaskit.atlassian.com/packages/core/tree) component for this behaviour\n\n![hover_to_expand](https://user-images.githubusercontent.com/2182637/45996092-3d637100-c0de-11e8-8837-8d66e7cc73b8.gif)\n\n## Rules\n\n> We attempt to print helpful debug information to the `console` if you do not follow these rules in development builds\n\n- You are allowed to add or remove `Draggables` during a drag\n- You can only add or remove `Draggables` that are of the same `type` as the dragging item.\n- Any changes must occur within a `<Droppable />` that is a _scroll container_ (has `overflow: auto` or `overflow: scroll`). _This is prevent accidental shifts to other `Droppables` on the page_\n- The size of the internal content of the _scroll container_ can change, but the outer bounds of the _scroll container_ itself cannot change.\n- You cannot modify the sizes of any existing `<Draggable />` or `<Droppable />` during a drag\n- You cannot add or remove a `<Droppable />` during a drag. _We did this to avoid accidental shifting of other `<Droppable />`s_\n- When an item is removed or added it must be done instantly. You cannot animate the size of the item. You are welcome to animate a property when adding a `<Draggable />` that does not impact the size of the item, such as `opacity`\n\n## `<DragDropContext /> > onDragUpdate` behavior\n\n- `onDragUpdate` will be called if the `DragUpdate > source > index` of the dragging item has changed as the result of `Draggables` being added or removed before it.\n- `onDragUpdate` will be called if the `DragUpdate > destination` of the dragging item has changed as a result of the addition or removal.\n\n## `<DragDropContext /> > onDragEnd` behavior\n\n`onDragEnd` will be called with values that are adjusted for any additions or removals of `Draggables` during a drag. This can mean that the `onDragStart: DragStart > source > index` can be different from the `onDragEnd: DropResult > source > index`.\n\n### Sample `onDragEnd` flow\n\n> What is important to note is that the `source` property can change during a drag as a result of dynamic changes.\n\n1. A drag starts.\n\n`onDragStart` is called with:\n\n```js\n{\n  draggableId: 'item-1',,\n  type: 'TYPE',\n  source: {\n    droppableId: 'droppable',\n    index: 1,\n  },\n}\n```\n\n2. The first `<Draggable />` in the list (`item-0`) is removed.\n\n`onDragUpdate` is called with `DragUpdate`:\n\n```diff\n{\n  draggableId: 'item-1',,\n  type: 'TYPE',\n  source: {\n    droppableId: 'droppable',\n+   // item-1 is now in index 0 as item-0 is gone\n+    index: 0,\n  },\n  // adjusted destination\n  destination: null,\n}\n```\n\n3. The drag ends\n\n`onDragEnd` is called with `DropResult`:\n\n```diff\n{\n  draggableId: 'item-1',,\n  type: 'TYPE',\n  source: {\n    droppableId: 'droppable',\n+   // the source reflects the change\n+    index: 0,\n  },\n  destination: null,\n  reason: 'DROP',\n}\n```\n\n## Drag end while we are patching the virtual model\n\nIf a drag ends after a `<Draggable />` has been added or removed, but we have not finished collecting and patching the _virtual dimension model_ then we will delay the drop until the patch is finished. This is usually only a single frame. The `onDropEnd` callback will be called with a `DropResult` that is correct after the patch.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/combining.md",
    "content": "# Combining\n\n> 👶 This feature is still quite young. We wanted to get it out there for people to play with\n\n`react-beautiful-dnd` supports the combining of `<Draggable />`s 🤩\n\n![combining](https://user-images.githubusercontent.com/2182637/48045145-318dc300-e1e3-11e8-83bd-22c9bd44c442.gif)\n\n> 🌲 If you are looking to build a tree view, we have built one already! [@atlaskit/tree](https://atlaskit.atlassian.com/packages/confluence/tree)\n\n## Setup\n\nIn order to enable combining you need to set `isCombineEnabled` to `true` on a `<Droppable />` and you are good to go!\n\n```js\n<Droppable droppableId=\"droppable\" isCombineEnabled>\n  ...\n</Droppable>\n```\n\n## Behaviour\n\nWhen `isCombineEnabled` is set on a list _any_ item in the list can be combine with. You can toggle `isCombineEnabled` during a drag. `react-beautiful-dnd` works hard to ensure that users are able to combine and reorder within the same list in a way that feels intuitive and natural.\n\n## Current limitations\n\n- No granular control over which items can be combined with within the list. We could move to the `isCombineEnabled` prop from a `<Droppable />` to a `<Draggable />` to allow this sort of customisation. However, in order to ship this huge feature we went a bit simplier to start with\n- A list must be reorderable to also have items that can be combined with. It is not possible for a list to be 'combine only' at this stage\n\n## `<Draggable />` > `DraggableStateSnapshot`\n\n```diff\ntype DraggableStateSnapshot = {|\n  isDragging: boolean,\n  isDropAnimating: boolean,\n  dropAnimation: ?DropAnimation,\n  draggingOver: ?DroppableId,\n+  combineWith: ?DraggableId,\n+  combineTargetFor: ?DraggableId,\n  mode: ?MovementMode,\n|};\n```\n\nIf you are dragging a `<Draggable />` over another `<Draggable />` in combine mode then the id of the `<Draggable />` being dragged over will be populated in `combineWith`\n\nIf a `<Draggable />` is being dragged over in combine mode then the id of the `<Draggable />` being dragged will be populated in `combineTargetFor`\n\n## `<DragDropContext />` > `Responders`\n\n`onDragUpdate` and `onDragEnd` will be updated with any changes to a `combine`\n\n> See our [type guide](/docs/guides/types.md) for more details\n\n## Persisting a `combine`\n\nA `combine` result might signify different operations depending on your problem domain.\n\nWhen combining, a simple operation is to just remove the item that was dragging\n\n```js\nfunction onDragEnd(result) {\n  // combining item\n  if (result.combine) {\n    // super simple: just removing the dragging item\n    const items: Quote[] = [...this.state.items];\n    items.splice(result.source.index, 1);\n    setState({ items });\n    return;\n  }\n}\n```\n\n## Drop animation\n\nOne of the goals of `react-beautiful-dnd` is to create a drag and drop experience that feels physical. This is a bit tricky to achieve in a generic way when it comes to combining two things.\n\nWhat we have gone for out of the box in the following animation:\n\n- move the dragging item onto the center of the item being grouped with\n- fade the opacity of the dragging item down to `0`\n- scale the dragging item down\n\nThis animation attempts to communicate one item _moving into_ another item in a fairly generic way.\n\n![combining](https://user-images.githubusercontent.com/2182637/48045145-318dc300-e1e3-11e8-83bd-22c9bd44c442.gif)\n\nYou are welcome to customise this animation using the information found in our [drop animation guide](/docs/guides/drop-animation.md)\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/common-setup-issues.md",
    "content": "# Common setup issues\n\nThis is a little guide to help you with some common setup issues\n\n## Check your `console`\n\nFor detectable setup issues we try to log information in the `console` for `development` builds of `react-beautiful-dnd`. If things are not working, first thing to do is check your `console`.\n\n## React version\n\nPlease ensure that you meet our peer dependency version of `React`. Your React version needs to be greater than or equal to `16.8.5`.\n\nIf you want to know what React version you are on take a look at your [`package.json`](https://docs.npmjs.com/files/package.json) or use `console.log(React.version)`.\n\nIf you are not sure if your `package.json` version satisfies `16.8.5` have a read of [npm: about semantic versioning](https://docs.npmjs.com/about-semantic-versioning) and try out the [npm sermver calculator](https://semver.npmjs.com/)\n\n## No duplicate ids\n\n`draggableId` and `droppableId` values must be unique for the whole `<DragDropContext />` and not just a list.\n\nMore information: [identifiers guide](/docs/guides/identifiers.md)\n\n## `<Draggable />` indexes\n\nRules:\n\n- Must be unique within a `<Droppable />` (no duplicates)\n- Must be consecutive. `[0, 1, 2]` and not `[1, 2, 8]`\n\nIndexes do not need to start from `0` (this is often the case in [virtual lists](/docs/patterns/virtual-lists.md))\n\n[More information](/docs/api/draggable.md#draggable-props)\n\n## No margin collapsing between `<Draggable />`s\n\nThis can happen if you have a `margin-top` as well as a `margin-bottom` on a `<Draggable />`.\n\n[More information](/docs/api/draggable.md#unsupported-margin-setups)\n\n## `key`s for a list of `<Draggable />`\n\nIf you are rendering a list of `<Draggable />`s then it is important that you add a [`key`](https://reactjs.org/docs/lists-and-keys.html) prop to each `<Draggable />`.\n\n```js\nreturn items.map((item, index) => (\n  <Draggable\n    // adding a key is important!\n    key={item.id}\n    draggableId={item.id}\n    index={index}\n  >\n    {(provided, snapshot) => (\n      <div\n        ref={provided.innerRef}\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n      >\n        {item.content}\n      </div>\n    )}\n  </Draggable>\n));\n```\n\n[More information](/docs/api/draggable.md)\n\n## Avoid empty lists\n\nWe recommend you set a `min-height` or `min-width` on a `<Droppable />` to ensure that there is a visible drop target when a list is empty\n\nWe go over this in our [Get started with `react-beautiful-dnd` course](https://egghead.io/lessons/react-move-items-between-columns-with-react-beautiful-dnd-using-ondragend)\n\n## Image flickering in a `<Draggable />`\n\nSee our [avoiding image flickering guide](/docs/guides/avoiding-image-flickering.md)\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/content-security-policy.md",
    "content": "# Content Security Policy\n\n> This page is to help you get around the CSP error: \"Refused to apply inline style because it violates the following Content Security Policy directive: \"style-src 'self'\".\"\n> A huge thankyou to [@Zweder](https://github.com/Zweder) for driving this effort\n\nContent Security Policy (CSP) is a way of controlling where a browser can download assets from, as well as what those assets are allowed to do.\n\nBackground reading on CSP\n\n- [Google guide](https://developer.chrome.com/extensions/contentSecurityPolicy)\n- [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)\n- [Helmetjs guide](https://helmetjs.github.io/docs/csp/)\n\n`react-beautiful-dnd` creates a `<style>` element in the `<head>` and dynamically updates it's value (see [/docs/guides/preset-styles.md] and [Dragging React performance forward](https://medium.com/@alexandereardon/dragging-react-performance-forward-688b30d40a33)). This is considered an _unsafe inline_ and will violate the strict CSP policy: `Content-Security-Policy: style-src 'self'`\n\n## Option 1: use `unsafe-inline`\n\nSimple solution number one, use a looser `style-src 'unsafe-inline'`. ⚠️ This is not ideal as it will loosen your CSP.\n\n```diff\n- Content-Security-Policy: style-src 'self'\n+ Content-Security-Policy: style-src 'unsafe-inline'\n```\n\n## Option 2: Use a `nonce`\n\nYou can use the stricter directive `Content-Security-Policy: style-src 'self'` as long as you provide a `nonce` (number used once).\n\nThe [JSS](https://cssinjs.org/?v=v10.0.0) project has a great [CSP guide](https://cssinjs.org/csp) which goes through how you can setup a a `nonce`. Once you have a `nonce` value in the browser you can pass it into a `<DragDropContext />` to tell `react-beautiful-dnd` to use the `nonce`.\n\n```js\n<DragDropContext nonce={getNonce()}>{/*...*/}</DragDropContext>\n```\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/doctype.md",
    "content": "# Use the html5 `doctype`\n\nBe sure that you have specified the html5 `doctype` ([Document Type Definition - DTD](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)) for your `html` page:\n\n```html\n<!DOCTYPE html>\n```\n\nA `doctype` impacts browser layout and measurement apis. Not specifying a `doctype` is a world of pain 🔥. Browsers will use some other `doctype` such as [\"Quirks mode\"](https://en.wikipedia.org/wiki/Quirks_mode) which can drastically change layout and measurement ([more information](https://www.w3.org/QA/Tips/Doctype)). The html5 `doctype` is our only supported `doctype`.\n\nFor non `production` builds we will log a warning to the `console` if a html5 `doctype` is not found. You can [disable the warning](#disable-warnings) if you like.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/dragging-svgs.md",
    "content": "# Dragging `<svg>`s\n\n> Summary: `react-beautiful-dnd` does not support the usage of `<svg>` (`SVGElement`) for a `<Draggable />` or it's _drag handle_. You are still able to drag SVG's around using a number of different strategies listed below\n\n## Background: [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement)\n\nWe require that a `<Draggable />` and its drag handle be a `HTMLElement`. Almost every element that you make in the browser is a `HTMLElement`. [See huge list on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element). A `HTMLElement` extends [`Element`](https://developer.mozilla.org/en-US/docs/Web/API/Element)\n\n![HTMLElement](https://user-images.githubusercontent.com/2182637/42302315-9150d4e0-805d-11e8-8345-71bc32135203.png)\n\n## Focus management\n\nWe use and manipulate focus on a drag handle during a drag if it is needed. This is especially true for keyboard dragging that relies on focus management. See our [focus guide](/docs/guides/browser-focus.md).\n\n## Enter [`SVGElement`](https://developer.mozilla.org/en-US/docs/Web/API/SVGElement) 🖼\n\nAn `SVGElement` does not implement `HTMLElement`, and directly extends `Element`.\n\n![SVGElement](https://user-images.githubusercontent.com/2182637/42304424-8360143e-8069-11e8-9693-64f5e9763315.png)\n\n`SVGElement` has **inconsistent**, and sometimes, **non-existent** focus management behavior across browsers. [more information](https://allyjs.io/tutorials/focusing-in-svg.html). Trying to call `svgElement.focus()` on IE11 will cause an exception. There are also additional concerns:\n\n- Applying `aria-*` to a `<svg>` has unknown screen reader implications.\n- Inconsistent `tabindex` behaviour in older browsers\n\nOne of the core values of `react-beautiful-dnd` is accessibility\n\n> Beautiful and **accessible** drag and drop for lists with `React`\n\n## But I want to drag using a `<svg>`!\n\n### Option 1: Wrap in an `HTMLElement`\n\nIn order to provide the best accessibility and cross browser experience for consumers we enforce that `SVGElement`s need to be wrapped in a `HTMLElement` such as `<span>` or `<div>` if you want to have them as your `<Draggable />` or _drag handle_.\n\n```js\n// ❌ not supported\n<Draggable draggableId=\"not-supported\" index={0}>\n  {provided => (\n    <svg\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n      ref={provided.innerRef}\n      {/* other SVG stuff */}\n    />\n  )}\n</Draggable>\n```\n\n```js\n// ✅ supported\n<Draggable draggableId=\"supported\" index={0}>\n{provided => (\n  <span\n    {...provided.draggableProps}\n    {...provided.dragHandleProps}\n    ref={provided.innerRef}\n    >\n      <svg {/* other SVG stuff */} />\n  </span>\n)}\n</Draggable>\n```\n\n### Option 2: use an `<img>` tag\n\nYou can use the `src` of an `<img>` tag (which is a `HTMLElement`) to have a draggable SVG.\n\n```js\n// ✅ supported\n<Draggable draggableId=\"supported\" index={0}>\n  {(provided) => (\n    <img\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n      ref={provided.innerRef}\n      src=\"my-cool-image.svg\"\n    />\n  )}\n</Draggable>\n```\n\n> You can read more about this approach on [CSS-Tricks](https://css-tricks.com/using-svg/)\n\n### Option 3: use `background-image`\n\nAlternatively you could also apply the SVG as a `background-image` to another `HTMLElement`.\n\n```css\n.item {\n  background-image: url(my-cool-image.svg);\n}\n```\n\n```js\n// ✅ supported\n<Draggable draggableId=\"supported\" index={0}>\n  {(provided) => (\n    <div\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n      ref={provided.innerRef}\n      className=\"item\"\n    />\n  )}\n</Draggable>\n```\n\n> You can read more about this approach on [CSS-Tricks](https://css-tricks.com/using-svg/)\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/drop-animation.md",
    "content": "# Drop animation\n\nOut of the box we provide a beautiful drop animation for you to use. We have worked hard to create an experience that feels responsive while also feeling like you are physically dropping an object. There may be situations in which you want to add an additional effect to the drop, or remove the drop animation entirely.\n\n## Styling a drop\n\nYou are able to add your own style to a `<Draggable />` while it is dropping (such as `background-color`). You know a drop is occurring when `DraggableStateSnapshot > DropAnimation` is populated.\n\n## Patching the drop animation\n\nIn some cases you might want to add an additional `transform` or change the `transition`. In which case, you can patch the style of a `<Draggable />` while a drop is occurring. (patch `DraggableProvided > DraggableProps > DraggableStyle`)\n\nHere is the shape of `DropAnimation`:\n\n```js\ntype DropReason = 'DROP' | 'CANCEL';\n\ntype DropAnimation = {|\n  // how long the animation will run for\n  duration: number,\n  // the animation curve that we will be using for the drop\n  curve: string,\n  // the x,y position will be be animating to as a part of the drop\n  moveTo: Position,\n  // when combining with another item, we animate the opacity when dropping\n  opacity: ?number,\n  // when combining with another item, we animate the scale when dropping\n  scale: ?number,\n|};\n```\n\nYou can use the `DraggableDroppingState` to build up your own `transform` and `transition` properties during a drop.\n\n```js\nfunction getStyle(style, snapshot) {\n  if (!snapshot.isDropAnimating) {\n    return style;\n  }\n  const { moveTo, curve, duration } = snapshot.dropAnimation;\n  // move to the right spot\n  const translate = `translate(${moveTo.x}px, ${moveTo.y}px)`;\n  // add a bit of turn for fun\n  const rotate = 'rotate(0.5turn)';\n\n  // patching the existing style\n  return {\n    ...style,\n    transform: `${translate} ${rotate}`,\n    // slowing down the drop because we can\n    transition: `all ${curve} ${duration + 1}s`,\n  };\n}\n\nfunction TaskItem(props) {\n  const { task, index } = props;\n  return (\n    <Draggable draggableId={task.id} index={index}>\n      {(provided, snapshot) => (\n        <div\n          ref={provided.innerRef}\n          {...provided.draggableProps}\n          {...provided.dragHandleProps}\n          isDragging={snapshot.isDragging && !snapshot.isDropAnimating}\n          style={getStyle(provided.draggableProps.style, snapshot)}\n        >\n          {task.content}\n        </div>\n      )}\n    </Draggable>\n  );\n}\n```\n\n## Skipping the drop animation\n\nGenerally speaking you should be avoiding this. A drop animation is an important affordance to communicate placement. Our drop animations do not prevent the user from dragging something else while the animation is running.\n\nIf you are seeing a strange drop behaviour, such as dropping to the wrong spot, our recommendation is to raise an issue as it could be a bug with `react-beautiful-dnd` or a setup issue.\n\nIf you do have use case where it makes sense to remove the drop animation you will need to add a [`transition-duration`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-duration) property of _almost_ `0s`. This will skip the drop animation.\n\nDo not make the `transition-duration` actually `0s`. It should be set at a near `0s` value such as `0.001s`. The reason for this is that if you set `transition-duration` to `0s` then a `onTransitionEnd` event will not fire - and we use that to know when the drop animation is finished.\n\n```js\nfunction getStyle(style, snapshot) {\n  if (!snapshot.isDropAnimating) {\n    return style;\n  }\n  return {\n    ...style,\n    // cannot be 0, but make it super tiny\n    transitionDuration: `0.001s`,\n  };\n}\n\nfunction TaskItem(props) {\n  const { task, index } = props;\n  return (\n    <Draggable draggableId={task.id} index={index}>\n      {(provided, snapshot) => (\n        <div\n          innerRef={provided.innerRef}\n          {...provided.draggableProps}\n          {...provided.dragHandleProps}\n          style={getStyle(provided.draggableProps.style, snapshot)}\n        >\n          {task.content}\n        </div>\n      )}\n    </Draggable>\n  );\n}\n```\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/how-we-detect-scroll-containers.md",
    "content": "# How we detect scroll containers\n\n> Generally you will not need to read this guide 😊. Detection of scroll containers \"should just work\". However, if you are having issues with it you can dig more deeply into this guide 🕵️‍\n\n`react-beautiful-dnd` will automatically detect the scroll containers for your application when a drag is starting. It does this by looking at the _computed_ `overflowX` and `overflowY` values of an element.\n\nIf `react-beautiful-dnd` finds an element that has a _computed_ `overflowX` or `overflowY` set to `scroll` or `auto` then that element is marked as a scroll container.\n\n## Background information about `overflow`\n\nThe css property `overflow` (and `overflow-x`, `overflow-y`) controls what happens when the content of an element is bigger than the elements size.\n\n> For more information about `overflow` you can check out the [CSS-Tricks overflow guide](https://css-tricks.com/almanac/properties/o/overflow/) or the [MDN overflow guide](https://developer.mozilla.org/en-US/docs/Web/CSS/overflow)\n\n### `overflow` values\n\n- `visible`: _(default)_ content will grow beyond boundary of any containing box without any clipping or scroll bars\n- `scroll`: clip overflow and always show a scroll bar, even if there is no content being overflowed\n- `auto`: clip overflow and only show scroll bar if there is any content in the overflow\n\n### Shorthand\n\nSetting `overflow: $value` is the same as setting `overflow-x: $value` and `overflow-y: $value`\n\n### _Computed_ values\n\nIf only one axis has `overflow-[x|y]: hidden` and the other is `visible` _(the default value)_ then it will be _computed_ as `auto`.\n\n> Computed value: as specified, except with visible/clip computing to auto/hidden (respectively) if one of overflow-x or overflow-y is neither visible nor clip\n>\n> - https://www.w3.org/TR/css-overflow-3/#overflow-properties\n\n## `<body>`\n\n`document.body` (`<body>`) is different from `document.documentElement` (the `<html>` element). Any scroll on the `html` element is considered a `window` scroll. Most of the time any scroll bar that would have appeared on the `body` will be merged with the `html` scroll bar. However, there are situations where they can have different scrollable areas.\n\n⚠️ We have not been able to find a reliable cross browser mechanism for detecting if a `body` has an independent scroll bar to the `html` element.\n\nThe `body` element _can_ be a scroll container if:\n\n1. the `body` element has `overflow-[x|y]` set to `auto` or `scroll` AND\n2. the `html` element has `overflow-x` or `overflow-y` set to anything other than `visible` (the default)\n\nThere seems to also be an additional requirement that we have not been able to accurately quantify regarding the relationship of the sizes of the `html` and `body` elements.\n\n### Want to help?\n\nWe have some playgrounds on `codepen` that can be a good start for digging into trying to find a reliable way to determine if `body` is an independent scroll container.\n\n- [scroll height on `body`](https://codepen.io/alexreardon/pen/RqLxPq)\n- [algorithm test](https://codepen.io/alexreardon/pen/RqLVNP?editors=1111)\n- [scroll height on a `div`](https://codepen.io/alexreardon/pen/xQXdKm?editors=1111)\n- [another `body` playground](https://codepen.io/alexreardon/pen/oQGeea?editors=1111) things get weird\n- [looking at browser apis](https://codepen.io/alexreardon/pen/dQZWpE?editors=1111)\n\n> Try changing the `overflow`, `height` and `width` properties on the `html` and `body` elements\n\nIt looks like when the `html` element has some `width` and `height` related properties set then this can impact things. However, finding a purely javascript solution for detecting this has alluded us so far\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/how-we-use-dom-events.md",
    "content": "# How we use DOM events\n\n> This page details how we use DOM input events, what we do with them, and how you can build things on top of our usage. **Generally you will not need to know this information** but it can be helpful if you are also binding your own event handlers to the window or to a _drag handle_.\n> ⚠️ Note: due to a [bug in webkit](https://bugs.webkit.org/show_bug.cgi?id=184250), particular events such as `mousemove` will not correctly set `event.defaultPrevented` to `true` when `event.preventDefault()` is called. You can follow progress on this issue [here](https://github.com/atlassian/react-beautiful-dnd/issues/413).\n\n## Prior knowledge\n\nThis page assumes a working knowledge of DOM events. For a good introduction to DOM events see:\n\n- [An introduction to browser events](https://javascript.info/introduction-browser-events)\n- [How event capturing and bubbling works](https://javascript.info/bubbling-and-capturing)\n\n## Safe event bindings\n\nWithout needing going into all the details below, here are the safest event handlers to build on top of `react-beautiful-dnd`:\n\n> These can be added on the _drag handle_, anywhere else higher on the tree or to the window directly.\n\n- `onClick`: the `event.defaultPrevented` property will be set to `true` if occurred as a part of the drag interaction. This is true even if the drag was not finished with a pre-click action such as `mouseup` or `touchend`. See [sloppy clicks and click prevention](/docs/sensors/mouse.md#sloppy-clicks-and-click-prevention-).\n- `onKeyDown`: the `event.defaultPrevented` property will be set to `true` if it was used as a part of a drag.\n\n## General rules\n\n### Event prevention\n\nWhen we use an input event as part of a drag and drop interaction we generally call `event.preventDefault()` on the event to opt out of standard browser behaviour for the event. We **do not stop** the propagation of events that we call `event.preventDefault()` on so even though we may use a `mousemove` event for dragging **we will not block** that event from being published (propagating) and received by your event handlers.\n\n- we use: `event.preventDefault()`\n- we do not use: `event.stopPropagation()`\n\nWe add all event handlers to the `window` in the [capture phase](https://javascript.info/bubbling-and-capturing#capturing). What this means is as long as you are applying your events handlers in the [bubbling phase](https://javascript.info/bubbling-and-capturing#bubbling) (which is the default for event handlers) then behaviour of events will be as described on this page.\n\nIn order to know if we have already used the event for the purpose of drag and drop you need to check the [`event.defaultPrevented`](https://developer.mozilla.org/en-US/docs/Web/API/Event/defaultPrevented) property.\n\nSo let's say you want to add a window `click` handler. You could do something like this:\n\n```js\nwindow.addEventListener('click', (event: MouseEvent) => {\n  // event has already been used for drag and drop\n  if (event.defaultPrevented) {\n    return;\n  }\n\n  doMyCoolThing();\n});\n```\n\n### Direct and indirect actions\n\nSome user events have a direct impact on a drag: such as a `mousemove` when dragging with a mouse or the **up arrow** <kbd>↑</kbd> `keydown` event while dragging with a keyboard. These direct events will have `event.preventDefault()` called on them to prevent their default browser behaviours. Some events indirectly impact a drag such as a `resize` event which cancels a drag. For events that indirectly impact a drag we do not call `event.preventDefault()` on them. Generally indirect events that impact drag are events that cancel a drag such as `resize` and `orientationchange` events.\n\n## Mouse dragging 🐭\n\n### Initial `mousedown`\n\n- `preventDefault()` **is called on `mousedown`** 😞\n\n> This is the only known exception to our rule set. It is unfortunate that it is the first one to appear in this guide!\n\nWhen the user first performs a `mousedown` on a _drag handle_ we are not sure if they are intending to click or drag. Ideally we would not call `preventDefault()` on this event as we are not sure if it is a part of a drag. However, we need to call `preventDefault()` in order to avoid the item obtaining focus as it has a `tabIndex`.\n\n### We are not sure yet if a drag will start\n\n- `preventDefault()` not called on `mousemove`\n\nThe user needs to move a small threshold before we consider the movement to be a drag. In this period of time we do not call `preventDefault()` on any `mousemove` events as we are not sure if they are dragging or just performing a [sloppy click](/docs/sensors/mouse.md#sloppy-clicks-and-click-prevention-)\n\n### The user has indicated that they are not mouse dragging\n\n- `preventDefault()` not called on the event that caused the pending drag to end (such as `mouseup` and `keydown`). Any `keydown` event that is firered while there is a pending drag will be considered an indirect cancel\n- `preventDefault()` is not called on the subsequent `click` event if there is one\n\n### A mouse drag has started and the user is now dragging\n\n- `preventDefault()` is called on `mousemove` events\n- `preventDefault()` is called on a few `keydown` events to prevent their standard browser behaviour\n- `preventDefault()` is not called on `keyup` events even if the `keydown` was prevented\n\n### A drag is ending\n\n- `preventDefault()` is called on a `mouseup` if it ended the drag\n- `preventDefault()` is called on a **escape** <kbd>esc</kbd> `keydown` if it ended the drag as it directly ended the drag\n- `preventDefault()` is called on the next `click` event regardless of how the drag ended. See [sloppy clicks and click prevention](/docs/sensors/mouse.md#sloppy-clicks-and-click-prevention-)\n- `preventDefault()` is not called on other events such as `resize` that indirectly ended a drag\n- `preventDefault()` is not called on `keyup` events even if they caused the drag to end\n\n## Touch dragging 📱\n\n> The logic for touch dragging works in a similar way to mouse dragging\n\n### Initial `touchstart`\n\n- `preventDefault()` is not called on `touchstart`.\n\nWhen a user presses their finger (or other input) on a `<Draggable />` we are not sure if they where intending to _tap_, _force press_, _scroll the container_ or _drag_. Because we do not know what the user is trying to do yet we do not call `preventDefault()` on the event.\n\n### The user has indicated that they are not touch dragging\n\n- `preventDefault()` is not called on any events\n\nA user can start a drag by holding their finger 👇 on an element for a small period of time 🕑 (long press). If the user moves during this time with `touchmove` then we do not call `preventDefault()` on the event.\n\nIt is possible to cancel a touch drag with over events such as an `orientationchange` or a `touchcancel`. We do not call `preventDefault` on these events.\n\n### A touch drag has started and the user is now dragging\n\n- `preventDefault()` is called on `touchmove` events\n\n✌️\n\n### A touch drag is ending\n\n- `preventDefault()` is called on `touchend`\n- `preventDefault()` is called on `touchcancel`\n- `preventDefault()` is called on an **escape** <kbd>esc</kbd> `keydown` as a direct cancel. `preventDefault()` is not call on any other `keydown` as it is an indirect cancel.\n- `preventDefault()` is not called on other events such as `orientationchange` that can cancel a drag\n\n### Force press\n\n> See our [force press guide](/docs/api/draggable.md)\n\n#### `<Draggable shouldRespectForcePress={false} />` (the default)\n\n> Opting out of force change events by default for a more consistent drag experience\n\n- `preventDefault()` is called on all `touchforcechange` events after a `touchstart` event is fired and a pending drag timer has started\n\n#### `<Draggable shouldRespectForcePress />`\n\n> Respecting standard force touch interactions\n\n- `preventDefault()` is not called on `touchforcechange` if a drag has not started yet\n- `preventDefault()` is not called on `touchforcechange` a drag that has started but no movement has occurred yet. The force press cancels the drag and is an indirect cancel.\n- `preventDefault()` is called after on `touchforcechange` a drag has started and a `touchmove` has fired. This is defensive as a force press `touchforcechange` should not occur after a `touchmove`.\n\n## Keyboard dragging 🎹\n\n> We only use `keydown` events for keyboard dragging so `keyup` events never have `preventDefault()` called on them\n\n### Drag start\n\n> `preventDefault()` is called on `keydown`\n\nUnlike mouse dragging a keyboard drag starts as soon as the user presses the **spacebar** <kbd>space</kbd>. This initial keyboard interaction has `event.preventDefault()` called on it.\n\n### While dragging\n\n- `preventDefault()` is called on a `keydown` event if the event is used as part of the drag (such as the **up arrow** <kbd>↑</kbd>)\n- `preventDefault()` is called on `keydown` events were we want to block the stanard browser behaviours (such as `enter` for submission)\n- `preventDefault()` is not called on `keydown` events that we do not use for the drag\n\n### Drag ending\n\n- `preventDefault()` is called on a `keydown` if it is the **spacebar** <kbd>space</kbd> key as it is dropping the item\n- `preventDefault()` is called on a `keydown` if it is the **escape** <kbd>esc</kbd> key as it is explicitly cancelling the drag\n- `preventDefault()` is not called on events that indirectly cancel a drag such as `resize` or `mousedown`.\n\n## Error events\n\n> Background: please see [Setup problem detection and error recovery](/docs/guides/setup-problem-detection-and-error-recovery.md).\n\nIf an `rbd` error is thrown and is caught by our `window` `error` listener, we will call `event.preventDefault()` on the error event to mark it as consumed. We do this as well as aborting the existing drag and logging warnings in development mode.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/identifiers.md",
    "content": "# Identifiers (ids)\n\n> `<Draggable /> > draggableId` and `<Droppable /> > droppableId`\n\nA `<Draggable />` and a `<Droppable />` have an id. These are `draggableId` and `droppableId` respectively.\n\n## String\n\nWe expect an id to be a `string`\n\n```js\ntype Id = string;\ntype DroppableId = Id;\ntype DraggableId = Id;\n```\n\n> More information: [types guide](/docs/guides/types.md)\n\n## Ids must be unique\n\nA id must uniquely identify a `<Draggable />` or `<Droppable />` within a `<DragDropContext />`. So if you have multiple connected lists, each `<Droppable />` needs to have a unique id and each `<Draggable />` needs to have a unique id, even if the item is in a different list.\n\nThe id must also be unique even if the `type` argument on the `<Droppable />` is different.\n\n## Ids must be a string\n\nRight now it is important that all `Id`'s be strings. `rbd` will throw an error if an `Id` is not a string.\n\n## Avoid reusing ids\n\nFor simplicity, it is best to avoid changing a `draggableId` or `droppableId` when a reorder occurs. The safest option is to associate an id with a piece of data and do not update the id between reorders.\n\nYou can change the `draggableId` or `droppableId` at any time except during a drag. Including after reorder. However, to avoid an exception you need to avoid reusing id's between two components. This can happen if you base a draggableId or droppableId on an index.\n\n> **Don't base an id on a index**\n\n### What this looks like internally\n\n#### 1. Update droppable\n\nold droppableId: \"droppable-0\"\nnew droppableId: \"droppable-1\"\n\n👉 delete reference to \"droppable-0\"\n👉 add reference to \"droppable-1\"\n\n#### 2. Update droppable\n\nold droppableId: \"droppable-1\" 😢\nnew droppableId: \"droppable-2\"\n\n👉 delete reference to \"droppable-1\" 😢 (will remove reference to our new \"droppable-1\")\n👉 add a reference to \"droppable-2\"\n\n#### 3. Update droppable\n\nold droppableId: \"droppable-1\" 💥\nnew droppableId: \"droppable-5\"\n\n👉 delete reference to \"droppable-1\" 💥 (will cause an exception because \"droppable-1\" is not found)\n\n## Could we change these rules?\n\nYep!\n\nBut we do things this way for simplicity and performance. Feel free to continue this conversation in a Github issue if you feel strongly about it.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/preset-styles.md",
    "content": "# Preset styles\n\nWe apply a number of **non-visible** styles to facilitate the dragging experience. We do this using combination of styling targets and techniques. It is a goal of the library to provide unopinioned styling. However, we do apply some reasonable `cursor` styling on drag handles by default. This is designed to make the library work as simply as possible out of the box. If you want to use your own cursors you are more than welcome to. All you need to do is override our cursor style rules by using a rule with [higher specificity](https://css-tricks.com/specifics-on-css-specificity/).\n\nHere are the styles that are applied at various points in the drag lifecycle:\n\n## In every phase\n\n### Always: drag handle\n\nStyles applied to: **drag handle element** using the `data-rbd-drag-handle-context-id` attribute.\n\nA long press on anchors usually pops a content menu that has options for the link such as 'Open in new tab'. Because long press is used to start a drag we need to opt out of this behavior\n\n```css\n-webkit-touch-callout: none;\n```\n\nWebkit based browsers add a grey overlay to anchors when they are active. We remove this tap overlay as it is confusing for users. [more information](https://css-tricks.com/snippets/css/remove-gray-highlight-when-tapping-links-in-mobile-safari/).\n\n```css\n-webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n```\n\nAvoid the _pull to refresh action_ and _delayed anchor focus_ on Android Chrome\n\n```css\ntouch-action: manipulation;\n```\n\n### Always: Droppable\n\nStyles applied to: **droppable element** using the `data-rbd-droppable-context-id` attribute.\n\nOpting out of the browser feature which tries to maintain the scroll position when the DOM changes above the fold. We already correctly maintain the scroll position. The automatic `overflow-anchor` behavior leads to incorrect scroll positioning post drop.\n\n```css\noverflow-anchor: none;\n```\n\n## Phase: resting\n\n### (Phase: resting): drag handle\n\nStyles applied to: **drag handle element** using the `data-rbd-drag-handle-context-id` attribute.\n\nAdding a cursor style to let the user know this element is draggable. You are welcome to override this.\n\n```css\ncursor: grab;\n```\n\n## Phase: dragging\n\n### (Phase: dragging): drag handle element\n\n**Styles applied using the `data-rbd-drag-handle-context-id` attribute**\n\nAn optimisation to avoid processing `pointer-events` while dragging. Also used to allow scrolling through a drag handle with a track pad or mouse wheel.\n\n```css\npointer-events: none;\n```\n\n### (Phase: dragging): Draggable element\n\n**Styles applied using the `data-rbd-draggable-context-id` attribute**\n\nThis is what we use to control `<Draggable />`s that need to move out of the way of a dragging `<Draggable />`.\n\n```css\ntransition: ${string};\n```\n\n### (Phase: dragging): Droppable element\n\n**Styles applied using the `data-rbd-droppable-context-id` attribute**\n\nWe apply `pointer-events: none` to a `<Droppable />` during a drag. This is technically not required as an optimisation. However, it gets around a common issue where hover styles are triggered during a drag. You are welcome to opt out of this one as it is it not required for functinality.\n\n```css\npointer-events: none;\n```\n\nYou are also welcome to extend this to every element under the body to ensure no hover styles for the entire application fire during a drag.\n\n```css\n/* You can add this yourself during onDragStart if you like */\nbody > * {\n  pointer-events: none;\n}\n```\n\n**Styles applied using inline styles**\n\nThis is described by the type `DraggableStyle`.\n\n### (Phase: dragging): body element\n\nWe apply a cursor while dragging to give user feedback that a drag is occurring. You are welcome to override this. A good point to do this is the `onDragStart` event.\n\n```css\ncursor: grabbing;\n```\n\nTo prevent the user selecting text as they drag apply this style\n\n```css\nuser-select: none;\n```\n\n## Phase: dropping\n\n### (Phase: dropping): drag handle element\n\n**Styles applied using the `data-rbd-drag-handle-context-id` attribute**\n\nWe apply the grab cursor to all drag handles except the drag handle for the dropping `<Draggable />`. At this point the user is able to drag other `<Draggable />`'s if they like.\n\n```css\ncursor: grab;\n```\n\n### (Phase: dropping): draggable\n\nSame as dragging phase\n\n## Phase: user cancel\n\n> When a user explicitly cancels a drag\n\nThis is the same as `Phase: dropping`. However we do not apply a `cursor: grab` to the drag handle. During a user initiated cancel we do not allow the dragging of other items until the drop animation is complete.\n\n## Preset styles are vendor prefixed\n\nAll styles applied are vendor prefixed correctly to meet the requirements of our [supported browser matrix](https://confluence.atlassian.com/cloud/supported-browsers-744721663.html). This is done by hand to avoid adding to react-beautiful-dnd's size by including a css-in-js library\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/reparenting.md",
    "content": "# Reparenting a `<Draggable />`\n\nThere are situations were you want to change the parent element of the dragging item while a drag is occurring. There are two approaches you can use to do this:\n\n1. Using our 1st class cloning API (required for [virtual lists](/docs/patterns/virtual-lists.md))\n2. Using your own `portal` with [`ReactDOM.createPortal`](https://reactjs.org/docs/portals.html)\n\n## Background\n\nWe leave elements in place when dragging. We apply `position: fixed` on elements when we are moving them around. This is quite robust and allows for you to have `position: relative | absolute | fixed` parents. However, unfortunately `position:fixed` is [impacted by `transform`](http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/) (such as `transform: rotate(10deg);`). This means that if you have a `transform: *` on one of the parents of a `<Draggable />` then the positioning logic will be incorrect while dragging. Lame! For most consumers this will not be an issue.\n\nTo get around this issue you need to move the dragging item to another location in the DOM - usually `document.body` or a direct descendent of it. This removes the impact of any parent styles on the `position:fixed`. The new parent is often referred to as a `portal`.\n\n## Cloning API\n\nOur cloning API is a first class way of reparenting a `<Draggable />`s into another DOM location while a drag is occurring. When using our cloning API the original `<Draggable />` is removed while the drag is being performed; a new _clone_ is rendered (using `renderClone`) into the container element (controllable using `getContainerForClone`)\n\n<img src=\"https://user-images.githubusercontent.com/2182637/66469796-439f7200-ead4-11e9-834e-c11d13dafab0.gif\" width=\"300px\" />\n\nGenerally you will want to render the same visual item as the one that is dragging, but you can render anything you want. The displacement will be based on the dimensions of the original item so we strongly recommend using an element that is exactly the same size.\n\nUsing our cloning API is required for compatibility with [virtual lists](/docs/patterns/virtual-lists.md).\n\n```js\nfunction List(props) {\n  const items = props.items;\n\n  return (\n    <Droppable\n      droppableId=\"droppable\"\n      renderClone={(provided, snapshot, rubric) => (\n        <div\n          {...provided.draggableProps}\n          {...provided.dragHandleProps}\n          ref={provided.innerRef}\n        >\n          Item id: {items[rubric.source.index].id}\n        </div>\n      )}\n    >\n      {provided => (\n        <div ref={provided.innerRef} {...provided.droppableProps}>\n          {items.map((item) => (\n            <Draggable draggableId={item.id} index={item.index}>\n              {(provided, snapshot) => (\n                <div\n                  {...provided.draggableProps}\n                  {...provided.dragHandleProps}\n                  ref={provided.innerRef}\n                >\n                  Item id: {item.id}\n                </div>\n              )}\n            </Draggable>\n          ))}\n        </div>\n      )}\n    </Droppable>\n  );\n}\n```\n\nYou can also reuse the `<Draggable /> | DraggableChildrenFn` if you want too!\n\n```js\nconst getRenderItem = (items) => (provided, snapshot, rubric) => (\n  <div\n    {...provided.draggableProps}\n    {...provided.dragHandleProps}\n    ref={provided.innerRef}\n  >\n    Item id: {items[rubric.source.index].id}\n  </div>\n);\n\nfunction List(props) {\n  const items = props.items;\n  const renderItem = getRenderItem(items);\n\n  return (\n    <Droppable\n      droppableId=\"droppable\"\n      renderClone={renderItem}\n    >\n      {(provided, snapshot) => (\n        <div ref={provided.innerRef} {...provided.droppableProps}>\n          {items.map((item) => (\n            <Draggable draggableId={item.id} index={item.index}>\n              {renderItem}\n            </Draggable>\n          ))}\n        </div>\n      )}\n    </Droppable>\n  );\n}\n```\n\n### `<Droppable /> | renderClone`\n\nThis function is called to get a clone to be rendered while dragging.\n\n```js\nrenderClone: ?DraggableChildrenFn\n```\n\n```js\ntype DraggableChildrenFn = (\n  Provided,\n  StateSnapshot,\n  DraggableRubric,\n) => Node | null;\n```\n\n> This is the same `type` as the child function for a `<Draggable />`. [See `<Draggable />` for more details](/docs/api/draggable.md).\n\n### `<Droppable /> | getContainerForClone`\n\nA function that is called to get the DOM element you would like to put the clone into. If function is not defined, then `document.body` is used\n\n```js\ngetContainerForClone: () => HTMLElement,\n```\n\n## Rolling your own `portal`\n\n⚠️ You are welcome to use your own `portal` solution if you want to from within your `<Draggable />`. Before we had a cloning API, reparenting needed to be done by using your own portal. It is now recommended that you use the cloning API.\n\nWe have created a [working example](https://react-beautiful-dnd.netlify.app/?selectedKind=Portals&selectedStory=Using%20your%20own%20portal&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybook%2Factions%2Factions-panel) that uses `ReactDOM.createPortal` directly to guide you. You can view the [source here](https://github.com/atlassian/react-beautiful-dnd/blob/master/stories/11-portal.stories.js).\n\nIf you are doing drag and drop reordering within a `<table>` we have created a portal section inside our [table guide](/docs/patterns/tables.md)\n\n## Performance ⚠️\n\nKeep in mind that anything that is reparented will be rendered from scratch. So you do not want to be moving large component trees into a `portal`: otherwise you will experience large UI jank. We do not recommend using reparenting out of the box because of this performance drawback.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/responders.md",
    "content": "# Responders\n\n> `<DragDropContext /> > Responders`\n\nResponders are top level application events that you can use to perform your own state updates, style updates, as well as to make screen reader announcements.\n\n> For more information about controlling the screen reader see our [screen reader guide](/docs/guides/screen-reader.md)\n\n## Life cycle ♻️\n\n1. `onBeforeCapture`: a drag is about to start and dimensions have **not been collected** from the DOM\n2. `onBeforeDragStart`: a drag is about to start and dimensions **have been captured** from the DOM\n3. `onDragStart`: A drag has started\n4. `onDragUpdate`: Something has changed during a drag\n5. `onDragEnd` **(required)**: A drag has ended. It is the responsibility of this responder to synchronously apply changes that has resulted from the drag\n\nWe try hard to ensure that an entire lifecycle is completed before a new one starts. If you find that not to be the case - it is a bug: please raise it!\n\n## Timing\n\n### Phase 1: capture\n\n- User initiates a drag\n- `onBeforeCapture` is called. You can add or remove `<Draggable />` and `<Droppable />` components or modify dimensions at this point.\n- dimensions for `<Draggable />` and `<Droppable />` components are captured from the DOM\n\n### Phase 2: start\n\n- `onBeforeDragStart` is called\n- `<Draggable />` and `<Droppable />` components are updated with initial `snapshot` values\n- `onDragStart` is called in the next event loop (via `setTimeout`)\n\n### Phase 3: updates\n\n- User moves a dragging item\n- `<Draggable />` and `<Droppable />` components are updated with latest `snapshot` values\n- `onDragUpdate` is called in the next event loop (via `setTimeout`)\n\n### Phase 4: drop\n\n- User drops a dragging item\n- There is an optional drop animation\n- When the drop animation finishes (or if there is ):\n  -- Any pending `onDragStart` and `onDragUpdate` calls are flushed\n  -- `<Draggable />` and `<Droppable />` components are updated with resting `snapshot` values.\n  -- You perform your reorder operation in `onDragEnd` which can result in a `setState` to update the order. The `<Draggable />` and `<Droppable />` snapshot updates and any `setState` caused by `onDragEnd` are batched together into the render cycle by `react ⚛️` 🤘\n\n## API\n\n### `onBeforeCapture`\n\nThis responder is called after we know a drag will start, but before any dimensions have been collected from the DOM. It is an opportunity to:\n\n- add or remove `<Draggable />` and `<Droppable />` components\n- modify element sizes\n\n> ⚠️ Misuse of this responder can lead to some terrible user interactions. You should not change the visible position of the dragging item to change as a result of your changes here.\n\n```js\n// We cannot give more information than this because things might change\ntype BeforeCapture = {|\n  draggableId: DraggableId,\n  mode: MovementMode,\n|};\n// No second 'provided' argument\nexport type OnBeforeCaptureResponder = (before: BeforeCapture) => mixed;\n\n// Otherwise the same type information as OnDragStartResponder\n```\n\n### `onBeforeDragStart`\n\n> The use cases for this responder is fairly limited\n\nOnce we have all of the information we need to start a drag we call the `onBeforeDragStart` function. This is called just before we update the `snapshot` values for the `<Draggable />` and `<Droppable />` components. At this point the application is not in a dragging state and so changing of props such as `isDropDisabled` will fail. The `onBeforeDragStart` responder is a good opportunity to do any dimension locking required for [table reordering](/docs/patterns/tables.md).\n\n- ✅ Can apply modifications to existing components to lock their sizes\n- ❌ Cannot remove or add any `<Draggable />` or `<Droppable />`\n- ❌ Cannot modify the sizes of any `<Draggable />` or `<Droppable />`\n\n```js\n// No second 'provided' argument\ntype OnBeforeDragStartResponder = (start: DragStart) => mixed;\n\n// Otherwise the same type information as OnDragStartResponder\n```\n\n### `provided: ResponderProvided`\n\n`onDragStart`, `onDragUpdate` and `onDragEnd` are given a `provided: ResponderProvided` object. This object has one property: `announce`. This function is used to synchronously announce a message to screen readers. If you do not use this function we will announce a default english message. We have created a [guide for screen reader usage](/docs/guides/screen-reader.md) which we recommend using if you are interested in controlling the screen reader messages for yourself and to support internationalisation. If you are using `announce` it must be called synchronously.\n\n```js\ntype ResponderProvided = {|\n  announce: Announce,\n|};\n\ntype Announce = (message: string) => void;\n```\n\n### `onDragStart`\n\n`onDragStart` will get notified when a drag starts. This responder is _optional_ and therefore does not need to be provided. It is **highly recommended** that you use this function to block updates to all `<Draggable />` and `<Droppable />` components during a drag. (See **Block updates during a drag** below)\n\n```js\n// While the return type is `mixed`, the return value is not used.\ntype OnDragStartResponder = (\n  start: DragStart,\n  provided: ResponderProvided,\n) => mixed;\n\n// supporting types\ntype DraggableRubric = {|\n  draggableId: DraggableId,\n  type: TypeId,\n  source: DraggableLocation,\n|};\n\ntype DragStart = {|\n  ...DraggableRubric,\n  mode: MovementMode,\n|};\n\ntype DraggableLocation = {|\n  droppableId: DroppableId,\n  // the position of the draggable within a droppable\n  index: number,\n|};\ntype Id = string;\ntype DraggableId = Id;\ntype DroppableId = Id;\ntype TypeId = Id;\n\ntype MovementMode = 'FLUID' | 'SNAP';\n```\n\n- `start.draggableId`: the id of the `<Draggable />` that is now dragging\n- `start.type`: the `type` of the `<Draggable />` that is now dragging\n- `start.source`: the location (`droppableId` and `index`) of where the dragging item has started within a `<Droppable />`.\n- `start.mode`: either `'SNAP'` or `'FLUID'`. This is a little bit of information about the type of movement that will be performed during this drag. `'SNAP'` mode is where items jump around between positions (such as with keyboard dragging) and `'FLUID'` mode is where the item moves underneath a pointer (such as mouse dragging).\n\n### `onDragUpdate`\n\n`onDragUpdate` is called whenever something changes during a drag. The possible changes are:\n\n- The position of the `<Draggable />` has changed\n- The `<Draggable />` is now over a different `<Droppable />`\n- The `<Draggable />` is now over no `<Droppable />`\n\nIt is important that you not do too much work as a result of this function as it will slow down the drag.\n\n```js\n// The return value of `mixed` is not used\ntype OnDragUpdateResponder = (\n  update: DragUpdate,\n  provided: ResponderProvided,\n) => mixed;\n\ntype DragUpdate = {|\n  // See above\n  ...DragStart,\n  // may not have any destination (drag to nowhere)\n  destination: ?DraggableLocation,\n  // populated when a draggable is dragging over another in combine mode\n  combine: ?Combine,\n|};\n\ntype Combine = {|\n  draggableId: DraggableId,\n  droppableId: DroppableId,\n|};\n```\n\n- `...DragStart`: _see above_\n- `update.destination`: the location (`droppableId` and `index`) of where the dragging item is now. This can be null if the user is currently not dragging over any `<Droppable />`.\n- `update.combine`: details of a `<Draggable />` that is currently being combine with. For more information see our [combining guide](/docs/guides/combining.md)\n\n### `onDragEnd` (required)\n\n> `react-beautiful-dnd` will throw an error if a `onDragEnd` prop is not provided\n\nThis function is _extremely_ important and has an critical role to play in the application lifecycle. **This function must result in the _synchronous_ reordering of a list of `Draggables`**\n\n```js\ntype OnDragEndResponder = (\n  result: DropResult,\n  provided: ResponderProvided,\n) => mixed;\n\ntype DropResult = {|\n  ...DragUpdate,\n  reason: DropReason,\n|};\n\ntype DropReason = 'DROP' | 'CANCEL';\n```\n\n- `...DragUpdate`: _see above_\n- `result.reason`: the reason a drop occurred. This information can be helpful in crafting more useful messaging in the `ResponderProvided` > `announce` function.\n\nIn the event of a cancelled drag, any `destination` or `combine` is set to `null`.\n\n## Persisting a reorder\n\nIf you need to persist a reorder to a remote data store - update the list synchronously (optimistically) on the client (such as through `setState()`) and fire off a request in the background to persist the change. If the remote save fails it is up to you how to communicate that to the user and update, or not update, the list.\n\n## No dimension changes during a drag\n\n`react-beautiful-dnd` does not support the changing of the size of any `<Draggable />` or `<Droppable />` after a drag has started. We build a virtual model of every `<Draggable />` and `<Droppable />` when a drag starts. We do not recollect these during a drag. So if you change the size of something: the user will see the updated size, but our virtual model will remain unchanged. If you want to modify dimensions before a drag starts you can use `onBeforeCapture`\n\n## Block updates during a drag\n\nIt is **highly** recommended that while a user is dragging that you block any state updates that might impact the amount of `<Draggable />`s and `<Droppable />`s, or their dimensions. Please listen to `onDragStart` and block updates to the `<Draggable />`s and `<Droppable />`s until you receive at `onDragEnd`.\n\n### How do you block updates?\n\nUpdate blocking will look different depending on how you manage your data. It is probably best to explain by example:\n\nLet's say you are using `React` component state to manage the state of your application. Your application state is tied to a REST endpoint that you poll every thirty seconds for data updates. During a drag you _should not_ apply any server updates that could effect what is visible.\n\nThis could mean:\n\n- stop your server poll during a drag\n- ignore any results from server calls during a drag (do not call `setState` in your component with the new data)\n\n### No update blocking will probably lead to bad times\n\nHere are a few poor user experiences that can occur if you change things _during a drag_:\n\n- If you increase the amount of nodes, then the library will not know about them and they will not be moved when the user would expect them to be.\n- If you decrease the amount of nodes, then there might be gaps and unexpected movements in your lists.\n- If you change the dimensions of any node, then it can cause the changed node as well as others to move at incorrect times.\n- If you remove the node that the user is dragging, then the drag will instantly end\n- If you change the dimension of the dragging node, then other things will not move out of the way at the correct time.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/screen-reader.md",
    "content": "# Screen reader guide\n\n> Because great features should be accessible for everyone\n\n`react-beautiful-dnd` ships with great screen reader support, in English, out of the box. If you just want to get started, then there's nothing you have to do. But if it's tailored messaging you're after, you have total control of that too.\n\nThis guide is here to help you create messaging that supports and delights your users. The screen reader experience is focused on keyboard interactions, but it's possible for a screen reader user to use any input type (for example mouse or touch).\n\n## On focus messaging\n\nA screen reader will read out information about [interactive content](https://www.w3.org/TR/html51/dom.html#interactive-content) when it is given browser focus (note: NVDA requires interactive content to have a `role` too causing it to be a `widget`). Interactive content has a number of _accessibility properties_ that are used to determine what a screen reader will announce when the element is given focus.\n\n<details>\n  <summary>A note about drag and drop accessibility</summary>\n  `rbd` does not use the HTML5 drag and drop API. It does not provide the experience we are trying to achieve. HTML5 drag and drop does not have a _great_ accessibility story out of the box as requires you to build a secondary widget for keyboard interactions.\n\nWe do not use the `aria-grabbed` and `aria-dropeffect` as they are [deprecated in WAI-ARIA 1.1](https://www.w3.org/TR/wai-aria-1.1/). There is currently no replacement in [WAI-ARIA 1.2](https://www.w3.org/TR/wai-aria-1.2/). For state information about a drag we rely on [live regions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) as an escape hatch to provide our own information to screen reader users during a drag.\n\n</details>\n\n<details>\n  <summary>Background on accessibility properties 📖</summary>\n\nScreen readers use these accessibility properties of a DOM element to tell assistive technologies what something is and how to describe it.\n\n| Attribute        | Description                                                                                                                                   | Notes                                                                                                                                                                                                                                                                                    | Examples                                                                                                                                                   |\n| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Name             | A way of identifying the element. Ideally these would be unique, but it doesn't need to be. Often the name is just the content of the element | This property is [computed](https://www.w3.org/TR/accname-1.1/#mapping_additional_nd_name). Can be based on visible text, or invisible attributes such as `aria-label`. The highest priority value will be picked as the name                                                            | `aria-label`, `aria-labelledby`, `title` (not recommended), element content                                                                             |\n| Role             | Main indicator for type of element. Can be inferred from semantic element type, or controlled by `role=\"button\"`                              | ARIA roles (the `role` attribute) communicate semantics to the accessibility API (and by extension, assistive technologies) only. Event handlers, focus styling, and interactivity must be added and managed as well.                                                                                                                                                                                                                                                                                        | `<div role=\"button\">Oh no</div>`                                                                                                                           |\n| Role description | Override the role text read out. Useful for adding a more specific role to a widget                                                           | Only applied on the rare occasions when HTML semantics and ARIA roles cannot describe what an element \"is\" in a meaningful way.                                                                                                                                                                                                                                                                                         | `<section aria-roledescription=\"slide\"> Quarterly Report</section>` Will announce as: _\"Quarterly Report, slide\"_ rather than _\"Quarterly Report, section\"_ |\n| Description      | Adds additional usage information about an element                                                                                            | This property is [computed](https://www.w3.org/TR/accname-1.1/#mapping_additional_nd_te). Typically controlled by `aria-describedby`<br />[\"Using the aria-describedby property to provide a descriptive label for user interface controls\"](https://www.w3.org/TR/WCAG20-TECHS/ARIA1.html) | `<label for=\"mob\">Mobile</label>`<br />`<input type=\"tel\" id=\"mob\" aria-describedby=\"mobLength\" />`<br />`<span id=\"mobLength\">Mobile must contain 10 digits</span>`                                                                                                                                                          |\n\n</details>\n\n> 👆This is actually pretty useful to know for accessibility generally 😊\n\nWhen a user focuses on a _drag handle_ (a _widget_) we need to let the user know that the item is draggable and how to start a drag.\n\nIdeally we would like the screen reader to announce:\n\n- `${name}, ${role}, ${description}`\n- `${name}, Draggable item, Press spacebar to lift`\n\nWe do not control the **name** of the element. The name is a way to identify the element and is usually the content of the element (see accessibility guide above)\n\n| Attribute               | Code                                                      | Notes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |\n| ----------------------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Interactive content** | `tabindex=\"0\"`                                            | By adding a `tabindex` to a _drag handle_ we are [marking it as interactive content](https://www.w3.org/TR/html51/dom.html#kinds-of-content-interactive-content) that a user can focus on, even if it is semanatically not an interactive element such as `div` or `span`.                                                                                                                                                                                                                                                                                                                                                          |\n| **Role**                | (not added by default - yet)                              | In order to correctly give a role like \"Draggable item\" we first need to add a `role` (such as `role=\"button\"`) and then give it a more accurate title with `aria-roledescription`. Given that we cannot use `aria-roledescription` for now (see below) we will not be using `role=\"button\"` yet. We plan on adding it in [soon](https://github.com/atlassian/react-beautiful-dnd/issues/1742)                                                                                                                                                                                                                                      |\n| **Role description**    | (not added by default - yet)                              | A role description adds more specific description of a widget. We would like the default to be `aria-roledescription=\"Draggable item\"`. However, this does not pass the current [Google lighthouse](https://developers.google.com/web/tools/lighthouse) accessibility audit. This is a bug in Google lighthouse, and should be fixed when they upgrade their `axe-core`. You are welcome to add the `aria-roledescription`, but keep in mind that lighthouse might punish you. We plan on adding the `aria-roledescription` in an upcoming release. [follow up issue](https://github.com/atlassian/react-beautiful-dnd/issues/1742) |\n| **Description**         | `DragHandleProps` <br/> `aria-describedby=\"${elementId}\"` | We are using the description of the element to provide usage instructions. The default usage instructions are `\"Press space bar to start a drag. When dragging you can use the arrow keys to move the item around and escape to cancel. Ensure your screen reader is in focus mode or forms mode\"`. We create a hidden element with this text which is pointed to be `aria-describedby`. If you want to change this text you will need to create your own hidden element with an `id` and point to that with `DragHandleProps` > `aria-describedby`.                                                                                |\n\n## Drag lifecycle announcements\n\nWe announce to screen reader users know what is going on during the drag and drop lifecycle. We provide default English messages for every stage of the drag and drop lifecycle out of the box. You can control these announcements by using the `announce` function is provided to each of the `<DragDropContext /> > Responder`s.\n\nMessages will be immediately read out. It's important to deliver messages immediately so your users have a fast and responsive experience. If you attempt to hold onto the `announce` function and call it later, it won't work and will just print a warning to the console. If you try to call announce twice for the same event, only the first will be read by the screen reader with subsequent calls to announce being ignored and a warning printed.\n\n> We use [live regions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) to do drag lifecycle announcements. They are a way of getting a screen reader to announce some text\n\n<details>\n  <summary>Some advice when using <code>announce</code></summary>\n\n### Use position, not index\n\n> `position = index + 1`\n\nWhen making a screen reader announcement we recommend announcing the position of an item in a list, rather than an index. index based listed start at `0`, where as position based lists start a `1`.\n\nIt reads more natural to hear \"You have moved an item to position 2\" than \"You have moved an item to index 1\"\n\n```js\nconst position = (index) => index + 1;\n\nconst startPosition = position(source.index);\nconst endPosition = destination ? position(destination.index) : null;\n```\n\n### Use names where possible\n\nAll of our built in screen reader messages use `id`'s to identify `<Draggable />` and `<Droppable />`s. You might want to consider replacing these with more readable names.\n\n> Potentially this could be a prop for `<Draggable />` and `<Droppable />` 🤔. Please raise an issue if you would like to see this happen!\n\n</details>\n\n### Drag starting\n\nWhen a user lifts a `<Draggable />` by using the `spacebar` we want to tell them a number of things.\n\n**Default message**: \"You have lifted an item in position `${startPosition}`.\"\n\nWe tell the user the following:\n\n- They have lifted the item\n- What position the item is in\n\nNotice that we don't tell them that they are in position `1 of x`. This is because we don't have access to the size of the list in the current api. This is especially true for [virtual lists](/docs/patterns/virtual-lists.md) where only a portion of the list is rendered at any one time. Feel free to add the the `1 of x` in your own messaging, and what list the item is in.\n\n**Message with more info**: \"You have lifted an item in position `${startPosition}` of `${listLength}` in the `${listName}` list.\"\n\nYou control the message printed to the user through the `<DragDropContext />` | `onDragStart` responder\n\n```js\nonDragStart = (start: DragStart, provided: ResponderProvided) => {\n  provided.announce('My super cool message');\n};\n```\n\n### Drag updates\n\nAfter a user has started a drag there are different scenarios that can spring from that, so we'll create different messaging for each scenario.\n\nWe can control the announcement through the `<DragDropContext />` | `onDragUpdate` responder.\n\n```js\nonDragUpdate = (update: DragUpdate, provided: ResponderProvided) => {\n  provided.announce('Update message');\n};\n```\n\n#### Scenario 1. Moved in the same list\n\nThe user has moved backwards or forwards within the same list, so we want to tell the user what position they are now in.\n\n**Default message**: \"You have moved the item from position `${startPosition}` to position `${endPosition}`\"\n\nThink about including of `${listLength}` in your messaging.\n\n#### Scenario 2. Moved into a different list\n\nThe user has moved on the cross axis into a different list, so we want to tell them a number of things.\n\n**Default message** \"You have moved the item from position `${startPosition}` in list `${source.droppableId}` to list `${destination.droppableId}` in position `${endPosition}`\"\n\nWe tell the user the following:\n\n- They have moved to a new list\n- Some information about the new list\n- What position they have moved from\n- What position they are now in\n\nThink about using friendlier text for the name of the droppable, and including the length of the lists in the messaging.\n\n**Message with more info**: \"You have moved the item from list `${sourceName}` in position `${sourcePosition}` of `${sourceLength}` to list `${destinationName}` in position `${newPosition}` of `${destinationLength}`\".\n\n#### Scenario 4. Combining in same list\n\nThe user has moved over another `<Draggable />` in [combine mode](/docs/guides/combining.md) in the same list\n\n**Default message** \"The item `${source.draggableId}` has been combined with `${combine.draggableId}`\"\n\n#### Scenario 5: Combining in different list\n\nThe user has moved over another `<Draggable />` in [combine mode](/docs/guides/combining.md) in a list that is not the list the dragging item started in\n\n**Default message** \"The item `${source.draggableId}` in list `${source.droppableId}` has been combined with `${combine.draggableId}` in list `${combine.droppableId}`\"\n\n#### Scenario 6. Over no drop target\n\nYou can't do this with a keyboard, but it's worthwhile having a message for this scenario, in case the user has a pointer for dragging.\n\n**Default message**: \"You are currently not dragging over a droppable area\".\n\nThink about how you could make this messaging friendlier and clearer.\n\n### Drag end\n\nThere are two ways a drop can happen. Either the drag is cancelled or the user drops the dragging item. You can control the messaging for these events using the `<DragDropContext /> > onDragEnd` responder.\n\n#### Scenario 1. Drag cancelled\n\nA `DropResult` object has a `reason` property which can either be `DROP` or `CANCEL`. You can use this to announce your cancel message.\n\n```js\nonDragEnd = (result: DropResult, provided: ResponderProvided) => {\n  if (result.reason === 'CANCEL') {\n    provided.announce('Your cancel message');\n    return;\n  }\n};\n```\n\n**Default message**: \"Movement cancelled. The item has returned to its starting position of `${startPosition}`\"\n\nWe tell the user the following:\n\n- The drag has been cancelled\n- Where the item has returned to\n\nThink about adding information about the length of the list, and the name of the list you have dropped into.\n\n**Message with more info**: \"Movement cancelled. The item has returned to its starting position `${startPosition}` of `${listLength}`\"\n\n#### Scenario 2. Dropped in the home list\n\n**Default message**: \"You have dropped the item. It has moved from position `${startPosition}` to `${endPosition}`\"\n\nWe tell the user the following:\n\n- They have completed the drag\n- What position the item is in now\n\n#### Scenario 3. Dropped on a foreign list\n\nThe messaging for this scenario should be similar to 'dropped in a home list', but we also add what list the item started in and where it finished.\n\n**Default message**: \"You have dropped the item. It has moved from position `${startPosition}` in list `${result.source.droppableId}` to position `${endPosition}` in list `${result.destination.droppableId}`\"\n\n#### Scenario 4. Dropped on another `<Draggable />` in the home list\n\nThe user has dropped onto another `<Draggable />` in [combine mode](/docs/guides/combining.md) in the same list that the drag started in\n\n**Default message**: \"You have dropped the item. The item `${source.draggableId}` has been combined with `${combine.draggableId}`\"\n\n#### Scenario 5. Dropped on another `<Draggable />` in a foreign list\n\nThe user has dropped onto another `<Draggable />` in [combine mode](/docs/guides/combining.md) in a list that is not the list the dragging item started in\n\n**Default message**: \"The item `${source.draggableId}` in list `${source.droppableId}` has been combined with `${combine.draggableId}` in list `${combine.droppableId}`\"\n\n#### Scenario 6. Dropped on no destination\n\nYou can't do this with a keyboard, but it's worthwhile having a message for this scenario, in case the user has a pointer for dragging.\n\n**Default message**: \"The item has been dropped while not over a droppable location. The item has returned to its starting position of \\${startPosition}\"\n\nWe tell the user the following:\n\n- They dropped over a location that is not droppable\n- Where the item has returned to\n\n## `VoiceOver` on Mac\n\nIf you are using Mac, test against the inbuilt `VoiceOver` screen reader. Here is a [quick start guide](https://www.imore.com/how-enable-voiceover-mac)\n\n> To start `VoiceOver`: <kbd>`cmd`</kbd> + <kbd>`f5`</kbd>\n\n## `NVDA` on Windows\n\nIf you are using Windows 7 SP 1 or later, [download the free NVDA screen reader](https://www.nvaccess.org/download/). Here is a very comprehensive [NVDA user guide](https://www.nvaccess.org/files/nvda/documentation/userGuide.html).\n\n## That's all folks\n\nWe hope you find this guide useful. Feel free to send in suggestions for scenarios you'd like to see included, or you might want to share your own default messages and grow the knowledge even further 🙂.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/setup-problem-detection-and-error-recovery.md",
    "content": "# When things mess up\n\n> \"People make mistakes. It's all a part of growing up and you never really stop growing\" - [Duke of nuts (Adventure time)](https://adventuretime.fandom.com/wiki/Duke_of_Nuts)\n\n- [Setup problem detection](#setup-problem-detection)\n- [Error recovery](#error-recovery)\n\n## Setup problem detection\n\nFor detectable setup problems `react-beautiful-dnd` will log some information `console` for development builds (`process.env.NODE_ENV !== 'production'`). These logs are stripped from productions builds to save kbs and to keep the `console` clean. Keep in mind, that any setup errors that are logged will cause things to **break** in fun and interesting ways - so it is worth ensuring that there are none.\n\n![dev only warnings](https://user-images.githubusercontent.com/2182637/46385261-98a8eb00-c6fe-11e8-9b46-0699bf3e6043.png)\n\n### Log rather than throw setup errors\n\nSome setup problems will cause errors. These are logged with `console.error`. We do not `throw` these errors. This is because an infinite loop can be created.\n\n<details>\n  <summary>More details if you are interested</summary>\n\nIf we threw setup errors, here is the infinite loop:\n\n1. Mount application\n2. Error detected (we usually do it in a `useEffect`) and thrown\n3. Error caught in `componentDidCatch`\n4. React tree recovered (remounted). Goto step 2.\n\nWe could work around this loop condition, but it would lead to conditionally throwing, and otherwise logging. It is also tricky to avoid double logging of errors. Given that we are trying to recover the React tree, there is not a lot of value in throwing any setup problem in the first place. So we just log the problem in the `console`.\n\n</details>\n\n### Production builds\n\nHere are a few guides on how to drop development only code from your production builds:\n\n- [React docs](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build)\n- [webpack instructions](https://webpack.js.org/guides/production/#specify-the-mode)\n- [rollup instructions](https://github.com/rollup/rollup-plugin-replace)\n\n### Disable logging\n\nIf you want to disable the warnings in _development_, you just need to update a flag on the `window`:\n\n```js\n// disable all react-beautiful-dnd development warnings\nwindow['__react-beautiful-dnd-disable-dev-warnings'] = true;\n```\n\nNote: this will not strip the messages from your production builds. See above for how to do that\n\n## Error recovery\n\nAn error can occur when:\n\n1. A `Error` is explicitly `throw`n by `react-beautiful-dnd` (an **rbd error**)\n2. A `Error` is `throw`n by something else (a **non-rbd error**)\n3. A **runtime error** occurs (eg `SyntaxError`, `TypeError`)\n\nReact [error boundaries](https://reactjs.org/docs/error-boundaries.html) do not catch all errors that can occur in `rbd`. So `rbd` uses a React error boundary as well as a `window` `error` event listener.\n\n### Error is caught by a `rbd` error boundary\n\n#### rbd error\n\n- cancel any active drag (no choice about this really, [an error unmounts everything under the error boundary](https://codesandbox.io/s/react-error-boundaries-rfyds))\n- log the error (non-production builds; will respect disabled logging)\n- recover the React tree\n\n#### non-rbd error or runtime error\n\n- cancel any active drag\n- **`throw` the error** for your own error boundary. We will not recover from errors that are not caused explicitly by `rbd`. A run time error (such as a `TypeError`) that is caused by `rbd` will not be recovered. `rbd` will only recover from explicitly thrown `rbd` errors.\n\n### Error is caught by `window` `error` listener\n\n#### rbd error\n\n- Cancel any active drag.\n- Log a warning stating that the drag has been cancelled (non-production builds; will respect disabled logging)\n- Log the error\n- Call `event.preventDefault()` on the event. This marks the event as consumed. See [how we use DOM events](/docs/guides/how-we-use-dom-events.md). It will also prevent any 'uncaught error' warnings in your `console`.\n\n#### non-rbd error or runtime error\n\n- Cancel any active drag.\n- Log a warning stating that the drag has been cancelled (non-production builds; will respect disabled logging)\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/types.md",
    "content": "# Types\n\n`react-beautiful-dnd` is typed using [`flowtype`](https://flow.org). This greatly improves internal consistency within the codebase. We also expose a number of public types which will allow you to type your javascript if you would like to. If you are not using `flowtype` this will not inhibit you from using the library. It is just extra safety for those who want it.\n\n## Public flow types\n\n### Ids\n\n```js\ntype Id = string;\ntype TypeId = Id;\ntype DroppableId = Id;\ntype DraggableId = Id;\n```\n\n### Responders\n\n```js\ntype Responders = {|\n  // optional\n  onBeforeCapture?: OnBeforeCaptureResponder,\n  onBeforeDragStart?: OnBeforeDragStartResponder,\n  onDragStart?: OnDragStartResponder,\n  onDragUpdate?: OnDragUpdateResponder,\n  // required\n  onDragEnd: OnDragEndResponder,\n|};\n\ntype OnBeforeCaptureResponder = (before: BeforeCapture) => mixed;\ntype OnBeforeDragStartResponder = (start: DragStart) => mixed;\ntype OnDragStartResponder = (\n  start: DragStart,\n  provided: ResponderProvided,\n) => mixed;\ntype OnDragUpdateResponder = (\n  update: DragUpdate,\n  provided: ResponderProvided,\n) => mixed;\ntype OnDragEndResponder = (\n  result: DropResult,\n  provided: ResponderProvided,\n) => mixed;\n\ntype BeforeCapture = {|\n  draggableId: DraggableId,\n  mode: MovementMode,\n|};\n\ntype DraggableRubric = {|\n  draggableId: DraggableId,\n  type: TypeId,\n  source: DraggableLocation,\n|};\n\ntype DragStart = {|\n  ...DraggableRubric,\n  mode: MovementMode,\n|};\n\ntype DragUpdate = {|\n  ...DragStart,\n  // populated if in a reorder position\n  destination: ?DraggableLocation,\n  // populated if combining with another draggable\n  combine: ?Combine,\n|};\n\n// details about the draggable that is being combined with\ntype Combine = {|\n  draggableId: DraggableId,\n  droppableId: DroppableId,\n|};\n\ntype DropResult = {|\n  ...DragUpdate,\n  reason: DropReason,\n|};\n\ntype DropReason = 'DROP' | 'CANCEL';\n\ntype DraggableLocation = {|\n  droppableId: DroppableId,\n  // the position of the droppable within a droppable\n  index: number,\n|};\n\n// There are two modes that a drag can be in\n// FLUID: everything is done in response to highly granular input (eg mouse)\n// SNAP: items snap between positions (eg keyboard);\ntype MovementMode = 'FLUID' | 'SNAP';\n```\n\n### Sensors\n\n```js\ntype Sensor = (api: SensorAPI) => void;\ntype SensorAPI = {|\n  tryGetLock: TryGetLock,\n  canGetLock: (id: DraggableId) => boolean,\n  isLockClaimed: () => boolean,\n  tryReleaseLock: () => void,\n  findClosestDraggableId: (event: Event) => ?DraggableId,\n  findOptionsForDraggable: (id: DraggableId) => ?DraggableOptions,\n|};\ntype TryGetLock = (\n  draggableId: DraggableId,\n  forceStop?: () => void,\n  options?: TryGetLockOptions,\n) => ?PreDragActions;\ntype TryGetLockOptions = {\n  sourceEvent?: Event,\n};\n```\n\n### Droppable\n\n```js\ntype DroppableProvided = {|\n  innerRef: (?HTMLElement) => void,\n  placeholder: ?ReactElement,\n  droppableProps: DroppableProps,\n|};\ntype DroppableProps = {|\n  // used for shared global styles\n  'data-rbd-droppable-context-id': ContextId,\n  // Used to lookup. Currently not used for drag and drop lifecycle\n  'data-rbd-droppable-id': DroppableId,\n|};\ntype DroppableStateSnapshot = {|\n  isDraggingOver: boolean,\n  draggingOverWith: ?DraggableId,\n  draggingFromThisWith: ?DraggableId,\n  isUsingPlaceholder: boolean,\n|};\n```\n\n### Draggable\n\n```js\ntype DraggableProvided = {|\n  innerRef: (?HTMLElement) => void,\n  draggableProps: DraggableProps,\n  dragHandleProps: ?DragHandleProps,\n|};\n\ntype DraggableStateSnapshot = {|\n  isDragging: boolean,\n  isDropAnimating: boolean,\n  dropAnimation: ?DropAnimation,\n  draggingOver: ?DroppableId,\n  combineWith: ?DraggableId,\n  combineTargetFor: ?DraggableId,\n  mode: ?MovementMode,\n|};\n\ntype DraggableProps = {|\n  style: ?DraggableStyle,\n  'data-rbd-draggable-context-id': string,\n  'data-rbd-draggable-id': string,\n  onTransitionEnd: ?(event: TransitionEvent) => void,\n|};\ntype DraggableChildrenFn = (\n  DraggableProvided,\n  DraggableStateSnapshot,\n  DraggableRubric,\n) => Node | null;\n|};\ntype DraggableStyle = DraggingStyle | NotDraggingStyle;\ntype DraggingStyle = {|\n  position: 'fixed',\n  top: number,\n  left: number,\n  boxSizing: 'border-box',\n  width: number,\n  height: number,\n  transition: string,\n  transform: ?string,\n  zIndex: number,\n  opacity: ?number,\n  pointerEvents: 'none',\n|};\ntype NotDraggingStyle = {|\n  transition: ?string,\n  transition: null | 'none',\n|};\n\ntype DragHandleProps = {|\n  onFocus: () => void,\n  onBlur: () => void,\n  onMouseDown: (event: MouseEvent) => void,\n  onKeyDown: (event: KeyboardEvent) => void,\n  onTouchStart: (event: TouchEvent) => void,\n  tabIndex: number,\n  'data-rbd-drag-handle-draggable-id': string,\n  'data-rbd-drag-handle-context-id': string,\n  role: string,\n  'aria-describedby': string,\n  draggable: boolean,\n  onDragStart: (event: DragEvent) => void,\n|};\n\ntype DropAnimation = {|\n  duration: number,\n  curve: string,\n  moveTo: Position,\n  opacity: ?number,\n  scale: ?number,\n|};\n```\n\n## Using the flow types\n\nThe types are exported as part of the module so using them is as simple as:\n\n```js\nimport type { DroppableProvided } from 'react-beautiful-dnd';\n```\n\n## Typescript\n\nIf you are using [TypeScript](https://www.typescriptlang.org/) you can use the community maintained [DefinitelyTyped type definitions](https://www.npmjs.com/package/@types/react-beautiful-dnd). [Installation instructions](http://definitelytyped.org/).\n\nHere is an [example written in typescript](https://github.com/abeaudoin2013/react-beautiful-dnd-multi-list-typescript-example).\n\n## Sample application with flow types\n\nWe have created a [sample application](https://github.com/alexreardon/react-beautiful-dnd-flow-example) which exercises the flowtypes. It is a super simple `React` project based on [`react-create-app`](https://github.com/facebookincubator/create-react-app). You can use this as a reference to see how to set things up correctly.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/guides/using-inner-ref.md",
    "content": "# Using `innerRef`\n\n> If you have not used `ref`'s before, please take a look at the [`React`: Refs and the DOM guide](https://reactjs.org/docs/refs-and-the-dom.html) on their documentation website.\n\nOur `<Draggable />` and `<Droppable />` components both require a [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) to be provided to them. This is done using the `innerRef` property on the `DraggableProvided` and `DroppableProvided` objects.\n\n```diff\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => (\n    <div\n+      ref={provided.innerRef}\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n    >\n      <h4>My draggable</h4>\n    </div>\n  )}\n</Draggable>;\n```\n\n```diff\n<Droppable droppableId=\"droppable-1\">\n  {(provided, snapshot) => (\n    <div\n+     ref={provided.innerRef}\n      {...provided.droppableProps}\n    >\n      <h2>I am a droppable!</h2>\n      {provided.placeholder}\n    </div>\n  )}\n</Droppable>;\n```\n\n## Not all `ref`s are created equal\n\nConfusion can arise because of how the `ref` callback works in `React`.\n\nOn a _Component_ such as `<Person />` the `ref` callback will return the _instance_ of the `Person` component.\n\nOn a _ReactElement_ such as `<div />` the `ref` callback will return the _HTMLElement_ that the _ReactElement_ is tied to.\n\n[See on `codesandbox.io`](https://codesandbox.io/s/xok96ovo8p)\n\n```js\nclass Person extends React.Component {\n  state = {\n    sayHello: false,\n  };\n  sayHello() {\n    this.setState({\n      sayHello: true,\n    });\n  }\n  render() {\n    if (this.state.sayHello) {\n      return <div {...this.props}>Hello</div>;\n    }\n\n    return <div {...this.props}>'I am a person, I think..'</div>;\n  }\n}\n\nclass App extends React.Component {\n  setPersonRef = (ref) => {\n    this.personRef = ref;\n\n    // When the ref changes it will firstly be set to null\n    if (this.personRef) {\n      // personRef is an instance of the Person class\n      this.personRef.sayHello();\n    }\n  };\n  setDivRef = (ref) => {\n    this.divRef = ref;\n\n    if (this.divRef) {\n      // div ref is a HTMLElement\n      this.divRef.style.backgroundColor = 'lightgreen';\n    }\n  };\n  render() {\n    return (\n      <React.Fragment>\n        <Person ref={this.setPersonRef} />\n        <div ref={this.setDivRef}>hi there</div>\n      </React.Fragment>\n    );\n  }\n}\n```\n\n## A common error 🐞\n\nTake a look at this example:\n\n```js\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => (\n    <Person\n      ref={provided.innerRef}\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n    />\n  )}\n</Draggable>\n```\n\nWhile it looks correct, it **will cause your application to explode 💥!**\n\nThis is because `react-beautiful-dnd` expects the `provided.innerRef` function for a `<Draggable />` and a `<Droppable />` to be called with the DOM node of the component, and not the _instance_ of the class. In this example we are calling `provided.innerRef` with an _instance_ of `Person` and not the underlying DOM node.\n\n## Exposing a DOM ref from your Component 🤩\n\nA simple way to expose the _HTMLElement_ of your component is to **create your own `innerRef` prop**:\n\n```js\nclass Person extends React.Component {\n  render() {\n    return (\n      <div {...this.props} ref={this.props.innerRef}>\n        I am a person, I think..\n      </div>\n    );\n  }\n}\n```\n\n> Note, the name `innerRef` is just a convention. You could call it whatever you want for your component. Something like `domRef` is fine.\n\nYou can then correctly supply the DOM node to a `<Draggable />` or `<Droppable />`\n\n```diff\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => (\n    <Person\n-      ref={provided.innerRef}\n+      innerRef={provided.innerRef}\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n    >\n      <h4>My draggable</h4>\n    </Person>\n  )}\n</Draggable>\n```\n\n> Note, if you are using **styled-components v4** the `innerRef` prop was replaced with just `ref`. It uses the [React 16 `forwardRef` API](https://reactjs.org/docs/forwarding-refs.html) to pass the DOM node through the `ref` callback rather than the instance of the Component. Similarly, **emotion v10+** the `innerRef` prop was deprecated in favor `ref` with a `forwardRef` passthrough.\n\n⚠️ This approach will cause a `React` warning as we are spreading all of the props of the component onto the DOM node. `{...this.props}` This includes the `innerRef` prop which `React` does not like you adding to an element. So you can set things up like this:\n\n```diff\nclass Person extends React.Component {\n  render() {\n-    return (\n-      <div {...this.props} ref={this.props.innerRef}>\n-        I am a person, I think..\n-      </div>\n-    );\n  }\n}\nclass Person extends React.Component {\n  render() {\n+    const { provided, innerRef } = this.props;\n+    return (\n+      <div\n+        {...provided.draggableProps}\n+        {...provided.dragHandleProps}\n+        ref={innerRef}\n+      >\n+        I am a person, I think..\n+      </div>\n+    );\n  }\n}\n\n<Draggable draggableId=\"draggable-1\" index={0}>\n  {(provided, snapshot) => (\n    <Person\n      innerRef={provided.innerRef}\n-      {...provided.draggableProps}\n-      {...provided.dragHandleProps}\n+      provided={provided}\n    />\n  )}\n</Draggable>\n```\n\nIf you also need to use the _HTMLElement_ within your _Component_ you can have a more powerful ref setting approach:\n\n```js\nclass Person extends React.Component {\n  setRef = (ref) => {\n    // keep a reference to the dom ref as an instance property\n    this.ref = ref;\n    // give the dom ref to react-beautiful-dnd\n    this.props.innerRef(ref);\n  };\n  render() {\n    const { provided, innerRef } = this.props;\n    return (\n      <div\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        ref={this.setRef}\n      >\n        I am a person, I think..\n      </div>\n    );\n  }\n}\n```\n\n## Putting it all together\n\nHere is an example that shows off the learnings presented in this guide: https://codesandbox.io/s/v3p0q71qn5\n\n## A note on SVG's\n\n`react-beautiful-dnd` does not support the dragging of `<svg>` elements. Wrap your `<svg>` in a `HTMLElement` such as `<span>` or `<div>` for great accessibility and cross browser support. See our [using SVGs guide](https://github.com/atlassian/react-beautiful-dnd/tree/master/docs/guides/using-svgs.md) for more information.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/patterns/multi-drag.md",
    "content": "# Multi drag\n\n> This page is designed to guide you through adding your own multi drag experience to your `react-beautiful-dnd` lists.\n\nDragging multiple `<Draggable />`s at once (multi drag) is currently a pattern that needs to be built on top of `react-beautiful-dnd`. We have not included the interaction into the library itself. This is done because a multi drag experience introduces a lot of concepts, decisions and opinions. We have done a lot of work to ensure there is a standard base of [dom event management](/docs/guides/how-we-use-dom-events.md) to build on.\n\nWe have created a [reference application](https://react-beautiful-dnd.netlify.app/?path=/story/multi-drag--pattern) ([source](/stories/src/multi-drag)) which implements this multi drag pattern. The application is fairly basic and does not handle performance in large lists well. As such, there is are [a few performance recommendations](#performance) that we suggest you also add on to our reference application if you want to support lists greater than 50 in size.\n\n![multi drag demo](https://user-images.githubusercontent.com/2182637/37322724-7843a218-26d3-11e8-9ebb-8d5853387bb3.gif)\n\n## Experience\n\nWe have decided on a simple, but very flexible and scalable multi drag pattern to start with. It is not as _beautiful_ as our standard drag interactions - but it is a great base to build from and will scale across many problem spaces.\n\n## User experience\n\nWe can break the user experience down in three phases.\n\n1. [**Selection**](#selection): The user selects one or more items.\n2. [**Dragging**](#dragging): The user drags one item as a representation of the whole group.\n3. [**Dropping**](#dropping): The user drops an item into a new location. We move all of the selected items into the new location\n\n## Announcements\n\nKeep in mind that internally `react-beautiful-dnd` is not aware of multi drag. Therefore it is advised that you use the `ResponderProvided > Announce` to announce meaningful screen reader messages for a multi drag. See our [screen reader guide](/docs/guides/screen-reader.md) for details on how to control screen reader messaging.\n\n## Selection\n\nBefore a drag starts we need to allow the user to _optionally_ select a number of `<Draggable />`s to drag. When an item is selected you should apply a style update to the `<Draggable />` such as a background color change to indicate that the item is selected.\n\n### Selection interaction recommendations\n\n> These interactions are based on the Mac OSX [_Finder_](https://support.apple.com/en-au/HT201732) (file browser) application.\n\n### Action: toggle section\n\nIf a user clicks on an item the selected state of the item should be toggled. Additionally, the selected state of the item should be updated when the user presses **enter** <kbd>⏎</kbd> key. The **enter** <kbd>⏎</kbd> key is quite nice because we do not use it for lifting or dropping - we use **spacebar** <kbd>space</kbd> for those.\n\n![toggle-selection](https://user-images.githubusercontent.com/2182637/37323080-6d67f04a-26d5-11e8-8bc1-8ff5178018bc.gif)\n\n#### `onClick` event handler\n\n- Attach an `onClick` handler to your _drag handle_ or `<Draggable />`\n- Only toggle selection if the user is using the [`primaryButton`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button) (`event.button === 0`)\n- Prevent the default action on the `click` as you are using it for selection (it is only useful to call `event.preventDefault()` to avoid _selection clearing_)\n\n#### Keyboard event handler\n\n- When the user presses **enter** <kbd>⏎</kbd> toggle the selection of the item\n- **Option 1**: Attach an `onKeyDown` handler to your _drag handle_ or `<Draggable />`\n- **Option 2**: Attach an `onKeyUp` handler to your _drag handle_. `keyup` events will not have their default action prevented so you will not be able to check `event.defaultPrevented` to see if the keypress was used for a drag. If you are only using the **enter** <kbd>⏎</kbd> key in your event handler then you should be fine as that is not used as a part of dragging.\n- Prevent the default action on the `keydown` / `keyup` event if you are toggling selection as you are using it for selection and you want to opt out of the standard browser behaviour - and also provide a clue that this event has been used.\n\n#### Toggle selection behaviour\n\n- If the item was not previously selected - make it the only selected item\n- If the item was previously selected **and was not a part** of a selection group: unselect the item\n- If the item was previous selected **and was a part** of a selection group: make it the only selected item\n\n### Action: toggle selection in a group\n\nThis is providing the ability for a user to add or remove items to a selection group.\n\n![toggle-selection-in-a-group](https://user-images.githubusercontent.com/2182637/37323084-73c31eec-26d5-11e8-8c5c-7a1fc82f098b.gif)\n\n#### Event handlers\n\nWe perform this action if the user performs a `click` or presses the **enter** <kbd>⏎</kbd> key in addition to holding the appropriate modifier key to toggle item selection for their operating system.\n\n> Note: On Macintosh systems, this is the `⌘ Command` key. On Windows systems, this is the `⎈ Ctrl` key.\n\n#### Toggle selection in a group behaviour\n\n- If the item was not selected then add the item to the selected items\n- If the item was previously selected then remove it from the selected items.\n\n### Action: multi select\n\nThe ability to click on an item further down a list and select everything inbetween.\n\n#### Event handlers\n\nWe perform this action if the user performs a `click` or presses the **enter** <kbd>⏎</kbd> key in addition to holding the the [shift key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/shiftKey).\n\n### multi select: behaviour\n\nWith this action the user is able to select multiple items using a single command. This behaviour is the most complex. It deviates slightly from the `MacOSX` behaviour for simplicity.\n\n![multi-select](https://user-images.githubusercontent.com/2182637/37323230-7a108d60-26d6-11e8-84b1-1a608bab3686.gif)\n\n#### Nothing was selected\n\nIf nothing is previously selected when the user triggers this action: simply set the selected item as the only selected item.\n\n#### Selecting to a different list\n\nIf the user is selecting to an item that is in a different list to the last selected item: clear all the selected items and select everything up to the index of the selected to item in the new list\n\n#### Selecting to in the same list\n\n- Select everything between the newly selected item and the last selected item.\n\n> MacOSX is a little more complicated than this, but for our purposes this seems like a good default\n\n- If dropping on the same index as we started on - we do not need to do anything\n\n### Event logic map\n\nHere is an example of composing the above event handling logic in a component\n\n```js\nclass Task extends Component<Props> {\n  onKeyDown = (event: KeyboardEvent, snapshot: DraggableStateSnapshot) => {\n    // already used\n    if (event.defaultPrevented) {\n      return;\n    }\n\n    if (snapshot.isDragging) {\n      return;\n    }\n\n    if (event.keyCode !== keyCodes.enter) {\n      return;\n    }\n\n    // we are using the event for selection\n    event.preventDefault();\n\n    this.performAction(event);\n  };\n\n  // Using onClick as it will be correctly\n  // preventing if there was a drag\n  onClick = (event: MouseEvent) => {\n    if (event.defaultPrevented) {\n      return;\n    }\n\n    if (event.button !== primaryButton) {\n      return;\n    }\n\n    // marking the event as used\n    event.preventDefault();\n\n    this.performAction(event);\n  };\n\n  // Determines if the platform specific toggle selection in group key was used\n  wasToggleInSelectionGroupKeyUsed = (event: MouseEvent | KeyboardEvent) => {\n    const isUsingWindows = navigator.platform.indexOf('Win') >= 0;\n    return isUsingWindows ? event.ctrlKey : event.metaKey;\n  };\n\n  // Determines if the multiSelect key was used\n  wasMultiSelectKeyUsed = (event: MouseEvent | KeyboardEvent) => event.shiftKey;\n\n  performAction = (event: MouseEvent | KeyboardEvent) => {\n    const {\n      task,\n      toggleSelection,\n      toggleSelectionInGroup,\n      multiSelectTo,\n    } = this.props;\n\n    if (this.wasToggleInSelectionGroupKeyUsed(event)) {\n      toggleSelectionInGroup(task.id);\n      return;\n    }\n\n    if (this.wasMultiSelectKeyUsed(event)) {\n      multiSelectTo(task.id);\n      return;\n    }\n\n    toggleSelection(task.id);\n  };\n\n  render() {\n    return (\n      <Draggable draggableId={task.id} index={this.props.index}>\n        {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n          <Container\n            innerRef={provided.innerRef}\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n            onClick={this.onClick}\n            onKeyDown={(event: KeyboardEvent) =>\n              this.onKeyDown(event, snapshot)\n            }\n          >\n            {task.content}\n          </Container>\n        )}\n      </Draggable>\n    );\n  }\n}\n```\n\n### Action: clear selection\n\n#### `window` `click` handler\n\nWe add a `click` handler to the `window` to detect for a click that is not on a `<Draggable />`. We call `preventDefault` in our selection `onClick` handler so `click` events used for selection will have the `event.defaultPrevented` property set to `true`. Additionally, if a drag occurred the default `click` action [will be prevented](/docs/sensors/mouse.md#sloppy-clicks-and-click-prevention-). So if we receive a `click` event on the window that has not has `event.defaultPrevented` set to false we clear the current selection.\n\n#### `window` `keydown` handler\n\nThis event handler operates in a similar way to the _`window` `click` handler_ described above. If a `keydown` event that is not prevented and is the **escape** key then we clear the current selection. The **escape** `keydown` event will be prevented if it is used to cancel a drag.\n\n### Mobile selection\n\nRather than performing a 'toggle selection' action when the user presses an item using a touch input, the 'toggle selection in group' should be performed. On a touch device there is no way of adding extra input such as a `metaKey` or `shiftKey`.\n\nYou can use the `onTouchEnd` event on the element to trigger this action. As with the other handlers - only trigger a selection changed if the `event.defaultPrevented` property is `false`. When fire an action be sure to call `event.preventDefault()` to mark the event as used.\n\nYou will also want to add a `window` `touchend` handler which works in the same way as the `click` and `keydown` `window` handlers. This handler will be used to unselect everything when the user performs a `touchend` that is not a part of a drag or a selection.\n\nWe use `touchend` because that is part of the drag and drop lifecycle. We do not call `preventDefault()` on a `touchstart` as we do not know at that point if the event is a part of a drag or not. [More information](/docs/guides/how-we-use-dom-events.md).\n\n### Action: tem walking\n\n> This is not implemented in our reference application\n\nYou are welcome to build a selection walking keyboard interaction pattern. You could use the arrow keys (<kbd>↑</kbd> <kbd>↓</kbd> <kbd>→</kbd> <kbd>←</kbd>) to move the selection around. Ideally these movements would also shift browser focus so that a user can press **spacebar** <kbd>space</kbd> to lift immediately.\n\n### Action: mouse selection box\n\n> This is not implemented in our reference application\n\nYou could build your own abstraction (or use some elses) to add the idea of a selection box. You could use this to allow a user to drag a box around the items they want to select. [Example](http://threedubmedia.com/code/event/drop/demo/selection)\n\n## Dragging\n\nWe need to do one check in `onDragStart`. If the user is starting to drag something that is not selected then we need to clear the selection.\n\nAs the drag starts we need to add a few visual affordances:\n\n1.  Add a count to the dragging item to indicate how many items this drag is representative of. If only a single item is dragging then do not show a count.\n2.  Change the appearance of the selected items that are not dragging to a greyed out / disabled state. This can be a [performance](#performance) issue at scale.\n\nWe do not remove the selected items from the list. If we remove the items completely that can change the dimensions of the list which can lead to list collapsing and scroll jumps. If we leave them in the list and make them invisible then there are big blank sections in a list that have no meaning and can be confusing to interact with. Therefore we recommend leaving the items in the list and giving them a visual change.\n\n## Dropping\n\nAs much as possible we want to preserve the selection that the user had before the drag started. That way they could continue to move the same items around after the drag.\n\n### No change\n\nThis occurs when you cancel the drag, drop nowhere or drop in the same location. No reordering is required and you can keep the previous selection\n\n### Dropping in a different list\n\nWhen moving the items to the new list they should be inserted into the new list at the index in which the dragging item was dropped. We suggest the moved items be placed in the following order:\n\n1.  Move the selected item to the first position\n\nThis is done to ensure that the item the user is dragging does not disappear suddenly on drop.\n\n2.  Order by the items natural indexes regardless of list. For example if 'item alpha' started in column 1 of index 2 and 'item beta' started in column 2 of index 2 then 'item beta' should be placed before 'item alpha'\n\nThis gives priority to original index. However, you might want to give priority to list. So that items selected in previous lists go before items selected in subsequent lists.\n\n3.  In the event of a tie then sort by the order in which the item was selected.\n\nThis strategy does change the order of items semantically: specifically step 1 which always moves the selected item to the top. If you do not want this you do not have to do it - however it is much nicer visually and helps to keep the user grounded on a drop.\n\n### Dropping in the same list\n\nThe goal is to move the selected items to their new location. We want to insert all the items in at the index at which the dragging item was dropped. As with the strategy above we suggest the following order for the dropped items:\n\n1.  Move the selected item to the first position\n2.  Order the rest by their natural index\n\n## Performance\n\nDoing a multi drag interaction in a performant way can be challenging. The core thing you want to do is to avoid calling `render()` on components that do not need to update. The current best practice for this is to use [`redux`](https://github.com/reactjs/redux) in combination with [`react-redux`](https://github.com/reactjs/react-redux), [`reselect`](https://github.com/reactjs/reselect) and [`memoize-one`](https://github.com/alexreardon/memoize-one). We recommend you take a look at these resources:\n\n- [An introduction to React performance](https://medium.com/@alexandereardon/performance-optimisations-for-react-applications-b453c597b191)\n- [How `redux` can help you write fast apps](https://medium.com/@alexandereardon/performance-optimisations-for-react-applications-round-2-2042e5c9af97)\n- [Advanced optimisations](https://medium.com/@alexandereardon/dragging-react-performance-forward-688b30d40a33)\n\n### Selection state change\n\nIn response to a selection change you want to call `render` on the minimum amount of `<Draggable />` and `<Droppable />` components as possible. In our example application whenever the selection changes we re-render the entire tree. This approach will not scale. Therefore we suggest using the optimisations listed above.\n\nIn the event of a 'unselect all' action you might need to render a lot of components at once to clear their selected styles. For most usages this will be fine. If you want to go further you will need to avoid calling `render` for selection style changes.\n\n- You could look into using the [dynamic shared styles pattern](https://medium.com/@alexandereardon/dragging-react-performance-forward-688b30d40a33).\n- You could apply a **unique** data attribute to each item and then apply the _selected_ style to it using selectors dynamically in a parent component.\n\nAdditionally, when a drag starts we can also update the appearance of a lot of `Draggables` at once. Therefore you will need to solve this problem in the same was as the 'unselect all' action.\n\n### Drag count\n\nWhen dragging you need to display a count of the items that are dragging. In our example we provide this information down by re-rendering the tree. As with selection changes it would be good to only render the item that needs the change. You could publish this information down using `redux` and `redux-select`. For this particular problem you might be able to get away with [`unstated`](https://github.com/jamiebuilds/unstated) or the new [React 16.3 `Context` api](https://github.com/reactjs/rfcs/blob/master/text/0002-new-version-of-context.md).\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/patterns/tables.md",
    "content": "# Tables\n\n| Benefits of using `<table>`                      | Provider                 |\n| ------------------------------------------------ | ------------------------ |\n| Clean way of displaying tabular data             | Browser                  |\n| Great browser support                            | Browser                  |\n| Can copy paste the table into other applications | Browser                  |\n| Can reorder items in the table!                  | `react-beautiful-dnd` 😎 |\n\n`react-beautiful-dnd` requires no additional wrapping elements to create `<Draggable />` and `<Droppable />` components. Therefore it is possible to have a `<table>` that has valid HTML as well as supporting drag and drop.\n\n> We have not found a way to achieve semantic reordering of table columns at this stage. This is because there is no one element that represents a table column - rather, a column is a result of cell placements within repeating rows. As such as cannot wrap a `<Draggable />` around a 'column' in order to make it draggable. PR's to this guide are welcome if you find a working approach!\n\n## Strategies\n\nThere are two strategies you can use when reordering tables.\n\n1.  Fixed layouts (faster and simpler)\n2.  Dimension locking (slower but more robust)\n\n### Strategy 1: fixed layouts\n\nIn order to use this strategy the widths of your columns need to be fixed - that is, they will not change depending on what content is placed in the cells. This can be achieved with either a `table-layout: fixed` or `table-layout: auto` as long as you manually set the width of the cells (eg `50%`).\n\nThe only thing you need to do is set `display: table` on a `<Draggable />` row while it is dragging.\n\n[See example code here](https://react-beautiful-dnd.netlify.app/?selectedKind=Tables&selectedStory=with%20fixed%20width%20columns&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybook%2Factions%2Factions-panel)\n\nSome users have experienced issues using the `table-layout` and `display: table` approach. Specifically, that approach of fixed layouts doesn't keep the styling once an element is being dragged. An alternative is to not set `table-layout` or `display: table` when `<Draggable />` is dragging, but rather just set the `width` of each `<td>` permanently. This avoids the need to use any event responders. E.g. in the `<Draggable />`, set each `<td>` to `width: 100px` with inline styling or css. This approach can be found in the [Code Sandbox here](https://codesandbox.io/s/vertical-list-s9rx5?fontsize=14&hidenavigation=1&theme=dark)\n\n### Strategy 2: dimension locking\n\nThis strategy will work with columns that have automatic column widths based on content. It will also work with fixed layouts. **It is a more robust strategy than the first, but it is also less performant.**\n\nWhen we apply `position: fixed` to the dragging item it removes it from the automatic column width calculations that a table uses. So before a drag starts we _lock_ all of the cell widths using inline styles to prevent the column dimensions from changing when a drag starts. You can achieve this with the [`onBeforeDragStart` responder](/docs/guides/responders.md).\n\nThis has poor performance characteristics at scale as it requires:\n\n1.  Calling `render()` on every row\n2.  Reading the DOM (`window.getComputedStyles`) on every row\n\nFor tables with less than 50 rows this should approach be fine!\n\n[See example code here](https://react-beautiful-dnd.netlify.app/?selectedKind=Tables&selectedStory=with%20dimension%20locking&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybook%2Factions%2Factions-panel)\n\n## Advanced: reparenting\n\nIf you want to use reparenting (cloning or your own portal) in combination with table row reordering then there are few extra steps you need to go through.\n\nFirst up, have a read of our [reparenting pattern](/docs/guides/reparenting.md) to get familiar with the approach.\n\nIt is important to know the timings of mount / unmount actions in React. We have created a [codesandbox.io example](https://codesandbox.io/s/nkl52y1wn0) to show how the mount timings work when moving in and out of a `ReactDOM.createPortal`.\n\nWhen moving an existing `<tr>` into a `ReactDOM.createPortal` it is important to know that the existing `<tr>` is unmounted and a new `<tr>` is mounted into the portal. Here is the order of those operations:\n\n1.  The old `<tr>` has `componentWillUnmount` called\n2.  The new `<tr>` has `componentWillMount` called\n\nIn order to preserve the cell dimensions of the cells in the row that we are moving into a `ReactDOM.createPortal` we need to lock its dimensions using inline styles (see strategy #2). Sadly though, the new component does not directly have access to the information about the component that was in the tree before it moved to the portal. So in order to do this we need to obtain the cell dimensions of the `<tr>` when it is unmounting and re-apply it to the new `<tr>` when it mounted in `componentDidMount`.\n\nThere is no great way to do this as when `componentDidMount` is called we are not sure if the component is unmouting as the `<tr>` is no longer needed, or if it is unmounting because it is about to move into a portal.\n\nIt seems like the only way to get things working is to:\n\n1.  In `componentWillUnmount` of the `<tr>` read the current widths of the cells from the DOM. You then store this value outside of the component so that it can be read by new components that are mounting.\n2.  If a component is mounting and `DraggableStateSnapshot > isDragging` is true then you can see if there is a previously recorded width. If there is then you can apply that width.\n\nThis gets a little complicated - so we created some examples to show you how this technique works:\n\n- [With our cloning API](https://react-beautiful-dnd.netlify.app/?path=/story/tables--with-clone)\n- [With your own portal](https://react-beautiful-dnd.netlify.app/?path=/story/tables--with-portal)\n\nYou're welcome!\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/patterns/virtual-lists.md",
    "content": "# Virtual lists\n\n`react-beautiful-dnd` supports drag and drop within and between virtual lists. This lets you have fantastic performance with very large data sets. As a general rule, you will want to start using a virtual list when your list size is more than 500 items.\n\n![virtual-board](https://user-images.githubusercontent.com/2182637/66453948-e0044d00-eab1-11e9-88db-3e5165dde69b.gif)\n\n## Background: what are virtual lists?\n\nA \"virtual list\" is the name given to a _windowing_ performance optimisation technique where only the **visible** list items are rendered. See [Rendering large lists with react-window](https://addyosmani.com/blog/react-window/) by Addy Osmani for more background on virtual lists\n\n<img src=\"https://user-images.githubusercontent.com/2182637/65490523-a7307980-def0-11e9-9991-a7e0c2a6e30a.gif\" alt=\"windowing\" width=\"200px\"/>\n\n> Diagram from [Creating more efficient React views with windowing](https://bvaughn.github.io/forward-js-2017/#/0/0) by Brain Vaughn\n\nThere are drawbacks with using virtual lists. They stem from the fact that with a virtual list not all of the page content is rendered into the DOM.\n\n- Accessibility: screenreaders cannot read out all of the content of a page\n- Findability: native find (<kbd>meta</kbd> + <kbd>f</kbd>) will not find things that are not rendered in the DOM.\n\n## Support\n\n`react-beautiful-dnd` is designed to work with existing virtual list solutions and does not have it's own virtual list abstraction. There is no official \"virtual list\" specification or implementation for the web. Different virtual list libraries achieve windowing through various techniques. So we cannot guarentee that `react-beautiful-dnd` will work with every virtual list library. We have created examples for `react-window` and `react-virtualized` which are the two most popular virtual list libraries for `react`.\n\n## Premade examples 🎁\n\nPlease raise a pull request if you would like to add examples for other virtualization libraries! ❤\n\n### [`react-window`](https://github.com/bvaughn/react-window)\n\n- [List](https://react-beautiful-dnd.netlify.app/?path=/story/virtual-react-window--list) ([source](/stories/src/virtual/react-window/list.jsx))\n- [Board](https://react-beautiful-dnd.netlify.app/?path=/story/virtual-react-window--board) ([source](/stories/src/virtual/react-window/board.jsx))\n- [Basic list on `codesandbox.io`](https://codesandbox.io/s/simple-virtual-list-dark-c6wqc)\n- [Basic board on `codesandbox.io`](https://codesandbox.io/s/simple-virtual-list-board-vgvzt)\n\n### [`react-virtualized`](https://github.com/bvaughn/react-virtualized)\n\n- [List](https://react-beautiful-dnd.netlify.app/?path=/story/virtual-react-virtualized--list) ([source](/stories/src/virtual/react-virtualized/list.jsx))\n- [Board](https://react-beautiful-dnd.netlify.app/?path=/story/virtual-react-virtualized--board) ([source](/stories/src/virtual/react-virtualized/board.jsx))\n- [List](https://react-beautiful-dnd.netlify.app/?path=/story/virtual-react-virtualized--window-list) with [`WindowScroller`](https://github.com/bvaughn/react-virtualized/blob/master/docs/WindowScroller.md) ([source](/stories/src/virtual/react-virtualized/window-list.jsx))\n\n### [`react-virtuoso`](https://github.com/petyosi/react-virtuoso)\nReact Virtuoso comes with automatic item measurement out of the box.\n- [List with source](https://virtuoso.dev/react-beautiful-dnd/)\n- [Basic list on `codesandbox.io`](https://codesandbox.io/s/react-virutoso-with-react-beautiful-dnd-e6vmq)\n\n## Usage\n\n`react-beautiful-dnd` does not provide its own virtual list abstraction so there is a bit of wiring that you will need to do in order to get going with existing virtual list solutions 🛠\n\n### Enable overscanning\n\n> Virtualisation libraries often have overscanning enabled by default\n\nMost virtual list libraries support the concept of **overscanning**. Overscanning is where a small about of non-visible items are rendered near the boundary of the window. When a scroll occurs the overscanned item can be immediately moved into view and does not need to be created. Overscanning generally leads to a more fluid experience.\n\nIt is required that overscanning be enabled for `react-beautiful-dnd` to work correctly. If overscanning is not enabled, `rbd` cannot tell if there are more items in the list when an item is in the last visual position. We require an overscanning value of one or more.\n\n### Set `<Droppable /> | mode` to `virtual`\n\nVirtual lists behave differently to regular lists. You will need to tell `rbd` that your list is a virtual one.\n\n```js\n<Droppable droppableId=\"droppable\" mode=\"virtual\">\n  {/*...*/}\n</Droppable>\n```\n\n### Use the `<Droppable /> | renderClone` API\n\nWhen using a virtual list the original dragging item can be unmounted during a drag if it becomes invisible. To get around this we require that you drag a clone of the dragging item. See our [reparenting guide](/docs/guides/reparenting.md) for more details.\n\n```js\n<Droppable\n  droppableId=\"droppable\"\n  mode=\"virtual\"\n  renderClone={(provided, snapshot, rubric) => (\n    <div\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n      ref={provided.innerRef}\n    >\n      Item id: {items[rubric.source.index].id}\n    </div>\n  )}\n>\n  {/*...*/}\n</Droppable>\n```\n\n### Stand in for the placeholder\n\n> 👋 This is only required when you have multiple connected lists. This is not required when using a single list\n\nUsually we require consumers to put a `placeholder` (`<Droppable /> | DroppableProvided | placeholder`) into the list so that we can insert space into a list as needing during a drag.\n\n```js\n<Droppable droppableId=\"droppable\">\n  {(provided, snapshot) => (\n    <div ref={provided.innerRef} {...provided.droppableProps}>\n      {/* Usually needed. But not for virtual lists! */}\n      {provided.placeholder}\n    </div>\n  )}\n</Droppable>\n```\n\nHowever, a `placeholder` does not make sense in the context of a virtual list as the dimensions of the list is not based on collective size of the visual items, but rather is calculated based on things like `itemCount` and `itemSize`. (eg `height` = `itemSize` \\* `itemCount`). For virtual lists, inserting our own node into it would not increase the size of the list. **So we need you do insert the space for us!**\n\nA simple way to add extra space to a virtual list is to add a non-visible item to your list. It is important that this extra item is not a `<Draggable />`.\n\n```js\n// This example uses the `react-window` API\n\nconst Row = ({ data, index, style }: RowProps) => {\n  const item = data[index];\n\n   // We are rendering an extra item for the placeholder\n  if (!item) {\n    return null;\n  }\n\n  return (\n    <Draggable draggableId={item.id} index={index} key={item.id}>\n      {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n        {/*...*/}\n      )}\n    </Draggable>\n  );\n});\n\nfunction render(provided: DroppableProvided, snapshot: DroppableStateSnapshot) {\n  // Add an extra item to our list to make space for a dragging item\n  // Usually the DroppableProvided.placeholder does this, but that won't\n  // work in a virtual list\n  const itemCount: number = snapshot.isUsingPlaceholder\n    ? quotes.length + 1\n    : quotes.length;\n\n  return (\n    <List\n      height={500}\n      itemCount={itemCount}\n      itemSize={110}\n      width={300}\n      outerRef={provided.innerRef}\n      itemData={quotes}\n    >\n      {Row}\n    </List>\n  );\n}\n```\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/sensors/keyboard.md",
    "content": "# Keyboard dragging\n\n`react-beautiful-dnd` supports dragging with only a keyboard. We have audited how our keyboard shortcuts interact with standard browser keyboard interactions. When the user is not dragging they can use their keyboard as they normally would. While dragging we override and disable certain browser shortcuts (such as `tab`) to ensure a fluid experience for the user.\n\n> To see more indepth information about how we impact standard browser events see our [how we use DOM events guide](/docs/guides/how-we-use-dom-events.md)\n\n## Keyboard shortcuts: keyboard dragging\n\nWhen a drag is not occurring, the user will be able to navigate through the `<Draggable />`'s on a page using the standard **tab** <kbd>tab ↹</kbd> key to move forward through the tabbable elements and (**shift** + **tab**) (<kbd>shift</kbd> + )<kbd>tab ↹</kbd>) to move backwards. We achieve this by adding a `tab-index` to the `<Draggable />`. When a `<Draggable />` has focus the **spacebar** <kbd>space</kbd> will **lift** a `<Draggable />`. This will start the drag.\n\nOnce a drag is started the following keyboard shortcuts can be used:\n\n- **spacebar** <kbd>space</kbd> - drop the `<Draggable />`\n- **escape** <kbd>esc</kbd> - cancel the drag\n\nThe following commands are also available but they depend on the `type` of `<Droppable />` that the `<Draggable />` is _currently_ in:\n\n### Within a vertical list\n\n- **Up arrow** <kbd>↑</kbd> - move a `<Draggable />` upwards in a `<Droppable />`\n- **Down arrow** <kbd>↓</kbd> - move a `<Draggable />` downwards in a `<Droppable />`\n- **Right arrow** <kbd>→</kbd> - move a `<Draggable />` to a `<Droppable />` to the _right_ of the current `<Droppable />` (move to new list)\n- **Left arrow** <kbd>←</kbd> - move a `<Draggable />` to a `<Droppable />` to the _left_ of the current `<Droppable />` (move to new list)\n\n### Within a horizontal list\n\n- **Up arrow** <kbd>↑</kbd> - move a `<Draggable />` to a `<Droppable />` to _above_ the current `<Droppable />` (move to new list)\n- **Down arrow** <kbd>↓</kbd> - move a `<Draggable />` to a `<Droppable />` to _below_ the current `<Droppable />` (move to new list)\n- **Right arrow** <kbd>→</kbd> - move a `<Draggable />` to the _right_ in the current `<Droppable />`\n- **Left arrow** <kbd>←</kbd> - move a `<Draggable />` to the _left_ in the current `<Droppable />`\n\nDuring a drag the following standard keyboard events have their default behaviour prevented (through `event.preventDefault()`) to avoid a bad experience:\n\n- **tab** <kbd>tab ↹</kbd> - preventing tabbing\n- **enter** <kbd>⏎</kbd> - preventing submission\n\n## Auto scrolling\n\nWhen dragging with a keyboard, `react-beautiful-dnd` will also perform [auto scrolling](/docs/guides/auto-scrolling.md) operations to ensure the item can be moved around\n\n[auto-scroll-board-keyboard](https://user-images.githubusercontent.com/2182637/36520650-3d3638f8-17e6-11e8-9cba-1fb439070285.gif)\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/sensors/mouse.md",
    "content": "# Mouse dragging\n\n## Sloppy clicks and click prevention 🐱🎁\n\nWhen a user presses the mouse down on an element, we cannot determine if the user was clicking or dragging. Also, sometimes when a user clicks they can move the cursor slightly — a sloppy click. So we only start a drag once the user has moved beyond a certain distance with the mouse down (the drag threshold) — more than they would if they were just making a sloppy click. If the drag threshold is not exceeded then the user interaction behaves just like a regular click. If the drag threshold is exceeded then the interaction will be classified as a drag and the standard click behaviour will not occur.\n\nThis allows consumers to wrap interactive elements such as an anchor and have it be both a standard anchor as well as a draggable item in a natural way.\n\n(🐱🎁 is a [schrodinger's cat](https://www.youtube.com/watch?v=IOYyCHGWJq4) joke)\n\n> To see more in depth information about how we impact standard browser events see our [how we use DOM events guide](/docs/guides/how-we-use-dom-events.md)\n\n## Keyboard shortcuts\n\nWhen a drag **is not occurring** `react-beautiful-dnd` does not impact any of the standard keyboard interactions (it has no listeners bound).\n\nWhen a drag **is occurring** with a _mouse_ the user is able to execute the following keyboard shortcuts:\n\n- **escape** <kbd>esc</kbd> - cancel the drag\n\nDuring a mouse drag the following standard keyboard events are prevented to prevent a bad experience:\n\n- **tab** <kbd>tab ↹</kbd> - preventing tabbing\n- **enter** <kbd>⏎</kbd> - preventing submission\n\nOther than these explicitly prevented keyboard events all standard keyboard events should work as expected.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/sensors/sensor-api.md",
    "content": "# Sensor API 🎮\n\n![sensor api logo](https://user-images.githubusercontent.com/2182637/60233733-ec8ade00-98e4-11e9-88b2-6fe407cf6bcb.jpg)\n\nWith our Sensor API it is possible to:\n\n- Create drag and drop interactions from **any input** type you can think of\n- Create beautiful scripted **experiences**\n\nThe public Sensor API is the same API that our [mouse](/docs/sensors/mouse.md), [keyboard](/docs/sensors/keyboard.md), and [touch](/docs/sensors/touch.md) sensors use. So it is powerful enough to drive any experience we ship out of the box.\n\n## Examples\n\nThese are some examples to show off what is possible with the Sensor API. They are currently not built to be production ready. Feel free to reach out if you would like to help improve them or add your own!\n\n(Please be sure to use prefix `rbd-`)\n\n|                                                                 Voice 🗣                                                                  |                                                              Webcam 📷                                                               |                                                                  Thought 🧠                                                                  |\n| :--------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------: |\n|           ![voice sensor](https://user-images.githubusercontent.com/2182637/66467095-87dc4380-eacf-11e9-9e2e-7ae1a59bfddf.gif)           |        ![webcam sensor](https://user-images.githubusercontent.com/2182637/66466837-1603fa00-eacf-11e9-8c15-5ed324c8916f.gif)         |                    ![thought sensor](https://raw.githubusercontent.com/charliegerard/rbd-thought-sensor/master/demo.gif)                     |\n| [`rbd-voice-sensor`](https://github.com/danieldelcore/rbd-voice-sensor)<br>created by [@danieldelcore](https://github.com/danieldelcore) | [`rbd-webcam-sensor`](https://github.com/kangweichan/rbd-webcam-sensor)<br>created by [@kangweichan](https://github.com/kangweichan) | [`rbd-thought-sensor`](https://github.com/charliegerard/rbd-thought-sensor)<br>created by [@charliegerard](https://github.com/charliegerard) |\n\n|                                                  With controls                                                   |                                                             Run sheet                                                              |                                                     Onboarding                                                     |\n| :--------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------: |\n| ![controls](https://user-images.githubusercontent.com/2182637/66469550-c07e1c00-ead3-11e9-8e45-3cb114cf3c97.gif) | ![multiple-drag-drop-context](https://user-images.githubusercontent.com/2182637/66472177-6c296b00-ead8-11e9-8966-bd194d3f8070.gif) | ![onboarding](https://user-images.githubusercontent.com/2182637/66466850-1bf9db00-eacf-11e9-958f-82f970f4111b.gif) |\n|                                          Mapping controls to movements                                           |                                   Running scripted experiences along side a user controlled drag                                   |                          A scripted onboarding experience for a trip planning application                          |\n\n## Overview\n\nYou create a `sensor` that has the ability to attempt to claim a **lock**. A **lock** allows _exclusive_ control of dragging within a `<DragDropContext />`. When you are finished with your interaction, you can then release the **lock**.\n\n```js\nfunction mySimpleSensor(api: SensorAPI) {\n  const preDrag: ?PreDragActions = api.tryGetLock('item-1');\n  // Could not get lock\n  if (!preDrag) {\n    return;\n  }\n\n  const drag: SnapDragActions = preDrag.snapLift();\n\n  drag.moveDown();\n  drag.moveDown();\n  drag.moveDown();\n\n  drag.drop();\n}\n\nfunction App() {\n  return (\n    <DragDropContext sensors={[mySimpleSensor]}>{/*...*/}</DragDropContext>\n  );\n}\n```\n\n## Lifecycle\n\n![programmatic state flow](https://user-images.githubusercontent.com/2182637/58779115-35b67d80-8618-11e9-8934-6dfa2b14ce23.jpg)\n\n1. Try to get a **lock** when a `sensor` wants to drag an item. A sensor might not be able to claim a lock for a variety of reasons, such as when another `sensor` already has a **lock**.\n2. If a **lock** is obtained then there are a number of _pre drag_ actions available to you (`PreDragActions`). This allows a `sensor` to claim a lock before starting a drag. This is important for things like [sloppy click detection](/docs/sensors/mouse.md#sloppy-clicks-and-click-prevention-) where a drag is only started after a sufficiently large movement.\n3. A _pre drag_ lock can be upgraded to a _drag lock_, which contains a different set of APIs (`FluidDragActions` or `SnapDragActions`). Once a `<Draggable />` has been lifted, it can be moved around.\n\n## Rules\n\n- Only one `<Draggable />` can be dragging at a time for a `<DragDropContext />`\n- You cannot use outdated or aborted **locks** (see below)\n- That's it!\n\n## API\n\n### Creating a `sensor`\n\nA `sensor` is a [React hook](https://reactjs.org/docs/hooks-intro.html). It is fine if you do not want to use any of the React hook goodness, you can treat the `sensor` just as a function. React hooks are just functions that let you use the built in React hooks if you want to 🤫. You pass your `sensor` into the `sensors` array on a `<DragDropContext />`.\n\n```js\nfunction useMyCoolSensor(api: SensorAPI) {\n  const start = useCallback(function start(event: MouseEvent) {\n    const preDrag: ?PreDragActions = api.tryGetLock('item-2');\n    if (!preDrag) {\n      return;\n    }\n    preDrag.snapLift();\n    preDrag.moveDown();\n    preDrag.drop();\n  }, []);\n\n  useEffect(() => {\n    window.addEventListener('click', start);\n\n    return () => {\n      window.removeEventListener('click', start);\n    };\n  }, []);\n}\n\nfunction App() {\n  return (\n    <DragDropContext sensors={[useMyCoolSensor]}>\n      <Things />\n    </DragDropContext>\n  );\n}\n```\n\n**The `sensors` array should not change dynamically**. If you do this you run the risk of violating the [rules of React hooks](https://reactjs.org/docs/hooks-rules.html).\n\nYou can also disable all of the prebuilt sensors ([mouse](/docs/sensors/mouse.md), [keyboard](/docs/sensors/keyboard.md), and [touch](/docs/sensors/touch.md)) by setting `enableDefaultSensors={false}` on a `<DragDropContext />`. This is useful if you _only_ want a `<DragDropContext />` to be controlled programmatically.\n\n### Controlling a drag: try to get a lock\n\nA `sensor` is provided with a an object (`SensorAPI`) which is used to try to get a **lock**\n\n```js\ntype Sensor = (api: SensorAPI) => void;\n\ntype SensorAPI = {|\n  tryGetLock: TryGetLock,\n  canGetLock: (id: DraggableId) => boolean,\n  isLockClaimed: () => boolean,\n  tryReleaseLock: () => void,\n  findClosestDraggableId: (event: Event) => ?DraggableId,\n  findOptionsForDraggable: (id: DraggableId) => ?DraggableOptions,\n|};\n\ntype DraggableOptions = {|\n  canDragInteractiveElements: boolean,\n  shouldRespectForcePress: boolean,\n  isEnabled: boolean,\n|};\n```\n\n- `tryGetLock` (`TryGetLock`): a function that is used to **try** and get a **lock** for a `<Draggable />`\n- `canGetLock(id)`: returns whether a lock _could_ be claimed for a given `DraggableId`\n- `isLockClaimed()`: returns `true` if any sensor currently has a lock\n- `tryReleaseLock()`: will release any active lock. This can be useful for programmatically cancelling a drag.\n- `findClosestDraggableId(event)`: a function that will try to find the closest `draggableId` based on an event. It will look upwards from the `event.target` to try and find a _drag handle_\n- `findOptionsForDraggable(id)`: tries to lookup `DraggableOptions` associated with a `<Draggable />`\n\n```js\nexport type TryGetLock = (\n  draggableId: DraggableId,\n  forceStop?: () => void,\n  options?: TryGetLockOptions,\n) => ?PreDragActions;\n```\n\n- `draggableId`: The `DraggableId` of the `<Draggable />` that you want to drag.\n- `forceStop` (optional): a function that is called when the lock needs to be abandoned by the application. See **force abandoning locks**.\n\n```js\ntype TryGetLockOptions = {\n  sourceEvent?: Event,\n};\n```\n\n- `sourceEvent` (optional): Used to do further validation when starting the drag from a user input event. We will do some [interactive element checking](/docs/api/draggable.md#interactive-child-elements-within-a-draggable-)\n\n### Controlling a drag: pre drag (`PreDragAction`)\n\nThe `PreDragAction` object contains a number of functions:\n\n```js\ntype PreDragActions = {|\n  // discover if the lock is still active\n  isActive: () => boolean,\n  // whether it has been indicated if force press should be respected\n  shouldRespectForcePress: () => boolean,\n  // Lift the current item\n  fluidLift: (clientSelection: Position) => FluidDragActions,\n  snapLift: () => SnapDragActions,\n  // Cancel the pre drag without starting a drag. Releases the lock\n  abort: () => void,\n|};\n```\n\nThis phase allows you to conditionally start or abort a drag after obtaining an exclusive **lock**. This is useful if you are not sure if a drag should start such as when using [long press](/docs/sensors/touch.md) or [sloppy click detection](/docs/sensors/mouse.md). If you want to abort the pre drag without lifting you can call `.abort()`.\n\n### Controlling a drag: dragging\n\nYou can lift a dragging item by calling either `.fluidLift(clientSelection)` or `snapLift()`. This will start a visual drag and will also trigger the `onDragStart` responder. There are two different _lift_ functions, as there are two different dragging modes: **snap dragging** (`SnapDragActions`) and **fluid dragging** (`FluidDragActions`).\n\n#### Shared\n\n```js\ntype DragActions = {|\n  drop: (args?: StopDragOptions) => void,\n  cancel: (args?: StopDragOptions) => void,\n  isActive: () => boolean,\n  shouldRespectForcePress: () => boolean,\n|};\n\ntype StopDragOptions = {|\n  shouldBlockNextClick: boolean,\n|};\n```\n\n#### Fluid dragging\n\n> ✍️ [Raathi Kugarajan](https://twitter.com/Raathigesh) has written a blog : [\"Scripted natural motion with react-beautiful-dnd\"](https://dev.to/raathigesh/scripted-natural-motion-with-react-beautiful-dnd-4ifj) which outlines how you can create scripted user behaviour with the Sensor API 👏\n\n`<Draggable />`s move around naturally in response a moving point. The _impact_ of the drag is controlled by a _collision engine_. (This is what our [mouse sensor](/docs/sensors/mouse.md) and [touch sensor](/docs/sensors/touch.md) use)\n\n```js\ntype FluidDragActions = {|\n  ...DragActions,\n  move: (clientSelection: Position) => void,\n|};\n```\n\nCalls to `.move()` are throttled using [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame). So if you make multiple `.move()` calls in the same animation frame, it will only result in a single update\n\n```js\nconst drag: SnapDragActions = preDrag.fluidLift({ x: 0, y: 0 });\n\n// will all be batched into a single update\ndrag.move({ x: 0, y: 1 });\ndrag.move({ x: 0, y: 2 });\ndrag.move({ x: 0, y: 3 });\n\n// after animation frame\n// update(x: 0, y: 3)\n```\n\n#### Snap dragging\n\n`<Draggable />`s are forced to move to a new position using a single command. For example, \"move down\". (This is what our [keyboard sensor](/docs/sensors/keyboard.md) uses)\n\n```js\nexport type SnapDragActions = {|\n  ...DragActions,\n  moveUp: () => void,\n  moveDown: () => void,\n  moveRight: () => void,\n  moveLeft: () => void,\n|};\n```\n\n## Force abandoning locks\n\nA **lock** can be aborted at any time by the application, such as when an error occurs. If you try to perform actions on an aborted **lock** then it will not do anything. The second argument to `SensorAPI.tryGetLock()` is a `forceStop` function. The `forceStop` function will be called when the **lock** needs to be abandoned by the application. If you try to use any functions on the **lock** after it has been abandoned they will have no effect and will log a warning to the console.\n\n```js\nfunction useMySensor(api: SensorAPI) {\n  let unbindClick;\n\n  function forceStop() {\n    if (unbindClick) {\n      unbindClick();\n    }\n  }\n\n  const preDrag: ?PreDragActions = api.tryGetLock('item-1', forceStop);\n  // Could not get lock\n  if (!preDrag) {\n    return;\n  }\n\n  const drag: SnapDragActions = preDrag.snapLift();\n  const move = () => drag.moveDown();\n  window.addEventListener('click', move);\n  unbindClick = window.removeEventListener('click', move);\n}\n```\n\nThe `PreDragActions`, `FluidDragActions` and `SnapDragActions` all have a `isActive()` function which can be called to discover if a lock is still active. So if you do not want to provide a `forceStop()` function, it is best to defensively call api's with a `isActiveCheck`.\n\n```js\nfunction useMySensor(api: SensorAPI) {\n  const preDrag: ?PreDragActions = api.tryGetLock();\n  // Could not get lock\n  if (!preDrag) {\n    return;\n  }\n\n  const drag: SnapDragActions = preDrag.snapLift();\n  const move = () => {\n    if (drag.isActive()) {\n      drag.moveDown();\n      return;\n    }\n    // unbinding if no longer active\n    window.removeEventListener('click', move);\n  };\n  window.addEventListener('click', move);\n}\n```\n\n## Invalid behaviours\n\nThese are all caused by not respecting the lifecycle (see above)\n\n> ⚠️ = warning logged\n> ❌ = error thrown\n\n- ⚠️ Using any `PreDragAction`, `FluidDragAction` or `SnapDragAction` after `forceStop()` is called\n- ⚠️ Using any `PreDragAction` after `.abort()` has been called\n- ⚠️ Using any `FluidDragAction` or `SnapDragAction` after `.cancel()` or `.drop()` has been called.\n- ❌ Trying to call two `lift` functions on a `PreDragAction` will result in an error being thrown.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/sensors/touch.md",
    "content": "# Touch dragging\n\n`react-beautiful-dnd` supports dragging on touch devices such as mobiles and tablets.\n\n![Mobile landscape](https://github.com/alexreardon/files/blob/master/resources/iphone-landscape.gif?raw=true)\n\n> Recorded on iPhone 6s\n\n## Understanding intention: tap, force press, scroll and drag\n\nWhen a user presses their finger (or other input) on a `<Draggable />` we are not sure if they where intending to _tap_, _force press_, _scroll the container_ or _drag_. **As much as possible `react-beautiful-dnd` aims to ensure that a users default interaction experience remains unaffected**.\n\n> To see more indepth information about how we impact standard browser events see our [how we use DOM events guide](/docs/guides/how-we-use-dom-events.md)\n\n## Starting a drag: long press\n\nA user can start a drag by holding their finger 👇 on an element for a small period of time 🕑 (long press)\n\n## Tap support\n\nIf the user lifts their finger before the timer is finished then we release the event to the browser for it to determine whether to perform the standard tap / click action. This allows you to have a `<Draggable />` that is both clickable such as a anchor as well as draggable. If the item was dragged then we block the tap action from occurring.\n\n## Native scrolling support\n\nIf we detect a `touchmove` before the long press timer expires we cancel the pending drag and allow the user to scroll normally. This means that the user needs to be fairly intentional and precise with their grabbing. Once the first `touchmove` occurs we have to either opt in or out of native scrolling.\n\n- If the long press timer **has not** expired: _allow native scrolling and prevent dragging_\n- If the long press timer **has** expired: _a drag has started and we prevent native scrolling_\n\n## Force press support\n\n> See our [force press guide](/docs/api/draggable.md)\n\n## Vibration\n\n> This is merely an idea - it is up to you to add this if you want this behavior.\n\nIf you like you could also trigger a [vibration event](https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API) when the user picks up a `<Draggable />`. This can provide tactile feedback that the user is doing something. It currently is only supported in Chrome on Android.\n\n```js\nclass App extends React.Component {\n  onDragStart = () => {\n    // good times\n    if (window.navigator.vibrate) {\n      window.navigator.vibrate(100);\n    }\n  };\n  /*...*/\n}\n```\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/support/community-and-addons.md",
    "content": "# Community and addons\n\n## Community ❤️👋\n\n- [kanban-dnd](https://kanban-dnd.glitch.me) - A Kanban style to-do list, with the ability to create custom lanes and reorder them on the fly.\n- [react-beautiful-dnd-test-utils](https://github.com/colinrcummings/react-beautiful-dnd-test-utils) - 🧤 Test utils for `react-beautiful-dnd` built with `react-testing-library`.\n- Simple Trello - A simple cloning version of Trello, using React ecosystem.\n  - [Demo](https://simple-trello.netlify.app/)\n  - [Source](https://github.com/ng-hai/simple-trello)\n- 🎮 A drag'n'drop Checkers game\n  - [Demo](https://checkers-game.netlify.app/)\n  - [Source](https://github.com/emanuellarini/checkers)\n- [react-kanban](https://github.com/lourenci/react-kanban) - Another Kanban/Trello board lib for React, with customizations to use in projects.\n\n## Addons\n\n- [natural-drag-animation-rbdnd](https://github.com/rokborf/natural-drag-animation-rbdnd) adds natural dragging animation\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/support/engineering-health.md",
    "content": "# Engineering health\n\n[![CircleCI branch](https://img.shields.io/circleci/project/github/atlassian/react-beautiful-dnd/master.svg)](https://circleci.com/gh/atlassian/react-beautiful-dnd/tree/master)\n\n## Typed\n\n[![Typed with flow](https://img.shields.io/badge/typed%20with-flow-brightgreen.svg?style=flat)](https://flow.org/)\n\nThis codebase is typed with [flow](https://flow.org) to promote greater internal consistency and more resilient code.\n\nYou can learn more about our `TypeScript` and `flow` support on our [types guide](/docs/guides/types.md).\n\n## Tested\n\n[![Tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://www.npmjs.com/package/react-beautiful-dnd) [![Tested with cypress](https://img.shields.io/badge/tested%20with-cypress-brightgreen.svg?style=flat)](https://www.cypress.io/)\n\nThis code base employs a number of different testing strategies including unit, integration, browser and performance tests. Testing various aspects of the system helps to promote its quality and stability.\n\nWhile code coverage is [not a guarantee of code health](https://stackoverflow.com/a/90021/1374236), it is a good indicator. This code base currently sits at **~94% coverage**.\n\n## Linting\n\n- [`eslint`](https://eslint.org/)\n- [`stylelint`](https://github.com/stylelint/stylelint)\n- [`prettier`](https://github.com/prettier/prettier) - well, not strictly a linter, but close enough\n\n## Performance\n\n[![CircleCI branch](https://img.shields.io/badge/speed-blazing%20%F0%9F%94%A5-brightgreen.svg?style=flat)](https://circleci.com/gh/atlassian/react-beautiful-dnd/tree/master)\n\nThis codebase is designed to be **extremely performant** - it is part of its DNA. It is designed to perform the smallest amount of updates possible. You can have a read about performance work done for `react-beautiful-dnd` here:\n\n- [Rethinking drag and drop](https://medium.com/@alexandereardon/rethinking-drag-and-drop-d9f5770b4e6b)\n- [Dragging React performance forward](https://medium.com/@alexandereardon/dragging-react-performance-forward-688b30d40a33)\n- [Grabbing the flame 🔥](https://medium.com/@alexandereardon/grabbing-the-flame-290c794fe852)\n\n> More in [media](/docs/support/media.md)\n\n## Size\n\n[![minzip](https://img.shields.io/bundlephobia/minzip/react-beautiful-dnd.svg)](https://www.npmjs.com/package/react-beautiful-dnd)\n\nGreat care has been taken to keep the library as light as possible. There could be a smaller net cost if you where already using one of the underlying dependencies.\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/support/media.md",
    "content": "# Media\n\nThis page contains a list of articles, blogs and newsletters that `react-beautiful-dnd` has appeared in.\n\n## Blogs by the `react-beautiful-dnd` team\n\n### Project related\n\n- [Rethinking drag and drop](https://medium.com/@alexandereardon/rethinking-drag-and-drop-d9f5770b4e6b)\n- [Natural keyboard movement between lists](https://medium.com/@alexandereardon/friction-gravity-and-collisions-3adac3a94e19)\n- [Beautiful drag and drop: a year in review](https://medium.com/@alexandereardon/beautiful-drag-and-drop-a-year-in-review-1febc3fac7ce)\n- [Beautiful interactions: Crafting elegant and robust drag and drop animations](https://medium.com/@alexandereardon/beautiful-interactions-8f67502ccf73)\n- [Design process for our new logo](https://www.maryannemade.com/reactbeautifuldnd-logo)\n- [Overhauling our collision engine](https://dev.to/alexandereardon/overhauling-our-collision-engine-962)\n- [react-beautiful-dnd: behind the magic](https://www.youtube.com/watch?v=Kz50msV-zq0)\n\n### Performance related\n\n- [Performance optimisations for React applications](https://medium.com/@alexandereardon/performance-optimisations-for-react-applications-b453c597b191)\n- [Performance optimisations for React applications: Round 2](https://medium.com/@alexandereardon/performance-optimisations-for-react-applications-round-2-2042e5c9af97)\n- [Dragging React performance forward](https://medium.com/@alexandereardon/dragging-react-performance-forward-688b30d40a33)\n- [Grabbing the flame 🔥](https://medium.com/@alexandereardon/grabbing-the-flame-290c794fe852)\n\n## Other\n\n- [What does react-beautiful-dnd cost to maintain?](https://dev.to/alexandereardon/what-does-react-beautiful-dnd-cost-to-maintain-52e8)\n- [Deep Sea Fishing with React Hooks](https://www.youtube.com/watch?v=MVi17tk3VsI)\n\n## Podcasts\n\n- [React podcast: Fast, Accessible, and Beautiful Drag and Drop with Alex Reardon](https://reactpodcast.simplecast.fm/17)\n\n## Newsletters\n\n- Tiny letter [November 04, 2019](https://tinyletter.com/cassidoo/letters/the-world-is-changed-by-your-example-not-by-your-opinion-paulo-coelho)\n- Ponyfoo [issue 78](https://ponyfoo.com/weekly/78/javascript-and-css-engines-pwa-drag-and-drop-web-components-and-http-2)\n- PonyFoo [issue 99](https://ponyfoo.com/weekly/99/react-across-the-universe-typography-load-balancing-and-javascript-frameworks)\n- PonyFoo [issue 141](https://ponyfoo.com/weekly/141/http-3-bgp-leaks-react-as-native-dom-typescript-tensorflow-and-all-things-performance)\n- JavaScript Weekly [issue 369](http://javascriptweekly.com/issues/369)\n- JavaScript Weekly [issue 369](https://javascriptweekly.com/issues/369)\n- JavaScript Weekly [issue 412](https://javascriptweekly.com/issues/412)\n- Weekend JavaScript [issue 125](https://www.weekendjs.com/issues/125-webassembly-null-vs-undefined-the-ultimage-guide-to-js-frameworks-and-more)\n- React Newsletter [issue 81](http://reactjsnewsletter.com/issues/81?m=web#X4GMoSn)\n- React Newsletter [issue 93](http://reactjsnewsletter.com/issues/93?m=web#PIERdu)\n- React Newsletter [issue 102](http://reactjsnewsletter.com/issues/102?#start)\n- React Newsletter [issue 124](http://reactjsnewsletter.com/issues/124?#start)\n- React Newsletter [issue 139](http://reactjsnewsletter.com/issues/139?m=web&#5nGfyf)\n- React Newsletter [issue 153](http://reactjsnewsletter.com/issues/153?#start)\n- React Newsletter [issue 195](http://reactjsnewsletter.com/issues/195)\n- React Status [issue 49](https://react.statuscode.com/issues/49)\n- React Status [issue 63](https://react.statuscode.com/issues/63)\n- React Status [issue 71](https://react.statuscode.com/issues/71)\n- React Status [issue 114](https://react.statuscode.com/issues/114)\n- React Status [issue 129](https://react.statuscode.com/issues/129)\n- React Status [issue 134](https://react.statuscode.com/issues/134)\n- React Status [issue 139](https://react.statuscode.com/issues/139)\n- React Status [issue 177](https://react.statuscode.com/issues/177)\n- Fullstack React [issue 72](http://newsletter.fullstackreact.com/issues/72)\n- React Digest [issue 201](https://www.reactdigest.net/digests/201)\n- HashBang Weekly [issue 52](http://hashbangweekly.okgrow.com/2018/01/22/issue-52)\n- CSS Animation Weekly [issue 60](http://weekly.cssanimation.rocks/issues/css-animation-weekly-60-working-with-animations-skeleton-screens-and-rethinking-drag-and-drop-73446)\n- Codrops [collective 340](https://tympanus.net/codrops/collective/collective-340/)\n- Product Design Weekly [issue 139](http://us12.campaign-archive2.com/?u=aa09d0e5a44742b7c1c444765&id=8cf1802ab9&e=95b47a038c)\n- Web Design Weekly [issue 288](http://email.jakebresnehan.com/t/ViewEmail/r/54BEACFB4B9F50C82540EF23F30FEDED/05178437DEDE86556B5BE456C00C2519)\n- sidebar.io - [28/8/16](https://sidebar.io/?after=2017-08-21&before=2017-08-21)\n- Best of JS [issue 25](https://weekly.bestofjs.org/issues/25/)\n- BxJS Weekly [episode 59](https://dev.to/yamalight/bxjs-weekly-episode-59-javascript-news-podcast-b28)\n- FASination Daily [May 21st](http://opensource.faseidl.com/#/)\n- The Week of React [issue 57](http://www.theweekofreact.com/issues/fold-up-images-in-react-using-webassembly-w-react-react-europe-livestream-more-179542)\n- React Digest [issue 201](https://reactdigest.net/digests/201)\n\n## Articles, tutorials and blogs\n\n- [Here Are 5 Useful React Components](https://medium.com/javascript-in-plain-english/here-are-5-useful-react-components-fb3927e7d790)\n- [Build a beautiful, draggable kanban board with react-beautiful-dnd](https://www.youtube.com/watch?v=uHO3mQgs-e8)\n- [Drag and Drop Tables with React-Beautiful-DND (Part I)](https://dev.to/milandhar/drag-and-drop-table-with-react-beautiful-dnd-54ad)\n- [Scripted natural motion with react-beautiful-dnd](https://dev.to/raathigesh/scripted-natural-motion-with-react-beautiful-dnd-4ifj)\n- [Drag n’Drop with react-beautiful-dnd](https://medium.com/@reireynoso/drag-ndrop-with-react-beautiful-dnd-73014e5937f2)\n- [How to add Drag and Drop features to your React app](https://medium.com/javascript-in-plain-english/how-to-add-drag-and-drop-feature-to-your-react-app-20cb22fb180)\n- [`awesome-react-components`](https://github.com/brillout/awesome-react-components)\n- CSS-Tricks [tweet](https://twitter.com/css/status/1138866065965010945)\n- dev.to 7 most popular DEV posts [May 27th, 2019](https://dev.to/devteam/the-7-most-popular-dev-posts-from-the-past-week-2ice)\n- [React Drag and Drop - Multiple Horizontal Lists](https://www.youtube.com/watch?v=RI9kA09Egas)\n- [Building a Drag-and-Drop Game with react-beautiful-dnd](https://able.bio/drenther/building-a-drag-and-drop-game-with-react-beautiful-dnd--094r3g8)\n- [Let's Create a Trello Clone with React + Redux](https://www.youtube.com/watch?v=RDQGPs7StNA)\n- [Dynamically Update Positions During Drag Using react-beautiful-dnd](https://itnext.io/dynamically-update-positions-during-drag-using-react-beautiful-dnd-4a986d704c2e)\n- [Want To Recruit Better Engineers? Open Source Your Code](https://angel.co/blog/want-to-recruit-better-engineers-open-source-your-code)\n- [How To Implement Better Drag and Drop in your React App](https://blog.bitsrc.io/implement-better-drag-and-drop-in-your-react-app-beafc4451599)\n- [Beautiful drag and drop with React — The beginner’s guide](https://medium.com/@AlejandroSobko/7798e3928290)\n- [The New Jira Beings Now (in the examples)](https://www.atlassian.com/blog/jira-software/the-new-jira-begins-now)\n- 15 Awesome React Components [Article](https://tutorialzine.com/2017/11/15-awesome-react-components)\n- 15 Interesting JavaScript and CSS Libraries for September 2017 [September edition](https://tutorialzine.com/2017/09/15-interesting-javascript-and-css-libraries-for-september-2017)\n- Mybridge React.JS Top 10 Articles For the Past Month [v.Sep 2017](https://medium.mybridge.co/react-js-top-10-articles-for-the-past-month-v-sep-2017-1894c4d91e0c)\n- Inside Dev [Sep 3rd, 2017](https://inside.com/campaigns/inside-dev-2017-09-03-3154/sections/dive-deeper-arcore-17345)\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "docs/support/upgrading.md",
    "content": "# Upgrading\n\nWe have created upgrade instructions in our [Github release notes](https://github.com/atlassian/react-beautiful-dnd/releases) to help you upgrade to the latest version!\n\n- [Upgrading from `9.x` to `10.x`](https://github.com/atlassian/react-beautiful-dnd/releases/tag/v10.0.0)\n- [Upgrading from `8.x` to `9.x`](https://github.com/atlassian/react-beautiful-dnd/releases/tag/v9.0.0)\n- [Upgrading from `7.x` to `8.x`](https://github.com/atlassian/react-beautiful-dnd/releases/tag/v8.0.0)\n- [Upgrading from `6.x` to `7.x`](https://github.com/atlassian/react-beautiful-dnd/releases/tag/v7.0.0)\n- [Upgrading from `5.x` to `6.x`](https://github.com/atlassian/react-beautiful-dnd/releases/tag/v6.0.0)\n- [Upgrading from `4.x` to `5.x`](https://github.com/atlassian/react-beautiful-dnd/releases/tag/v5.0.0)\n- [Upgrading from `3.x` to `4.x`](https://github.com/atlassian/react-beautiful-dnd/releases/tag/v4.0.0)\n\n[← Back to documentation](/README.md#documentation-)\n"
  },
  {
    "path": "flow-typed/custom/cypress.js",
    "content": "// There is currently no flowtype definition for cypress\n// Currently just opting out of flow for the cy global\n// https://github.com/cypress-io/cypress/issues/2732\n// https://github.com/flow-typed/flow-typed/pull/3028\ndeclare var cy: any;\n"
  },
  {
    "path": "flow-typed/custom/raf.js",
    "content": "declare function raf(callback: (timestamp: number) => void): AnimationFrameID;\n\n// TODO: would like to use `import type {Stub} from 'raf-stub'\n// This is not supported right now: https://github.com/flow-typed/flow-typed/issues/2023\ndeclare var requestAnimationFrame: {\n  add: (cb: Function) => number,\n  remove: (id: number) => void,\n  flush: (duration?: number) => void,\n  reset: () => void,\n  step: (steps?: number, duration?: number) => void,\n} & typeof raf;\n"
  },
  {
    "path": "flow-typed/npm/@atlaskit/css-reset_vx.x.x.js",
    "content": "// flow-typed signature: 9bd96871f7bfae2bd1e656bbd6660608\n// flow-typed version: <<STUB>>/@atlaskit/css-reset_v^5.0.9/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@atlaskit/css-reset'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@atlaskit/css-reset' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@atlaskit/css-reset/dist/cjs/base' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/cjs/browser-fixes' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/cjs' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/cjs/reset' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/cjs/tables' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/cjs/utils' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/cjs/utils/evaluate-inner' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/esm/base' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/esm/browser-fixes' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/esm' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/esm/reset' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/esm/tables' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/esm/utils' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/css-reset/dist/esm/utils/evaluate-inner' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@atlaskit/css-reset/dist/cjs/base.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/cjs/base'>;\n}\ndeclare module '@atlaskit/css-reset/dist/cjs/browser-fixes.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/cjs/browser-fixes'>;\n}\ndeclare module '@atlaskit/css-reset/dist/cjs/index' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/cjs'>;\n}\ndeclare module '@atlaskit/css-reset/dist/cjs/index.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/cjs'>;\n}\ndeclare module '@atlaskit/css-reset/dist/cjs/reset.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/cjs/reset'>;\n}\ndeclare module '@atlaskit/css-reset/dist/cjs/tables.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/cjs/tables'>;\n}\ndeclare module '@atlaskit/css-reset/dist/cjs/utils.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/cjs/utils'>;\n}\ndeclare module '@atlaskit/css-reset/dist/cjs/utils/evaluate-inner.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/cjs/utils/evaluate-inner'>;\n}\ndeclare module '@atlaskit/css-reset/dist/esm/base.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/esm/base'>;\n}\ndeclare module '@atlaskit/css-reset/dist/esm/browser-fixes.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/esm/browser-fixes'>;\n}\ndeclare module '@atlaskit/css-reset/dist/esm/index' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/esm'>;\n}\ndeclare module '@atlaskit/css-reset/dist/esm/index.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/esm'>;\n}\ndeclare module '@atlaskit/css-reset/dist/esm/reset.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/esm/reset'>;\n}\ndeclare module '@atlaskit/css-reset/dist/esm/tables.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/esm/tables'>;\n}\ndeclare module '@atlaskit/css-reset/dist/esm/utils.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/esm/utils'>;\n}\ndeclare module '@atlaskit/css-reset/dist/esm/utils/evaluate-inner.js' {\n  declare module.exports: $Exports<'@atlaskit/css-reset/dist/esm/utils/evaluate-inner'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@atlaskit/theme_vx.x.x.js",
    "content": "// flow-typed signature: 6347194133e49b25a98feec719ba6d4b\n// flow-typed version: <<STUB>>/@atlaskit/theme_v^9.5.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@atlaskit/theme'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@atlaskit/theme' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@atlaskit/theme/dist/cjs/color-palettes' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/colors' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/components' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/components/Appearance' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/components/AtlaskitThemeProvider' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/components/Context' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/components/Reset' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/components/Theme' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/constants' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/elevation' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/hoc' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/math' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/types' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/typography' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/utils/createTheme' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/utils/getTheme' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/utils/math' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/cjs/utils/themed' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/color-palettes' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/colors' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/components' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/components/Appearance' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/components/AtlaskitThemeProvider' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/components/Context' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/components/Reset' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/components/Theme' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/constants' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/elevation' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/hoc' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/math' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/types' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/typography' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/utils/createTheme' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/utils/getTheme' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/utils/math' {\n  declare module.exports: any;\n}\n\ndeclare module '@atlaskit/theme/dist/esm/utils/themed' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@atlaskit/theme/dist/cjs/color-palettes.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/color-palettes'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/colors.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/colors'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/components.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/components'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/components/Appearance.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/components/Appearance'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/components/AtlaskitThemeProvider.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/components/AtlaskitThemeProvider'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/components/Context.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/components/Context'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/components/Reset.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/components/Reset'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/components/Theme.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/components/Theme'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/constants.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/constants'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/elevation.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/elevation'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/hoc.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/hoc'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/index' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/index.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/math.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/math'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/types.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/types'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/typography.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/typography'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/utils/createTheme.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/utils/createTheme'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/utils/getTheme.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/utils/getTheme'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/utils/math.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/utils/math'>;\n}\ndeclare module '@atlaskit/theme/dist/cjs/utils/themed.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/cjs/utils/themed'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/color-palettes.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/color-palettes'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/colors.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/colors'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/components.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/components'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/components/Appearance.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/components/Appearance'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/components/AtlaskitThemeProvider.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/components/AtlaskitThemeProvider'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/components/Context.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/components/Context'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/components/Reset.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/components/Reset'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/components/Theme.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/components/Theme'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/constants.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/constants'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/elevation.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/elevation'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/hoc.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/hoc'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/index' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/index.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/math.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/math'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/types.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/types'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/typography.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/typography'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/utils/createTheme.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/utils/createTheme'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/utils/getTheme.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/utils/getTheme'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/utils/math.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/utils/math'>;\n}\ndeclare module '@atlaskit/theme/dist/esm/utils/themed.js' {\n  declare module.exports: $Exports<'@atlaskit/theme/dist/esm/utils/themed'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@babel/core_vx.x.x.js",
    "content": "// flow-typed signature: cb7d3014a793d1556dc1e82d56b79cce\n// flow-typed version: <<STUB>>/@babel/core_v^7.8.4/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@babel/core'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@babel/core' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@babel/core/lib/config/caching' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/config-chain' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/config-descriptors' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/files/configuration' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/files/import' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/files/index-browser' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/files' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/files/module-types' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/files/package' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/files/plugins' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/files/types' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/files/utils' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/full' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/helpers/config-api' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/helpers/environment' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/item' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/partial' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/pattern-to-regex' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/plugin' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/util' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/validation/option-assertions' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/validation/options' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/validation/plugins' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/config/validation/removed' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/gensync-utils/async' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/gensync-utils/fs' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/gensync-utils/resolve' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/parse' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/parser' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/parser/util/missing-plugin-helper' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/tools/build-external-helpers' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transform-ast' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transform-file-browser' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transform-file' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transform' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transformation/block-hoist-plugin' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transformation/file/file' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transformation/file/generate' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transformation/file/merge-map' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transformation' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transformation/normalize-file' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transformation/normalize-opts' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/core/lib/transformation/plugin-pass' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@babel/core/lib/config/caching.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/caching'>;\n}\ndeclare module '@babel/core/lib/config/config-chain.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/config-chain'>;\n}\ndeclare module '@babel/core/lib/config/config-descriptors.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/config-descriptors'>;\n}\ndeclare module '@babel/core/lib/config/files/configuration.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files/configuration'>;\n}\ndeclare module '@babel/core/lib/config/files/import.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files/import'>;\n}\ndeclare module '@babel/core/lib/config/files/index-browser.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files/index-browser'>;\n}\ndeclare module '@babel/core/lib/config/files/index' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files'>;\n}\ndeclare module '@babel/core/lib/config/files/index.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files'>;\n}\ndeclare module '@babel/core/lib/config/files/module-types.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files/module-types'>;\n}\ndeclare module '@babel/core/lib/config/files/package.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files/package'>;\n}\ndeclare module '@babel/core/lib/config/files/plugins.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files/plugins'>;\n}\ndeclare module '@babel/core/lib/config/files/types.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files/types'>;\n}\ndeclare module '@babel/core/lib/config/files/utils.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/files/utils'>;\n}\ndeclare module '@babel/core/lib/config/full.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/full'>;\n}\ndeclare module '@babel/core/lib/config/helpers/config-api.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/helpers/config-api'>;\n}\ndeclare module '@babel/core/lib/config/helpers/environment.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/helpers/environment'>;\n}\ndeclare module '@babel/core/lib/config/index' {\n  declare module.exports: $Exports<'@babel/core/lib/config'>;\n}\ndeclare module '@babel/core/lib/config/index.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config'>;\n}\ndeclare module '@babel/core/lib/config/item.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/item'>;\n}\ndeclare module '@babel/core/lib/config/partial.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/partial'>;\n}\ndeclare module '@babel/core/lib/config/pattern-to-regex.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/pattern-to-regex'>;\n}\ndeclare module '@babel/core/lib/config/plugin.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/plugin'>;\n}\ndeclare module '@babel/core/lib/config/util.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/util'>;\n}\ndeclare module '@babel/core/lib/config/validation/option-assertions.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/validation/option-assertions'>;\n}\ndeclare module '@babel/core/lib/config/validation/options.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/validation/options'>;\n}\ndeclare module '@babel/core/lib/config/validation/plugins.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/validation/plugins'>;\n}\ndeclare module '@babel/core/lib/config/validation/removed.js' {\n  declare module.exports: $Exports<'@babel/core/lib/config/validation/removed'>;\n}\ndeclare module '@babel/core/lib/gensync-utils/async.js' {\n  declare module.exports: $Exports<'@babel/core/lib/gensync-utils/async'>;\n}\ndeclare module '@babel/core/lib/gensync-utils/fs.js' {\n  declare module.exports: $Exports<'@babel/core/lib/gensync-utils/fs'>;\n}\ndeclare module '@babel/core/lib/gensync-utils/resolve.js' {\n  declare module.exports: $Exports<'@babel/core/lib/gensync-utils/resolve'>;\n}\ndeclare module '@babel/core/lib/index' {\n  declare module.exports: $Exports<'@babel/core/lib'>;\n}\ndeclare module '@babel/core/lib/index.js' {\n  declare module.exports: $Exports<'@babel/core/lib'>;\n}\ndeclare module '@babel/core/lib/parse.js' {\n  declare module.exports: $Exports<'@babel/core/lib/parse'>;\n}\ndeclare module '@babel/core/lib/parser/index' {\n  declare module.exports: $Exports<'@babel/core/lib/parser'>;\n}\ndeclare module '@babel/core/lib/parser/index.js' {\n  declare module.exports: $Exports<'@babel/core/lib/parser'>;\n}\ndeclare module '@babel/core/lib/parser/util/missing-plugin-helper.js' {\n  declare module.exports: $Exports<'@babel/core/lib/parser/util/missing-plugin-helper'>;\n}\ndeclare module '@babel/core/lib/tools/build-external-helpers.js' {\n  declare module.exports: $Exports<'@babel/core/lib/tools/build-external-helpers'>;\n}\ndeclare module '@babel/core/lib/transform-ast.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transform-ast'>;\n}\ndeclare module '@babel/core/lib/transform-file-browser.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transform-file-browser'>;\n}\ndeclare module '@babel/core/lib/transform-file.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transform-file'>;\n}\ndeclare module '@babel/core/lib/transform.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transform'>;\n}\ndeclare module '@babel/core/lib/transformation/block-hoist-plugin.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transformation/block-hoist-plugin'>;\n}\ndeclare module '@babel/core/lib/transformation/file/file.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transformation/file/file'>;\n}\ndeclare module '@babel/core/lib/transformation/file/generate.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transformation/file/generate'>;\n}\ndeclare module '@babel/core/lib/transformation/file/merge-map.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transformation/file/merge-map'>;\n}\ndeclare module '@babel/core/lib/transformation/index' {\n  declare module.exports: $Exports<'@babel/core/lib/transformation'>;\n}\ndeclare module '@babel/core/lib/transformation/index.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transformation'>;\n}\ndeclare module '@babel/core/lib/transformation/normalize-file.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transformation/normalize-file'>;\n}\ndeclare module '@babel/core/lib/transformation/normalize-opts.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transformation/normalize-opts'>;\n}\ndeclare module '@babel/core/lib/transformation/plugin-pass.js' {\n  declare module.exports: $Exports<'@babel/core/lib/transformation/plugin-pass'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@babel/plugin-proposal-class-properties_vx.x.x.js",
    "content": "// flow-typed signature: 31fdad1fca61525eb03b9d103b304677\n// flow-typed version: <<STUB>>/@babel/plugin-proposal-class-properties_v^7.8.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@babel/plugin-proposal-class-properties'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@babel/plugin-proposal-class-properties' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@babel/plugin-proposal-class-properties/lib' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@babel/plugin-proposal-class-properties/lib/index' {\n  declare module.exports: $Exports<'@babel/plugin-proposal-class-properties/lib'>;\n}\ndeclare module '@babel/plugin-proposal-class-properties/lib/index.js' {\n  declare module.exports: $Exports<'@babel/plugin-proposal-class-properties/lib'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@babel/plugin-transform-modules-commonjs_vx.x.x.js",
    "content": "// flow-typed signature: 389d13a8e0e9311477b7468424978e7a\n// flow-typed version: <<STUB>>/@babel/plugin-transform-modules-commonjs_v^7.8.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@babel/plugin-transform-modules-commonjs'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@babel/plugin-transform-modules-commonjs' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@babel/plugin-transform-modules-commonjs/lib' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@babel/plugin-transform-modules-commonjs/lib/index' {\n  declare module.exports: $Exports<'@babel/plugin-transform-modules-commonjs/lib'>;\n}\ndeclare module '@babel/plugin-transform-modules-commonjs/lib/index.js' {\n  declare module.exports: $Exports<'@babel/plugin-transform-modules-commonjs/lib'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@babel/plugin-transform-object-assign_vx.x.x.js",
    "content": "// flow-typed signature: 00fa6c27d03ce929444546477c2d34ce\n// flow-typed version: <<STUB>>/@babel/plugin-transform-object-assign_v^7.8.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@babel/plugin-transform-object-assign'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@babel/plugin-transform-object-assign' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@babel/plugin-transform-object-assign/lib' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@babel/plugin-transform-object-assign/lib/index' {\n  declare module.exports: $Exports<'@babel/plugin-transform-object-assign/lib'>;\n}\ndeclare module '@babel/plugin-transform-object-assign/lib/index.js' {\n  declare module.exports: $Exports<'@babel/plugin-transform-object-assign/lib'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@babel/plugin-transform-runtime_vx.x.x.js",
    "content": "// flow-typed signature: 61d11e08502afe95033bf65a551e5de0\n// flow-typed version: <<STUB>>/@babel/plugin-transform-runtime_v^7.8.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@babel/plugin-transform-runtime'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@babel/plugin-transform-runtime' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@babel/plugin-transform-runtime/lib/helpers' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/plugin-transform-runtime/lib' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/plugin-transform-runtime/lib/runtime-corejs2-definitions' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/plugin-transform-runtime/lib/runtime-corejs3-definitions' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@babel/plugin-transform-runtime/lib/helpers.js' {\n  declare module.exports: $Exports<'@babel/plugin-transform-runtime/lib/helpers'>;\n}\ndeclare module '@babel/plugin-transform-runtime/lib/index' {\n  declare module.exports: $Exports<'@babel/plugin-transform-runtime/lib'>;\n}\ndeclare module '@babel/plugin-transform-runtime/lib/index.js' {\n  declare module.exports: $Exports<'@babel/plugin-transform-runtime/lib'>;\n}\ndeclare module '@babel/plugin-transform-runtime/lib/runtime-corejs2-definitions.js' {\n  declare module.exports: $Exports<'@babel/plugin-transform-runtime/lib/runtime-corejs2-definitions'>;\n}\ndeclare module '@babel/plugin-transform-runtime/lib/runtime-corejs3-definitions.js' {\n  declare module.exports: $Exports<'@babel/plugin-transform-runtime/lib/runtime-corejs3-definitions'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@babel/preset-env_vx.x.x.js",
    "content": "// flow-typed signature: 0708f8eb3ada2b98aef5b285732ff27d\n// flow-typed version: <<STUB>>/@babel/preset-env_v^7.8.4/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@babel/preset-env'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@babel/preset-env' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@babel/preset-env/data/built-in-modules' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/data/built-in-modules.json' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/data/built-ins' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/data/built-ins.json' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/data/corejs2-built-ins' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/data/corejs2-built-ins.json' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/data/plugins' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/data/plugins.json' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/data/shipped-proposals' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/data/unreleased-labels' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/available-plugins' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/debug' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/filter-items' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/get-option-specific-excludes' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/module-transformations' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/normalize-options' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/options' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/corejs2/built-in-definitions' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/corejs2/entry-plugin' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/corejs2/get-platform-specific-default' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/corejs2/usage-plugin' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/corejs3/built-in-definitions' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/corejs3/entry-plugin' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/corejs3/shipped-proposals' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/corejs3/usage-plugin' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/regenerator/entry-plugin' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/polyfills/regenerator/usage-plugin' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/targets-parser' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/preset-env/lib/utils' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@babel/preset-env/data/built-in-modules.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/built-in-modules'>;\n}\ndeclare module '@babel/preset-env/data/built-in-modules.json.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/built-in-modules.json'>;\n}\ndeclare module '@babel/preset-env/data/built-ins.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/built-ins'>;\n}\ndeclare module '@babel/preset-env/data/built-ins.json.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/built-ins.json'>;\n}\ndeclare module '@babel/preset-env/data/corejs2-built-ins.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/corejs2-built-ins'>;\n}\ndeclare module '@babel/preset-env/data/corejs2-built-ins.json.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/corejs2-built-ins.json'>;\n}\ndeclare module '@babel/preset-env/data/plugins.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/plugins'>;\n}\ndeclare module '@babel/preset-env/data/plugins.json.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/plugins.json'>;\n}\ndeclare module '@babel/preset-env/data/shipped-proposals.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/shipped-proposals'>;\n}\ndeclare module '@babel/preset-env/data/unreleased-labels.js' {\n  declare module.exports: $Exports<'@babel/preset-env/data/unreleased-labels'>;\n}\ndeclare module '@babel/preset-env/lib/available-plugins.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/available-plugins'>;\n}\ndeclare module '@babel/preset-env/lib/debug.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/debug'>;\n}\ndeclare module '@babel/preset-env/lib/filter-items.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/filter-items'>;\n}\ndeclare module '@babel/preset-env/lib/get-option-specific-excludes.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/get-option-specific-excludes'>;\n}\ndeclare module '@babel/preset-env/lib/index' {\n  declare module.exports: $Exports<'@babel/preset-env/lib'>;\n}\ndeclare module '@babel/preset-env/lib/index.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib'>;\n}\ndeclare module '@babel/preset-env/lib/module-transformations.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/module-transformations'>;\n}\ndeclare module '@babel/preset-env/lib/normalize-options.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/normalize-options'>;\n}\ndeclare module '@babel/preset-env/lib/options.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/options'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/corejs2/built-in-definitions.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/corejs2/built-in-definitions'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/corejs2/entry-plugin.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/corejs2/entry-plugin'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/corejs2/get-platform-specific-default.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/corejs2/get-platform-specific-default'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/corejs2/usage-plugin.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/corejs2/usage-plugin'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/corejs3/built-in-definitions.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/corejs3/built-in-definitions'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/corejs3/entry-plugin.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/corejs3/entry-plugin'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/corejs3/shipped-proposals.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/corejs3/shipped-proposals'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/corejs3/usage-plugin.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/corejs3/usage-plugin'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/regenerator/entry-plugin.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/regenerator/entry-plugin'>;\n}\ndeclare module '@babel/preset-env/lib/polyfills/regenerator/usage-plugin.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/polyfills/regenerator/usage-plugin'>;\n}\ndeclare module '@babel/preset-env/lib/targets-parser.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/targets-parser'>;\n}\ndeclare module '@babel/preset-env/lib/utils.js' {\n  declare module.exports: $Exports<'@babel/preset-env/lib/utils'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@babel/preset-flow_vx.x.x.js",
    "content": "// flow-typed signature: 38cf00e2aa5f45239d4d90d87957e8f3\n// flow-typed version: <<STUB>>/@babel/preset-flow_v^7.8.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@babel/preset-flow'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@babel/preset-flow' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@babel/preset-flow/lib' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@babel/preset-flow/lib/index' {\n  declare module.exports: $Exports<'@babel/preset-flow/lib'>;\n}\ndeclare module '@babel/preset-flow/lib/index.js' {\n  declare module.exports: $Exports<'@babel/preset-flow/lib'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@babel/preset-react_vx.x.x.js",
    "content": "// flow-typed signature: 167390b2c580ca10695cac64f2c42113\n// flow-typed version: <<STUB>>/@babel/preset-react_v^7.8.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@babel/preset-react'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@babel/preset-react' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@babel/preset-react/lib' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@babel/preset-react/lib/index' {\n  declare module.exports: $Exports<'@babel/preset-react/lib'>;\n}\ndeclare module '@babel/preset-react/lib/index.js' {\n  declare module.exports: $Exports<'@babel/preset-react/lib'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@babel/runtime_vx.x.x.js",
    "content": "// flow-typed signature: 560a2517484e985de18fbd2d5e0a5b1e\n// flow-typed version: <<STUB>>/@babel/runtime_v^7.8.4/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@babel/runtime'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@babel/runtime' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@babel/runtime/helpers/applyDecoratedDescriptor' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/arrayWithHoles' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/arrayWithoutHoles' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/assertThisInitialized' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/AsyncGenerator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/asyncGeneratorDelegate' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/asyncIterator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/asyncToGenerator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/awaitAsyncGenerator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/AwaitValue' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classCallCheck' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classNameTDZError' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classPrivateFieldDestructureSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classPrivateFieldGet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classPrivateFieldLooseBase' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classPrivateFieldLooseKey' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classPrivateFieldSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classPrivateMethodGet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classPrivateMethodSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classStaticPrivateFieldSpecGet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classStaticPrivateFieldSpecSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classStaticPrivateMethodGet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/classStaticPrivateMethodSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/construct' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/createClass' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/decorate' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/defaults' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/defineEnumerableProperties' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/defineProperty' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/applyDecoratedDescriptor' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/arrayWithHoles' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/arrayWithoutHoles' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/assertThisInitialized' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/AsyncGenerator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/asyncGeneratorDelegate' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/asyncIterator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/asyncToGenerator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/awaitAsyncGenerator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/AwaitValue' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classCallCheck' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classNameTDZError' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldDestructureSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldGet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldLooseBase' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldLooseKey' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classPrivateMethodGet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classPrivateMethodSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classStaticPrivateFieldSpecGet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classStaticPrivateFieldSpecSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classStaticPrivateMethodGet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/classStaticPrivateMethodSet' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/construct' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/createClass' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/decorate' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/defaults' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/defineEnumerableProperties' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/defineProperty' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/extends' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/get' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/getPrototypeOf' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/inherits' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/inheritsLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/initializerDefineProperty' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/initializerWarningHelper' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/instanceof' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/interopRequireDefault' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/interopRequireWildcard' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/isNativeFunction' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/iterableToArray' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/iterableToArrayLimit' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/iterableToArrayLimitLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/jsx' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/newArrowCheck' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/nonIterableRest' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/nonIterableSpread' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/objectDestructuringEmpty' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/objectSpread' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/objectSpread2' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/objectWithoutProperties' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/possibleConstructorReturn' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/readOnlyError' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/set' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/setPrototypeOf' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/skipFirstGeneratorNext' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/slicedToArray' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/slicedToArrayLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/superPropBase' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/taggedTemplateLiteral' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/taggedTemplateLiteralLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/tdz' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/temporalRef' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/temporalUndefined' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/toArray' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/toConsumableArray' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/toPrimitive' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/toPropertyKey' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/typeof' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/wrapAsyncGenerator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/wrapNativeSuper' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/esm/wrapRegExp' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/extends' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/get' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/getPrototypeOf' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/inherits' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/inheritsLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/initializerDefineProperty' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/initializerWarningHelper' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/instanceof' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/interopRequireDefault' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/interopRequireWildcard' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/isNativeFunction' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/iterableToArray' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/iterableToArrayLimit' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/iterableToArrayLimitLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/jsx' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/newArrowCheck' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/nonIterableRest' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/nonIterableSpread' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/objectDestructuringEmpty' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/objectSpread' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/objectSpread2' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/objectWithoutProperties' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/objectWithoutPropertiesLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/possibleConstructorReturn' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/readOnlyError' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/set' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/setPrototypeOf' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/skipFirstGeneratorNext' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/slicedToArray' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/slicedToArrayLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/superPropBase' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/taggedTemplateLiteral' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/taggedTemplateLiteralLoose' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/tdz' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/temporalRef' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/temporalUndefined' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/toArray' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/toConsumableArray' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/toPrimitive' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/toPropertyKey' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/typeof' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/wrapAsyncGenerator' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/wrapNativeSuper' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/helpers/wrapRegExp' {\n  declare module.exports: any;\n}\n\ndeclare module '@babel/runtime/regenerator' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@babel/runtime/helpers/applyDecoratedDescriptor.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/applyDecoratedDescriptor'>;\n}\ndeclare module '@babel/runtime/helpers/arrayWithHoles.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/arrayWithHoles'>;\n}\ndeclare module '@babel/runtime/helpers/arrayWithoutHoles.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/arrayWithoutHoles'>;\n}\ndeclare module '@babel/runtime/helpers/assertThisInitialized.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/assertThisInitialized'>;\n}\ndeclare module '@babel/runtime/helpers/AsyncGenerator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/AsyncGenerator'>;\n}\ndeclare module '@babel/runtime/helpers/asyncGeneratorDelegate.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/asyncGeneratorDelegate'>;\n}\ndeclare module '@babel/runtime/helpers/asyncIterator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/asyncIterator'>;\n}\ndeclare module '@babel/runtime/helpers/asyncToGenerator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/asyncToGenerator'>;\n}\ndeclare module '@babel/runtime/helpers/awaitAsyncGenerator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/awaitAsyncGenerator'>;\n}\ndeclare module '@babel/runtime/helpers/AwaitValue.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/AwaitValue'>;\n}\ndeclare module '@babel/runtime/helpers/classCallCheck.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classCallCheck'>;\n}\ndeclare module '@babel/runtime/helpers/classNameTDZError.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classNameTDZError'>;\n}\ndeclare module '@babel/runtime/helpers/classPrivateFieldDestructureSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classPrivateFieldDestructureSet'>;\n}\ndeclare module '@babel/runtime/helpers/classPrivateFieldGet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classPrivateFieldGet'>;\n}\ndeclare module '@babel/runtime/helpers/classPrivateFieldLooseBase.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classPrivateFieldLooseBase'>;\n}\ndeclare module '@babel/runtime/helpers/classPrivateFieldLooseKey.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classPrivateFieldLooseKey'>;\n}\ndeclare module '@babel/runtime/helpers/classPrivateFieldSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classPrivateFieldSet'>;\n}\ndeclare module '@babel/runtime/helpers/classPrivateMethodGet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classPrivateMethodGet'>;\n}\ndeclare module '@babel/runtime/helpers/classPrivateMethodSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classPrivateMethodSet'>;\n}\ndeclare module '@babel/runtime/helpers/classStaticPrivateFieldSpecGet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classStaticPrivateFieldSpecGet'>;\n}\ndeclare module '@babel/runtime/helpers/classStaticPrivateFieldSpecSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classStaticPrivateFieldSpecSet'>;\n}\ndeclare module '@babel/runtime/helpers/classStaticPrivateMethodGet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classStaticPrivateMethodGet'>;\n}\ndeclare module '@babel/runtime/helpers/classStaticPrivateMethodSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/classStaticPrivateMethodSet'>;\n}\ndeclare module '@babel/runtime/helpers/construct.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/construct'>;\n}\ndeclare module '@babel/runtime/helpers/createClass.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/createClass'>;\n}\ndeclare module '@babel/runtime/helpers/decorate.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/decorate'>;\n}\ndeclare module '@babel/runtime/helpers/defaults.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/defaults'>;\n}\ndeclare module '@babel/runtime/helpers/defineEnumerableProperties.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/defineEnumerableProperties'>;\n}\ndeclare module '@babel/runtime/helpers/defineProperty.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/defineProperty'>;\n}\ndeclare module '@babel/runtime/helpers/esm/applyDecoratedDescriptor.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/applyDecoratedDescriptor'>;\n}\ndeclare module '@babel/runtime/helpers/esm/arrayWithHoles.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/arrayWithHoles'>;\n}\ndeclare module '@babel/runtime/helpers/esm/arrayWithoutHoles.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/arrayWithoutHoles'>;\n}\ndeclare module '@babel/runtime/helpers/esm/assertThisInitialized.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/assertThisInitialized'>;\n}\ndeclare module '@babel/runtime/helpers/esm/AsyncGenerator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/AsyncGenerator'>;\n}\ndeclare module '@babel/runtime/helpers/esm/asyncGeneratorDelegate.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/asyncGeneratorDelegate'>;\n}\ndeclare module '@babel/runtime/helpers/esm/asyncIterator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/asyncIterator'>;\n}\ndeclare module '@babel/runtime/helpers/esm/asyncToGenerator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/asyncToGenerator'>;\n}\ndeclare module '@babel/runtime/helpers/esm/awaitAsyncGenerator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/awaitAsyncGenerator'>;\n}\ndeclare module '@babel/runtime/helpers/esm/AwaitValue.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/AwaitValue'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classCallCheck.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classCallCheck'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classNameTDZError.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classNameTDZError'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldDestructureSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classPrivateFieldDestructureSet'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldGet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classPrivateFieldGet'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldLooseBase.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classPrivateFieldLooseBase'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldLooseKey.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classPrivateFieldLooseKey'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classPrivateFieldSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classPrivateFieldSet'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classPrivateMethodGet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classPrivateMethodGet'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classPrivateMethodSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classPrivateMethodSet'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classStaticPrivateFieldSpecGet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classStaticPrivateFieldSpecGet'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classStaticPrivateFieldSpecSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classStaticPrivateFieldSpecSet'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classStaticPrivateMethodGet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classStaticPrivateMethodGet'>;\n}\ndeclare module '@babel/runtime/helpers/esm/classStaticPrivateMethodSet.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/classStaticPrivateMethodSet'>;\n}\ndeclare module '@babel/runtime/helpers/esm/construct.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/construct'>;\n}\ndeclare module '@babel/runtime/helpers/esm/createClass.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/createClass'>;\n}\ndeclare module '@babel/runtime/helpers/esm/decorate.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/decorate'>;\n}\ndeclare module '@babel/runtime/helpers/esm/defaults.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/defaults'>;\n}\ndeclare module '@babel/runtime/helpers/esm/defineEnumerableProperties.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/defineEnumerableProperties'>;\n}\ndeclare module '@babel/runtime/helpers/esm/defineProperty.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/defineProperty'>;\n}\ndeclare module '@babel/runtime/helpers/esm/extends.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/extends'>;\n}\ndeclare module '@babel/runtime/helpers/esm/get.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/get'>;\n}\ndeclare module '@babel/runtime/helpers/esm/getPrototypeOf.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/getPrototypeOf'>;\n}\ndeclare module '@babel/runtime/helpers/esm/inherits.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/inherits'>;\n}\ndeclare module '@babel/runtime/helpers/esm/inheritsLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/inheritsLoose'>;\n}\ndeclare module '@babel/runtime/helpers/esm/initializerDefineProperty.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/initializerDefineProperty'>;\n}\ndeclare module '@babel/runtime/helpers/esm/initializerWarningHelper.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/initializerWarningHelper'>;\n}\ndeclare module '@babel/runtime/helpers/esm/instanceof.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/instanceof'>;\n}\ndeclare module '@babel/runtime/helpers/esm/interopRequireDefault.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/interopRequireDefault'>;\n}\ndeclare module '@babel/runtime/helpers/esm/interopRequireWildcard.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/interopRequireWildcard'>;\n}\ndeclare module '@babel/runtime/helpers/esm/isNativeFunction.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/isNativeFunction'>;\n}\ndeclare module '@babel/runtime/helpers/esm/iterableToArray.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/iterableToArray'>;\n}\ndeclare module '@babel/runtime/helpers/esm/iterableToArrayLimit.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/iterableToArrayLimit'>;\n}\ndeclare module '@babel/runtime/helpers/esm/iterableToArrayLimitLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/iterableToArrayLimitLoose'>;\n}\ndeclare module '@babel/runtime/helpers/esm/jsx.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/jsx'>;\n}\ndeclare module '@babel/runtime/helpers/esm/newArrowCheck.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/newArrowCheck'>;\n}\ndeclare module '@babel/runtime/helpers/esm/nonIterableRest.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/nonIterableRest'>;\n}\ndeclare module '@babel/runtime/helpers/esm/nonIterableSpread.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/nonIterableSpread'>;\n}\ndeclare module '@babel/runtime/helpers/esm/objectDestructuringEmpty.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/objectDestructuringEmpty'>;\n}\ndeclare module '@babel/runtime/helpers/esm/objectSpread.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/objectSpread'>;\n}\ndeclare module '@babel/runtime/helpers/esm/objectSpread2.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/objectSpread2'>;\n}\ndeclare module '@babel/runtime/helpers/esm/objectWithoutProperties.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/objectWithoutProperties'>;\n}\ndeclare module '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/objectWithoutPropertiesLoose'>;\n}\ndeclare module '@babel/runtime/helpers/esm/possibleConstructorReturn.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/possibleConstructorReturn'>;\n}\ndeclare module '@babel/runtime/helpers/esm/readOnlyError.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/readOnlyError'>;\n}\ndeclare module '@babel/runtime/helpers/esm/set.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/set'>;\n}\ndeclare module '@babel/runtime/helpers/esm/setPrototypeOf.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/setPrototypeOf'>;\n}\ndeclare module '@babel/runtime/helpers/esm/skipFirstGeneratorNext.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/skipFirstGeneratorNext'>;\n}\ndeclare module '@babel/runtime/helpers/esm/slicedToArray.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/slicedToArray'>;\n}\ndeclare module '@babel/runtime/helpers/esm/slicedToArrayLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/slicedToArrayLoose'>;\n}\ndeclare module '@babel/runtime/helpers/esm/superPropBase.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/superPropBase'>;\n}\ndeclare module '@babel/runtime/helpers/esm/taggedTemplateLiteral.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/taggedTemplateLiteral'>;\n}\ndeclare module '@babel/runtime/helpers/esm/taggedTemplateLiteralLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/taggedTemplateLiteralLoose'>;\n}\ndeclare module '@babel/runtime/helpers/esm/tdz.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/tdz'>;\n}\ndeclare module '@babel/runtime/helpers/esm/temporalRef.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/temporalRef'>;\n}\ndeclare module '@babel/runtime/helpers/esm/temporalUndefined.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/temporalUndefined'>;\n}\ndeclare module '@babel/runtime/helpers/esm/toArray.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/toArray'>;\n}\ndeclare module '@babel/runtime/helpers/esm/toConsumableArray.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/toConsumableArray'>;\n}\ndeclare module '@babel/runtime/helpers/esm/toPrimitive.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/toPrimitive'>;\n}\ndeclare module '@babel/runtime/helpers/esm/toPropertyKey.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/toPropertyKey'>;\n}\ndeclare module '@babel/runtime/helpers/esm/typeof.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/typeof'>;\n}\ndeclare module '@babel/runtime/helpers/esm/wrapAsyncGenerator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/wrapAsyncGenerator'>;\n}\ndeclare module '@babel/runtime/helpers/esm/wrapNativeSuper.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/wrapNativeSuper'>;\n}\ndeclare module '@babel/runtime/helpers/esm/wrapRegExp.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/esm/wrapRegExp'>;\n}\ndeclare module '@babel/runtime/helpers/extends.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/extends'>;\n}\ndeclare module '@babel/runtime/helpers/get.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/get'>;\n}\ndeclare module '@babel/runtime/helpers/getPrototypeOf.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/getPrototypeOf'>;\n}\ndeclare module '@babel/runtime/helpers/inherits.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/inherits'>;\n}\ndeclare module '@babel/runtime/helpers/inheritsLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/inheritsLoose'>;\n}\ndeclare module '@babel/runtime/helpers/initializerDefineProperty.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/initializerDefineProperty'>;\n}\ndeclare module '@babel/runtime/helpers/initializerWarningHelper.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/initializerWarningHelper'>;\n}\ndeclare module '@babel/runtime/helpers/instanceof.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/instanceof'>;\n}\ndeclare module '@babel/runtime/helpers/interopRequireDefault.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/interopRequireDefault'>;\n}\ndeclare module '@babel/runtime/helpers/interopRequireWildcard.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/interopRequireWildcard'>;\n}\ndeclare module '@babel/runtime/helpers/isNativeFunction.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/isNativeFunction'>;\n}\ndeclare module '@babel/runtime/helpers/iterableToArray.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/iterableToArray'>;\n}\ndeclare module '@babel/runtime/helpers/iterableToArrayLimit.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/iterableToArrayLimit'>;\n}\ndeclare module '@babel/runtime/helpers/iterableToArrayLimitLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/iterableToArrayLimitLoose'>;\n}\ndeclare module '@babel/runtime/helpers/jsx.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/jsx'>;\n}\ndeclare module '@babel/runtime/helpers/newArrowCheck.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/newArrowCheck'>;\n}\ndeclare module '@babel/runtime/helpers/nonIterableRest.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/nonIterableRest'>;\n}\ndeclare module '@babel/runtime/helpers/nonIterableSpread.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/nonIterableSpread'>;\n}\ndeclare module '@babel/runtime/helpers/objectDestructuringEmpty.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/objectDestructuringEmpty'>;\n}\ndeclare module '@babel/runtime/helpers/objectSpread.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/objectSpread'>;\n}\ndeclare module '@babel/runtime/helpers/objectSpread2.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/objectSpread2'>;\n}\ndeclare module '@babel/runtime/helpers/objectWithoutProperties.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/objectWithoutProperties'>;\n}\ndeclare module '@babel/runtime/helpers/objectWithoutPropertiesLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/objectWithoutPropertiesLoose'>;\n}\ndeclare module '@babel/runtime/helpers/possibleConstructorReturn.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/possibleConstructorReturn'>;\n}\ndeclare module '@babel/runtime/helpers/readOnlyError.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/readOnlyError'>;\n}\ndeclare module '@babel/runtime/helpers/set.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/set'>;\n}\ndeclare module '@babel/runtime/helpers/setPrototypeOf.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/setPrototypeOf'>;\n}\ndeclare module '@babel/runtime/helpers/skipFirstGeneratorNext.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/skipFirstGeneratorNext'>;\n}\ndeclare module '@babel/runtime/helpers/slicedToArray.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/slicedToArray'>;\n}\ndeclare module '@babel/runtime/helpers/slicedToArrayLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/slicedToArrayLoose'>;\n}\ndeclare module '@babel/runtime/helpers/superPropBase.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/superPropBase'>;\n}\ndeclare module '@babel/runtime/helpers/taggedTemplateLiteral.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/taggedTemplateLiteral'>;\n}\ndeclare module '@babel/runtime/helpers/taggedTemplateLiteralLoose.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/taggedTemplateLiteralLoose'>;\n}\ndeclare module '@babel/runtime/helpers/tdz.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/tdz'>;\n}\ndeclare module '@babel/runtime/helpers/temporalRef.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/temporalRef'>;\n}\ndeclare module '@babel/runtime/helpers/temporalUndefined.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/temporalUndefined'>;\n}\ndeclare module '@babel/runtime/helpers/toArray.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/toArray'>;\n}\ndeclare module '@babel/runtime/helpers/toConsumableArray.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/toConsumableArray'>;\n}\ndeclare module '@babel/runtime/helpers/toPrimitive.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/toPrimitive'>;\n}\ndeclare module '@babel/runtime/helpers/toPropertyKey.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/toPropertyKey'>;\n}\ndeclare module '@babel/runtime/helpers/typeof.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/typeof'>;\n}\ndeclare module '@babel/runtime/helpers/wrapAsyncGenerator.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/wrapAsyncGenerator'>;\n}\ndeclare module '@babel/runtime/helpers/wrapNativeSuper.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/wrapNativeSuper'>;\n}\ndeclare module '@babel/runtime/helpers/wrapRegExp.js' {\n  declare module.exports: $Exports<'@babel/runtime/helpers/wrapRegExp'>;\n}\ndeclare module '@babel/runtime/regenerator/index' {\n  declare module.exports: $Exports<'@babel/runtime/regenerator'>;\n}\ndeclare module '@babel/runtime/regenerator/index.js' {\n  declare module.exports: $Exports<'@babel/runtime/regenerator'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@emotion/babel-preset-css-prop_vx.x.x.js",
    "content": "// flow-typed signature: 805b1d4e95b6d31d83ce3945119b930f\n// flow-typed version: <<STUB>>/@emotion/babel-preset-css-prop_v^10.0.27/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@emotion/babel-preset-css-prop'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@emotion/babel-preset-css-prop' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.cjs.dev' {\n  declare module.exports: any;\n}\n\ndeclare module '@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module '@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.cjs.prod' {\n  declare module.exports: any;\n}\n\ndeclare module '@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.esm' {\n  declare module.exports: any;\n}\n\ndeclare module '@emotion/babel-preset-css-prop/src' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.cjs.dev.js' {\n  declare module.exports: $Exports<'@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.cjs.dev'>;\n}\ndeclare module '@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.cjs.js' {\n  declare module.exports: $Exports<'@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.cjs'>;\n}\ndeclare module '@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.cjs.prod.js' {\n  declare module.exports: $Exports<'@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.cjs.prod'>;\n}\ndeclare module '@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.esm.js' {\n  declare module.exports: $Exports<'@emotion/babel-preset-css-prop/dist/babel-preset-css-prop.esm'>;\n}\ndeclare module '@emotion/babel-preset-css-prop/src/index' {\n  declare module.exports: $Exports<'@emotion/babel-preset-css-prop/src'>;\n}\ndeclare module '@emotion/babel-preset-css-prop/src/index.js' {\n  declare module.exports: $Exports<'@emotion/babel-preset-css-prop/src'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@storybook/react_v5.x.x.js",
    "content": "// flow-typed signature: e484579841f3cb1e8f57a768abc4642d\n// flow-typed version: c6154227d1/@storybook/react_v5.x.x/flow_>=v0.104.x\n\ntype NodeModule = typeof module;\n\ndeclare module '@storybook/react' {\n  declare type Context = {\n    kind: string,\n    story: string,\n    ...\n  };\n  declare type Renderable =\n    | string\n    | number\n    | React$Element<any>\n    | Iterable<?Renderable>;\n  declare type RenderCallback = (\n    context: Context\n  ) => Renderable;\n  declare type RenderFunction = () => Renderable;\n\n  declare type StoryDecorator = (\n    story: RenderFunction,\n    context: Context\n  ) => Renderable;\n\n  declare type DecoratorParameters = { [key: string]: any, ... };\n\n  declare interface Story {\n    +kind: string;\n    add(\n      storyName: string,\n      callback: RenderCallback,\n      parameters?: DecoratorParameters\n    ): Story;\n    addDecorator(decorator: StoryDecorator): Story;\n    addParameters(parameters: DecoratorParameters): Story;\n  }\n\n  declare interface StoryObject {\n    name: string;\n    render: RenderFunction;\n  }\n\n  declare interface StoryBucket {\n    kind: string;\n    filename: string;\n    stories: Array<StoryObject>;\n  }\n\n  declare function addDecorator(decorator: StoryDecorator): void;\n  declare function addParameters(parameters: DecoratorParameters): void;\n  declare function clearDecorators(): void;\n  declare function configure(fn: () => void, module: NodeModule): void;\n  declare function setAddon(addon: Object): void;\n  declare function storiesOf(name: string, module: NodeModule): Story;\n  declare function storiesOf<T>(name: string, module: NodeModule): Story & T;\n  declare function forceReRender(): void;\n\n  declare function getStorybook(): Array<StoryBucket>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@storybook/theming_vx.x.x.js",
    "content": "// flow-typed signature: 080f7d0bbf0e3c93ed82de3782d4b9f9\n// flow-typed version: <<STUB>>/@storybook/theming_v^5.3.10/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   '@storybook/theming'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module '@storybook/theming' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module '@storybook/theming/create' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/animation' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/base' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/convert' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/create' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/ensure' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/global' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/modules/syntax' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/themes/dark' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/themes/light' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/types' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/typings.d' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/dist/utils' {\n  declare module.exports: any;\n}\n\ndeclare module '@storybook/theming/paths' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module '@storybook/theming/create.js' {\n  declare module.exports: $Exports<'@storybook/theming/create'>;\n}\ndeclare module '@storybook/theming/dist/animation.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/animation'>;\n}\ndeclare module '@storybook/theming/dist/base.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/base'>;\n}\ndeclare module '@storybook/theming/dist/convert.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/convert'>;\n}\ndeclare module '@storybook/theming/dist/create.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/create'>;\n}\ndeclare module '@storybook/theming/dist/ensure.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/ensure'>;\n}\ndeclare module '@storybook/theming/dist/global.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/global'>;\n}\ndeclare module '@storybook/theming/dist/index' {\n  declare module.exports: $Exports<'@storybook/theming/dist'>;\n}\ndeclare module '@storybook/theming/dist/index.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist'>;\n}\ndeclare module '@storybook/theming/dist/modules/syntax.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/modules/syntax'>;\n}\ndeclare module '@storybook/theming/dist/themes/dark.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/themes/dark'>;\n}\ndeclare module '@storybook/theming/dist/themes/light.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/themes/light'>;\n}\ndeclare module '@storybook/theming/dist/types.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/types'>;\n}\ndeclare module '@storybook/theming/dist/typings.d.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/typings.d'>;\n}\ndeclare module '@storybook/theming/dist/utils.js' {\n  declare module.exports: $Exports<'@storybook/theming/dist/utils'>;\n}\ndeclare module '@storybook/theming/paths.js' {\n  declare module.exports: $Exports<'@storybook/theming/paths'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/@testing-library/react_v9.x.x.js",
    "content": "// flow-typed signature: 38ccc5bbcbb54d21f37adca5cc3ed7a1\n// flow-typed version: 0b0eb4afe9/@testing-library/react_v9.x.x/flow_>=v0.104.x\n\ndeclare module '@testing-library/react' {\n  // This type comes from\n  // https://github.com/facebook/flow/blob/v0.104.0/lib/react-dom.js#L64\n  declare type ReactDOMTestUtilsThenable = {\n    then(resolve: () => mixed, reject?: () => mixed): mixed,\n    ...\n  };\n  // This type comes from\n  // https://github.com/facebook/flow/blob/v0.104.0/lib/react-dom.js#L116\n  declare type ReactDOMTestUtilsAct = (\n    callback: () => void | ReactDOMTestUtilsThenable\n  ) => ReactDOMTestUtilsThenable;\n\n  declare type TextMatch =\n    | string\n    | RegExp\n    | ((content: string, element: HTMLElement) => boolean);\n\n  declare type TextMatchOptions = {\n    exact?: boolean,\n    trim?: boolean,\n    collapseWhitespace?: boolean,\n    ...\n  };\n\n  declare type SelectorMatchOptions = {\n    selector?: string,\n    ...\n  } & TextMatchOptions;\n\n  declare type GetByText = (\n    text: TextMatch,\n    options?: SelectorMatchOptions\n  ) => HTMLElement;\n\n  declare type QueryByText = (\n    text: TextMatch,\n    options?: SelectorMatchOptions\n  ) => ?HTMLElement;\n\n  declare type AllByText = (\n    text: TextMatch,\n    options?: SelectorMatchOptions\n  ) => Array<HTMLElement>;\n\n  declare type GetByBoundAttribute = (\n    text: TextMatch,\n    options?: TextMatchOptions\n  ) => HTMLElement;\n\n  declare type QueryByBoundAttribute = (\n    text: TextMatch,\n    options?: TextMatchOptions\n  ) => ?HTMLElement;\n\n  declare type AllByBoundAttribute = (\n    text: TextMatch,\n    options?: TextMatchOptions\n  ) => Array<HTMLElement>;\n\n  declare type GetsAndQueries = {|\n    getByAltText: GetByBoundAttribute,\n    getAllByAltText: AllByBoundAttribute,\n    queryByAltText: QueryByBoundAttribute,\n    queryAllByAltText: AllByBoundAttribute,\n\n    getByDisplayValue: GetByBoundAttribute,\n    getAllByDisplayValue: AllByBoundAttribute,\n    queryByDisplayValue: QueryByBoundAttribute,\n    queryAllByDisplayValue: AllByBoundAttribute,\n\n    getByLabelText: GetByText,\n    getAllByLabelText: AllByText,\n    queryByLabelText: QueryByText,\n    queryAllByLabelText: AllByText,\n\n    getByPlaceholderText: GetByBoundAttribute,\n    getAllByPlaceholderText: AllByBoundAttribute,\n    queryByPlaceholderText: QueryByBoundAttribute,\n    queryAllByPlaceholderText: AllByBoundAttribute,\n\n    getByRole: GetByBoundAttribute,\n    getAllByRole: AllByBoundAttribute,\n    queryByRole: QueryByBoundAttribute,\n    queryAllByRole: AllByBoundAttribute,\n\n    getBySelectText: GetByBoundAttribute,\n    getAllBySelectText: AllByBoundAttribute,\n    queryBySelectText: QueryByBoundAttribute,\n    queryAllBySelectText: AllByBoundAttribute,\n\n    getByTestId: GetByBoundAttribute,\n    getAllByTestId: AllByBoundAttribute,\n    queryByTestId: QueryByBoundAttribute,\n    queryAllByTestId: AllByBoundAttribute,\n\n    getByText: GetByText,\n    getAllByText: AllByText,\n    queryByText: QueryByText,\n    queryAllByText: AllByText,\n\n    getByTitle: GetByBoundAttribute,\n    getAllByTitle: AllByBoundAttribute,\n    queryByTitle: QueryByBoundAttribute,\n    queryAllByTitle: AllByBoundAttribute,\n\n    getByValue: GetByBoundAttribute,\n    getAllByValue: AllByBoundAttribute,\n    queryByValue: QueryByBoundAttribute,\n    queryAllByValue: AllByBoundAttribute,\n  |};\n\n  declare type FireEvent<TInit> = (\n    element: HTMLElement,\n    eventProperties?: TInit\n  ) => boolean;\n\n  declare type RenderResult<Queries = GetsAndQueries> = {\n    ...Queries,\n    container: HTMLDivElement,\n    unmount: () => void,\n    baseElement: HTMLElement,\n    asFragment: () => DocumentFragment,\n    debug: (baseElement?: HTMLElement) => void,\n    rerender: (ui: React$Element<*>) => void,\n    ...\n  };\n\n  declare export type RenderOptionsWithoutCustomQueries = {|\n    container?: HTMLElement,\n    baseElement?: HTMLElement,\n    hydrate?: boolean,\n    wrapper?: React.ComponentType,\n  |};\n\n  declare export type RenderOptionsWithCustomQueries<\n    CustomQueries: { ... }\n  > = {|\n    queries: CustomQueries,\n    container?: HTMLElement,\n    baseElement?: HTMLElement,\n    hydrate?: boolean,\n    wrapper?: React.ComponentType,\n  |};\n\n  declare export function render(\n    ui: React.ReactElement<any>,\n    options?: RenderOptionsWithoutCustomQueries\n  ): RenderResult<>;\n  declare export function render<\n    CustomQueries: { [string]: (...args: Array<any>) => any, ... }\n  >(\n    ui: React.ReactElement<any>,\n    options: RenderOptionsWithCustomQueries<CustomQueries>\n  ): RenderResult<CustomQueries>;\n\n  declare export var act: ReactDOMTestUtilsAct;\n  declare export function cleanup(): void;\n  declare export function wait(\n    callback?: () => void,\n    options?: {\n      timeout?: number,\n      interval?: number,\n      ...\n    }\n  ): Promise<void>;\n  declare export function waitForDomChange<T>(options?: {\n    container?: HTMLElement,\n    timeout?: number,\n    mutationObserverOptions?: MutationObserverInit,\n    ...\n  }): Promise<T>;\n  declare export function waitForElement<T>(\n    callback?: () => T,\n    options?: {\n      container?: HTMLElement,\n      timeout?: number,\n      mutationObserverOptions?: MutationObserverInit,\n      ...\n    }\n  ): Promise<T>;\n  declare export function within(\n    element: HTMLElement,\n    queriesToBind?: GetsAndQueries | Array<GetsAndQueries>\n  ): GetsAndQueries;\n\n  // Loose custom type\n  declare export var createEvent: {|\n    [key: string]: (...any[]) => any,\n  |};\n\n  declare export var fireEvent: {|\n    (element: HTMLElement, event: Event): void,\n\n    copy: FireEvent<Event$Init>,\n    cut: FireEvent<Event$Init>,\n    paste: FireEvent<Event$Init>,\n    compositionEnd: FireEvent<Event$Init>,\n    compositionStart: FireEvent<Event$Init>,\n    compositionUpdate: FireEvent<Event$Init>,\n    keyDown: FireEvent<Event$Init>,\n    keyPress: FireEvent<Event$Init>,\n    keyUp: FireEvent<Event$Init>,\n    focus: FireEvent<Event$Init>,\n    blur: FireEvent<Event$Init>,\n    change: FireEvent<Event$Init>,\n    input: FireEvent<Event$Init>,\n    invalid: FireEvent<Event$Init>,\n    submit: FireEvent<Event$Init>,\n    click: FireEvent<MouseEvent$MouseEventInit>,\n    contextMenu: FireEvent<MouseEvent$MouseEventInit>,\n    dblClick: FireEvent<MouseEvent$MouseEventInit>,\n    doubleClick: FireEvent<MouseEvent$MouseEventInit>,\n    drag: FireEvent<MouseEvent$MouseEventInit>,\n    dragEnd: FireEvent<MouseEvent$MouseEventInit>,\n    dragEnter: FireEvent<MouseEvent$MouseEventInit>,\n    dragExit: FireEvent<MouseEvent$MouseEventInit>,\n    dragLeave: FireEvent<MouseEvent$MouseEventInit>,\n    dragOver: FireEvent<MouseEvent$MouseEventInit>,\n    dragStart: FireEvent<MouseEvent$MouseEventInit>,\n    drop: FireEvent<MouseEvent$MouseEventInit>,\n    mouseDown: FireEvent<MouseEvent$MouseEventInit>,\n    mouseEnter: FireEvent<MouseEvent$MouseEventInit>,\n    mouseLeave: FireEvent<MouseEvent$MouseEventInit>,\n    mouseMove: FireEvent<MouseEvent$MouseEventInit>,\n    mouseOut: FireEvent<MouseEvent$MouseEventInit>,\n    mouseOver: FireEvent<MouseEvent$MouseEventInit>,\n    mouseUp: FireEvent<MouseEvent$MouseEventInit>,\n    select: FireEvent<Event$Init>,\n    touchCancel: FireEvent<Event$Init>,\n    touchEnd: FireEvent<Event$Init>,\n    touchMove: FireEvent<Event$Init>,\n    touchStart: FireEvent<Event$Init>,\n    scroll: FireEvent<Event$Init>,\n    wheel: FireEvent<MouseEvent$MouseEventInit>,\n    abort: FireEvent<Event$Init>,\n    canPlay: FireEvent<Event$Init>,\n    canPlayThrough: FireEvent<Event$Init>,\n    durationChange: FireEvent<Event$Init>,\n    emptied: FireEvent<Event$Init>,\n    encrypted: FireEvent<Event$Init>,\n    ended: FireEvent<Event$Init>,\n    loadedData: FireEvent<Event$Init>,\n    loadedMetadata: FireEvent<Event$Init>,\n    loadStart: FireEvent<Event$Init>,\n    pause: FireEvent<Event$Init>,\n    play: FireEvent<Event$Init>,\n    playing: FireEvent<Event$Init>,\n    progress: FireEvent<Event$Init>,\n    rateChange: FireEvent<Event$Init>,\n    seeked: FireEvent<Event$Init>,\n    seeking: FireEvent<Event$Init>,\n    stalled: FireEvent<Event$Init>,\n    suspend: FireEvent<Event$Init>,\n    timeUpdate: FireEvent<Event$Init>,\n    volumeChange: FireEvent<Event$Init>,\n    waiting: FireEvent<Event$Init>,\n    load: FireEvent<Event$Init>,\n    error: FireEvent<Event$Init>,\n    animationStart: FireEvent<Event$Init>,\n    animationEnd: FireEvent<Event$Init>,\n    animationIteration: FireEvent<Event$Init>,\n    transitionEnd: FireEvent<Event$Init>,\n  |};\n\n  // dom-testing-library re-exports\n  declare export function queryByTestId(\n    container: HTMLElement,\n    id: TextMatch,\n    options?: TextMatchOptions\n  ): ?HTMLElement;\n  declare export function getByTestId(\n    container: HTMLElement,\n    id: TextMatch,\n    options?: TextMatchOptions\n  ): HTMLElement;\n  declare export function queryByText(\n    container: HTMLElement,\n    text: TextMatch,\n    options?: TextMatchOptions\n  ): ?HTMLElement;\n  declare export function getByText(\n    container: HTMLElement,\n    text: TextMatch,\n    options?: { selector?: string, ... } & TextMatchOptions\n  ): HTMLElement;\n  declare export function queryByPlaceholderText(\n    container: HTMLElement,\n    text: TextMatch,\n    options?: TextMatchOptions\n  ): ?HTMLElement;\n  declare export function getByPlaceholderText(\n    container: HTMLElement,\n    text: TextMatch,\n    options?: TextMatchOptions\n  ): HTMLElement;\n  declare export function queryByLabelText(\n    container: HTMLElement,\n    text: TextMatch,\n    options?: TextMatchOptions\n  ): ?HTMLElement;\n  declare export function getByLabelText(\n    container: HTMLElement,\n    text: TextMatch,\n    options?: { selector?: string, ... } & TextMatchOptions\n  ): HTMLElement;\n  declare export function queryByAltText(\n    container: HTMLElement,\n    text: TextMatch,\n    options?: TextMatchOptions\n  ): ?HTMLElement;\n  declare export function getByAltText(\n    container: HTMLElement,\n    text: TextMatch,\n    options?: TextMatchOptions\n  ): HTMLElement;\n}\n"
  },
  {
    "path": "flow-typed/npm/babel-core_vx.x.x.js",
    "content": "// flow-typed signature: 38a9f796011f49b3d1a03bf8b2a9de1b\n// flow-typed version: <<STUB>>/babel-core_v^7.0.0-bridge.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'babel-core'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'babel-core' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\n\n\n// Filename aliases\ndeclare module 'babel-core/index' {\n  declare module.exports: $Exports<'babel-core'>;\n}\ndeclare module 'babel-core/index.js' {\n  declare module.exports: $Exports<'babel-core'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/babel-eslint_vx.x.x.js",
    "content": "// flow-typed signature: 438f0fc9d82d9e6059d884f790138904\n// flow-typed version: <<STUB>>/babel-eslint_v^10.0.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'babel-eslint'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'babel-eslint' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'babel-eslint/lib/analyze-scope' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/babylon-to-espree/attachComments' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/babylon-to-espree/convertComments' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/babylon-to-espree/convertTemplateType' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/babylon-to-espree' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/babylon-to-espree/toAST' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/babylon-to-espree/toToken' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/babylon-to-espree/toTokens' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/parse-with-scope' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/parse' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/require-from-eslint' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-eslint/lib/visitor-keys' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'babel-eslint/lib/analyze-scope.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/analyze-scope'>;\n}\ndeclare module 'babel-eslint/lib/babylon-to-espree/attachComments.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/attachComments'>;\n}\ndeclare module 'babel-eslint/lib/babylon-to-espree/convertComments.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/convertComments'>;\n}\ndeclare module 'babel-eslint/lib/babylon-to-espree/convertTemplateType.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/convertTemplateType'>;\n}\ndeclare module 'babel-eslint/lib/babylon-to-espree/index' {\n  declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree'>;\n}\ndeclare module 'babel-eslint/lib/babylon-to-espree/index.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree'>;\n}\ndeclare module 'babel-eslint/lib/babylon-to-espree/toAST.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/toAST'>;\n}\ndeclare module 'babel-eslint/lib/babylon-to-espree/toToken.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/toToken'>;\n}\ndeclare module 'babel-eslint/lib/babylon-to-espree/toTokens.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/toTokens'>;\n}\ndeclare module 'babel-eslint/lib/index' {\n  declare module.exports: $Exports<'babel-eslint/lib'>;\n}\ndeclare module 'babel-eslint/lib/index.js' {\n  declare module.exports: $Exports<'babel-eslint/lib'>;\n}\ndeclare module 'babel-eslint/lib/parse-with-scope.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/parse-with-scope'>;\n}\ndeclare module 'babel-eslint/lib/parse.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/parse'>;\n}\ndeclare module 'babel-eslint/lib/require-from-eslint.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/require-from-eslint'>;\n}\ndeclare module 'babel-eslint/lib/visitor-keys.js' {\n  declare module.exports: $Exports<'babel-eslint/lib/visitor-keys'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/babel-jest_vx.x.x.js",
    "content": "// flow-typed signature: 2c1aa1e92b7497568f30f639b5c77ac5\n// flow-typed version: <<STUB>>/babel-jest_v^25.1.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'babel-jest'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'babel-jest' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'babel-jest/build' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'babel-jest/build/index' {\n  declare module.exports: $Exports<'babel-jest/build'>;\n}\ndeclare module 'babel-jest/build/index.js' {\n  declare module.exports: $Exports<'babel-jest/build'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/babel-loader_vx.x.x.js",
    "content": "// flow-typed signature: acf554b99e834af6f952d1fc21701cb7\n// flow-typed version: <<STUB>>/babel-loader_v^8.0.6/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'babel-loader'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'babel-loader' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'babel-loader/lib/cache' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-loader/lib/Error' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-loader/lib' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-loader/lib/injectCaller' {\n  declare module.exports: any;\n}\n\ndeclare module 'babel-loader/lib/transform' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'babel-loader/lib/cache.js' {\n  declare module.exports: $Exports<'babel-loader/lib/cache'>;\n}\ndeclare module 'babel-loader/lib/Error.js' {\n  declare module.exports: $Exports<'babel-loader/lib/Error'>;\n}\ndeclare module 'babel-loader/lib/index' {\n  declare module.exports: $Exports<'babel-loader/lib'>;\n}\ndeclare module 'babel-loader/lib/index.js' {\n  declare module.exports: $Exports<'babel-loader/lib'>;\n}\ndeclare module 'babel-loader/lib/injectCaller.js' {\n  declare module.exports: $Exports<'babel-loader/lib/injectCaller'>;\n}\ndeclare module 'babel-loader/lib/transform.js' {\n  declare module.exports: $Exports<'babel-loader/lib/transform'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/babel-plugin-dev-expression_vx.x.x.js",
    "content": "// flow-typed signature: f7a859a0f3359b3dda3451326996c333\n// flow-typed version: <<STUB>>/babel-plugin-dev-expression_v^0.2.2/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'babel-plugin-dev-expression'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'babel-plugin-dev-expression' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'babel-plugin-dev-expression/dev-expression' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'babel-plugin-dev-expression/dev-expression.js' {\n  declare module.exports: $Exports<'babel-plugin-dev-expression/dev-expression'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/cross-env_vx.x.x.js",
    "content": "// flow-typed signature: d2faacc42641099c850dd003d8c69717\n// flow-typed version: <<STUB>>/cross-env_v^7.0.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'cross-env'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'cross-env' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'cross-env/src/bin/cross-env-shell' {\n  declare module.exports: any;\n}\n\ndeclare module 'cross-env/src/bin/cross-env' {\n  declare module.exports: any;\n}\n\ndeclare module 'cross-env/src/command' {\n  declare module.exports: any;\n}\n\ndeclare module 'cross-env/src' {\n  declare module.exports: any;\n}\n\ndeclare module 'cross-env/src/is-windows' {\n  declare module.exports: any;\n}\n\ndeclare module 'cross-env/src/variable' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'cross-env/src/bin/cross-env-shell.js' {\n  declare module.exports: $Exports<'cross-env/src/bin/cross-env-shell'>;\n}\ndeclare module 'cross-env/src/bin/cross-env.js' {\n  declare module.exports: $Exports<'cross-env/src/bin/cross-env'>;\n}\ndeclare module 'cross-env/src/command.js' {\n  declare module.exports: $Exports<'cross-env/src/command'>;\n}\ndeclare module 'cross-env/src/index' {\n  declare module.exports: $Exports<'cross-env/src'>;\n}\ndeclare module 'cross-env/src/index.js' {\n  declare module.exports: $Exports<'cross-env/src'>;\n}\ndeclare module 'cross-env/src/is-windows.js' {\n  declare module.exports: $Exports<'cross-env/src/is-windows'>;\n}\ndeclare module 'cross-env/src/variable.js' {\n  declare module.exports: $Exports<'cross-env/src/variable'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/cypress_vx.x.x.js",
    "content": "// flow-typed signature: 9029122d83d84e51d7c2cec68d3e659e\n// flow-typed version: <<STUB>>/cypress_v^3.8.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'cypress'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'cypress' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'cypress/lib/cli' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/cypress' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/errors' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/exec/open' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/exec/run' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/exec/spawn' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/exec/versions' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/exec/xvfb' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/fs' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/logger' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/tasks/cache' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/tasks/download' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/tasks/install' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/tasks/state' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/tasks/unzip' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/tasks/verify' {\n  declare module.exports: any;\n}\n\ndeclare module 'cypress/lib/util' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'cypress/index' {\n  declare module.exports: $Exports<'cypress'>;\n}\ndeclare module 'cypress/index.js' {\n  declare module.exports: $Exports<'cypress'>;\n}\ndeclare module 'cypress/lib/cli.js' {\n  declare module.exports: $Exports<'cypress/lib/cli'>;\n}\ndeclare module 'cypress/lib/cypress.js' {\n  declare module.exports: $Exports<'cypress/lib/cypress'>;\n}\ndeclare module 'cypress/lib/errors.js' {\n  declare module.exports: $Exports<'cypress/lib/errors'>;\n}\ndeclare module 'cypress/lib/exec/open.js' {\n  declare module.exports: $Exports<'cypress/lib/exec/open'>;\n}\ndeclare module 'cypress/lib/exec/run.js' {\n  declare module.exports: $Exports<'cypress/lib/exec/run'>;\n}\ndeclare module 'cypress/lib/exec/spawn.js' {\n  declare module.exports: $Exports<'cypress/lib/exec/spawn'>;\n}\ndeclare module 'cypress/lib/exec/versions.js' {\n  declare module.exports: $Exports<'cypress/lib/exec/versions'>;\n}\ndeclare module 'cypress/lib/exec/xvfb.js' {\n  declare module.exports: $Exports<'cypress/lib/exec/xvfb'>;\n}\ndeclare module 'cypress/lib/fs.js' {\n  declare module.exports: $Exports<'cypress/lib/fs'>;\n}\ndeclare module 'cypress/lib/logger.js' {\n  declare module.exports: $Exports<'cypress/lib/logger'>;\n}\ndeclare module 'cypress/lib/tasks/cache.js' {\n  declare module.exports: $Exports<'cypress/lib/tasks/cache'>;\n}\ndeclare module 'cypress/lib/tasks/download.js' {\n  declare module.exports: $Exports<'cypress/lib/tasks/download'>;\n}\ndeclare module 'cypress/lib/tasks/install.js' {\n  declare module.exports: $Exports<'cypress/lib/tasks/install'>;\n}\ndeclare module 'cypress/lib/tasks/state.js' {\n  declare module.exports: $Exports<'cypress/lib/tasks/state'>;\n}\ndeclare module 'cypress/lib/tasks/unzip.js' {\n  declare module.exports: $Exports<'cypress/lib/tasks/unzip'>;\n}\ndeclare module 'cypress/lib/tasks/verify.js' {\n  declare module.exports: $Exports<'cypress/lib/tasks/verify'>;\n}\ndeclare module 'cypress/lib/util.js' {\n  declare module.exports: $Exports<'cypress/lib/util'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/enzyme-adapter-react-16_vx.x.x.js",
    "content": "// flow-typed signature: 4a647a6bd381dffe1da0ade1776f7aea\n// flow-typed version: <<STUB>>/enzyme-adapter-react-16_v^1.15.2/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'enzyme-adapter-react-16'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'enzyme-adapter-react-16' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'enzyme-adapter-react-16/build/detectFiberTags' {\n  declare module.exports: any;\n}\n\ndeclare module 'enzyme-adapter-react-16/build/findCurrentFiberUsingSlowPath' {\n  declare module.exports: any;\n}\n\ndeclare module 'enzyme-adapter-react-16/build' {\n  declare module.exports: any;\n}\n\ndeclare module 'enzyme-adapter-react-16/build/ReactSixteenAdapter' {\n  declare module.exports: any;\n}\n\ndeclare module 'enzyme-adapter-react-16/src/detectFiberTags' {\n  declare module.exports: any;\n}\n\ndeclare module 'enzyme-adapter-react-16/src/findCurrentFiberUsingSlowPath' {\n  declare module.exports: any;\n}\n\ndeclare module 'enzyme-adapter-react-16/src' {\n  declare module.exports: any;\n}\n\ndeclare module 'enzyme-adapter-react-16/src/ReactSixteenAdapter' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'enzyme-adapter-react-16/build/detectFiberTags.js' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/build/detectFiberTags'>;\n}\ndeclare module 'enzyme-adapter-react-16/build/findCurrentFiberUsingSlowPath.js' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/build/findCurrentFiberUsingSlowPath'>;\n}\ndeclare module 'enzyme-adapter-react-16/build/index' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/build'>;\n}\ndeclare module 'enzyme-adapter-react-16/build/index.js' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/build'>;\n}\ndeclare module 'enzyme-adapter-react-16/build/ReactSixteenAdapter.js' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/build/ReactSixteenAdapter'>;\n}\ndeclare module 'enzyme-adapter-react-16/src/detectFiberTags.js' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/src/detectFiberTags'>;\n}\ndeclare module 'enzyme-adapter-react-16/src/findCurrentFiberUsingSlowPath.js' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/src/findCurrentFiberUsingSlowPath'>;\n}\ndeclare module 'enzyme-adapter-react-16/src/index' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/src'>;\n}\ndeclare module 'enzyme-adapter-react-16/src/index.js' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/src'>;\n}\ndeclare module 'enzyme-adapter-react-16/src/ReactSixteenAdapter.js' {\n  declare module.exports: $Exports<'enzyme-adapter-react-16/src/ReactSixteenAdapter'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/enzyme_v3.x.x.js",
    "content": "// flow-typed signature: 1b68a1969e8305bf53fbaa98b4a5aaae\n// flow-typed version: f7ac3b9713/enzyme_v3.x.x/flow_>=v0.104.x\n\ndeclare module \"enzyme\" {\n  declare type PredicateFunction<T: Wrapper<*>> = (\n    wrapper: T,\n    index: number\n  ) => boolean;\n  declare type UntypedSelector = string | { [key: string]: number|string|boolean, ... };\n  declare type EnzymeSelector = UntypedSelector | React$ElementType;\n\n  // CheerioWrapper is a type alias for an actual cheerio instance\n  // TODO: Reference correct type from cheerio's type declarations\n  declare type CheerioWrapper = any;\n\n  declare class Wrapper<RootComponent> {\n    equals(node: React$Element<any>): boolean,\n    find(selector: UntypedSelector): this,\n    find<T: React$ElementType>(selector: T): ReactWrapper<T>,\n    findWhere(predicate: PredicateFunction<this>): this,\n    filter(selector: UntypedSelector): this,\n    filter<T: React$ElementType>(selector: T): ReactWrapper<T>,\n    filterWhere(predicate: PredicateFunction<this>): this,\n    hostNodes(): this,\n    contains(nodes: React$Node): boolean,\n    containsMatchingElement(node: React$Node): boolean,\n    containsAllMatchingElements(nodes: React$Node): boolean,\n    containsAnyMatchingElements(nodes: React$Node): boolean,\n    dive(option?: { context?: Object, ... }): this,\n    exists(selector?: EnzymeSelector): boolean,\n    isEmptyRender(): boolean,\n    matchesElement(node: React$Node): boolean,\n    hasClass(className: string): boolean,\n    is(selector: EnzymeSelector): boolean,\n    isEmpty(): boolean,\n    not(selector: EnzymeSelector): this,\n    children(selector?: UntypedSelector): this,\n    children<T: React$ElementType>(selector: T): ReactWrapper<T>,\n    childAt(index: number): this,\n    parents(selector?: UntypedSelector): this,\n    parents<T: React$ElementType>(selector: T): ReactWrapper<T>,\n    parent(): this,\n    closest(selector: UntypedSelector): this,\n    closest<T: React$ElementType>(selector: T): ReactWrapper<T>,\n    render(): CheerioWrapper,\n    renderProp(propName: string): (...args: Array<any>) => this,\n    unmount(): this,\n    text(): string,\n    html(): string,\n    get(index: number): React$Node,\n    getDOMNode(): HTMLElement | HTMLInputElement,\n    at(index: number): this,\n    first(): this,\n    last(): this,\n    state(key?: string): any,\n    context(key?: string): any,\n    props(): Object,\n    prop(key: string): any,\n    key(): string,\n    simulate(event: string, ...args: Array<any>): this,\n    simulateError(error: Error): this,\n    slice(begin?: number, end?: number): this,\n    setState(state: {...}, callback?: () => void): this,\n    setProps(props: {...}, callback?: () => void): this,\n    setContext(context: Object): this,\n    instance(): React$ElementRef<RootComponent>,\n    update(): this,\n    debug(options?: Object): string,\n    type(): string | Function | null,\n    name(): string,\n    forEach(fn: (node: this, index: number) => mixed): this,\n    map<T>(fn: (node: this, index: number) => T): Array<T>,\n    reduce<T>(\n      fn: (value: T, node: this, index: number) => T,\n      initialValue?: T\n    ): Array<T>,\n    reduceRight<T>(\n      fn: (value: T, node: this, index: number) => T,\n      initialValue?: T\n    ): Array<T>,\n    some(selector: EnzymeSelector): boolean,\n    someWhere(predicate: PredicateFunction<this>): boolean,\n    every(selector: EnzymeSelector): boolean,\n    everyWhere(predicate: PredicateFunction<this>): boolean,\n    length: number\n  }\n\n  declare class ReactWrapper<T> extends Wrapper<T> {\n    constructor(nodes: React$Element<T>, root: any, options?: ?Object): ReactWrapper<T>,\n    mount(): this,\n    ref(refName: string): this,\n    detach(): void\n  }\n\n  declare class ShallowWrapper<T> extends Wrapper<T> {\n    constructor(\n      nodes: React$Element<T>,\n      root: any,\n      options?: ?Object\n    ): ShallowWrapper<T>,\n    equals(node: React$Node): boolean,\n    shallow(options?: { context?: Object, ... }): ShallowWrapper<T>,\n    getElement(): React$Node,\n    getElements(): Array<React$Node>\n  }\n\n  declare function shallow<T>(\n    node: React$Element<T>,\n    options?: {\n      context?: Object,\n      disableLifecycleMethods?: boolean,\n      ...\n    }\n  ): ShallowWrapper<T>;\n  declare function mount<T>(\n    node: React$Element<T>,\n    options?: {\n      context?: Object,\n      attachTo?: HTMLElement,\n      childContextTypes?: Object,\n      ...\n    }\n  ): ReactWrapper<T>;\n  declare function render(\n    node: React$Node,\n    options?: { context?: Object, ... }\n  ): CheerioWrapper;\n\n  declare module.exports: {\n    configure(options: {\n      Adapter?: any,\n      disableLifecycleMethods?: boolean,\n      ...\n    }): void,\n    render: typeof render,\n    mount: typeof mount,\n    shallow: typeof shallow,\n    ShallowWrapper: typeof ShallowWrapper,\n    ReactWrapper: typeof ReactWrapper,\n    ...\n  };\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-config-airbnb_vx.x.x.js",
    "content": "// flow-typed signature: dd4b7be93e21836cc6f6a192dc5ba52b\n// flow-typed version: <<STUB>>/eslint-config-airbnb_v^18.0.1/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-config-airbnb'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-config-airbnb' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-config-airbnb/base' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-airbnb/hooks' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-airbnb/legacy' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-airbnb/rules/react-a11y' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-airbnb/rules/react-hooks' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-airbnb/rules/react' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-airbnb/test/requires' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-airbnb/test/test-base' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-airbnb/test/test-react-order' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-airbnb/whitespace' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-config-airbnb/base.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/base'>;\n}\ndeclare module 'eslint-config-airbnb/hooks.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/hooks'>;\n}\ndeclare module 'eslint-config-airbnb/index' {\n  declare module.exports: $Exports<'eslint-config-airbnb'>;\n}\ndeclare module 'eslint-config-airbnb/index.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb'>;\n}\ndeclare module 'eslint-config-airbnb/legacy.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/legacy'>;\n}\ndeclare module 'eslint-config-airbnb/rules/react-a11y.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/rules/react-a11y'>;\n}\ndeclare module 'eslint-config-airbnb/rules/react-hooks.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/rules/react-hooks'>;\n}\ndeclare module 'eslint-config-airbnb/rules/react.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/rules/react'>;\n}\ndeclare module 'eslint-config-airbnb/test/requires.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/test/requires'>;\n}\ndeclare module 'eslint-config-airbnb/test/test-base.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/test/test-base'>;\n}\ndeclare module 'eslint-config-airbnb/test/test-react-order.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/test/test-react-order'>;\n}\ndeclare module 'eslint-config-airbnb/whitespace.js' {\n  declare module.exports: $Exports<'eslint-config-airbnb/whitespace'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-config-prettier_vx.x.x.js",
    "content": "// flow-typed signature: e7ff0ea723c344e5e1d2b4f08def3894\n// flow-typed version: <<STUB>>/eslint-config-prettier_v^6.10.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-config-prettier'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-config-prettier' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-config-prettier/@typescript-eslint' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-prettier/babel' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-prettier/bin/cli' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-prettier/bin/validators' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-prettier/flowtype' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-prettier/react' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-prettier/standard' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-prettier/unicorn' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-config-prettier/vue' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-config-prettier/@typescript-eslint.js' {\n  declare module.exports: $Exports<'eslint-config-prettier/@typescript-eslint'>;\n}\ndeclare module 'eslint-config-prettier/babel.js' {\n  declare module.exports: $Exports<'eslint-config-prettier/babel'>;\n}\ndeclare module 'eslint-config-prettier/bin/cli.js' {\n  declare module.exports: $Exports<'eslint-config-prettier/bin/cli'>;\n}\ndeclare module 'eslint-config-prettier/bin/validators.js' {\n  declare module.exports: $Exports<'eslint-config-prettier/bin/validators'>;\n}\ndeclare module 'eslint-config-prettier/flowtype.js' {\n  declare module.exports: $Exports<'eslint-config-prettier/flowtype'>;\n}\ndeclare module 'eslint-config-prettier/index' {\n  declare module.exports: $Exports<'eslint-config-prettier'>;\n}\ndeclare module 'eslint-config-prettier/index.js' {\n  declare module.exports: $Exports<'eslint-config-prettier'>;\n}\ndeclare module 'eslint-config-prettier/react.js' {\n  declare module.exports: $Exports<'eslint-config-prettier/react'>;\n}\ndeclare module 'eslint-config-prettier/standard.js' {\n  declare module.exports: $Exports<'eslint-config-prettier/standard'>;\n}\ndeclare module 'eslint-config-prettier/unicorn.js' {\n  declare module.exports: $Exports<'eslint-config-prettier/unicorn'>;\n}\ndeclare module 'eslint-config-prettier/vue.js' {\n  declare module.exports: $Exports<'eslint-config-prettier/vue'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-plugin-cypress_vx.x.x.js",
    "content": "// flow-typed signature: fb843ab160cf4f44ca9c288e887b36b1\n// flow-typed version: <<STUB>>/eslint-plugin-cypress_v^2.8.1/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-plugin-cypress'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-plugin-cypress' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-plugin-cypress/lib/config/recommended' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-cypress/lib/rules/assertion-before-screenshot' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-cypress/lib/rules/no-assigning-return-values' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-cypress/lib/rules/no-unnecessary-waiting' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-cypress/lib/rules/require-data-selectors' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-cypress/tests/config' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-cypress/tests/lib/rules/assertion-before-screenshot' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-cypress/tests/lib/rules/no-assigning-return-values' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-cypress/tests/lib/rules/no-unnecessary-waiting' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-cypress/tests/lib/rules/require-data-selectors' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-plugin-cypress/index' {\n  declare module.exports: $Exports<'eslint-plugin-cypress'>;\n}\ndeclare module 'eslint-plugin-cypress/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress'>;\n}\ndeclare module 'eslint-plugin-cypress/lib/config/recommended.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/lib/config/recommended'>;\n}\ndeclare module 'eslint-plugin-cypress/lib/rules/assertion-before-screenshot.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/lib/rules/assertion-before-screenshot'>;\n}\ndeclare module 'eslint-plugin-cypress/lib/rules/no-assigning-return-values.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/lib/rules/no-assigning-return-values'>;\n}\ndeclare module 'eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/lib/rules/no-unnecessary-waiting'>;\n}\ndeclare module 'eslint-plugin-cypress/lib/rules/require-data-selectors.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/lib/rules/require-data-selectors'>;\n}\ndeclare module 'eslint-plugin-cypress/tests/config.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/tests/config'>;\n}\ndeclare module 'eslint-plugin-cypress/tests/lib/rules/assertion-before-screenshot.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/tests/lib/rules/assertion-before-screenshot'>;\n}\ndeclare module 'eslint-plugin-cypress/tests/lib/rules/no-assigning-return-values.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/tests/lib/rules/no-assigning-return-values'>;\n}\ndeclare module 'eslint-plugin-cypress/tests/lib/rules/no-unnecessary-waiting.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/tests/lib/rules/no-unnecessary-waiting'>;\n}\ndeclare module 'eslint-plugin-cypress/tests/lib/rules/require-data-selectors.js' {\n  declare module.exports: $Exports<'eslint-plugin-cypress/tests/lib/rules/require-data-selectors'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-plugin-es5_vx.x.x.js",
    "content": "// flow-typed signature: 1027b306c59965d0a498098fe9b0b82e\n// flow-typed version: <<STUB>>/eslint-plugin-es5_v^1.5.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-plugin-es5'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-plugin-es5' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-plugin-es5/src' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-arrow-functions' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-binary-and-octal-literals' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-block-scoping' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-classes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-computed-properties' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-default-parameters' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-destructuring' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-es6-methods' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-es6-static-methods' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-exponentiation-operator' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-for-of' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-generators' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-modules' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-object-super' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-rest-parameters' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-shorthand-properties' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-spread' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-template-literals' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-typeof-symbol' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-unicode-code-point-escape' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-es5/src/rules/no-unicode-regex' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-plugin-es5/src/index' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src'>;\n}\ndeclare module 'eslint-plugin-es5/src/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-arrow-functions.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-arrow-functions'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-binary-and-octal-literals.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-binary-and-octal-literals'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-block-scoping.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-block-scoping'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-classes.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-classes'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-computed-properties.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-computed-properties'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-default-parameters.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-default-parameters'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-destructuring.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-destructuring'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-es6-methods.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-es6-methods'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-es6-static-methods.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-es6-static-methods'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-exponentiation-operator.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-exponentiation-operator'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-for-of.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-for-of'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-generators.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-generators'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-modules.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-modules'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-object-super.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-object-super'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-rest-parameters.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-rest-parameters'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-shorthand-properties.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-shorthand-properties'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-spread.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-spread'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-template-literals.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-template-literals'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-typeof-symbol.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-typeof-symbol'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-unicode-code-point-escape.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-unicode-code-point-escape'>;\n}\ndeclare module 'eslint-plugin-es5/src/rules/no-unicode-regex.js' {\n  declare module.exports: $Exports<'eslint-plugin-es5/src/rules/no-unicode-regex'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-plugin-flowtype_vx.x.x.js",
    "content": "// flow-typed signature: af5fa14bde3c28148511b01992c981bd\n// flow-typed version: <<STUB>>/eslint-plugin-flowtype_v^4.6.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-plugin-flowtype'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-plugin-flowtype' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-plugin-flowtype/dist/bin/addAssertions' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/bin/checkDocs' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/bin/checkTests' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/bin/utilities' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyle' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyle/isSimpleType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyle/needWrap' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyleComplexType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyleSimpleType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrowParens' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/booleanStyle' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/defineFlowType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/delimiterDangle' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/genericSpacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/newlineAfterFlowAnnotation' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/noDupeKeys' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/noExistentialType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/noFlowFixMeComments' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/noMixed' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/noMutableArray' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/noTypesMissingFileAnnotation' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/noUnusedExpressions' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/noWeakTypes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireCompoundTypeAlias' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireExactType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireIndexerName' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireInexactType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireParameterType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireReadonlyReactProps' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireReturnType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireTypesAtTop' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireVariableType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/semi' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/sortKeys' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/spreadExactType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateVariables' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeIdMatch' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeImportStyle' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/useFlowType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/rules/validSyntax' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/getParameterName' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/isFlowFile' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/quoteName' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-flowtype/dist/utilities/spacingFixers' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-plugin-flowtype/dist/bin/addAssertions.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/bin/addAssertions'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/bin/checkDocs.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/bin/checkDocs'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/bin/checkTests.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/bin/checkTests'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/bin/utilities.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/bin/utilities'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/index' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyle/index' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/arrayStyle'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyle/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/arrayStyle'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyle/isSimpleType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/arrayStyle/isSimpleType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyle/needWrap.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/arrayStyle/needWrap'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyleComplexType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/arrayStyleComplexType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrayStyleSimpleType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/arrayStyleSimpleType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/arrowParens.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/arrowParens'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/booleanStyle.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/booleanStyle'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/defineFlowType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/defineFlowType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/delimiterDangle.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/delimiterDangle'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/genericSpacing.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/genericSpacing'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/newlineAfterFlowAnnotation.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/newlineAfterFlowAnnotation'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/noDupeKeys.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noDupeKeys'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/noExistentialType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noExistentialType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/noFlowFixMeComments.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noFlowFixMeComments'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/noMixed.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noMixed'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/noMutableArray.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noMutableArray'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/noTypesMissingFileAnnotation.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noTypesMissingFileAnnotation'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/noUnusedExpressions.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noUnusedExpressions'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/noWeakTypes.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noWeakTypes'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireCompoundTypeAlias.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireCompoundTypeAlias'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireExactType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireExactType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireIndexerName.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireIndexerName'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireInexactType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireInexactType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireParameterType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireParameterType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireReadonlyReactProps.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireReadonlyReactProps'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireReturnType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireReturnType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireTypesAtTop.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireTypesAtTop'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/requireVariableType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireVariableType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/semi.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/semi'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/sortKeys.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/sortKeys'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/spreadExactType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spreadExactType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateVariables.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateVariables'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeIdMatch.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeIdMatch'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/typeImportStyle.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeImportStyle'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/useFlowType.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/useFlowType'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/rules/validSyntax.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/validSyntax'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/getParameterName.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getParameterName'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/index' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/isFlowFile.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/isFlowFile'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/quoteName.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/quoteName'>;\n}\ndeclare module 'eslint-plugin-flowtype/dist/utilities/spacingFixers.js' {\n  declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/spacingFixers'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-plugin-import_vx.x.x.js",
    "content": "// flow-typed signature: 01963a8e628a249a55841ddd9dba5d3d\n// flow-typed version: <<STUB>>/eslint-plugin-import_v^2.20.1/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-plugin-import'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-plugin-import' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-plugin-import/config/electron' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/config/errors' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/config/react-native' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/config/react' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/config/recommended' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/config/stage-0' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/config/typescript' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/config/warnings' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/core/importType' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/core/staticRequire' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/docsUrl' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/ExportMap' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/importDeclaration' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/default' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/dynamic-import-chunkname' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/export' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/exports-last' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/extensions' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/first' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/group-exports' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/imports-first' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/max-dependencies' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/named' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/namespace' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/newline-after-import' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-absolute-path' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-amd' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-anonymous-default-export' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-commonjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-cycle' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-default-export' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-deprecated' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-duplicates' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-dynamic-require' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-extraneous-dependencies' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-internal-modules' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-mutable-exports' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-named-as-default-member' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-named-as-default' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-named-default' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-named-export' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-namespace' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-nodejs-modules' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-relative-parent-imports' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-restricted-paths' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-self-import' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-unassigned-import' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-unresolved' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-unused-modules' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-useless-path-segments' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/no-webpack-loader-syntax' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/order' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/prefer-default-export' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/lib/rules/unambiguous' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-import/memo-parser' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-plugin-import/config/electron.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/config/electron'>;\n}\ndeclare module 'eslint-plugin-import/config/errors.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/config/errors'>;\n}\ndeclare module 'eslint-plugin-import/config/react-native.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/config/react-native'>;\n}\ndeclare module 'eslint-plugin-import/config/react.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/config/react'>;\n}\ndeclare module 'eslint-plugin-import/config/recommended.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/config/recommended'>;\n}\ndeclare module 'eslint-plugin-import/config/stage-0.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/config/stage-0'>;\n}\ndeclare module 'eslint-plugin-import/config/typescript.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/config/typescript'>;\n}\ndeclare module 'eslint-plugin-import/config/warnings.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/config/warnings'>;\n}\ndeclare module 'eslint-plugin-import/lib/core/importType.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/core/importType'>;\n}\ndeclare module 'eslint-plugin-import/lib/core/staticRequire.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/core/staticRequire'>;\n}\ndeclare module 'eslint-plugin-import/lib/docsUrl.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/docsUrl'>;\n}\ndeclare module 'eslint-plugin-import/lib/ExportMap.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/ExportMap'>;\n}\ndeclare module 'eslint-plugin-import/lib/importDeclaration.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/importDeclaration'>;\n}\ndeclare module 'eslint-plugin-import/lib/index' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib'>;\n}\ndeclare module 'eslint-plugin-import/lib/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/default.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/default'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/dynamic-import-chunkname.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/dynamic-import-chunkname'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/export.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/export'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/exports-last.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/exports-last'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/extensions.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/extensions'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/first.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/first'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/group-exports.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/group-exports'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/imports-first.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/imports-first'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/max-dependencies.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/max-dependencies'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/named.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/named'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/namespace.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/namespace'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/newline-after-import.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/newline-after-import'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-absolute-path.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-absolute-path'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-amd.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-amd'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-anonymous-default-export.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-anonymous-default-export'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-commonjs.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-commonjs'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-cycle.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-cycle'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-default-export.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-default-export'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-deprecated.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-deprecated'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-duplicates.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-duplicates'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-dynamic-require.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-dynamic-require'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-extraneous-dependencies.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-extraneous-dependencies'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-internal-modules.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-internal-modules'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-mutable-exports.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-mutable-exports'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-named-as-default-member.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-as-default-member'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-named-as-default.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-as-default'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-named-default.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-default'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-named-export.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-export'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-namespace.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-namespace'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-nodejs-modules.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-nodejs-modules'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-relative-parent-imports.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-relative-parent-imports'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-restricted-paths.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-restricted-paths'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-self-import.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-self-import'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-unassigned-import.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-unassigned-import'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-unresolved.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-unresolved'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-unused-modules.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-unused-modules'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-useless-path-segments.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-useless-path-segments'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/no-webpack-loader-syntax.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-webpack-loader-syntax'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/order.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/order'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/prefer-default-export.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/prefer-default-export'>;\n}\ndeclare module 'eslint-plugin-import/lib/rules/unambiguous.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/lib/rules/unambiguous'>;\n}\ndeclare module 'eslint-plugin-import/memo-parser/index' {\n  declare module.exports: $Exports<'eslint-plugin-import/memo-parser'>;\n}\ndeclare module 'eslint-plugin-import/memo-parser/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-import/memo-parser'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-plugin-jest_vx.x.x.js",
    "content": "// flow-typed signature: 713946c45dba9f21c16a5b53060b5691\n// flow-typed version: <<STUB>>/eslint-plugin-jest_v^23.6.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-plugin-jest'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-plugin-jest' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-plugin-jest/lib/__tests__/rules.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/processors/snapshot-processor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/consistent-test-it' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/expect-expect' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/lowercase-name' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-alias-methods' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-commented-out-tests' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-disabled-tests' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-duplicate-hooks' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-expect-resolves' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-export' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-focused-tests' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-hooks' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-identical-title' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-if' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-jasmine-globals' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-jest-import' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-large-snapshots' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-mocks-import' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-standalone-expect' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-test-callback' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-test-prefixes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-test-return-statement' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-truthy-falsy' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/no-try-expect' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-called-with' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-expect-assertions' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-hooks-on-top' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-inline-snapshots' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-spy-on' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-strict-equal' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-to-be-null' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-to-be-undefined' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-to-contain' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-to-have-length' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-todo' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/require-to-throw-message' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/require-top-level-describe' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/utils' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/valid-describe' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/valid-expect-in-promise' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/valid-expect' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jest/lib/rules/valid-title' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-plugin-jest/lib/__tests__/rules.test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/__tests__/rules.test'>;\n}\ndeclare module 'eslint-plugin-jest/lib/index' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib'>;\n}\ndeclare module 'eslint-plugin-jest/lib/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib'>;\n}\ndeclare module 'eslint-plugin-jest/lib/processors/snapshot-processor.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/processors/snapshot-processor'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/consistent-test-it.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/consistent-test-it'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/expect-expect.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/expect-expect'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/lowercase-name.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/lowercase-name'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-alias-methods.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-alias-methods'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-commented-out-tests.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-commented-out-tests'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-disabled-tests.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-disabled-tests'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-duplicate-hooks.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-duplicate-hooks'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-expect-resolves.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-expect-resolves'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-export.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-export'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-focused-tests.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-focused-tests'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-hooks.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-hooks'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-identical-title.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-identical-title'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-if.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-if'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-jasmine-globals.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-jasmine-globals'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-jest-import.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-jest-import'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-large-snapshots.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-large-snapshots'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-mocks-import.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-mocks-import'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-standalone-expect.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-standalone-expect'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-test-callback.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-test-callback'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-test-prefixes.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-test-prefixes'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-test-return-statement.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-test-return-statement'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-truthy-falsy.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-truthy-falsy'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/no-try-expect.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/no-try-expect'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-called-with.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-called-with'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-expect-assertions.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-expect-assertions'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-hooks-on-top.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-hooks-on-top'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-inline-snapshots.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-inline-snapshots'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-spy-on.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-spy-on'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-strict-equal.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-strict-equal'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-to-be-null.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-to-be-null'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-to-be-undefined.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-to-be-undefined'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-to-contain.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-to-contain'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-to-have-length.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-to-have-length'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/prefer-todo.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/prefer-todo'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/require-to-throw-message.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/require-to-throw-message'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/require-top-level-describe.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/require-top-level-describe'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/utils.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/utils'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/valid-describe.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/valid-describe'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/valid-expect-in-promise.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/valid-expect-in-promise'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/valid-expect.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/valid-expect'>;\n}\ndeclare module 'eslint-plugin-jest/lib/rules/valid-title.js' {\n  declare module.exports: $Exports<'eslint-plugin-jest/lib/rules/valid-title'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-plugin-jsx-a11y_vx.x.x.js",
    "content": "// flow-typed signature: d23e64242f2815a4c965f93350319071\n// flow-typed version: <<STUB>>/eslint-plugin-jsx-a11y_v^6.2.1/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-plugin-jsx-a11y'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-plugin-jsx-a11y' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/genInteractives' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/IdentifierMock' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXAttributeMock' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXElementMock' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXExpressionContainerMock' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXSpreadAttributeMock' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXTextMock' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/LiteralMock' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/__util__/parserOptionsMapper' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/__util__/ruleOptionsMapperFactory' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/index-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/accessible-emoji-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/alt-text-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-has-content-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-is-valid-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-activedescendant-has-tabindex-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-props-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-proptypes-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-role-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-unsupported-elements-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/click-events-have-key-events-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/control-has-associated-label-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/heading-has-content-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/html-has-lang-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/iframe-has-title-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/img-redundant-alt-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/interactive-supports-focus-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-associated-control-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-for-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/lang-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/media-has-caption-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/mouse-events-have-key-events-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-access-key-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-autofocus-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-distracting-elements-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-interactive-element-to-noninteractive-role-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-noninteractive-element-interactions-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-noninteractive-element-to-interactive-role-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-noninteractive-tabindex-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-onchange-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-redundant-roles-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-static-element-interactions-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/role-has-required-aria-props-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/role-supports-aria-props-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/scope-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/tabindex-no-positive-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/attributesComparator-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getComputedRole-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getExplicitRole-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getImplicitRole-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getSuggestion-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getTabIndex-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/hasAccessibleChild-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/input-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menu-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menuitem-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isAbstractRole-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isDisabledElement-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isDOMElement-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveElement-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveRole-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveElement-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveRole-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isNonLiteralProperty-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isSemanticRoleElement-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/mayContainChildComponent-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/mayHaveAccessibleLabel-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/parserOptionsMapper-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/schemas-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/accessible-emoji' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/alt-text' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/anchor-has-content' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/anchor-is-valid' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-activedescendant-has-tabindex' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-proptypes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-role' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-unsupported-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/click-events-have-key-events' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/control-has-associated-label' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/heading-has-content' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/html-has-lang' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/iframe-has-title' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/img-redundant-alt' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/interactive-supports-focus' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/label-has-associated-control' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/label-has-for' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/lang' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/media-has-caption' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/mouse-events-have-key-events' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-access-key' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-autofocus' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-distracting-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-interactive-element-to-noninteractive-role' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-noninteractive-element-interactions' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-noninteractive-element-to-interactive-role' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-noninteractive-tabindex' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-onchange' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-redundant-roles' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-static-element-interactions' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/role-has-required-aria-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/role-supports-aria-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/scope' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/tabindex-no-positive' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/attributesComparator' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getComputedRole' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getExplicitRole' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getImplicitRole' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getSuggestion' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getTabIndex' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/hasAccessibleChild' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/a' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/area' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/article' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/aside' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/body' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/button' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/datalist' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/details' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dialog' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dl' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/form' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h1' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h2' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h3' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h4' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h5' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h6' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/hr' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/img' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/input' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/li' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/link' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menu' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menuitem' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/meter' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/nav' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ol' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/option' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/output' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/progress' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/section' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/select' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tbody' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/textarea' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tfoot' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/thead' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ul' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isAbstractRole' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isDisabledElement' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isDOMElement' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isHiddenFromScreenReader' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isInteractiveElement' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isInteractiveRole' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isNonInteractiveElement' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isNonInteractiveRole' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isNonLiteralProperty' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isPresentationRole' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isSemanticRoleElement' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/mayContainChildComponent' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/mayHaveAccessibleLabel' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/schemas' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/scripts/addRuleToIndex' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/doc' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/rule' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/test' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-jsx-a11y/scripts/create-rule' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/genInteractives.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/genInteractives'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/IdentifierMock.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/IdentifierMock'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXAttributeMock.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/JSXAttributeMock'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXElementMock.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/JSXElementMock'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXExpressionContainerMock.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/JSXExpressionContainerMock'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXSpreadAttributeMock.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/JSXSpreadAttributeMock'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/JSXTextMock.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/JSXTextMock'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__mocks__/LiteralMock.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/LiteralMock'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/__util__/parserOptionsMapper.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/__util__/parserOptionsMapper'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/__util__/ruleOptionsMapperFactory.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/__util__/ruleOptionsMapperFactory'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/index-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/index-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/accessible-emoji-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/accessible-emoji-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/alt-text-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/alt-text-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-has-content-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-has-content-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-is-valid-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-is-valid-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-activedescendant-has-tabindex-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-props-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-props-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-proptypes-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-proptypes-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-role-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-role-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-unsupported-elements-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-unsupported-elements-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/click-events-have-key-events-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/click-events-have-key-events-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/control-has-associated-label-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/control-has-associated-label-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/heading-has-content-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/heading-has-content-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/html-has-lang-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/html-has-lang-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/iframe-has-title-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/iframe-has-title-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/img-redundant-alt-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/img-redundant-alt-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/interactive-supports-focus-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/interactive-supports-focus-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-associated-control-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-associated-control-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-for-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-for-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/lang-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/lang-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/media-has-caption-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/media-has-caption-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/mouse-events-have-key-events-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/mouse-events-have-key-events-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-access-key-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-access-key-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-autofocus-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-autofocus-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-distracting-elements-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-distracting-elements-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-interactive-element-to-noninteractive-role-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-interactive-element-to-noninteractive-role-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-noninteractive-element-interactions-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-noninteractive-element-interactions-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-noninteractive-element-to-interactive-role-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-noninteractive-element-to-interactive-role-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-noninteractive-tabindex-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-noninteractive-tabindex-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-onchange-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-onchange-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-redundant-roles-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-redundant-roles-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-static-element-interactions-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-static-element-interactions-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/role-has-required-aria-props-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/role-has-required-aria-props-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/role-supports-aria-props-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/role-supports-aria-props-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/scope-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/scope-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/tabindex-no-positive-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/tabindex-no-positive-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/attributesComparator-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/attributesComparator-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getComputedRole-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/getComputedRole-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getExplicitRole-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/getExplicitRole-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getImplicitRole-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/getImplicitRole-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getSuggestion-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/getSuggestion-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getTabIndex-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/getTabIndex-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/hasAccessibleChild-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/hasAccessibleChild-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/input-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/input-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menu-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menu-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menuitem-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/implicitRoles/menuitem-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isAbstractRole-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isAbstractRole-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isDisabledElement-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isDisabledElement-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isDOMElement-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isDOMElement-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveElement-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveElement-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveRole-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveRole-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveElement-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveElement-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveRole-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isNonInteractiveRole-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isNonLiteralProperty-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isNonLiteralProperty-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isSemanticRoleElement-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isSemanticRoleElement-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/mayContainChildComponent-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/mayContainChildComponent-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/mayHaveAccessibleLabel-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/mayHaveAccessibleLabel-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/parserOptionsMapper-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/parserOptionsMapper-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/__tests__/src/util/schemas-test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/schemas-test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/index' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/accessible-emoji.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/accessible-emoji'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/alt-text.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/alt-text'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/anchor-has-content.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/anchor-has-content'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/anchor-is-valid.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/anchor-is-valid'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-activedescendant-has-tabindex.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-activedescendant-has-tabindex'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-props'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-proptypes.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-proptypes'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-role.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-role'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/aria-unsupported-elements.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-unsupported-elements'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/click-events-have-key-events.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/click-events-have-key-events'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/control-has-associated-label.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/control-has-associated-label'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/heading-has-content.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/heading-has-content'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/html-has-lang.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/html-has-lang'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/iframe-has-title.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/iframe-has-title'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/img-redundant-alt.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/img-redundant-alt'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/interactive-supports-focus.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/interactive-supports-focus'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/label-has-associated-control.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/label-has-associated-control'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/label-has-for.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/label-has-for'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/lang.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/lang'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/media-has-caption.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/media-has-caption'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/mouse-events-have-key-events.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/mouse-events-have-key-events'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-access-key.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-access-key'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-autofocus.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-autofocus'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-distracting-elements.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-distracting-elements'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-interactive-element-to-noninteractive-role.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-interactive-element-to-noninteractive-role'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-noninteractive-element-interactions.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-noninteractive-element-interactions'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-noninteractive-element-to-interactive-role.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-noninteractive-element-to-interactive-role'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-noninteractive-tabindex.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-noninteractive-tabindex'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-onchange.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-onchange'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-redundant-roles.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-redundant-roles'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/no-static-element-interactions.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-static-element-interactions'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/role-has-required-aria-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/role-has-required-aria-props'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/role-supports-aria-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/role-supports-aria-props'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/scope.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/scope'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/rules/tabindex-no-positive.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/tabindex-no-positive'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/attributesComparator.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/attributesComparator'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getComputedRole.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/getComputedRole'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getExplicitRole.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/getExplicitRole'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getImplicitRole.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/getImplicitRole'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getSuggestion.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/getSuggestion'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/getTabIndex.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/getTabIndex'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/hasAccessibleChild.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/hasAccessibleChild'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/a.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/a'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/area.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/area'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/article.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/article'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/aside.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/aside'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/body.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/body'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/button.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/button'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/datalist.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/datalist'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/details.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/details'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dialog.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dialog'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dl.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dl'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/form.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/form'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h1.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h1'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h2.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h2'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h3.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h3'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h4.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h4'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h5.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h5'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h6.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h6'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/hr.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/hr'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/img.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/img'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/index' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/input.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/input'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/li.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/li'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/link.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/link'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menu.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menu'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menuitem.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menuitem'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/meter.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/meter'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/nav.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/nav'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ol.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ol'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/option.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/option'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/output.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/output'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/progress.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/progress'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/section.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/section'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/select.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/select'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tbody.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tbody'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/textarea.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/textarea'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tfoot.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tfoot'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/thead.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/thead'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ul.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ul'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isAbstractRole.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isAbstractRole'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isDisabledElement.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isDisabledElement'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isDOMElement.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isDOMElement'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isHiddenFromScreenReader.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isHiddenFromScreenReader'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isInteractiveElement.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isInteractiveElement'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isInteractiveRole.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isInteractiveRole'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isNonInteractiveElement.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isNonInteractiveElement'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isNonInteractiveRole.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isNonInteractiveRole'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isNonLiteralProperty.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isNonLiteralProperty'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isPresentationRole.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isPresentationRole'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/isSemanticRoleElement.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isSemanticRoleElement'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/mayContainChildComponent.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/mayContainChildComponent'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/mayHaveAccessibleLabel.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/mayHaveAccessibleLabel'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/lib/util/schemas.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/schemas'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/scripts/addRuleToIndex.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/addRuleToIndex'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/doc.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/boilerplate/doc'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/rule.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/boilerplate/rule'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/test.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/boilerplate/test'>;\n}\ndeclare module 'eslint-plugin-jsx-a11y/scripts/create-rule.js' {\n  declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/create-rule'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-plugin-prettier_vx.x.x.js",
    "content": "// flow-typed signature: 912ade96a1dba898160e27d7047a7b6a\n// flow-typed version: <<STUB>>/eslint-plugin-prettier_v^3.1.2/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-plugin-prettier'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-plugin-prettier' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-plugin-prettier/eslint-plugin-prettier' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-plugin-prettier/eslint-plugin-prettier.js' {\n  declare module.exports: $Exports<'eslint-plugin-prettier/eslint-plugin-prettier'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-plugin-react-hooks_vx.x.x.js",
    "content": "// flow-typed signature: 3c1a48ed4cefbb17c2b68c1b5e758411\n// flow-typed version: <<STUB>>/eslint-plugin-react-hooks_v^2.3.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-plugin-react-hooks'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-plugin-react-hooks' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.production.min' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js' {\n  declare module.exports: $Exports<'eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development'>;\n}\ndeclare module 'eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.production.min.js' {\n  declare module.exports: $Exports<'eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.production.min'>;\n}\ndeclare module 'eslint-plugin-react-hooks/index' {\n  declare module.exports: $Exports<'eslint-plugin-react-hooks'>;\n}\ndeclare module 'eslint-plugin-react-hooks/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-react-hooks'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint-plugin-react_vx.x.x.js",
    "content": "// flow-typed signature: ead9a32eae161cd79b14ec31802eab92\n// flow-typed version: <<STUB>>/eslint-plugin-react_v^7.18.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint-plugin-react'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint-plugin-react' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint-plugin-react/lib/rules/boolean-prop-naming' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/button-has-type' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/default-props-match-prop-types' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/destructuring-assignment' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/display-name' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/forbid-component-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/forbid-dom-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/forbid-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/forbid-foreign-prop-types' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/forbid-prop-types' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/function-component-definition' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-boolean-value' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-child-element-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-closing-bracket-location' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-closing-tag-location' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-curly-brace-presence' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-curly-newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-curly-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-equals-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-filename-extension' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-first-prop-new-line' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-fragments' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-handler-names' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-indent-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-indent' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-key' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-max-depth' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-max-props-per-line' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-bind' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-comment-textnodes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-duplicate-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-literals' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-script-url' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-target-blank' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-undef' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-useless-fragment' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-one-expression-per-line' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-pascal-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-props-no-multi-spaces' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-props-no-spreading' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-sort-default-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-sort-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-space-before-closing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-tag-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-uses-react' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-uses-vars' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/jsx-wrap-multilines' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-access-state-in-setstate' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-adjacent-inline-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-array-index-key' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-children-prop' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-danger-with-children' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-danger' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-deprecated' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-did-mount-set-state' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-did-update-set-state' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-direct-mutation-state' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-find-dom-node' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-is-mounted' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-multi-comp' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-redundant-should-component-update' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-render-return-value' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-set-state' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-string-refs' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-this-in-sfc' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-typos' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-unescaped-entities' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-unknown-property' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-unsafe' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-unused-prop-types' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-unused-state' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/no-will-update-set-state' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/prefer-es6-class' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/prefer-read-only-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/prefer-stateless-function' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/prop-types' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/react-in-jsx-scope' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/require-default-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/require-optimization' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/require-render-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/self-closing-comp' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/sort-comp' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/sort-prop-types' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/state-in-constructor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/static-property-placement' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/style-prop-object' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/rules/void-dom-elements-no-children' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/annotations' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/ast' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/Components' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/defaultProps' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/docsUrl' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/error' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/getTokenBeforeClosingBracket' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/jsx' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/linkComponents' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/log' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/makeNoMethodSetStateRule' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/pragma' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/propTypes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/propTypesSort' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/propWrapper' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/usedPropTypes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/variable' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint-plugin-react/lib/util/version' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint-plugin-react/index' {\n  declare module.exports: $Exports<'eslint-plugin-react'>;\n}\ndeclare module 'eslint-plugin-react/index.js' {\n  declare module.exports: $Exports<'eslint-plugin-react'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/boolean-prop-naming.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/boolean-prop-naming'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/button-has-type.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/button-has-type'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/default-props-match-prop-types.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/default-props-match-prop-types'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/destructuring-assignment.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/destructuring-assignment'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/display-name.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/display-name'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/forbid-component-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/forbid-component-props'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/forbid-dom-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/forbid-dom-props'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/forbid-elements.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/forbid-elements'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/forbid-foreign-prop-types.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/forbid-foreign-prop-types'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/forbid-prop-types.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/forbid-prop-types'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/function-component-definition.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/function-component-definition'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-boolean-value.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-boolean-value'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-child-element-spacing.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-child-element-spacing'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-closing-bracket-location.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-closing-bracket-location'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-closing-tag-location.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-closing-tag-location'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-curly-brace-presence.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-curly-brace-presence'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-curly-newline.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-curly-newline'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-curly-spacing.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-curly-spacing'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-equals-spacing.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-equals-spacing'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-filename-extension.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-filename-extension'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-first-prop-new-line.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-first-prop-new-line'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-fragments.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-fragments'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-handler-names.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-handler-names'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-indent-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-indent-props'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-indent.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-indent'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-key.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-key'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-max-depth.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-max-depth'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-max-props-per-line.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-max-props-per-line'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-bind.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-bind'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-comment-textnodes.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-comment-textnodes'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-duplicate-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-duplicate-props'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-literals.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-literals'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-script-url.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-script-url'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-target-blank.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-target-blank'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-undef.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-undef'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-no-useless-fragment.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-useless-fragment'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-one-expression-per-line.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-one-expression-per-line'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-pascal-case.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-pascal-case'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-props-no-multi-spaces.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-props-no-multi-spaces'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-props-no-spreading.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-props-no-spreading'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-sort-default-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-sort-default-props'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-sort-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-sort-props'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-space-before-closing.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-space-before-closing'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-tag-spacing.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-tag-spacing'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-uses-react.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-uses-react'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-uses-vars.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-uses-vars'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/jsx-wrap-multilines.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-wrap-multilines'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-access-state-in-setstate.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-access-state-in-setstate'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-adjacent-inline-elements.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-adjacent-inline-elements'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-array-index-key.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-array-index-key'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-children-prop.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-children-prop'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-danger-with-children.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-danger-with-children'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-danger.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-danger'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-deprecated.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-deprecated'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-did-mount-set-state.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-did-mount-set-state'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-did-update-set-state.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-did-update-set-state'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-direct-mutation-state.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-direct-mutation-state'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-find-dom-node.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-find-dom-node'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-is-mounted.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-is-mounted'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-multi-comp.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-multi-comp'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-redundant-should-component-update.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-redundant-should-component-update'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-render-return-value.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-render-return-value'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-set-state.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-set-state'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-string-refs.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-string-refs'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-this-in-sfc.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-this-in-sfc'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-typos.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-typos'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-unescaped-entities.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-unescaped-entities'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-unknown-property.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-unknown-property'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-unsafe.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-unsafe'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-unused-prop-types.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-unused-prop-types'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-unused-state.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-unused-state'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/no-will-update-set-state.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-will-update-set-state'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/prefer-es6-class.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/prefer-es6-class'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/prefer-read-only-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/prefer-read-only-props'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/prefer-stateless-function.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/prefer-stateless-function'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/prop-types.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/prop-types'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/react-in-jsx-scope.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/react-in-jsx-scope'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/require-default-props.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/require-default-props'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/require-optimization.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/require-optimization'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/require-render-return.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/require-render-return'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/self-closing-comp.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/self-closing-comp'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/sort-comp.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/sort-comp'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/sort-prop-types.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/sort-prop-types'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/state-in-constructor.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/state-in-constructor'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/static-property-placement.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/static-property-placement'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/style-prop-object.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/style-prop-object'>;\n}\ndeclare module 'eslint-plugin-react/lib/rules/void-dom-elements-no-children.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/rules/void-dom-elements-no-children'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/annotations.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/annotations'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/ast.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/ast'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/Components.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/Components'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/defaultProps.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/defaultProps'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/docsUrl.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/docsUrl'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/error.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/error'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/getTokenBeforeClosingBracket.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/getTokenBeforeClosingBracket'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/jsx.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/jsx'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/linkComponents.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/linkComponents'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/log.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/log'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/makeNoMethodSetStateRule.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/makeNoMethodSetStateRule'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/pragma.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/pragma'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/props.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/props'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/propTypes.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/propTypes'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/propTypesSort.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/propTypesSort'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/propWrapper.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/propWrapper'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/usedPropTypes.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/usedPropTypes'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/variable.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/variable'>;\n}\ndeclare module 'eslint-plugin-react/lib/util/version.js' {\n  declare module.exports: $Exports<'eslint-plugin-react/lib/util/version'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/eslint_vx.x.x.js",
    "content": "// flow-typed signature: 1aa7c19bebaa2d421f6d046223cbda10\n// flow-typed version: <<STUB>>/eslint_v6.8.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'eslint'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'eslint' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'eslint/bin/eslint' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/conf/config-schema' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/conf/default-cli-options' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/conf/environments' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/conf/eslint-all' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/conf/eslint-recommended' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/api' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/cascading-config-array-factory' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/cli-engine' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/config-array-factory' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/config-array/config-array' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/config-array/config-dependency' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/config-array/extracted-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/config-array/ignore-pattern' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/config-array' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/config-array/override-tester' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/file-enumerator' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/checkstyle' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/codeframe' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/compact' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/html' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/jslint-xml' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/json-with-metadata' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/json' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/junit' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/stylish' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/table' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/tap' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/unix' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/formatters/visualstudio' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/hash' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/lint-result-cache' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/load-rules' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli-engine/xml-escape' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/cli' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/init/autoconfig' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/init/config-file' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/init/config-initializer' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/init/config-rule' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/init/npm-utils' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/init/source-code-utils' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/apply-disable-directives' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/code-path-analysis/code-path-analyzer' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/code-path-analysis/code-path-segment' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/code-path-analysis/code-path-state' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/code-path-analysis/code-path' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/code-path-analysis/debug-helpers' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/code-path-analysis/fork-context' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/code-path-analysis/id-generator' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/config-comment-parser' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/interpolate' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/linter' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/node-event-generator' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/report-translator' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/rule-fixer' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/rules' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/safe-emitter' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/source-code-fixer' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/linter/timing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/options' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rule-tester' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rule-tester/rule-tester' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/accessor-pairs' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/array-bracket-newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/array-bracket-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/array-callback-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/array-element-newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/arrow-body-style' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/arrow-parens' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/arrow-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/block-scoped-var' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/block-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/brace-style' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/callback-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/camelcase' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/capitalized-comments' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/class-methods-use-this' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/comma-dangle' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/comma-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/comma-style' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/complexity' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/computed-property-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/consistent-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/consistent-this' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/constructor-super' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/curly' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/default-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/default-param-last' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/dot-location' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/dot-notation' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/eol-last' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/eqeqeq' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/for-direction' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/func-call-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/func-name-matching' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/func-names' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/func-style' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/function-call-argument-newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/function-paren-newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/generator-star-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/getter-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/global-require' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/grouped-accessor-pairs' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/guard-for-in' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/handle-callback-err' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/id-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/id-length' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/id-match' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/implicit-arrow-linebreak' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/indent-legacy' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/indent' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/init-declarations' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/jsx-quotes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/key-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/keyword-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/line-comment-position' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/linebreak-style' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/lines-around-comment' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/lines-around-directive' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/lines-between-class-members' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/max-classes-per-file' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/max-depth' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/max-len' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/max-lines-per-function' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/max-lines' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/max-nested-callbacks' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/max-params' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/max-statements-per-line' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/max-statements' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/multiline-comment-style' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/multiline-ternary' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/new-cap' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/new-parens' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/newline-after-var' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/newline-before-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/newline-per-chained-call' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-alert' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-array-constructor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-async-promise-executor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-await-in-loop' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-bitwise' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-buffer-constructor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-caller' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-case-declarations' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-catch-shadow' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-class-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-compare-neg-zero' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-cond-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-confusing-arrow' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-console' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-const-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-constant-condition' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-constructor-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-continue' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-control-regex' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-debugger' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-delete-var' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-div-regex' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-dupe-args' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-dupe-class-members' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-dupe-else-if' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-dupe-keys' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-duplicate-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-duplicate-imports' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-else-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-empty-character-class' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-empty-function' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-empty-pattern' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-empty' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-eq-null' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-eval' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-ex-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-extend-native' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-extra-bind' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-extra-boolean-cast' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-extra-label' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-extra-parens' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-extra-semi' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-fallthrough' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-floating-decimal' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-func-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-global-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-implicit-coercion' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-implicit-globals' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-implied-eval' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-import-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-inline-comments' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-inner-declarations' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-invalid-regexp' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-invalid-this' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-irregular-whitespace' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-iterator' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-label-var' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-labels' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-lone-blocks' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-lonely-if' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-loop-func' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-magic-numbers' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-misleading-character-class' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-mixed-operators' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-mixed-requires' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-mixed-spaces-and-tabs' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-multi-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-multi-spaces' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-multi-str' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-multiple-empty-lines' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-native-reassign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-negated-condition' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-negated-in-lhs' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-nested-ternary' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-new-func' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-new-object' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-new-require' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-new-symbol' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-new-wrappers' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-new' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-obj-calls' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-octal-escape' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-octal' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-param-reassign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-path-concat' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-plusplus' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-process-env' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-process-exit' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-proto' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-prototype-builtins' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-redeclare' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-regex-spaces' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-restricted-globals' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-restricted-imports' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-restricted-modules' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-restricted-properties' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-restricted-syntax' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-return-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-return-await' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-script-url' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-self-assign' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-self-compare' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-sequences' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-setter-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-shadow-restricted-names' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-shadow' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-spaced-func' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-sparse-arrays' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-sync' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-tabs' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-template-curly-in-string' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-ternary' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-this-before-super' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-throw-literal' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-trailing-spaces' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-undef-init' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-undef' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-undefined' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-underscore-dangle' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-unexpected-multiline' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-unmodified-loop-condition' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-unneeded-ternary' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-unreachable' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-unsafe-finally' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-unsafe-negation' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-unused-expressions' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-unused-labels' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-unused-vars' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-use-before-define' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-useless-call' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-useless-catch' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-useless-computed-key' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-useless-concat' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-useless-constructor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-useless-escape' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-useless-rename' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-useless-return' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-var' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-void' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-warning-comments' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-whitespace-before-property' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/no-with' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/nonblock-statement-body-position' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/object-curly-newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/object-curly-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/object-property-newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/object-shorthand' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/one-var-declaration-per-line' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/one-var' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/operator-assignment' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/operator-linebreak' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/padded-blocks' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/padding-line-between-statements' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-arrow-callback' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-const' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-destructuring' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-exponentiation-operator' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-named-capture-group' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-numeric-literals' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-object-spread' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-promise-reject-errors' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-reflect' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-regex-literals' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-rest-params' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-spread' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/prefer-template' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/quote-props' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/quotes' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/radix' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/require-atomic-updates' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/require-await' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/require-jsdoc' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/require-unicode-regexp' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/require-yield' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/rest-spread-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/semi-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/semi-style' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/semi' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/sort-imports' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/sort-keys' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/sort-vars' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/space-before-blocks' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/space-before-function-paren' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/space-in-parens' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/space-infix-ops' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/space-unary-ops' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/spaced-comment' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/strict' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/switch-colon-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/symbol-description' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/template-curly-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/template-tag-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/unicode-bom' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/use-isnan' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/ast-utils' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/fix-tracker' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/keywords' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/lazy-loading-rule-map' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/patterns/letters' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/unicode' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/unicode/is-combining-character' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/unicode/is-emoji-modifier' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/unicode/is-regional-indicator-symbol' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/utils/unicode/is-surrogate-pair' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/valid-jsdoc' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/valid-typeof' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/vars-on-top' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/wrap-iife' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/wrap-regex' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/yield-star-spacing' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/rules/yoda' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/ajv' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/ast-utils' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/config-ops' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/config-validator' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/logging' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/naming' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/relative-module-resolver' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/runtime-info' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/traverser' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/shared/types' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/source-code' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/backward-token-comment-cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/backward-token-cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/cursors' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/decorative-cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/filter-cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/forward-token-comment-cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/forward-token-cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/limit-cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/padded-token-cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/skip-cursor' {\n  declare module.exports: any;\n}\n\ndeclare module 'eslint/lib/source-code/token-store/utils' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'eslint/bin/eslint.js' {\n  declare module.exports: $Exports<'eslint/bin/eslint'>;\n}\ndeclare module 'eslint/conf/config-schema.js' {\n  declare module.exports: $Exports<'eslint/conf/config-schema'>;\n}\ndeclare module 'eslint/conf/default-cli-options.js' {\n  declare module.exports: $Exports<'eslint/conf/default-cli-options'>;\n}\ndeclare module 'eslint/conf/environments.js' {\n  declare module.exports: $Exports<'eslint/conf/environments'>;\n}\ndeclare module 'eslint/conf/eslint-all.js' {\n  declare module.exports: $Exports<'eslint/conf/eslint-all'>;\n}\ndeclare module 'eslint/conf/eslint-recommended.js' {\n  declare module.exports: $Exports<'eslint/conf/eslint-recommended'>;\n}\ndeclare module 'eslint/lib/api.js' {\n  declare module.exports: $Exports<'eslint/lib/api'>;\n}\ndeclare module 'eslint/lib/cli-engine/cascading-config-array-factory.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/cascading-config-array-factory'>;\n}\ndeclare module 'eslint/lib/cli-engine/cli-engine.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/cli-engine'>;\n}\ndeclare module 'eslint/lib/cli-engine/config-array-factory.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/config-array-factory'>;\n}\ndeclare module 'eslint/lib/cli-engine/config-array/config-array.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/config-array/config-array'>;\n}\ndeclare module 'eslint/lib/cli-engine/config-array/config-dependency.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/config-array/config-dependency'>;\n}\ndeclare module 'eslint/lib/cli-engine/config-array/extracted-config.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/config-array/extracted-config'>;\n}\ndeclare module 'eslint/lib/cli-engine/config-array/ignore-pattern.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/config-array/ignore-pattern'>;\n}\ndeclare module 'eslint/lib/cli-engine/config-array/index' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/config-array'>;\n}\ndeclare module 'eslint/lib/cli-engine/config-array/index.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/config-array'>;\n}\ndeclare module 'eslint/lib/cli-engine/config-array/override-tester.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/config-array/override-tester'>;\n}\ndeclare module 'eslint/lib/cli-engine/file-enumerator.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/file-enumerator'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/checkstyle.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/checkstyle'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/codeframe.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/codeframe'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/compact.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/compact'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/html.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/html'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/jslint-xml.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/jslint-xml'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/json-with-metadata.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/json-with-metadata'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/json.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/json'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/junit.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/junit'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/stylish.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/stylish'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/table.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/table'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/tap.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/tap'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/unix.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/unix'>;\n}\ndeclare module 'eslint/lib/cli-engine/formatters/visualstudio.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/formatters/visualstudio'>;\n}\ndeclare module 'eslint/lib/cli-engine/hash.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/hash'>;\n}\ndeclare module 'eslint/lib/cli-engine/index' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine'>;\n}\ndeclare module 'eslint/lib/cli-engine/index.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine'>;\n}\ndeclare module 'eslint/lib/cli-engine/lint-result-cache.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/lint-result-cache'>;\n}\ndeclare module 'eslint/lib/cli-engine/load-rules.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/load-rules'>;\n}\ndeclare module 'eslint/lib/cli-engine/xml-escape.js' {\n  declare module.exports: $Exports<'eslint/lib/cli-engine/xml-escape'>;\n}\ndeclare module 'eslint/lib/cli.js' {\n  declare module.exports: $Exports<'eslint/lib/cli'>;\n}\ndeclare module 'eslint/lib/init/autoconfig.js' {\n  declare module.exports: $Exports<'eslint/lib/init/autoconfig'>;\n}\ndeclare module 'eslint/lib/init/config-file.js' {\n  declare module.exports: $Exports<'eslint/lib/init/config-file'>;\n}\ndeclare module 'eslint/lib/init/config-initializer.js' {\n  declare module.exports: $Exports<'eslint/lib/init/config-initializer'>;\n}\ndeclare module 'eslint/lib/init/config-rule.js' {\n  declare module.exports: $Exports<'eslint/lib/init/config-rule'>;\n}\ndeclare module 'eslint/lib/init/npm-utils.js' {\n  declare module.exports: $Exports<'eslint/lib/init/npm-utils'>;\n}\ndeclare module 'eslint/lib/init/source-code-utils.js' {\n  declare module.exports: $Exports<'eslint/lib/init/source-code-utils'>;\n}\ndeclare module 'eslint/lib/linter/apply-disable-directives.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/apply-disable-directives'>;\n}\ndeclare module 'eslint/lib/linter/code-path-analysis/code-path-analyzer.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/code-path-analysis/code-path-analyzer'>;\n}\ndeclare module 'eslint/lib/linter/code-path-analysis/code-path-segment.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/code-path-analysis/code-path-segment'>;\n}\ndeclare module 'eslint/lib/linter/code-path-analysis/code-path-state.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/code-path-analysis/code-path-state'>;\n}\ndeclare module 'eslint/lib/linter/code-path-analysis/code-path.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/code-path-analysis/code-path'>;\n}\ndeclare module 'eslint/lib/linter/code-path-analysis/debug-helpers.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/code-path-analysis/debug-helpers'>;\n}\ndeclare module 'eslint/lib/linter/code-path-analysis/fork-context.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/code-path-analysis/fork-context'>;\n}\ndeclare module 'eslint/lib/linter/code-path-analysis/id-generator.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/code-path-analysis/id-generator'>;\n}\ndeclare module 'eslint/lib/linter/config-comment-parser.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/config-comment-parser'>;\n}\ndeclare module 'eslint/lib/linter/index' {\n  declare module.exports: $Exports<'eslint/lib/linter'>;\n}\ndeclare module 'eslint/lib/linter/index.js' {\n  declare module.exports: $Exports<'eslint/lib/linter'>;\n}\ndeclare module 'eslint/lib/linter/interpolate.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/interpolate'>;\n}\ndeclare module 'eslint/lib/linter/linter.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/linter'>;\n}\ndeclare module 'eslint/lib/linter/node-event-generator.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/node-event-generator'>;\n}\ndeclare module 'eslint/lib/linter/report-translator.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/report-translator'>;\n}\ndeclare module 'eslint/lib/linter/rule-fixer.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/rule-fixer'>;\n}\ndeclare module 'eslint/lib/linter/rules.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/rules'>;\n}\ndeclare module 'eslint/lib/linter/safe-emitter.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/safe-emitter'>;\n}\ndeclare module 'eslint/lib/linter/source-code-fixer.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/source-code-fixer'>;\n}\ndeclare module 'eslint/lib/linter/timing.js' {\n  declare module.exports: $Exports<'eslint/lib/linter/timing'>;\n}\ndeclare module 'eslint/lib/options.js' {\n  declare module.exports: $Exports<'eslint/lib/options'>;\n}\ndeclare module 'eslint/lib/rule-tester/index' {\n  declare module.exports: $Exports<'eslint/lib/rule-tester'>;\n}\ndeclare module 'eslint/lib/rule-tester/index.js' {\n  declare module.exports: $Exports<'eslint/lib/rule-tester'>;\n}\ndeclare module 'eslint/lib/rule-tester/rule-tester.js' {\n  declare module.exports: $Exports<'eslint/lib/rule-tester/rule-tester'>;\n}\ndeclare module 'eslint/lib/rules/accessor-pairs.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/accessor-pairs'>;\n}\ndeclare module 'eslint/lib/rules/array-bracket-newline.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/array-bracket-newline'>;\n}\ndeclare module 'eslint/lib/rules/array-bracket-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/array-bracket-spacing'>;\n}\ndeclare module 'eslint/lib/rules/array-callback-return.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/array-callback-return'>;\n}\ndeclare module 'eslint/lib/rules/array-element-newline.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/array-element-newline'>;\n}\ndeclare module 'eslint/lib/rules/arrow-body-style.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/arrow-body-style'>;\n}\ndeclare module 'eslint/lib/rules/arrow-parens.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/arrow-parens'>;\n}\ndeclare module 'eslint/lib/rules/arrow-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/arrow-spacing'>;\n}\ndeclare module 'eslint/lib/rules/block-scoped-var.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/block-scoped-var'>;\n}\ndeclare module 'eslint/lib/rules/block-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/block-spacing'>;\n}\ndeclare module 'eslint/lib/rules/brace-style.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/brace-style'>;\n}\ndeclare module 'eslint/lib/rules/callback-return.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/callback-return'>;\n}\ndeclare module 'eslint/lib/rules/camelcase.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/camelcase'>;\n}\ndeclare module 'eslint/lib/rules/capitalized-comments.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/capitalized-comments'>;\n}\ndeclare module 'eslint/lib/rules/class-methods-use-this.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/class-methods-use-this'>;\n}\ndeclare module 'eslint/lib/rules/comma-dangle.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/comma-dangle'>;\n}\ndeclare module 'eslint/lib/rules/comma-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/comma-spacing'>;\n}\ndeclare module 'eslint/lib/rules/comma-style.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/comma-style'>;\n}\ndeclare module 'eslint/lib/rules/complexity.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/complexity'>;\n}\ndeclare module 'eslint/lib/rules/computed-property-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/computed-property-spacing'>;\n}\ndeclare module 'eslint/lib/rules/consistent-return.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/consistent-return'>;\n}\ndeclare module 'eslint/lib/rules/consistent-this.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/consistent-this'>;\n}\ndeclare module 'eslint/lib/rules/constructor-super.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/constructor-super'>;\n}\ndeclare module 'eslint/lib/rules/curly.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/curly'>;\n}\ndeclare module 'eslint/lib/rules/default-case.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/default-case'>;\n}\ndeclare module 'eslint/lib/rules/default-param-last.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/default-param-last'>;\n}\ndeclare module 'eslint/lib/rules/dot-location.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/dot-location'>;\n}\ndeclare module 'eslint/lib/rules/dot-notation.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/dot-notation'>;\n}\ndeclare module 'eslint/lib/rules/eol-last.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/eol-last'>;\n}\ndeclare module 'eslint/lib/rules/eqeqeq.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/eqeqeq'>;\n}\ndeclare module 'eslint/lib/rules/for-direction.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/for-direction'>;\n}\ndeclare module 'eslint/lib/rules/func-call-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/func-call-spacing'>;\n}\ndeclare module 'eslint/lib/rules/func-name-matching.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/func-name-matching'>;\n}\ndeclare module 'eslint/lib/rules/func-names.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/func-names'>;\n}\ndeclare module 'eslint/lib/rules/func-style.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/func-style'>;\n}\ndeclare module 'eslint/lib/rules/function-call-argument-newline.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/function-call-argument-newline'>;\n}\ndeclare module 'eslint/lib/rules/function-paren-newline.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/function-paren-newline'>;\n}\ndeclare module 'eslint/lib/rules/generator-star-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/generator-star-spacing'>;\n}\ndeclare module 'eslint/lib/rules/getter-return.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/getter-return'>;\n}\ndeclare module 'eslint/lib/rules/global-require.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/global-require'>;\n}\ndeclare module 'eslint/lib/rules/grouped-accessor-pairs.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/grouped-accessor-pairs'>;\n}\ndeclare module 'eslint/lib/rules/guard-for-in.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/guard-for-in'>;\n}\ndeclare module 'eslint/lib/rules/handle-callback-err.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/handle-callback-err'>;\n}\ndeclare module 'eslint/lib/rules/id-blacklist.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/id-blacklist'>;\n}\ndeclare module 'eslint/lib/rules/id-length.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/id-length'>;\n}\ndeclare module 'eslint/lib/rules/id-match.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/id-match'>;\n}\ndeclare module 'eslint/lib/rules/implicit-arrow-linebreak.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/implicit-arrow-linebreak'>;\n}\ndeclare module 'eslint/lib/rules/indent-legacy.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/indent-legacy'>;\n}\ndeclare module 'eslint/lib/rules/indent.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/indent'>;\n}\ndeclare module 'eslint/lib/rules/index' {\n  declare module.exports: $Exports<'eslint/lib/rules'>;\n}\ndeclare module 'eslint/lib/rules/index.js' {\n  declare module.exports: $Exports<'eslint/lib/rules'>;\n}\ndeclare module 'eslint/lib/rules/init-declarations.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/init-declarations'>;\n}\ndeclare module 'eslint/lib/rules/jsx-quotes.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/jsx-quotes'>;\n}\ndeclare module 'eslint/lib/rules/key-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/key-spacing'>;\n}\ndeclare module 'eslint/lib/rules/keyword-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/keyword-spacing'>;\n}\ndeclare module 'eslint/lib/rules/line-comment-position.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/line-comment-position'>;\n}\ndeclare module 'eslint/lib/rules/linebreak-style.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/linebreak-style'>;\n}\ndeclare module 'eslint/lib/rules/lines-around-comment.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/lines-around-comment'>;\n}\ndeclare module 'eslint/lib/rules/lines-around-directive.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/lines-around-directive'>;\n}\ndeclare module 'eslint/lib/rules/lines-between-class-members.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/lines-between-class-members'>;\n}\ndeclare module 'eslint/lib/rules/max-classes-per-file.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/max-classes-per-file'>;\n}\ndeclare module 'eslint/lib/rules/max-depth.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/max-depth'>;\n}\ndeclare module 'eslint/lib/rules/max-len.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/max-len'>;\n}\ndeclare module 'eslint/lib/rules/max-lines-per-function.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/max-lines-per-function'>;\n}\ndeclare module 'eslint/lib/rules/max-lines.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/max-lines'>;\n}\ndeclare module 'eslint/lib/rules/max-nested-callbacks.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/max-nested-callbacks'>;\n}\ndeclare module 'eslint/lib/rules/max-params.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/max-params'>;\n}\ndeclare module 'eslint/lib/rules/max-statements-per-line.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/max-statements-per-line'>;\n}\ndeclare module 'eslint/lib/rules/max-statements.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/max-statements'>;\n}\ndeclare module 'eslint/lib/rules/multiline-comment-style.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/multiline-comment-style'>;\n}\ndeclare module 'eslint/lib/rules/multiline-ternary.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/multiline-ternary'>;\n}\ndeclare module 'eslint/lib/rules/new-cap.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/new-cap'>;\n}\ndeclare module 'eslint/lib/rules/new-parens.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/new-parens'>;\n}\ndeclare module 'eslint/lib/rules/newline-after-var.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/newline-after-var'>;\n}\ndeclare module 'eslint/lib/rules/newline-before-return.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/newline-before-return'>;\n}\ndeclare module 'eslint/lib/rules/newline-per-chained-call.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/newline-per-chained-call'>;\n}\ndeclare module 'eslint/lib/rules/no-alert.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-alert'>;\n}\ndeclare module 'eslint/lib/rules/no-array-constructor.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-array-constructor'>;\n}\ndeclare module 'eslint/lib/rules/no-async-promise-executor.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-async-promise-executor'>;\n}\ndeclare module 'eslint/lib/rules/no-await-in-loop.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-await-in-loop'>;\n}\ndeclare module 'eslint/lib/rules/no-bitwise.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-bitwise'>;\n}\ndeclare module 'eslint/lib/rules/no-buffer-constructor.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-buffer-constructor'>;\n}\ndeclare module 'eslint/lib/rules/no-caller.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-caller'>;\n}\ndeclare module 'eslint/lib/rules/no-case-declarations.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-case-declarations'>;\n}\ndeclare module 'eslint/lib/rules/no-catch-shadow.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-catch-shadow'>;\n}\ndeclare module 'eslint/lib/rules/no-class-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-class-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-compare-neg-zero.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-compare-neg-zero'>;\n}\ndeclare module 'eslint/lib/rules/no-cond-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-cond-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-confusing-arrow.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-confusing-arrow'>;\n}\ndeclare module 'eslint/lib/rules/no-console.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-console'>;\n}\ndeclare module 'eslint/lib/rules/no-const-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-const-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-constant-condition.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-constant-condition'>;\n}\ndeclare module 'eslint/lib/rules/no-constructor-return.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-constructor-return'>;\n}\ndeclare module 'eslint/lib/rules/no-continue.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-continue'>;\n}\ndeclare module 'eslint/lib/rules/no-control-regex.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-control-regex'>;\n}\ndeclare module 'eslint/lib/rules/no-debugger.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-debugger'>;\n}\ndeclare module 'eslint/lib/rules/no-delete-var.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-delete-var'>;\n}\ndeclare module 'eslint/lib/rules/no-div-regex.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-div-regex'>;\n}\ndeclare module 'eslint/lib/rules/no-dupe-args.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-dupe-args'>;\n}\ndeclare module 'eslint/lib/rules/no-dupe-class-members.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-dupe-class-members'>;\n}\ndeclare module 'eslint/lib/rules/no-dupe-else-if.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-dupe-else-if'>;\n}\ndeclare module 'eslint/lib/rules/no-dupe-keys.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-dupe-keys'>;\n}\ndeclare module 'eslint/lib/rules/no-duplicate-case.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-duplicate-case'>;\n}\ndeclare module 'eslint/lib/rules/no-duplicate-imports.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-duplicate-imports'>;\n}\ndeclare module 'eslint/lib/rules/no-else-return.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-else-return'>;\n}\ndeclare module 'eslint/lib/rules/no-empty-character-class.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-empty-character-class'>;\n}\ndeclare module 'eslint/lib/rules/no-empty-function.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-empty-function'>;\n}\ndeclare module 'eslint/lib/rules/no-empty-pattern.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-empty-pattern'>;\n}\ndeclare module 'eslint/lib/rules/no-empty.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-empty'>;\n}\ndeclare module 'eslint/lib/rules/no-eq-null.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-eq-null'>;\n}\ndeclare module 'eslint/lib/rules/no-eval.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-eval'>;\n}\ndeclare module 'eslint/lib/rules/no-ex-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-ex-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-extend-native.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-extend-native'>;\n}\ndeclare module 'eslint/lib/rules/no-extra-bind.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-extra-bind'>;\n}\ndeclare module 'eslint/lib/rules/no-extra-boolean-cast.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-extra-boolean-cast'>;\n}\ndeclare module 'eslint/lib/rules/no-extra-label.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-extra-label'>;\n}\ndeclare module 'eslint/lib/rules/no-extra-parens.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-extra-parens'>;\n}\ndeclare module 'eslint/lib/rules/no-extra-semi.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-extra-semi'>;\n}\ndeclare module 'eslint/lib/rules/no-fallthrough.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-fallthrough'>;\n}\ndeclare module 'eslint/lib/rules/no-floating-decimal.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-floating-decimal'>;\n}\ndeclare module 'eslint/lib/rules/no-func-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-func-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-global-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-global-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-implicit-coercion.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-implicit-coercion'>;\n}\ndeclare module 'eslint/lib/rules/no-implicit-globals.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-implicit-globals'>;\n}\ndeclare module 'eslint/lib/rules/no-implied-eval.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-implied-eval'>;\n}\ndeclare module 'eslint/lib/rules/no-import-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-import-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-inline-comments.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-inline-comments'>;\n}\ndeclare module 'eslint/lib/rules/no-inner-declarations.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-inner-declarations'>;\n}\ndeclare module 'eslint/lib/rules/no-invalid-regexp.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-invalid-regexp'>;\n}\ndeclare module 'eslint/lib/rules/no-invalid-this.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-invalid-this'>;\n}\ndeclare module 'eslint/lib/rules/no-irregular-whitespace.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-irregular-whitespace'>;\n}\ndeclare module 'eslint/lib/rules/no-iterator.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-iterator'>;\n}\ndeclare module 'eslint/lib/rules/no-label-var.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-label-var'>;\n}\ndeclare module 'eslint/lib/rules/no-labels.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-labels'>;\n}\ndeclare module 'eslint/lib/rules/no-lone-blocks.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-lone-blocks'>;\n}\ndeclare module 'eslint/lib/rules/no-lonely-if.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-lonely-if'>;\n}\ndeclare module 'eslint/lib/rules/no-loop-func.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-loop-func'>;\n}\ndeclare module 'eslint/lib/rules/no-magic-numbers.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-magic-numbers'>;\n}\ndeclare module 'eslint/lib/rules/no-misleading-character-class.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-misleading-character-class'>;\n}\ndeclare module 'eslint/lib/rules/no-mixed-operators.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-mixed-operators'>;\n}\ndeclare module 'eslint/lib/rules/no-mixed-requires.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-mixed-requires'>;\n}\ndeclare module 'eslint/lib/rules/no-mixed-spaces-and-tabs.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-mixed-spaces-and-tabs'>;\n}\ndeclare module 'eslint/lib/rules/no-multi-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-multi-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-multi-spaces.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-multi-spaces'>;\n}\ndeclare module 'eslint/lib/rules/no-multi-str.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-multi-str'>;\n}\ndeclare module 'eslint/lib/rules/no-multiple-empty-lines.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-multiple-empty-lines'>;\n}\ndeclare module 'eslint/lib/rules/no-native-reassign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-native-reassign'>;\n}\ndeclare module 'eslint/lib/rules/no-negated-condition.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-negated-condition'>;\n}\ndeclare module 'eslint/lib/rules/no-negated-in-lhs.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-negated-in-lhs'>;\n}\ndeclare module 'eslint/lib/rules/no-nested-ternary.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-nested-ternary'>;\n}\ndeclare module 'eslint/lib/rules/no-new-func.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-new-func'>;\n}\ndeclare module 'eslint/lib/rules/no-new-object.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-new-object'>;\n}\ndeclare module 'eslint/lib/rules/no-new-require.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-new-require'>;\n}\ndeclare module 'eslint/lib/rules/no-new-symbol.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-new-symbol'>;\n}\ndeclare module 'eslint/lib/rules/no-new-wrappers.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-new-wrappers'>;\n}\ndeclare module 'eslint/lib/rules/no-new.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-new'>;\n}\ndeclare module 'eslint/lib/rules/no-obj-calls.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-obj-calls'>;\n}\ndeclare module 'eslint/lib/rules/no-octal-escape.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-octal-escape'>;\n}\ndeclare module 'eslint/lib/rules/no-octal.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-octal'>;\n}\ndeclare module 'eslint/lib/rules/no-param-reassign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-param-reassign'>;\n}\ndeclare module 'eslint/lib/rules/no-path-concat.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-path-concat'>;\n}\ndeclare module 'eslint/lib/rules/no-plusplus.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-plusplus'>;\n}\ndeclare module 'eslint/lib/rules/no-process-env.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-process-env'>;\n}\ndeclare module 'eslint/lib/rules/no-process-exit.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-process-exit'>;\n}\ndeclare module 'eslint/lib/rules/no-proto.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-proto'>;\n}\ndeclare module 'eslint/lib/rules/no-prototype-builtins.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-prototype-builtins'>;\n}\ndeclare module 'eslint/lib/rules/no-redeclare.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-redeclare'>;\n}\ndeclare module 'eslint/lib/rules/no-regex-spaces.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-regex-spaces'>;\n}\ndeclare module 'eslint/lib/rules/no-restricted-globals.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-restricted-globals'>;\n}\ndeclare module 'eslint/lib/rules/no-restricted-imports.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-restricted-imports'>;\n}\ndeclare module 'eslint/lib/rules/no-restricted-modules.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-restricted-modules'>;\n}\ndeclare module 'eslint/lib/rules/no-restricted-properties.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-restricted-properties'>;\n}\ndeclare module 'eslint/lib/rules/no-restricted-syntax.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-restricted-syntax'>;\n}\ndeclare module 'eslint/lib/rules/no-return-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-return-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-return-await.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-return-await'>;\n}\ndeclare module 'eslint/lib/rules/no-script-url.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-script-url'>;\n}\ndeclare module 'eslint/lib/rules/no-self-assign.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-self-assign'>;\n}\ndeclare module 'eslint/lib/rules/no-self-compare.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-self-compare'>;\n}\ndeclare module 'eslint/lib/rules/no-sequences.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-sequences'>;\n}\ndeclare module 'eslint/lib/rules/no-setter-return.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-setter-return'>;\n}\ndeclare module 'eslint/lib/rules/no-shadow-restricted-names.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-shadow-restricted-names'>;\n}\ndeclare module 'eslint/lib/rules/no-shadow.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-shadow'>;\n}\ndeclare module 'eslint/lib/rules/no-spaced-func.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-spaced-func'>;\n}\ndeclare module 'eslint/lib/rules/no-sparse-arrays.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-sparse-arrays'>;\n}\ndeclare module 'eslint/lib/rules/no-sync.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-sync'>;\n}\ndeclare module 'eslint/lib/rules/no-tabs.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-tabs'>;\n}\ndeclare module 'eslint/lib/rules/no-template-curly-in-string.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-template-curly-in-string'>;\n}\ndeclare module 'eslint/lib/rules/no-ternary.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-ternary'>;\n}\ndeclare module 'eslint/lib/rules/no-this-before-super.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-this-before-super'>;\n}\ndeclare module 'eslint/lib/rules/no-throw-literal.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-throw-literal'>;\n}\ndeclare module 'eslint/lib/rules/no-trailing-spaces.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-trailing-spaces'>;\n}\ndeclare module 'eslint/lib/rules/no-undef-init.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-undef-init'>;\n}\ndeclare module 'eslint/lib/rules/no-undef.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-undef'>;\n}\ndeclare module 'eslint/lib/rules/no-undefined.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-undefined'>;\n}\ndeclare module 'eslint/lib/rules/no-underscore-dangle.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-underscore-dangle'>;\n}\ndeclare module 'eslint/lib/rules/no-unexpected-multiline.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-unexpected-multiline'>;\n}\ndeclare module 'eslint/lib/rules/no-unmodified-loop-condition.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-unmodified-loop-condition'>;\n}\ndeclare module 'eslint/lib/rules/no-unneeded-ternary.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-unneeded-ternary'>;\n}\ndeclare module 'eslint/lib/rules/no-unreachable.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-unreachable'>;\n}\ndeclare module 'eslint/lib/rules/no-unsafe-finally.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-unsafe-finally'>;\n}\ndeclare module 'eslint/lib/rules/no-unsafe-negation.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-unsafe-negation'>;\n}\ndeclare module 'eslint/lib/rules/no-unused-expressions.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-unused-expressions'>;\n}\ndeclare module 'eslint/lib/rules/no-unused-labels.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-unused-labels'>;\n}\ndeclare module 'eslint/lib/rules/no-unused-vars.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-unused-vars'>;\n}\ndeclare module 'eslint/lib/rules/no-use-before-define.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-use-before-define'>;\n}\ndeclare module 'eslint/lib/rules/no-useless-call.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-useless-call'>;\n}\ndeclare module 'eslint/lib/rules/no-useless-catch.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-useless-catch'>;\n}\ndeclare module 'eslint/lib/rules/no-useless-computed-key.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-useless-computed-key'>;\n}\ndeclare module 'eslint/lib/rules/no-useless-concat.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-useless-concat'>;\n}\ndeclare module 'eslint/lib/rules/no-useless-constructor.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-useless-constructor'>;\n}\ndeclare module 'eslint/lib/rules/no-useless-escape.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-useless-escape'>;\n}\ndeclare module 'eslint/lib/rules/no-useless-rename.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-useless-rename'>;\n}\ndeclare module 'eslint/lib/rules/no-useless-return.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-useless-return'>;\n}\ndeclare module 'eslint/lib/rules/no-var.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-var'>;\n}\ndeclare module 'eslint/lib/rules/no-void.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-void'>;\n}\ndeclare module 'eslint/lib/rules/no-warning-comments.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-warning-comments'>;\n}\ndeclare module 'eslint/lib/rules/no-whitespace-before-property.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-whitespace-before-property'>;\n}\ndeclare module 'eslint/lib/rules/no-with.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/no-with'>;\n}\ndeclare module 'eslint/lib/rules/nonblock-statement-body-position.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/nonblock-statement-body-position'>;\n}\ndeclare module 'eslint/lib/rules/object-curly-newline.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/object-curly-newline'>;\n}\ndeclare module 'eslint/lib/rules/object-curly-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/object-curly-spacing'>;\n}\ndeclare module 'eslint/lib/rules/object-property-newline.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/object-property-newline'>;\n}\ndeclare module 'eslint/lib/rules/object-shorthand.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/object-shorthand'>;\n}\ndeclare module 'eslint/lib/rules/one-var-declaration-per-line.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/one-var-declaration-per-line'>;\n}\ndeclare module 'eslint/lib/rules/one-var.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/one-var'>;\n}\ndeclare module 'eslint/lib/rules/operator-assignment.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/operator-assignment'>;\n}\ndeclare module 'eslint/lib/rules/operator-linebreak.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/operator-linebreak'>;\n}\ndeclare module 'eslint/lib/rules/padded-blocks.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/padded-blocks'>;\n}\ndeclare module 'eslint/lib/rules/padding-line-between-statements.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/padding-line-between-statements'>;\n}\ndeclare module 'eslint/lib/rules/prefer-arrow-callback.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-arrow-callback'>;\n}\ndeclare module 'eslint/lib/rules/prefer-const.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-const'>;\n}\ndeclare module 'eslint/lib/rules/prefer-destructuring.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-destructuring'>;\n}\ndeclare module 'eslint/lib/rules/prefer-exponentiation-operator.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-exponentiation-operator'>;\n}\ndeclare module 'eslint/lib/rules/prefer-named-capture-group.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-named-capture-group'>;\n}\ndeclare module 'eslint/lib/rules/prefer-numeric-literals.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-numeric-literals'>;\n}\ndeclare module 'eslint/lib/rules/prefer-object-spread.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-object-spread'>;\n}\ndeclare module 'eslint/lib/rules/prefer-promise-reject-errors.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-promise-reject-errors'>;\n}\ndeclare module 'eslint/lib/rules/prefer-reflect.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-reflect'>;\n}\ndeclare module 'eslint/lib/rules/prefer-regex-literals.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-regex-literals'>;\n}\ndeclare module 'eslint/lib/rules/prefer-rest-params.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-rest-params'>;\n}\ndeclare module 'eslint/lib/rules/prefer-spread.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-spread'>;\n}\ndeclare module 'eslint/lib/rules/prefer-template.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/prefer-template'>;\n}\ndeclare module 'eslint/lib/rules/quote-props.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/quote-props'>;\n}\ndeclare module 'eslint/lib/rules/quotes.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/quotes'>;\n}\ndeclare module 'eslint/lib/rules/radix.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/radix'>;\n}\ndeclare module 'eslint/lib/rules/require-atomic-updates.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/require-atomic-updates'>;\n}\ndeclare module 'eslint/lib/rules/require-await.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/require-await'>;\n}\ndeclare module 'eslint/lib/rules/require-jsdoc.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/require-jsdoc'>;\n}\ndeclare module 'eslint/lib/rules/require-unicode-regexp.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/require-unicode-regexp'>;\n}\ndeclare module 'eslint/lib/rules/require-yield.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/require-yield'>;\n}\ndeclare module 'eslint/lib/rules/rest-spread-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/rest-spread-spacing'>;\n}\ndeclare module 'eslint/lib/rules/semi-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/semi-spacing'>;\n}\ndeclare module 'eslint/lib/rules/semi-style.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/semi-style'>;\n}\ndeclare module 'eslint/lib/rules/semi.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/semi'>;\n}\ndeclare module 'eslint/lib/rules/sort-imports.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/sort-imports'>;\n}\ndeclare module 'eslint/lib/rules/sort-keys.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/sort-keys'>;\n}\ndeclare module 'eslint/lib/rules/sort-vars.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/sort-vars'>;\n}\ndeclare module 'eslint/lib/rules/space-before-blocks.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/space-before-blocks'>;\n}\ndeclare module 'eslint/lib/rules/space-before-function-paren.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/space-before-function-paren'>;\n}\ndeclare module 'eslint/lib/rules/space-in-parens.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/space-in-parens'>;\n}\ndeclare module 'eslint/lib/rules/space-infix-ops.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/space-infix-ops'>;\n}\ndeclare module 'eslint/lib/rules/space-unary-ops.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/space-unary-ops'>;\n}\ndeclare module 'eslint/lib/rules/spaced-comment.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/spaced-comment'>;\n}\ndeclare module 'eslint/lib/rules/strict.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/strict'>;\n}\ndeclare module 'eslint/lib/rules/switch-colon-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/switch-colon-spacing'>;\n}\ndeclare module 'eslint/lib/rules/symbol-description.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/symbol-description'>;\n}\ndeclare module 'eslint/lib/rules/template-curly-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/template-curly-spacing'>;\n}\ndeclare module 'eslint/lib/rules/template-tag-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/template-tag-spacing'>;\n}\ndeclare module 'eslint/lib/rules/unicode-bom.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/unicode-bom'>;\n}\ndeclare module 'eslint/lib/rules/use-isnan.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/use-isnan'>;\n}\ndeclare module 'eslint/lib/rules/utils/ast-utils.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/ast-utils'>;\n}\ndeclare module 'eslint/lib/rules/utils/fix-tracker.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/fix-tracker'>;\n}\ndeclare module 'eslint/lib/rules/utils/keywords.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/keywords'>;\n}\ndeclare module 'eslint/lib/rules/utils/lazy-loading-rule-map.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/lazy-loading-rule-map'>;\n}\ndeclare module 'eslint/lib/rules/utils/patterns/letters.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/patterns/letters'>;\n}\ndeclare module 'eslint/lib/rules/utils/unicode/index' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/unicode'>;\n}\ndeclare module 'eslint/lib/rules/utils/unicode/index.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/unicode'>;\n}\ndeclare module 'eslint/lib/rules/utils/unicode/is-combining-character.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/unicode/is-combining-character'>;\n}\ndeclare module 'eslint/lib/rules/utils/unicode/is-emoji-modifier.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/unicode/is-emoji-modifier'>;\n}\ndeclare module 'eslint/lib/rules/utils/unicode/is-regional-indicator-symbol.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/unicode/is-regional-indicator-symbol'>;\n}\ndeclare module 'eslint/lib/rules/utils/unicode/is-surrogate-pair.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/utils/unicode/is-surrogate-pair'>;\n}\ndeclare module 'eslint/lib/rules/valid-jsdoc.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/valid-jsdoc'>;\n}\ndeclare module 'eslint/lib/rules/valid-typeof.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/valid-typeof'>;\n}\ndeclare module 'eslint/lib/rules/vars-on-top.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/vars-on-top'>;\n}\ndeclare module 'eslint/lib/rules/wrap-iife.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/wrap-iife'>;\n}\ndeclare module 'eslint/lib/rules/wrap-regex.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/wrap-regex'>;\n}\ndeclare module 'eslint/lib/rules/yield-star-spacing.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/yield-star-spacing'>;\n}\ndeclare module 'eslint/lib/rules/yoda.js' {\n  declare module.exports: $Exports<'eslint/lib/rules/yoda'>;\n}\ndeclare module 'eslint/lib/shared/ajv.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/ajv'>;\n}\ndeclare module 'eslint/lib/shared/ast-utils.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/ast-utils'>;\n}\ndeclare module 'eslint/lib/shared/config-ops.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/config-ops'>;\n}\ndeclare module 'eslint/lib/shared/config-validator.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/config-validator'>;\n}\ndeclare module 'eslint/lib/shared/logging.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/logging'>;\n}\ndeclare module 'eslint/lib/shared/naming.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/naming'>;\n}\ndeclare module 'eslint/lib/shared/relative-module-resolver.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/relative-module-resolver'>;\n}\ndeclare module 'eslint/lib/shared/runtime-info.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/runtime-info'>;\n}\ndeclare module 'eslint/lib/shared/traverser.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/traverser'>;\n}\ndeclare module 'eslint/lib/shared/types.js' {\n  declare module.exports: $Exports<'eslint/lib/shared/types'>;\n}\ndeclare module 'eslint/lib/source-code/index' {\n  declare module.exports: $Exports<'eslint/lib/source-code'>;\n}\ndeclare module 'eslint/lib/source-code/index.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code'>;\n}\ndeclare module 'eslint/lib/source-code/source-code.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/source-code'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/backward-token-comment-cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/backward-token-comment-cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/backward-token-cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/backward-token-cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/cursors.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/cursors'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/decorative-cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/decorative-cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/filter-cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/filter-cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/forward-token-comment-cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/forward-token-comment-cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/forward-token-cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/forward-token-cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/index' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/index.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/limit-cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/limit-cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/padded-token-cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/padded-token-cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/skip-cursor.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/skip-cursor'>;\n}\ndeclare module 'eslint/lib/source-code/token-store/utils.js' {\n  declare module.exports: $Exports<'eslint/lib/source-code/token-store/utils'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/flow-bin_v0.x.x.js",
    "content": "// flow-typed signature: 28fdff7f110e1c75efab63ff205dda30\n// flow-typed version: c6154227d1/flow-bin_v0.x.x/flow_>=v0.104.x\n\ndeclare module \"flow-bin\" {\n  declare module.exports: string;\n}\n"
  },
  {
    "path": "flow-typed/npm/fs-extra_vx.x.x.js",
    "content": "// flow-typed signature: aee54212928d20cc8911ec75fbdd31ed\n// flow-typed version: <<STUB>>/fs-extra_v^8.0.1/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'fs-extra'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'fs-extra' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'fs-extra/lib/copy-sync/copy-sync' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/copy-sync' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/copy/copy' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/copy' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/empty' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/ensure/file' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/ensure' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/ensure/link' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/ensure/symlink-paths' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/ensure/symlink-type' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/ensure/symlink' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/fs' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/json' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/json/jsonfile' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/json/output-json-sync' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/json/output-json' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/mkdirs' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/mkdirs/mkdirs-sync' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/mkdirs/mkdirs' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/mkdirs/win32' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/move-sync' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/move-sync/move-sync' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/move' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/move/move' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/output' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/path-exists' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/remove' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/remove/rimraf' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/util/buffer' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/util/stat' {\n  declare module.exports: any;\n}\n\ndeclare module 'fs-extra/lib/util/utimes' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'fs-extra/lib/copy-sync/copy-sync.js' {\n  declare module.exports: $Exports<'fs-extra/lib/copy-sync/copy-sync'>;\n}\ndeclare module 'fs-extra/lib/copy-sync/index' {\n  declare module.exports: $Exports<'fs-extra/lib/copy-sync'>;\n}\ndeclare module 'fs-extra/lib/copy-sync/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/copy-sync'>;\n}\ndeclare module 'fs-extra/lib/copy/copy.js' {\n  declare module.exports: $Exports<'fs-extra/lib/copy/copy'>;\n}\ndeclare module 'fs-extra/lib/copy/index' {\n  declare module.exports: $Exports<'fs-extra/lib/copy'>;\n}\ndeclare module 'fs-extra/lib/copy/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/copy'>;\n}\ndeclare module 'fs-extra/lib/empty/index' {\n  declare module.exports: $Exports<'fs-extra/lib/empty'>;\n}\ndeclare module 'fs-extra/lib/empty/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/empty'>;\n}\ndeclare module 'fs-extra/lib/ensure/file.js' {\n  declare module.exports: $Exports<'fs-extra/lib/ensure/file'>;\n}\ndeclare module 'fs-extra/lib/ensure/index' {\n  declare module.exports: $Exports<'fs-extra/lib/ensure'>;\n}\ndeclare module 'fs-extra/lib/ensure/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/ensure'>;\n}\ndeclare module 'fs-extra/lib/ensure/link.js' {\n  declare module.exports: $Exports<'fs-extra/lib/ensure/link'>;\n}\ndeclare module 'fs-extra/lib/ensure/symlink-paths.js' {\n  declare module.exports: $Exports<'fs-extra/lib/ensure/symlink-paths'>;\n}\ndeclare module 'fs-extra/lib/ensure/symlink-type.js' {\n  declare module.exports: $Exports<'fs-extra/lib/ensure/symlink-type'>;\n}\ndeclare module 'fs-extra/lib/ensure/symlink.js' {\n  declare module.exports: $Exports<'fs-extra/lib/ensure/symlink'>;\n}\ndeclare module 'fs-extra/lib/fs/index' {\n  declare module.exports: $Exports<'fs-extra/lib/fs'>;\n}\ndeclare module 'fs-extra/lib/fs/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/fs'>;\n}\ndeclare module 'fs-extra/lib/index' {\n  declare module.exports: $Exports<'fs-extra/lib'>;\n}\ndeclare module 'fs-extra/lib/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib'>;\n}\ndeclare module 'fs-extra/lib/json/index' {\n  declare module.exports: $Exports<'fs-extra/lib/json'>;\n}\ndeclare module 'fs-extra/lib/json/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/json'>;\n}\ndeclare module 'fs-extra/lib/json/jsonfile.js' {\n  declare module.exports: $Exports<'fs-extra/lib/json/jsonfile'>;\n}\ndeclare module 'fs-extra/lib/json/output-json-sync.js' {\n  declare module.exports: $Exports<'fs-extra/lib/json/output-json-sync'>;\n}\ndeclare module 'fs-extra/lib/json/output-json.js' {\n  declare module.exports: $Exports<'fs-extra/lib/json/output-json'>;\n}\ndeclare module 'fs-extra/lib/mkdirs/index' {\n  declare module.exports: $Exports<'fs-extra/lib/mkdirs'>;\n}\ndeclare module 'fs-extra/lib/mkdirs/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/mkdirs'>;\n}\ndeclare module 'fs-extra/lib/mkdirs/mkdirs-sync.js' {\n  declare module.exports: $Exports<'fs-extra/lib/mkdirs/mkdirs-sync'>;\n}\ndeclare module 'fs-extra/lib/mkdirs/mkdirs.js' {\n  declare module.exports: $Exports<'fs-extra/lib/mkdirs/mkdirs'>;\n}\ndeclare module 'fs-extra/lib/mkdirs/win32.js' {\n  declare module.exports: $Exports<'fs-extra/lib/mkdirs/win32'>;\n}\ndeclare module 'fs-extra/lib/move-sync/index' {\n  declare module.exports: $Exports<'fs-extra/lib/move-sync'>;\n}\ndeclare module 'fs-extra/lib/move-sync/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/move-sync'>;\n}\ndeclare module 'fs-extra/lib/move-sync/move-sync.js' {\n  declare module.exports: $Exports<'fs-extra/lib/move-sync/move-sync'>;\n}\ndeclare module 'fs-extra/lib/move/index' {\n  declare module.exports: $Exports<'fs-extra/lib/move'>;\n}\ndeclare module 'fs-extra/lib/move/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/move'>;\n}\ndeclare module 'fs-extra/lib/move/move.js' {\n  declare module.exports: $Exports<'fs-extra/lib/move/move'>;\n}\ndeclare module 'fs-extra/lib/output/index' {\n  declare module.exports: $Exports<'fs-extra/lib/output'>;\n}\ndeclare module 'fs-extra/lib/output/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/output'>;\n}\ndeclare module 'fs-extra/lib/path-exists/index' {\n  declare module.exports: $Exports<'fs-extra/lib/path-exists'>;\n}\ndeclare module 'fs-extra/lib/path-exists/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/path-exists'>;\n}\ndeclare module 'fs-extra/lib/remove/index' {\n  declare module.exports: $Exports<'fs-extra/lib/remove'>;\n}\ndeclare module 'fs-extra/lib/remove/index.js' {\n  declare module.exports: $Exports<'fs-extra/lib/remove'>;\n}\ndeclare module 'fs-extra/lib/remove/rimraf.js' {\n  declare module.exports: $Exports<'fs-extra/lib/remove/rimraf'>;\n}\ndeclare module 'fs-extra/lib/util/buffer.js' {\n  declare module.exports: $Exports<'fs-extra/lib/util/buffer'>;\n}\ndeclare module 'fs-extra/lib/util/stat.js' {\n  declare module.exports: $Exports<'fs-extra/lib/util/stat'>;\n}\ndeclare module 'fs-extra/lib/util/utimes.js' {\n  declare module.exports: $Exports<'fs-extra/lib/util/utimes'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/globby_vx.x.x.js",
    "content": "// flow-typed signature: 8f77d308b3b3fbe3fc41ae8026ea44e5\n// flow-typed version: <<STUB>>/globby_v^11.0.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'globby'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'globby' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'globby/gitignore' {\n  declare module.exports: any;\n}\n\ndeclare module 'globby/stream-utils' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'globby/gitignore.js' {\n  declare module.exports: $Exports<'globby/gitignore'>;\n}\ndeclare module 'globby/index' {\n  declare module.exports: $Exports<'globby'>;\n}\ndeclare module 'globby/index.js' {\n  declare module.exports: $Exports<'globby'>;\n}\ndeclare module 'globby/stream-utils.js' {\n  declare module.exports: $Exports<'globby/stream-utils'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/jest-axe_vx.x.x.js",
    "content": "// flow-typed signature: aa29ce2ae2ecea0ec9f3c1f57fdf520a\n// flow-typed version: <<STUB>>/jest-axe_v^3.3.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'jest-axe'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'jest-axe' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'jest-axe/extend-expect' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'jest-axe/extend-expect.js' {\n  declare module.exports: $Exports<'jest-axe/extend-expect'>;\n}\ndeclare module 'jest-axe/index' {\n  declare module.exports: $Exports<'jest-axe'>;\n}\ndeclare module 'jest-axe/index.js' {\n  declare module.exports: $Exports<'jest-axe'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/jest-junit_vx.x.x.js",
    "content": "// flow-typed signature: 6521445381a3dade7a644d6e5c6beb86\n// flow-typed version: <<STUB>>/jest-junit_v^10.0.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'jest-junit'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'jest-junit' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'jest-junit/constants' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-junit/utils/buildJsonResults' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-junit/utils/getOptions' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-junit/utils/replaceRootDirInPath' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'jest-junit/constants/index' {\n  declare module.exports: $Exports<'jest-junit/constants'>;\n}\ndeclare module 'jest-junit/constants/index.js' {\n  declare module.exports: $Exports<'jest-junit/constants'>;\n}\ndeclare module 'jest-junit/index' {\n  declare module.exports: $Exports<'jest-junit'>;\n}\ndeclare module 'jest-junit/index.js' {\n  declare module.exports: $Exports<'jest-junit'>;\n}\ndeclare module 'jest-junit/utils/buildJsonResults.js' {\n  declare module.exports: $Exports<'jest-junit/utils/buildJsonResults'>;\n}\ndeclare module 'jest-junit/utils/getOptions.js' {\n  declare module.exports: $Exports<'jest-junit/utils/getOptions'>;\n}\ndeclare module 'jest-junit/utils/replaceRootDirInPath.js' {\n  declare module.exports: $Exports<'jest-junit/utils/replaceRootDirInPath'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/jest-watch-typeahead_vx.x.x.js",
    "content": "// flow-typed signature: eddb908ec00b0d5393afc44d350fd960\n// flow-typed version: <<STUB>>/jest-watch-typeahead_v^0.4.2/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'jest-watch-typeahead'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'jest-watch-typeahead' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'jest-watch-typeahead/build/file_name_plugin/plugin' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/build/file_name_plugin/prompt' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/build' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/build/lib/pattern_mode_helpers' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/build/lib/scroll' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/build/lib/utils' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/build/test_name_plugin/plugin' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/build/test_name_plugin/prompt' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/build/test_utils/pluginTester' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/build/types/Config' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/filename' {\n  declare module.exports: any;\n}\n\ndeclare module 'jest-watch-typeahead/testname' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'jest-watch-typeahead/build/file_name_plugin/plugin.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build/file_name_plugin/plugin'>;\n}\ndeclare module 'jest-watch-typeahead/build/file_name_plugin/prompt.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build/file_name_plugin/prompt'>;\n}\ndeclare module 'jest-watch-typeahead/build/index' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build'>;\n}\ndeclare module 'jest-watch-typeahead/build/index.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build'>;\n}\ndeclare module 'jest-watch-typeahead/build/lib/pattern_mode_helpers.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build/lib/pattern_mode_helpers'>;\n}\ndeclare module 'jest-watch-typeahead/build/lib/scroll.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build/lib/scroll'>;\n}\ndeclare module 'jest-watch-typeahead/build/lib/utils.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build/lib/utils'>;\n}\ndeclare module 'jest-watch-typeahead/build/test_name_plugin/plugin.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build/test_name_plugin/plugin'>;\n}\ndeclare module 'jest-watch-typeahead/build/test_name_plugin/prompt.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build/test_name_plugin/prompt'>;\n}\ndeclare module 'jest-watch-typeahead/build/test_utils/pluginTester.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build/test_utils/pluginTester'>;\n}\ndeclare module 'jest-watch-typeahead/build/types/Config.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/build/types/Config'>;\n}\ndeclare module 'jest-watch-typeahead/filename.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/filename'>;\n}\ndeclare module 'jest-watch-typeahead/testname.js' {\n  declare module.exports: $Exports<'jest-watch-typeahead/testname'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/jest_vx.x.x.js",
    "content": "// flow-typed signature: 27f8467378a99b6130bd20f54f31a644\n// flow-typed version: 6cb9e99836/jest_v24.x.x/flow_>=v0.104.x\n\ntype JestMockFn<TArguments: $ReadOnlyArray<*>, TReturn> = {\n  (...args: TArguments): TReturn,\n  /**\n   * An object for introspecting mock calls\n   */\n  mock: {\n   /**\n    * An array that represents all calls that have been made into this mock\n    * function. Each call is represented by an array of arguments that were\n    * passed during the call.\n    */\n   calls: Array<TArguments>,\n   /**\n    * An array that contains all the object instances that have been\n    * instantiated from this mock function.\n    */\n   instances: Array<TReturn>,\n   /**\n    * An array that contains all the object results that have been\n    * returned by this mock function call\n    */\n   results: Array<{\n    isThrow: boolean,\n    value: TReturn,\n    ...\n   }>,\n   ...\n  },\n  /**\n   * Resets all information stored in the mockFn.mock.calls and\n   * mockFn.mock.instances arrays. Often this is useful when you want to clean\n   * up a mock's usage data between two assertions.\n   */\n  mockClear(): void,\n  /**\n   * Resets all information stored in the mock. This is useful when you want to\n   * completely restore a mock back to its initial state.\n   */\n  mockReset(): void,\n  /**\n   * Removes the mock and restores the initial implementation. This is useful\n   * when you want to mock functions in certain test cases and restore the\n   * original implementation in others. Beware that mockFn.mockRestore only\n   * works when mock was created with jest.spyOn. Thus you have to take care of\n   * restoration yourself when manually assigning jest.fn().\n   */\n  mockRestore(): void,\n  /**\n   * Accepts a function that should be used as the implementation of the mock.\n   * The mock itself will still record all calls that go into and instances\n   * that come from itself -- the only difference is that the implementation\n   * will also be executed when the mock is called.\n   */\n  mockImplementation(\n    fn: (...args: TArguments) => TReturn\n  ): JestMockFn<TArguments, TReturn>,\n  /**\n   * Accepts a function that will be used as an implementation of the mock for\n   * one call to the mocked function. Can be chained so that multiple function\n   * calls produce different results.\n   */\n  mockImplementationOnce(\n    fn: (...args: TArguments) => TReturn\n  ): JestMockFn<TArguments, TReturn>,\n  /**\n   * Accepts a string to use in test result output in place of \"jest.fn()\" to\n   * indicate which mock function is being referenced.\n   */\n  mockName(name: string): JestMockFn<TArguments, TReturn>,\n  /**\n   * Just a simple sugar function for returning `this`\n   */\n  mockReturnThis(): void,\n  /**\n   * Accepts a value that will be returned whenever the mock function is called.\n   */\n  mockReturnValue(value: TReturn): JestMockFn<TArguments, TReturn>,\n  /**\n   * Sugar for only returning a value once inside your mock\n   */\n  mockReturnValueOnce(value: TReturn): JestMockFn<TArguments, TReturn>,\n  /**\n   * Sugar for jest.fn().mockImplementation(() => Promise.resolve(value))\n   */\n  mockResolvedValue(value: TReturn): JestMockFn<TArguments, Promise<TReturn>>,\n  /**\n   * Sugar for jest.fn().mockImplementationOnce(() => Promise.resolve(value))\n   */\n  mockResolvedValueOnce(\n    value: TReturn\n  ): JestMockFn<TArguments, Promise<TReturn>>,\n  /**\n   * Sugar for jest.fn().mockImplementation(() => Promise.reject(value))\n   */\n  mockRejectedValue(value: TReturn): JestMockFn<TArguments, Promise<any>>,\n  /**\n   * Sugar for jest.fn().mockImplementationOnce(() => Promise.reject(value))\n   */\n  mockRejectedValueOnce(value: TReturn): JestMockFn<TArguments, Promise<any>>,\n  ...\n };\n\n type JestAsymmetricEqualityType = { /**\n  * A custom Jasmine equality tester\n  */\n asymmetricMatch(value: mixed): boolean, ... };\n\n type JestCallsType = {\n  allArgs(): mixed,\n  all(): mixed,\n  any(): boolean,\n  count(): number,\n  first(): mixed,\n  mostRecent(): mixed,\n  reset(): void,\n  ...\n };\n\n type JestClockType = {\n  install(): void,\n  mockDate(date: Date): void,\n  tick(milliseconds?: number): void,\n  uninstall(): void,\n  ...\n };\n\n type JestMatcherResult = {\n  message?: string | (() => string),\n  pass: boolean,\n  ...\n };\n\n type JestMatcher = (\n   received: any,\n   ...actual: Array<any>\n ) => JestMatcherResult | Promise<JestMatcherResult>;\n\n type JestPromiseType = {\n  /**\n   * Use rejects to unwrap the reason of a rejected promise so any other\n   * matcher can be chained. If the promise is fulfilled the assertion fails.\n   */\n  rejects: JestExpectType,\n  /**\n   * Use resolves to unwrap the value of a fulfilled promise so any other\n   * matcher can be chained. If the promise is rejected the assertion fails.\n   */\n  resolves: JestExpectType,\n  ...\n };\n\n /**\n  * Jest allows functions and classes to be used as test names in test() and\n  * describe()\n  */\n type JestTestName = string | Function;\n\n /**\n  *  Plugin: jest-styled-components\n  */\n\n type JestStyledComponentsMatcherValue =\n   | string\n   | JestAsymmetricEqualityType\n   | RegExp\n   | typeof undefined;\n\n type JestStyledComponentsMatcherOptions = {\n  media?: string,\n  modifier?: string,\n  supports?: string,\n  ...\n };\n\n type JestStyledComponentsMatchersType = { toHaveStyleRule(\n   property: string,\n   value: JestStyledComponentsMatcherValue,\n   options?: JestStyledComponentsMatcherOptions\n ): void, ... };\n\n /**\n  *  Plugin: jest-enzyme\n  */\n type EnzymeMatchersType = {\n  // 5.x\n  toBeEmpty(): void,\n  toBePresent(): void,\n  // 6.x\n  toBeChecked(): void,\n  toBeDisabled(): void,\n  toBeEmptyRender(): void,\n  toContainMatchingElement(selector: string): void,\n  toContainMatchingElements(n: number, selector: string): void,\n  toContainExactlyOneMatchingElement(selector: string): void,\n  toContainReact(element: React$Element<any>): void,\n  toExist(): void,\n  toHaveClassName(className: string): void,\n  toHaveHTML(html: string): void,\n  toHaveProp: ((propKey: string, propValue?: any) => void) &\n    ((props: {...}) => void),\n  toHaveRef(refName: string): void,\n  toHaveState: ((stateKey: string, stateValue?: any) => void) &\n    ((state: {...}) => void),\n  toHaveStyle: ((styleKey: string, styleValue?: any) => void) &\n    ((style: {...}) => void),\n  toHaveTagName(tagName: string): void,\n  toHaveText(text: string): void,\n  toHaveValue(value: any): void,\n  toIncludeText(text: string): void,\n  toMatchElement(\n    element: React$Element<any>,\n    options?: {| ignoreProps?: boolean, verbose?: boolean |}\n  ): void,\n  toMatchSelector(selector: string): void,\n  // 7.x\n  toHaveDisplayName(name: string): void,\n  ...\n };\n\n // DOM testing library extensions (jest-dom)\n // https://github.com/testing-library/jest-dom\n type DomTestingLibraryType = {\n  /**\n   * @deprecated\n   */\n  toBeInTheDOM(container?: HTMLElement): void,\n  toBeInTheDocument(): void,\n  toBeVisible(): void,\n  toBeEmpty(): void,\n  toBeDisabled(): void,\n  toBeEnabled(): void,\n  toBeInvalid(): void,\n  toBeRequired(): void,\n  toBeValid(): void,\n  toContainElement(element: HTMLElement | null): void,\n  toContainHTML(htmlText: string): void,\n  toHaveAttribute(attr: string, value?: any): void,\n  toHaveClass(...classNames: string[]): void,\n  toHaveFocus(): void,\n  toHaveFormValues(expectedValues: { [name: string]: any, ... }): void,\n  toHaveStyle(css: string): void,\n  toHaveTextContent(\n    text: string | RegExp,\n    options?: { normalizeWhitespace: boolean, ... }\n  ): void,\n  toHaveValue(value?: string | string[] | number): void,\n  ...\n };\n\n // Jest JQuery Matchers: https://github.com/unindented/custom-jquery-matchers\n type JestJQueryMatchersType = {\n  toExist(): void,\n  toHaveLength(len: number): void,\n  toHaveId(id: string): void,\n  toHaveClass(className: string): void,\n  toHaveTag(tag: string): void,\n  toHaveAttr(key: string, val?: any): void,\n  toHaveProp(key: string, val?: any): void,\n  toHaveText(text: string | RegExp): void,\n  toHaveData(key: string, val?: any): void,\n  toHaveValue(val: any): void,\n  toHaveCss(css: { [key: string]: any, ... }): void,\n  toBeChecked(): void,\n  toBeDisabled(): void,\n  toBeEmpty(): void,\n  toBeHidden(): void,\n  toBeSelected(): void,\n  toBeVisible(): void,\n  toBeFocused(): void,\n  toBeInDom(): void,\n  toBeMatchedBy(sel: string): void,\n  toHaveDescendant(sel: string): void,\n  toHaveDescendantWithText(sel: string, text: string | RegExp): void,\n  ...\n };\n\n // Jest Extended Matchers: https://github.com/jest-community/jest-extended\n type JestExtendedMatchersType = {\n  /**\n   * Note: Currently unimplemented\n   * Passing assertion\n   *\n   * @param {String} message\n   */\n  //  pass(message: string): void;\n\n  /**\n   * Note: Currently unimplemented\n   * Failing assertion\n   *\n   * @param {String} message\n   */\n  //  fail(message: string): void;\n\n  /**\n   * Use .toBeEmpty when checking if a String '', Array [] or Object {} is empty.\n   */\n  toBeEmpty(): void,\n  /**\n   * Use .toBeOneOf when checking if a value is a member of a given Array.\n   * @param {Array.<*>} members\n   */\n  toBeOneOf(members: any[]): void,\n  /**\n   * Use `.toBeNil` when checking a value is `null` or `undefined`.\n   */\n  toBeNil(): void,\n  /**\n   * Use `.toSatisfy` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean`.\n   * @param {Function} predicate\n   */\n  toSatisfy(predicate: (n: any) => boolean): void,\n  /**\n   * Use `.toBeArray` when checking if a value is an `Array`.\n   */\n  toBeArray(): void,\n  /**\n   * Use `.toBeArrayOfSize` when checking if a value is an `Array` of size x.\n   * @param {Number} x\n   */\n  toBeArrayOfSize(x: number): void,\n  /**\n   * Use `.toIncludeAllMembers` when checking if an `Array` contains all of the same members of a given set.\n   * @param {Array.<*>} members\n   */\n  toIncludeAllMembers(members: any[]): void,\n  /**\n   * Use `.toIncludeAnyMembers` when checking if an `Array` contains any of the members of a given set.\n   * @param {Array.<*>} members\n   */\n  toIncludeAnyMembers(members: any[]): void,\n  /**\n   * Use `.toSatisfyAll` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean` for all values in an array.\n   * @param {Function} predicate\n   */\n  toSatisfyAll(predicate: (n: any) => boolean): void,\n  /**\n   * Use `.toBeBoolean` when checking if a value is a `Boolean`.\n   */\n  toBeBoolean(): void,\n  /**\n   * Use `.toBeTrue` when checking a value is equal (===) to `true`.\n   */\n  toBeTrue(): void,\n  /**\n   * Use `.toBeFalse` when checking a value is equal (===) to `false`.\n   */\n  toBeFalse(): void,\n  /**\n   * Use .toBeDate when checking if a value is a Date.\n   */\n  toBeDate(): void,\n  /**\n   * Use `.toBeFunction` when checking if a value is a `Function`.\n   */\n  toBeFunction(): void,\n  /**\n   * Use `.toHaveBeenCalledBefore` when checking if a `Mock` was called before another `Mock`.\n   *\n   * Note: Required Jest version >22\n   * Note: Your mock functions will have to be asynchronous to cause the timestamps inside of Jest to occur in a differentJS event loop, otherwise the mock timestamps will all be the same\n   *\n   * @param {Mock} mock\n   */\n  toHaveBeenCalledBefore(mock: JestMockFn<any, any>): void,\n  /**\n   * Use `.toBeNumber` when checking if a value is a `Number`.\n   */\n  toBeNumber(): void,\n  /**\n   * Use `.toBeNaN` when checking a value is `NaN`.\n   */\n  toBeNaN(): void,\n  /**\n   * Use `.toBeFinite` when checking if a value is a `Number`, not `NaN` or `Infinity`.\n   */\n  toBeFinite(): void,\n  /**\n   * Use `.toBePositive` when checking if a value is a positive `Number`.\n   */\n  toBePositive(): void,\n  /**\n   * Use `.toBeNegative` when checking if a value is a negative `Number`.\n   */\n  toBeNegative(): void,\n  /**\n   * Use `.toBeEven` when checking if a value is an even `Number`.\n   */\n  toBeEven(): void,\n  /**\n   * Use `.toBeOdd` when checking if a value is an odd `Number`.\n   */\n  toBeOdd(): void,\n  /**\n   * Use `.toBeWithin` when checking if a number is in between the given bounds of: start (inclusive) and end (exclusive).\n   *\n   * @param {Number} start\n   * @param {Number} end\n   */\n  toBeWithin(start: number, end: number): void,\n  /**\n   * Use `.toBeObject` when checking if a value is an `Object`.\n   */\n  toBeObject(): void,\n  /**\n   * Use `.toContainKey` when checking if an object contains the provided key.\n   *\n   * @param {String} key\n   */\n  toContainKey(key: string): void,\n  /**\n   * Use `.toContainKeys` when checking if an object has all of the provided keys.\n   *\n   * @param {Array.<String>} keys\n   */\n  toContainKeys(keys: string[]): void,\n  /**\n   * Use `.toContainAllKeys` when checking if an object only contains all of the provided keys.\n   *\n   * @param {Array.<String>} keys\n   */\n  toContainAllKeys(keys: string[]): void,\n  /**\n   * Use `.toContainAnyKeys` when checking if an object contains at least one of the provided keys.\n   *\n   * @param {Array.<String>} keys\n   */\n  toContainAnyKeys(keys: string[]): void,\n  /**\n   * Use `.toContainValue` when checking if an object contains the provided value.\n   *\n   * @param {*} value\n   */\n  toContainValue(value: any): void,\n  /**\n   * Use `.toContainValues` when checking if an object contains all of the provided values.\n   *\n   * @param {Array.<*>} values\n   */\n  toContainValues(values: any[]): void,\n  /**\n   * Use `.toContainAllValues` when checking if an object only contains all of the provided values.\n   *\n   * @param {Array.<*>} values\n   */\n  toContainAllValues(values: any[]): void,\n  /**\n   * Use `.toContainAnyValues` when checking if an object contains at least one of the provided values.\n   *\n   * @param {Array.<*>} values\n   */\n  toContainAnyValues(values: any[]): void,\n  /**\n   * Use `.toContainEntry` when checking if an object contains the provided entry.\n   *\n   * @param {Array.<String, String>} entry\n   */\n  toContainEntry(entry: [string, string]): void,\n  /**\n   * Use `.toContainEntries` when checking if an object contains all of the provided entries.\n   *\n   * @param {Array.<Array.<String, String>>} entries\n   */\n  toContainEntries(entries: [string, string][]): void,\n  /**\n   * Use `.toContainAllEntries` when checking if an object only contains all of the provided entries.\n   *\n   * @param {Array.<Array.<String, String>>} entries\n   */\n  toContainAllEntries(entries: [string, string][]): void,\n  /**\n   * Use `.toContainAnyEntries` when checking if an object contains at least one of the provided entries.\n   *\n   * @param {Array.<Array.<String, String>>} entries\n   */\n  toContainAnyEntries(entries: [string, string][]): void,\n  /**\n   * Use `.toBeExtensible` when checking if an object is extensible.\n   */\n  toBeExtensible(): void,\n  /**\n   * Use `.toBeFrozen` when checking if an object is frozen.\n   */\n  toBeFrozen(): void,\n  /**\n   * Use `.toBeSealed` when checking if an object is sealed.\n   */\n  toBeSealed(): void,\n  /**\n   * Use `.toBeString` when checking if a value is a `String`.\n   */\n  toBeString(): void,\n  /**\n   * Use `.toEqualCaseInsensitive` when checking if a string is equal (===) to another ignoring the casing of both strings.\n   *\n   * @param {String} string\n   */\n  toEqualCaseInsensitive(string: string): void,\n  /**\n   * Use `.toStartWith` when checking if a `String` starts with a given `String` prefix.\n   *\n   * @param {String} prefix\n   */\n  toStartWith(prefix: string): void,\n  /**\n   * Use `.toEndWith` when checking if a `String` ends with a given `String` suffix.\n   *\n   * @param {String} suffix\n   */\n  toEndWith(suffix: string): void,\n  /**\n   * Use `.toInclude` when checking if a `String` includes the given `String` substring.\n   *\n   * @param {String} substring\n   */\n  toInclude(substring: string): void,\n  /**\n   * Use `.toIncludeRepeated` when checking if a `String` includes the given `String` substring the correct number of times.\n   *\n   * @param {String} substring\n   * @param {Number} times\n   */\n  toIncludeRepeated(substring: string, times: number): void,\n  /**\n   * Use `.toIncludeMultiple` when checking if a `String` includes all of the given substrings.\n   *\n   * @param {Array.<String>} substring\n   */\n  toIncludeMultiple(substring: string[]): void,\n  ...\n };\n\n interface JestExpectType {\n   not: JestExpectType &\n     EnzymeMatchersType &\n     DomTestingLibraryType &\n     JestJQueryMatchersType &\n     JestStyledComponentsMatchersType &\n     JestExtendedMatchersType;\n   /**\n    * If you have a mock function, you can use .lastCalledWith to test what\n    * arguments it was last called with.\n    */\n   lastCalledWith(...args: Array<any>): void;\n   /**\n    * toBe just checks that a value is what you expect. It uses === to check\n    * strict equality.\n    */\n   toBe(value: any): void;\n   /**\n    * Use .toBeCalledWith to ensure that a mock function was called with\n    * specific arguments.\n    */\n   toBeCalledWith(...args: Array<any>): void;\n   /**\n    * Using exact equality with floating point numbers is a bad idea. Rounding\n    * means that intuitive things fail.\n    */\n   toBeCloseTo(num: number, delta: any): void;\n   /**\n    * Use .toBeDefined to check that a variable is not undefined.\n    */\n   toBeDefined(): void;\n   /**\n    * Use .toBeFalsy when you don't care what a value is, you just want to\n    * ensure a value is false in a boolean context.\n    */\n   toBeFalsy(): void;\n   /**\n    * To compare floating point numbers, you can use toBeGreaterThan.\n    */\n   toBeGreaterThan(number: number): void;\n   /**\n    * To compare floating point numbers, you can use toBeGreaterThanOrEqual.\n    */\n   toBeGreaterThanOrEqual(number: number): void;\n   /**\n    * To compare floating point numbers, you can use toBeLessThan.\n    */\n   toBeLessThan(number: number): void;\n   /**\n    * To compare floating point numbers, you can use toBeLessThanOrEqual.\n    */\n   toBeLessThanOrEqual(number: number): void;\n   /**\n    * Use .toBeInstanceOf(Class) to check that an object is an instance of a\n    * class.\n    */\n   toBeInstanceOf(cls: Class<*>): void;\n   /**\n    * .toBeNull() is the same as .toBe(null) but the error messages are a bit\n    * nicer.\n    */\n   toBeNull(): void;\n   /**\n    * Use .toBeTruthy when you don't care what a value is, you just want to\n    * ensure a value is true in a boolean context.\n    */\n   toBeTruthy(): void;\n   /**\n    * Use .toBeUndefined to check that a variable is undefined.\n    */\n   toBeUndefined(): void;\n   /**\n    * Use .toContain when you want to check that an item is in a list. For\n    * testing the items in the list, this uses ===, a strict equality check.\n    */\n   toContain(item: any): void;\n   /**\n    * Use .toContainEqual when you want to check that an item is in a list. For\n    * testing the items in the list, this matcher recursively checks the\n    * equality of all fields, rather than checking for object identity.\n    */\n   toContainEqual(item: any): void;\n   /**\n    * Use .toEqual when you want to check that two objects have the same value.\n    * This matcher recursively checks the equality of all fields, rather than\n    * checking for object identity.\n    */\n   toEqual(value: any): void;\n   /**\n    * Use .toHaveBeenCalled to ensure that a mock function got called.\n    */\n   toHaveBeenCalled(): void;\n   toBeCalled(): void;\n   /**\n    * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact\n    * number of times.\n    */\n   toHaveBeenCalledTimes(number: number): void;\n   toBeCalledTimes(number: number): void;\n   /**\n    *\n    */\n   toHaveBeenNthCalledWith(nthCall: number, ...args: Array<any>): void;\n   nthCalledWith(nthCall: number, ...args: Array<any>): void;\n   /**\n    *\n    */\n   toHaveReturned(): void;\n   toReturn(): void;\n   /**\n    *\n    */\n   toHaveReturnedTimes(number: number): void;\n   toReturnTimes(number: number): void;\n   /**\n    *\n    */\n   toHaveReturnedWith(value: any): void;\n   toReturnWith(value: any): void;\n   /**\n    *\n    */\n   toHaveLastReturnedWith(value: any): void;\n   lastReturnedWith(value: any): void;\n   /**\n    *\n    */\n   toHaveNthReturnedWith(nthCall: number, value: any): void;\n   nthReturnedWith(nthCall: number, value: any): void;\n   /**\n    * Use .toHaveBeenCalledWith to ensure that a mock function was called with\n    * specific arguments.\n    */\n   toHaveBeenCalledWith(...args: Array<any>): void;\n   toBeCalledWith(...args: Array<any>): void;\n   /**\n    * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called\n    * with specific arguments.\n    */\n   toHaveBeenLastCalledWith(...args: Array<any>): void;\n   lastCalledWith(...args: Array<any>): void;\n   /**\n    * Check that an object has a .length property and it is set to a certain\n    * numeric value.\n    */\n   toHaveLength(number: number): void;\n   /**\n    *\n    */\n   toHaveProperty(propPath: string | $ReadOnlyArray<string>, value?: any): void;\n   /**\n    * Use .toMatch to check that a string matches a regular expression or string.\n    */\n   toMatch(regexpOrString: RegExp | string): void;\n   /**\n    * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object.\n    */\n   toMatchObject(object: Object | Array<Object>): void;\n   /**\n    * Use .toStrictEqual to check that a javascript object matches a subset of the properties of an object.\n    */\n   toStrictEqual(value: any): void;\n   /**\n    * This ensures that an Object matches the most recent snapshot.\n    */\n   toMatchSnapshot(propertyMatchers?: any, name?: string): void;\n   /**\n    * This ensures that an Object matches the most recent snapshot.\n    */\n   toMatchSnapshot(name: string): void;\n\n   toMatchInlineSnapshot(snapshot?: string): void;\n   toMatchInlineSnapshot(propertyMatchers?: any, snapshot?: string): void;\n   /**\n    * Use .toThrow to test that a function throws when it is called.\n    * If you want to test that a specific error gets thrown, you can provide an\n    * argument to toThrow. The argument can be a string for the error message,\n    * a class for the error, or a regex that should match the error.\n    *\n    * Alias: .toThrowError\n    */\n   toThrow(message?: string | Error | Class<Error> | RegExp): void;\n   toThrowError(message?: string | Error | Class<Error> | RegExp): void;\n   /**\n    * Use .toThrowErrorMatchingSnapshot to test that a function throws a error\n    * matching the most recent snapshot when it is called.\n    */\n   toThrowErrorMatchingSnapshot(): void;\n   toThrowErrorMatchingInlineSnapshot(snapshot?: string): void;\n }\n\n type JestObjectType = {\n  /**\n   *  Disables automatic mocking in the module loader.\n   *\n   *  After this method is called, all `require()`s will return the real\n   *  versions of each module (rather than a mocked version).\n   */\n  disableAutomock(): JestObjectType,\n  /**\n   * An un-hoisted version of disableAutomock\n   */\n  autoMockOff(): JestObjectType,\n  /**\n   * Enables automatic mocking in the module loader.\n   */\n  enableAutomock(): JestObjectType,\n  /**\n   * An un-hoisted version of enableAutomock\n   */\n  autoMockOn(): JestObjectType,\n  /**\n   * Clears the mock.calls and mock.instances properties of all mocks.\n   * Equivalent to calling .mockClear() on every mocked function.\n   */\n  clearAllMocks(): JestObjectType,\n  /**\n   * Resets the state of all mocks. Equivalent to calling .mockReset() on every\n   * mocked function.\n   */\n  resetAllMocks(): JestObjectType,\n  /**\n   * Restores all mocks back to their original value.\n   */\n  restoreAllMocks(): JestObjectType,\n  /**\n   * Removes any pending timers from the timer system.\n   */\n  clearAllTimers(): void,\n  /**\n   * Returns the number of fake timers still left to run.\n   */\n  getTimerCount(): number,\n  /**\n   * The same as `mock` but not moved to the top of the expectation by\n   * babel-jest.\n   */\n  doMock(moduleName: string, moduleFactory?: any): JestObjectType,\n  /**\n   * The same as `unmock` but not moved to the top of the expectation by\n   * babel-jest.\n   */\n  dontMock(moduleName: string): JestObjectType,\n  /**\n   * Returns a new, unused mock function. Optionally takes a mock\n   * implementation.\n   */\n  fn<TArguments: $ReadOnlyArray<*>, TReturn>(\n    implementation?: (...args: TArguments) => TReturn\n  ): JestMockFn<TArguments, TReturn>,\n  /**\n   * Determines if the given function is a mocked function.\n   */\n  isMockFunction(fn: Function): boolean,\n  /**\n   * Given the name of a module, use the automatic mocking system to generate a\n   * mocked version of the module for you.\n   */\n  genMockFromModule(moduleName: string): any,\n  /**\n   * Mocks a module with an auto-mocked version when it is being required.\n   *\n   * The second argument can be used to specify an explicit module factory that\n   * is being run instead of using Jest's automocking feature.\n   *\n   * The third argument can be used to create virtual mocks -- mocks of modules\n   * that don't exist anywhere in the system.\n   */\n  mock(\n    moduleName: string,\n    moduleFactory?: any,\n    options?: Object\n  ): JestObjectType,\n  /**\n   * Returns the actual module instead of a mock, bypassing all checks on\n   * whether the module should receive a mock implementation or not.\n   */\n  requireActual(moduleName: string): any,\n  /**\n   * Returns a mock module instead of the actual module, bypassing all checks\n   * on whether the module should be required normally or not.\n   */\n  requireMock(moduleName: string): any,\n  /**\n   * Resets the module registry - the cache of all required modules. This is\n   * useful to isolate modules where local state might conflict between tests.\n   */\n  resetModules(): JestObjectType,\n  /**\n   * Creates a sandbox registry for the modules that are loaded inside the\n   * callback function. This is useful to isolate specific modules for every\n   * test so that local module state doesn't conflict between tests.\n   */\n  isolateModules(fn: () => void): JestObjectType,\n  /**\n   * Exhausts the micro-task queue (usually interfaced in node via\n   * process.nextTick).\n   */\n  runAllTicks(): void,\n  /**\n   * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(),\n   * setInterval(), and setImmediate()).\n   */\n  runAllTimers(): void,\n  /**\n   * Exhausts all tasks queued by setImmediate().\n   */\n  runAllImmediates(): void,\n  /**\n   * Executes only the macro task queue (i.e. all tasks queued by setTimeout()\n   * or setInterval() and setImmediate()).\n   */\n  advanceTimersByTime(msToRun: number): void,\n  /**\n   * Executes only the macro task queue (i.e. all tasks queued by setTimeout()\n   * or setInterval() and setImmediate()).\n   *\n   * Renamed to `advanceTimersByTime`.\n   */\n  runTimersToTime(msToRun: number): void,\n  /**\n   * Executes only the macro-tasks that are currently pending (i.e., only the\n   * tasks that have been queued by setTimeout() or setInterval() up to this\n   * point)\n   */\n  runOnlyPendingTimers(): void,\n  /**\n   * Explicitly supplies the mock object that the module system should return\n   * for the specified module. Note: It is recommended to use jest.mock()\n   * instead.\n   */\n  setMock(moduleName: string, moduleExports: any): JestObjectType,\n  /**\n   * Indicates that the module system should never return a mocked version of\n   * the specified module from require() (e.g. that it should always return the\n   * real module).\n   */\n  unmock(moduleName: string): JestObjectType,\n  /**\n   * Instructs Jest to use fake versions of the standard timer functions\n   * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick,\n   * setImmediate and clearImmediate).\n   */\n  useFakeTimers(): JestObjectType,\n  /**\n   * Instructs Jest to use the real versions of the standard timer functions.\n   */\n  useRealTimers(): JestObjectType,\n  /**\n   * Creates a mock function similar to jest.fn but also tracks calls to\n   * object[methodName].\n   */\n  spyOn(\n    object: Object,\n    methodName: string,\n    accessType?: 'get' | 'set'\n  ): JestMockFn<any, any>,\n  /**\n   * Set the default timeout interval for tests and before/after hooks in milliseconds.\n   * Note: The default timeout interval is 5 seconds if this method is not called.\n   */\n  setTimeout(timeout: number): JestObjectType,\n  ...\n };\n\n type JestSpyType = { calls: JestCallsType, ... };\n\n type JestDoneFn = {|\n  (): void,\n  fail: (error: Error) => void,\n |};\n\n /** Runs this function after every test inside this context */\n declare function afterEach(\n   fn: (done: JestDoneFn) => ?Promise<mixed>,\n   timeout?: number\n ): void;\n /** Runs this function before every test inside this context */\n declare function beforeEach(\n   fn: (done: JestDoneFn) => ?Promise<mixed>,\n   timeout?: number\n ): void;\n /** Runs this function after all tests have finished inside this context */\n declare function afterAll(\n   fn: (done: JestDoneFn) => ?Promise<mixed>,\n   timeout?: number\n ): void;\n /** Runs this function before any tests have started inside this context */\n declare function beforeAll(\n   fn: (done: JestDoneFn) => ?Promise<mixed>,\n   timeout?: number\n ): void;\n\n /** A context for grouping tests together */\n declare var describe: {\n  /**\n   * Creates a block that groups together several related tests in one \"test suite\"\n   */\n  (name: JestTestName, fn: () => void): void,\n  /**\n   * Only run this describe block\n   */\n  only(name: JestTestName, fn: () => void): void,\n  /**\n   * Skip running this describe block\n   */\n  skip(name: JestTestName, fn: () => void): void,\n  /**\n   * each runs this test against array of argument arrays per each run\n   *\n   * @param {table} table of Test\n   */\n  each(\n    ...table: Array<Array<mixed> | mixed> | [Array<string>, string]\n  ): (\n    name: JestTestName,\n    fn?: (...args: Array<any>) => ?Promise<mixed>,\n    timeout?: number\n  ) => void,\n  ...\n };\n\n /** An individual test unit */\n declare var it: {\n  /**\n   * An individual test unit\n   *\n   * @param {JestTestName} Name of Test\n   * @param {Function} Test\n   * @param {number} Timeout for the test, in milliseconds.\n   */\n  (\n    name: JestTestName,\n    fn?: (done: JestDoneFn) => ?Promise<mixed>,\n    timeout?: number\n  ): void,\n  /**\n   * Only run this test\n   *\n   * @param {JestTestName} Name of Test\n   * @param {Function} Test\n   * @param {number} Timeout for the test, in milliseconds.\n   */\n  only: {|\n    (\n      name: JestTestName,\n      fn?: (done: JestDoneFn) => ?Promise<mixed>,\n      timeout?: number\n    ): void,\n    each(\n      ...table: Array<Array<mixed> | mixed> | [Array<string>, string]\n    ): (\n      name: JestTestName,\n      fn?: (...args: Array<any>) => ?Promise<mixed>,\n      timeout?: number\n    ) => void\n  |},\n  /**\n   * Skip running this test\n   *\n   * @param {JestTestName} Name of Test\n   * @param {Function} Test\n   * @param {number} Timeout for the test, in milliseconds.\n   */\n  skip(\n    name: JestTestName,\n    fn?: (done: JestDoneFn) => ?Promise<mixed>,\n    timeout?: number\n  ): void,\n  /**\n   * Highlight planned tests in the summary output\n   *\n   * @param {String} Name of Test to do\n   */\n  todo(name: string): void,\n  /**\n   * Run the test concurrently\n   *\n   * @param {JestTestName} Name of Test\n   * @param {Function} Test\n   * @param {number} Timeout for the test, in milliseconds.\n   */\n  concurrent(\n    name: JestTestName,\n    fn?: (done: JestDoneFn) => ?Promise<mixed>,\n    timeout?: number\n  ): void,\n  /**\n   * each runs this test against array of argument arrays per each run\n   *\n   * @param {table} table of Test\n   */\n  each(\n    ...table: Array<Array<mixed> | mixed> | [Array<string>, string]\n  ): (\n    name: JestTestName,\n    fn?: (...args: Array<any>) => ?Promise<mixed>,\n    timeout?: number\n  ) => void,\n  ...\n };\n\n declare function fit(\n   name: JestTestName,\n   fn: (done: JestDoneFn) => ?Promise<mixed>,\n   timeout?: number\n ): void;\n /** An individual test unit */\n declare var test: typeof it;\n /** A disabled group of tests */\n declare var xdescribe: typeof describe;\n /** A focused group of tests */\n declare var fdescribe: typeof describe;\n /** A disabled individual test */\n declare var xit: typeof it;\n /** A disabled individual test */\n declare var xtest: typeof it;\n\n type JestPrettyFormatColors = {\n  comment: {\n   close: string,\n   open: string,\n   ...\n  },\n  content: {\n   close: string,\n   open: string,\n   ...\n  },\n  prop: {\n   close: string,\n   open: string,\n   ...\n  },\n  tag: {\n   close: string,\n   open: string,\n   ...\n  },\n  value: {\n   close: string,\n   open: string,\n   ...\n  },\n  ...\n };\n\n type JestPrettyFormatIndent = string => string;\n type JestPrettyFormatRefs = Array<any>;\n type JestPrettyFormatPrint = any => string;\n type JestPrettyFormatStringOrNull = string | null;\n\n type JestPrettyFormatOptions = {|\n   callToJSON: boolean,\n   edgeSpacing: string,\n   escapeRegex: boolean,\n   highlight: boolean,\n   indent: number,\n   maxDepth: number,\n   min: boolean,\n   plugins: JestPrettyFormatPlugins,\n   printFunctionName: boolean,\n   spacing: string,\n   theme: {|\n     comment: string,\n     content: string,\n     prop: string,\n     tag: string,\n     value: string,\n   |},\n |};\n\n type JestPrettyFormatPlugin = {\n  print: (\n    val: any,\n    serialize: JestPrettyFormatPrint,\n    indent: JestPrettyFormatIndent,\n    opts: JestPrettyFormatOptions,\n    colors: JestPrettyFormatColors\n  ) => string,\n  test: any => boolean,\n  ...\n };\n\n type JestPrettyFormatPlugins = Array<JestPrettyFormatPlugin>;\n\n /** The expect function is used every time you want to test a value */\n declare var expect: {\n  /** The object that you want to make assertions against */\n  (\n    value: any\n  ): JestExpectType &\n    JestPromiseType &\n    EnzymeMatchersType &\n    DomTestingLibraryType &\n    JestJQueryMatchersType &\n    JestStyledComponentsMatchersType &\n    JestExtendedMatchersType,\n  /** Add additional Jasmine matchers to Jest's roster */\n  extend(matchers: { [name: string]: JestMatcher, ... }): void,\n  /** Add a module that formats application-specific data structures. */\n  addSnapshotSerializer(pluginModule: JestPrettyFormatPlugin): void,\n  assertions(expectedAssertions: number): void,\n  hasAssertions(): void,\n  any(value: mixed): JestAsymmetricEqualityType,\n  anything(): any,\n  arrayContaining(value: Array<mixed>): Array<mixed>,\n  objectContaining(value: Object): Object,\n  /** Matches any received string that contains the exact expected string. */\n  stringContaining(value: string): string,\n  stringMatching(value: string | RegExp): string,\n  not: {\n   arrayContaining: (value: $ReadOnlyArray<mixed>) => Array<mixed>,\n   objectContaining: (value: {...}) => Object,\n   stringContaining: (value: string) => string,\n   stringMatching: (value: string | RegExp) => string,\n   ...\n  },\n  ...\n };\n\n // TODO handle return type\n // http://jasmine.github.io/2.4/introduction.html#section-Spies\n declare function spyOn(value: mixed, method: string): Object;\n\n /** Holds all functions related to manipulating test runner */\n declare var jest: JestObjectType;\n\n /**\n  * The global Jasmine object, this is generally not exposed as the public API,\n  * using features inside here could break in later versions of Jest.\n  */\n declare var jasmine: {\n  DEFAULT_TIMEOUT_INTERVAL: number,\n  any(value: mixed): JestAsymmetricEqualityType,\n  anything(): any,\n  arrayContaining(value: Array<mixed>): Array<mixed>,\n  clock(): JestClockType,\n  createSpy(name: string): JestSpyType,\n  createSpyObj(\n    baseName: string,\n    methodNames: Array<string>\n  ): { [methodName: string]: JestSpyType, ... },\n  objectContaining(value: Object): Object,\n  stringMatching(value: string): string,\n  ...\n };\n"
  },
  {
    "path": "flow-typed/npm/lighthouse_vx.x.x.js",
    "content": "// flow-typed signature: 820b282b9b46e7ada66d43da8473a5e0\n// flow-typed version: <<STUB>>/lighthouse_v^5.6.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'lighthouse'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'lighthouse' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'lighthouse/commitlint.config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/docs/recipes/auth/example-lh-auth' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/docs/recipes/auth/server/server' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/docs/recipes/custom-audit/custom-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/docs/recipes/custom-audit/searchable-audit' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/docs/recipes/custom-audit/searchable-gatherer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/docs/recipes/gulp/gulpfile' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/docs/recipes/lighthouse-plugin-example/audits/preload-as' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/docs/recipes/lighthouse-plugin-example/plugin' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/eslint-local-rules' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/jest.config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/bin' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/cli-flags' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/commands/commands' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/commands/list-audits' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/commands/list-trace-categories' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/printer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/run' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/sentry-prompt' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/cli/bin-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/cli/cli-flags-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/cli/index-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/cli/printer-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/cli/run-test' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/byte-efficiency/script' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/dobetterweb/empty_module' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/dobetterweb/third_party/aggressive-promise-polyfill' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/offline-ready-sw' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/perf/level-2' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/perf/level-3' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/perf/perf-budgets/big-script' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/perf/preload_tester' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/static-server' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/tricky-main-thread-consumer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/tricky-main-thread-library' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/a11y/a11y-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/a11y/expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/byte-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/byte-efficiency/expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/dbw-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/error-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/error-expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/firehouse' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/lantern-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/offline-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/offline-local/offline-expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/oopif-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/oopif-expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/perf/expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/perf/lantern-expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/perf/perf-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/pwa-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/pwa-expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/pwa2-expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/pwa3-expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/redirects-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/redirects/expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/run-smoke' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/seo-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/seo/expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/smoke-test-dfns' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/smokehouse-report' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/smokehouse' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/tricky-metrics/expectations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/accesskeys' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-allowed-attr' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-required-attr' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-required-children' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-required-parent' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-roles' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-valid-attr-value' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-valid-attr' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/audio-caption' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/axe-audit' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/button-name' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/bypass' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/color-contrast' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/definition-list' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/dlitem' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/document-title' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/duplicate-id' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/frame-title' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/html-has-lang' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/html-lang-valid' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/image-alt' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/input-image-alt' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/label' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/layout-table' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/link-name' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/list' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/listitem' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/custom-controls-labels' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/custom-controls-roles' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/focus-traps' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/focusable-controls' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/heading-levels' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/interactive-element-affordance' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/logical-tab-order' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/managed-focus' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/offscreen-content-hidden' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/use-landmarks' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/visual-order-follows-dom' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/meta-refresh' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/meta-viewport' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/object-alt' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/tabindex' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/td-headers-attr' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/th-has-data-cells' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/valid-lang' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/video-caption' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/video-description' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/apple-touch-icon' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/audit' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/bootup-time' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/efficient-animated-content' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/offscreen-images' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/render-blocking-resources' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/total-byte-weight' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/unminified-css' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/unminified-javascript' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/unused-css-rules' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/unused-javascript' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-optimized-images' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-responsive-images' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-text-compression' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-webp-images' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/content-width' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/critical-request-chains' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/deprecations' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/diagnostics' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/appcache-manifest' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/doctype' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/dom-size' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/geolocation-on-start' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/js-libraries' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/no-document-write' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/no-vulnerable-libraries' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/notification-on-start' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/uses-http2' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/errors-in-console' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/final-screenshot' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/font-display' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/image-aspect-ratio' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/installable-manifest' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/is-on-https' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/load-fast-enough-for-pwa' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/main-thread-tasks' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/mainthread-work-breakdown' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/manual/manual-audit' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/manual/pwa-cross-browser' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/manual/pwa-each-page-has-url' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/manual/pwa-page-transitions' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/estimated-input-latency' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/first-contentful-paint-3g' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/first-contentful-paint' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/first-cpu-idle' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/first-meaningful-paint' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/interactive' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/max-potential-fid' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/speed-index' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/total-blocking-time' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/mixed-content' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/multi-check-audit' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/network-requests' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/network-rtt' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/network-server-latency' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/offline-start-url' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/performance-budget' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/predictive-perf' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/redirects-http' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/redirects' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/resource-summary' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/screenshot-thumbnails' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/canonical' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/font-size' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/hreflang' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/http-status-code' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/is-crawlable' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/link-text' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/manual/structured-data' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/meta-description' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/plugins' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/robots-txt' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/seo/tap-targets' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/service-worker' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/splash-screen' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/themed-omnibox' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/third-party-summary' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/time-to-first-byte' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/user-timings' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/uses-rel-preconnect' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/uses-rel-preload' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/viewport' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/violation-audit' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/without-javascript' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/audits/works-offline' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/computed-artifact' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/critical-request-chains' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/load-simulator' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/main-resource' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/main-thread-tasks' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/manifest-values' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/estimated-input-latency' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/first-contentful-paint' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/first-cpu-idle' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/first-meaningful-paint' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/interactive' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-estimated-input-latency' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-first-contentful-paint' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-first-cpu-idle' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-first-meaningful-paint' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-interactive' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-max-potential-fid' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-metric' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-speed-index' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-total-blocking-time' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/largest-contentful-paint' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/max-potential-fid' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/metric' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/speed-index' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/total-blocking-time' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/network-analysis' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/network-records' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/page-dependency-graph' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/resource-summary' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/screenshots' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/speedline' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/trace-of-tab' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/user-timings' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/computed/viewport-meta' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/budget' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/config-helpers' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/config-plugin' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/constants' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/default-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/full-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/lr-desktop-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/lr-mobile-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/mixed-content-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/config/perf-config' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/connections/connection' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/connections/cri' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/connections/extension' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/connections/raw' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/devtools-log' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/driver' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gather-runner' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/accessibility' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/anchor-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/cache-contents' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/console-messages' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/css-usage' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/appcache' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/doctype' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/domstats' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/optimized-images' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/password-inputs-with-prevented-paste' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/response-compression' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/tags-blocking-first-paint' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/gatherer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/html-without-javascript' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/http-redirect' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/iframe-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/image-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/js-usage' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/link-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/main-document-content' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/meta-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/mixed-content' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/offline' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/runtime-exceptions' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/script-elements' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/seo/embedded-content' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/seo/font-size' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/seo/robots-txt' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/seo/tap-targets' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/service-worker' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/source-maps' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/start-url' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/viewport-dimensions' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/arbitrary-equality-map' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/asset-saver' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/base-node' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/cpu-node' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/network-node' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/connection-pool' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/dns-cache' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/network-analyzer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/simulator' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/tcp-connection' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/emulation' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/file-namer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/i18n/i18n' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/i18n/locales' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/i18n/swap-locale' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/icons' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/lantern-trace-saver' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/lh-element' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/lh-error' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/manifest-parser' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/minification-estimator' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/minify-devtoolslog' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/minify-trace' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/network-recorder' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/network-request' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/page-functions' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/proto-preprocessor' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/rect-helpers' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/helpers/walk-object' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/json-expander' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/json-linter' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/jsonld-keyword-validator' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/line-number-from-jsonld-path' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/schema-validator' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/scripts/download-jsonldcontext' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/scripts/generate-schema-tree' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/sd-validation' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/sentry' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/stack-collector' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/stack-packs' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/statistics' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/tappable-rects' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/timing-trace-saver' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/tracehouse/main-thread-tasks' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/tracehouse/task-groups' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/tracehouse/trace-processor' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/traces/pwmetrics-events' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/lib/url-shim' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/html-report-assets' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/category-renderer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/crc-details-renderer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/details-renderer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/dom' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/logger' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/performance-category-renderer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/psi' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/pwa-category-renderer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/report-renderer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/report-ui-features' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/snippet-renderer' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/util' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/report/report-generator' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/runner' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/scoring' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/lighthouse-core/scripts/manual-chrome-launcher' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/stack-packs' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/stack-packs/packs/amp' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/stack-packs/packs/angular' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/stack-packs/packs/magento' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/stack-packs/packs/react' {\n  declare module.exports: any;\n}\n\ndeclare module 'lighthouse/stack-packs/packs/wordpress' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'lighthouse/commitlint.config.js' {\n  declare module.exports: $Exports<'lighthouse/commitlint.config'>;\n}\ndeclare module 'lighthouse/docs/recipes/auth/example-lh-auth.js' {\n  declare module.exports: $Exports<'lighthouse/docs/recipes/auth/example-lh-auth'>;\n}\ndeclare module 'lighthouse/docs/recipes/auth/server/server.js' {\n  declare module.exports: $Exports<'lighthouse/docs/recipes/auth/server/server'>;\n}\ndeclare module 'lighthouse/docs/recipes/custom-audit/custom-config.js' {\n  declare module.exports: $Exports<'lighthouse/docs/recipes/custom-audit/custom-config'>;\n}\ndeclare module 'lighthouse/docs/recipes/custom-audit/searchable-audit.js' {\n  declare module.exports: $Exports<'lighthouse/docs/recipes/custom-audit/searchable-audit'>;\n}\ndeclare module 'lighthouse/docs/recipes/custom-audit/searchable-gatherer.js' {\n  declare module.exports: $Exports<'lighthouse/docs/recipes/custom-audit/searchable-gatherer'>;\n}\ndeclare module 'lighthouse/docs/recipes/gulp/gulpfile.js' {\n  declare module.exports: $Exports<'lighthouse/docs/recipes/gulp/gulpfile'>;\n}\ndeclare module 'lighthouse/docs/recipes/lighthouse-plugin-example/audits/preload-as.js' {\n  declare module.exports: $Exports<'lighthouse/docs/recipes/lighthouse-plugin-example/audits/preload-as'>;\n}\ndeclare module 'lighthouse/docs/recipes/lighthouse-plugin-example/plugin.js' {\n  declare module.exports: $Exports<'lighthouse/docs/recipes/lighthouse-plugin-example/plugin'>;\n}\ndeclare module 'lighthouse/eslint-local-rules.js' {\n  declare module.exports: $Exports<'lighthouse/eslint-local-rules'>;\n}\ndeclare module 'lighthouse/jest.config.js' {\n  declare module.exports: $Exports<'lighthouse/jest.config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/bin.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/bin'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/cli-flags.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/cli-flags'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/commands/commands.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/commands/commands'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/commands/list-audits.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/commands/list-audits'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/commands/list-trace-categories.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/commands/list-trace-categories'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/index' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/index.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/printer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/printer'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/run.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/run'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/sentry-prompt.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/sentry-prompt'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/cli/bin-test.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/cli/bin-test'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/cli/cli-flags-test.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/cli/cli-flags-test'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/cli/index-test.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/cli/index-test'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/cli/printer-test.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/cli/printer-test'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/cli/run-test.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/cli/run-test'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/byte-efficiency/script.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/byte-efficiency/script'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/dobetterweb/empty_module.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/dobetterweb/empty_module'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/dobetterweb/third_party/aggressive-promise-polyfill.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/dobetterweb/third_party/aggressive-promise-polyfill'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/offline-ready-sw.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/offline-ready-sw'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/perf/level-2.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/perf/level-2'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/perf/level-3.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/perf/level-3'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/perf/perf-budgets/big-script.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/perf/perf-budgets/big-script'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/perf/preload_tester.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/perf/preload_tester'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/static-server.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/static-server'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/tricky-main-thread-consumer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/tricky-main-thread-consumer'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/fixtures/tricky-main-thread-library.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/fixtures/tricky-main-thread-library'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/a11y/a11y-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/a11y/a11y-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/a11y/expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/a11y/expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/byte-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/byte-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/byte-efficiency/expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/byte-efficiency/expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/dbw-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/dbw-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/error-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/error-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/error-expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/error-expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/firehouse.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/firehouse'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/lantern-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/lantern-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/offline-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/offline-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/offline-local/offline-expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/offline-local/offline-expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/oopif-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/oopif-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/oopif-expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/oopif-expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/perf/expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/perf/expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/perf/lantern-expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/perf/lantern-expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/perf/perf-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/perf/perf-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/pwa-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/pwa-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/pwa-expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/pwa-expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/pwa2-expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/pwa2-expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/pwa3-expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/pwa3-expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/redirects-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/redirects-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/redirects/expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/redirects/expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/run-smoke.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/run-smoke'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/seo-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/seo-config'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/seo/expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/seo/expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/smoke-test-dfns.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/smoke-test-dfns'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/smokehouse-report.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/smokehouse-report'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/smokehouse.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/smokehouse'>;\n}\ndeclare module 'lighthouse/lighthouse-cli/test/smokehouse/tricky-metrics/expectations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-cli/test/smokehouse/tricky-metrics/expectations'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/accesskeys.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/accesskeys'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-allowed-attr.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/aria-allowed-attr'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-required-attr.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/aria-required-attr'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-required-children.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/aria-required-children'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-required-parent.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/aria-required-parent'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-roles.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/aria-roles'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-valid-attr-value.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/aria-valid-attr-value'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/aria-valid-attr.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/aria-valid-attr'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/audio-caption.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/audio-caption'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/axe-audit.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/axe-audit'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/button-name.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/button-name'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/bypass.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/bypass'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/color-contrast.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/color-contrast'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/definition-list.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/definition-list'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/dlitem.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/dlitem'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/document-title.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/document-title'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/duplicate-id.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/duplicate-id'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/frame-title.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/frame-title'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/html-has-lang.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/html-has-lang'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/html-lang-valid.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/html-lang-valid'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/image-alt.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/image-alt'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/input-image-alt.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/input-image-alt'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/label.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/label'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/layout-table.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/layout-table'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/link-name.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/link-name'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/list.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/list'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/listitem.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/listitem'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/custom-controls-labels.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/custom-controls-labels'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/custom-controls-roles.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/custom-controls-roles'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/focus-traps.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/focus-traps'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/focusable-controls.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/focusable-controls'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/heading-levels.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/heading-levels'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/interactive-element-affordance.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/interactive-element-affordance'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/logical-tab-order.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/logical-tab-order'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/managed-focus.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/managed-focus'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/offscreen-content-hidden.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/offscreen-content-hidden'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/use-landmarks.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/use-landmarks'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/manual/visual-order-follows-dom.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/manual/visual-order-follows-dom'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/meta-refresh.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/meta-refresh'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/meta-viewport.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/meta-viewport'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/object-alt.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/object-alt'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/tabindex.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/tabindex'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/td-headers-attr.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/td-headers-attr'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/th-has-data-cells.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/th-has-data-cells'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/valid-lang.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/valid-lang'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/video-caption.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/video-caption'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/accessibility/video-description.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/accessibility/video-description'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/apple-touch-icon.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/apple-touch-icon'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/audit.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/audit'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/bootup-time.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/bootup-time'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/efficient-animated-content'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/offscreen-images.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/offscreen-images'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/render-blocking-resources'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/total-byte-weight.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/total-byte-weight'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/unminified-css.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/unminified-css'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/unminified-javascript.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/unminified-javascript'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/unused-css-rules.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/unused-css-rules'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/unused-javascript.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/unused-javascript'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/uses-optimized-images'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/uses-responsive-images'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-text-compression.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/uses-text-compression'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/byte-efficiency/uses-webp-images.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/byte-efficiency/uses-webp-images'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/content-width.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/content-width'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/critical-request-chains.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/critical-request-chains'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/deprecations.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/deprecations'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/diagnostics.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/diagnostics'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/appcache-manifest.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/appcache-manifest'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/doctype.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/doctype'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/dom-size.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/dom-size'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/external-anchors-use-rel-noopener'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/geolocation-on-start.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/geolocation-on-start'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/js-libraries.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/js-libraries'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/no-document-write.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/no-document-write'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/no-vulnerable-libraries.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/no-vulnerable-libraries'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/notification-on-start.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/notification-on-start'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/password-inputs-can-be-pasted-into'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/uses-http2.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/uses-http2'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/errors-in-console.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/errors-in-console'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/final-screenshot.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/final-screenshot'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/font-display.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/font-display'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/image-aspect-ratio.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/image-aspect-ratio'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/installable-manifest.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/installable-manifest'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/is-on-https.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/is-on-https'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/load-fast-enough-for-pwa.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/load-fast-enough-for-pwa'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/main-thread-tasks.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/main-thread-tasks'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/mainthread-work-breakdown.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/mainthread-work-breakdown'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/manual/manual-audit.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/manual/manual-audit'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/manual/pwa-cross-browser.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/manual/pwa-cross-browser'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/manual/pwa-each-page-has-url.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/manual/pwa-each-page-has-url'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/manual/pwa-page-transitions.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/manual/pwa-page-transitions'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/estimated-input-latency.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics/estimated-input-latency'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/first-contentful-paint-3g.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics/first-contentful-paint-3g'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/first-contentful-paint.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics/first-contentful-paint'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/first-cpu-idle.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics/first-cpu-idle'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/first-meaningful-paint.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics/first-meaningful-paint'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/interactive.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics/interactive'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/max-potential-fid.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics/max-potential-fid'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/speed-index.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics/speed-index'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/metrics/total-blocking-time.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/metrics/total-blocking-time'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/mixed-content.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/mixed-content'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/multi-check-audit.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/multi-check-audit'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/network-requests.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/network-requests'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/network-rtt.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/network-rtt'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/network-server-latency.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/network-server-latency'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/offline-start-url.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/offline-start-url'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/performance-budget.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/performance-budget'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/predictive-perf.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/predictive-perf'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/redirects-http.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/redirects-http'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/redirects.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/redirects'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/resource-summary.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/resource-summary'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/screenshot-thumbnails.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/screenshot-thumbnails'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/canonical.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/canonical'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/font-size.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/font-size'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/hreflang.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/hreflang'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/http-status-code.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/http-status-code'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/is-crawlable.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/is-crawlable'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/link-text.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/link-text'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/manual/structured-data.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/manual/structured-data'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/meta-description.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/meta-description'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/plugins.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/plugins'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/robots-txt.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/robots-txt'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/seo/tap-targets.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/seo/tap-targets'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/service-worker.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/service-worker'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/splash-screen.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/splash-screen'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/themed-omnibox.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/themed-omnibox'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/third-party-summary.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/third-party-summary'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/time-to-first-byte.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/time-to-first-byte'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/user-timings.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/user-timings'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/uses-rel-preconnect.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/uses-rel-preconnect'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/uses-rel-preload.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/uses-rel-preload'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/viewport.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/viewport'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/violation-audit.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/violation-audit'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/without-javascript.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/without-javascript'>;\n}\ndeclare module 'lighthouse/lighthouse-core/audits/works-offline.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/audits/works-offline'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/computed-artifact.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/computed-artifact'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/critical-request-chains.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/critical-request-chains'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/load-simulator.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/load-simulator'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/main-resource.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/main-resource'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/main-thread-tasks.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/main-thread-tasks'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/manifest-values.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/manifest-values'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/estimated-input-latency.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/estimated-input-latency'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/first-contentful-paint.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/first-contentful-paint'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/first-cpu-idle.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/first-cpu-idle'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/first-meaningful-paint.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/first-meaningful-paint'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/interactive.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/interactive'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-estimated-input-latency.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/lantern-estimated-input-latency'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/lantern-first-contentful-paint'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-first-cpu-idle.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/lantern-first-cpu-idle'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/lantern-first-meaningful-paint'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-interactive.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/lantern-interactive'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-max-potential-fid.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/lantern-max-potential-fid'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-metric.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/lantern-metric'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-speed-index.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/lantern-speed-index'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/lantern-total-blocking-time.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/lantern-total-blocking-time'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/largest-contentful-paint.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/largest-contentful-paint'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/max-potential-fid.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/max-potential-fid'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/metric.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/metric'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/speed-index.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/speed-index'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/metrics/total-blocking-time.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/metrics/total-blocking-time'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/network-analysis.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/network-analysis'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/network-records.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/network-records'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/page-dependency-graph.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/page-dependency-graph'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/resource-summary.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/resource-summary'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/screenshots.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/screenshots'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/speedline.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/speedline'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/trace-of-tab.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/trace-of-tab'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/user-timings.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/user-timings'>;\n}\ndeclare module 'lighthouse/lighthouse-core/computed/viewport-meta.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/computed/viewport-meta'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/budget.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/budget'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/config-helpers.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/config-helpers'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/config-plugin.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/config-plugin'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/config'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/constants.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/constants'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/default-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/default-config'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/full-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/full-config'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/lr-desktop-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/lr-desktop-config'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/lr-mobile-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/lr-mobile-config'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/mixed-content-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/mixed-content-config'>;\n}\ndeclare module 'lighthouse/lighthouse-core/config/perf-config.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/config/perf-config'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/connections/connection.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/connections/connection'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/connections/cri.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/connections/cri'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/connections/extension.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/connections/extension'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/connections/raw.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/connections/raw'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/devtools-log.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/devtools-log'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/driver.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/driver'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gather-runner.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gather-runner'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/accessibility.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/accessibility'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/anchor-elements.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/anchor-elements'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/cache-contents.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/cache-contents'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/console-messages.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/console-messages'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/css-usage.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/css-usage'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/appcache.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/appcache'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/doctype.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/doctype'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/domstats.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/domstats'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/optimized-images.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/optimized-images'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/password-inputs-with-prevented-paste.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/password-inputs-with-prevented-paste'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/response-compression.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/response-compression'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/dobetterweb/tags-blocking-first-paint'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/gatherer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/gatherer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/html-without-javascript.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/html-without-javascript'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/http-redirect.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/http-redirect'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/iframe-elements.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/iframe-elements'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/image-elements.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/image-elements'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/js-usage.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/js-usage'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/link-elements.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/link-elements'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/main-document-content.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/main-document-content'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/meta-elements.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/meta-elements'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/mixed-content.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/mixed-content'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/offline.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/offline'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/runtime-exceptions.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/runtime-exceptions'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/script-elements.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/script-elements'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/seo/embedded-content.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/seo/embedded-content'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/seo/font-size.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/seo/font-size'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/seo/robots-txt.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/seo/robots-txt'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/seo/tap-targets.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/seo/tap-targets'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/service-worker.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/service-worker'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/source-maps.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/source-maps'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/start-url.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/start-url'>;\n}\ndeclare module 'lighthouse/lighthouse-core/gather/gatherers/viewport-dimensions.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/gather/gatherers/viewport-dimensions'>;\n}\ndeclare module 'lighthouse/lighthouse-core/index' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core'>;\n}\ndeclare module 'lighthouse/lighthouse-core/index.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/arbitrary-equality-map.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/arbitrary-equality-map'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/asset-saver.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/asset-saver'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/base-node.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/dependency-graph/base-node'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/cpu-node.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/dependency-graph/cpu-node'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/network-node.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/dependency-graph/network-node'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/connection-pool.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/dependency-graph/simulator/connection-pool'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/dns-cache.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/dependency-graph/simulator/dns-cache'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/dependency-graph/simulator/network-analyzer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/simulator.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/dependency-graph/simulator/simulator'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/dependency-graph/simulator/tcp-connection.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/dependency-graph/simulator/tcp-connection'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/emulation.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/emulation'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/file-namer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/file-namer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/i18n/i18n.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/i18n/i18n'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/i18n/locales.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/i18n/locales'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/i18n/swap-locale.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/i18n/swap-locale'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/icons.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/icons'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/lantern-trace-saver.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/lantern-trace-saver'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/lh-element.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/lh-element'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/lh-error.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/lh-error'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/manifest-parser.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/manifest-parser'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/minification-estimator.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/minification-estimator'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/minify-devtoolslog.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/minify-devtoolslog'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/minify-trace.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/minify-trace'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/network-recorder.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/network-recorder'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/network-request.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/network-request'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/page-functions.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/page-functions'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/proto-preprocessor.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/proto-preprocessor'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/rect-helpers.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/rect-helpers'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/helpers/walk-object.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sd-validation/helpers/walk-object'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/json-expander.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sd-validation/json-expander'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/json-linter.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sd-validation/json-linter'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/jsonld-keyword-validator.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sd-validation/jsonld-keyword-validator'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/line-number-from-jsonld-path.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sd-validation/line-number-from-jsonld-path'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/schema-validator.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sd-validation/schema-validator'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/scripts/download-jsonldcontext.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sd-validation/scripts/download-jsonldcontext'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/scripts/generate-schema-tree.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sd-validation/scripts/generate-schema-tree'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sd-validation/sd-validation.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sd-validation/sd-validation'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/sentry.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/sentry'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/stack-collector.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/stack-collector'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/stack-packs.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/stack-packs'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/statistics.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/statistics'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/tappable-rects.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/tappable-rects'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/timing-trace-saver.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/timing-trace-saver'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/tracehouse/main-thread-tasks.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/tracehouse/main-thread-tasks'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/tracehouse/task-groups.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/tracehouse/task-groups'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/tracehouse/trace-processor.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/tracehouse/trace-processor'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/traces/pwmetrics-events.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/traces/pwmetrics-events'>;\n}\ndeclare module 'lighthouse/lighthouse-core/lib/url-shim.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/lib/url-shim'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/html-report-assets.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/html-report-assets'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/category-renderer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/category-renderer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/crc-details-renderer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/crc-details-renderer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/details-renderer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/details-renderer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/dom.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/dom'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/logger.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/logger'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/performance-category-renderer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/performance-category-renderer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/psi.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/psi'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/pwa-category-renderer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/pwa-category-renderer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/report-renderer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/report-renderer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/report-ui-features.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/report-ui-features'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/snippet-renderer.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/snippet-renderer'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/html/renderer/util.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/html/renderer/util'>;\n}\ndeclare module 'lighthouse/lighthouse-core/report/report-generator.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/report/report-generator'>;\n}\ndeclare module 'lighthouse/lighthouse-core/runner.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/runner'>;\n}\ndeclare module 'lighthouse/lighthouse-core/scoring.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/scoring'>;\n}\ndeclare module 'lighthouse/lighthouse-core/scripts/manual-chrome-launcher.js' {\n  declare module.exports: $Exports<'lighthouse/lighthouse-core/scripts/manual-chrome-launcher'>;\n}\ndeclare module 'lighthouse/stack-packs/index' {\n  declare module.exports: $Exports<'lighthouse/stack-packs'>;\n}\ndeclare module 'lighthouse/stack-packs/index.js' {\n  declare module.exports: $Exports<'lighthouse/stack-packs'>;\n}\ndeclare module 'lighthouse/stack-packs/packs/amp.js' {\n  declare module.exports: $Exports<'lighthouse/stack-packs/packs/amp'>;\n}\ndeclare module 'lighthouse/stack-packs/packs/angular.js' {\n  declare module.exports: $Exports<'lighthouse/stack-packs/packs/angular'>;\n}\ndeclare module 'lighthouse/stack-packs/packs/magento.js' {\n  declare module.exports: $Exports<'lighthouse/stack-packs/packs/magento'>;\n}\ndeclare module 'lighthouse/stack-packs/packs/react.js' {\n  declare module.exports: $Exports<'lighthouse/stack-packs/packs/react'>;\n}\ndeclare module 'lighthouse/stack-packs/packs/wordpress.js' {\n  declare module.exports: $Exports<'lighthouse/stack-packs/packs/wordpress'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/markdown-it_vx.x.x.js",
    "content": "// flow-typed signature: 96d7006b0f8fe2a1b3941df2904fcf3c\n// flow-typed version: <<STUB>>/markdown-it_v^10.0.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'markdown-it'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'markdown-it' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'markdown-it/bin/markdown-it' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/dist/markdown-it' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/dist/markdown-it.min' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/common/entities' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/common/html_blocks' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/common/html_re' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/common/utils' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/helpers' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/helpers/parse_link_destination' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/helpers/parse_link_label' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/helpers/parse_link_title' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/parser_block' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/parser_core' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/parser_inline' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/presets/commonmark' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/presets/default' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/presets/zero' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/renderer' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/ruler' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/blockquote' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/code' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/fence' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/heading' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/hr' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/html_block' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/lheading' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/list' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/paragraph' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/reference' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/state_block' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_block/table' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_core/block' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_core/inline' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_core/linkify' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_core/normalize' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_core/replacements' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_core/smartquotes' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_core/state_core' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/autolink' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/backticks' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/balance_pairs' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/emphasis' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/entity' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/escape' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/html_inline' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/image' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/link' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/state_inline' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/strikethrough' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/text_collapse' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/rules_inline/text' {\n  declare module.exports: any;\n}\n\ndeclare module 'markdown-it/lib/token' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'markdown-it/bin/markdown-it.js' {\n  declare module.exports: $Exports<'markdown-it/bin/markdown-it'>;\n}\ndeclare module 'markdown-it/dist/markdown-it.js' {\n  declare module.exports: $Exports<'markdown-it/dist/markdown-it'>;\n}\ndeclare module 'markdown-it/dist/markdown-it.min.js' {\n  declare module.exports: $Exports<'markdown-it/dist/markdown-it.min'>;\n}\ndeclare module 'markdown-it/index' {\n  declare module.exports: $Exports<'markdown-it'>;\n}\ndeclare module 'markdown-it/index.js' {\n  declare module.exports: $Exports<'markdown-it'>;\n}\ndeclare module 'markdown-it/lib/common/entities.js' {\n  declare module.exports: $Exports<'markdown-it/lib/common/entities'>;\n}\ndeclare module 'markdown-it/lib/common/html_blocks.js' {\n  declare module.exports: $Exports<'markdown-it/lib/common/html_blocks'>;\n}\ndeclare module 'markdown-it/lib/common/html_re.js' {\n  declare module.exports: $Exports<'markdown-it/lib/common/html_re'>;\n}\ndeclare module 'markdown-it/lib/common/utils.js' {\n  declare module.exports: $Exports<'markdown-it/lib/common/utils'>;\n}\ndeclare module 'markdown-it/lib/helpers/index' {\n  declare module.exports: $Exports<'markdown-it/lib/helpers'>;\n}\ndeclare module 'markdown-it/lib/helpers/index.js' {\n  declare module.exports: $Exports<'markdown-it/lib/helpers'>;\n}\ndeclare module 'markdown-it/lib/helpers/parse_link_destination.js' {\n  declare module.exports: $Exports<'markdown-it/lib/helpers/parse_link_destination'>;\n}\ndeclare module 'markdown-it/lib/helpers/parse_link_label.js' {\n  declare module.exports: $Exports<'markdown-it/lib/helpers/parse_link_label'>;\n}\ndeclare module 'markdown-it/lib/helpers/parse_link_title.js' {\n  declare module.exports: $Exports<'markdown-it/lib/helpers/parse_link_title'>;\n}\ndeclare module 'markdown-it/lib/index' {\n  declare module.exports: $Exports<'markdown-it/lib'>;\n}\ndeclare module 'markdown-it/lib/index.js' {\n  declare module.exports: $Exports<'markdown-it/lib'>;\n}\ndeclare module 'markdown-it/lib/parser_block.js' {\n  declare module.exports: $Exports<'markdown-it/lib/parser_block'>;\n}\ndeclare module 'markdown-it/lib/parser_core.js' {\n  declare module.exports: $Exports<'markdown-it/lib/parser_core'>;\n}\ndeclare module 'markdown-it/lib/parser_inline.js' {\n  declare module.exports: $Exports<'markdown-it/lib/parser_inline'>;\n}\ndeclare module 'markdown-it/lib/presets/commonmark.js' {\n  declare module.exports: $Exports<'markdown-it/lib/presets/commonmark'>;\n}\ndeclare module 'markdown-it/lib/presets/default.js' {\n  declare module.exports: $Exports<'markdown-it/lib/presets/default'>;\n}\ndeclare module 'markdown-it/lib/presets/zero.js' {\n  declare module.exports: $Exports<'markdown-it/lib/presets/zero'>;\n}\ndeclare module 'markdown-it/lib/renderer.js' {\n  declare module.exports: $Exports<'markdown-it/lib/renderer'>;\n}\ndeclare module 'markdown-it/lib/ruler.js' {\n  declare module.exports: $Exports<'markdown-it/lib/ruler'>;\n}\ndeclare module 'markdown-it/lib/rules_block/blockquote.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/blockquote'>;\n}\ndeclare module 'markdown-it/lib/rules_block/code.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/code'>;\n}\ndeclare module 'markdown-it/lib/rules_block/fence.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/fence'>;\n}\ndeclare module 'markdown-it/lib/rules_block/heading.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/heading'>;\n}\ndeclare module 'markdown-it/lib/rules_block/hr.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/hr'>;\n}\ndeclare module 'markdown-it/lib/rules_block/html_block.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/html_block'>;\n}\ndeclare module 'markdown-it/lib/rules_block/lheading.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/lheading'>;\n}\ndeclare module 'markdown-it/lib/rules_block/list.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/list'>;\n}\ndeclare module 'markdown-it/lib/rules_block/paragraph.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/paragraph'>;\n}\ndeclare module 'markdown-it/lib/rules_block/reference.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/reference'>;\n}\ndeclare module 'markdown-it/lib/rules_block/state_block.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/state_block'>;\n}\ndeclare module 'markdown-it/lib/rules_block/table.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_block/table'>;\n}\ndeclare module 'markdown-it/lib/rules_core/block.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_core/block'>;\n}\ndeclare module 'markdown-it/lib/rules_core/inline.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_core/inline'>;\n}\ndeclare module 'markdown-it/lib/rules_core/linkify.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_core/linkify'>;\n}\ndeclare module 'markdown-it/lib/rules_core/normalize.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_core/normalize'>;\n}\ndeclare module 'markdown-it/lib/rules_core/replacements.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_core/replacements'>;\n}\ndeclare module 'markdown-it/lib/rules_core/smartquotes.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_core/smartquotes'>;\n}\ndeclare module 'markdown-it/lib/rules_core/state_core.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_core/state_core'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/autolink.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/autolink'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/backticks.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/backticks'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/balance_pairs.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/balance_pairs'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/emphasis.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/emphasis'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/entity.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/entity'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/escape.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/escape'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/html_inline.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/html_inline'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/image.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/image'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/link.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/link'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/newline.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/newline'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/state_inline.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/state_inline'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/strikethrough.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/strikethrough'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/text_collapse.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/text_collapse'>;\n}\ndeclare module 'markdown-it/lib/rules_inline/text.js' {\n  declare module.exports: $Exports<'markdown-it/lib/rules_inline/text'>;\n}\ndeclare module 'markdown-it/lib/token.js' {\n  declare module.exports: $Exports<'markdown-it/lib/token'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/prettier_v1.x.x.js",
    "content": "// flow-typed signature: ec743a1b5c1197353e0849812930f32a\n// flow-typed version: c6154227d1/prettier_v1.x.x/flow_>=v0.104.x\n\ndeclare module \"prettier\" {\n  declare export type AST = { [key: string]: any, ... };\n  declare export type Doc = {\n    [key: string]: any,\n    ...\n  };\n  declare export type FastPath<T = any> = {\n    stack: any[],\n    getName(): null | string | number | Symbol,\n    getValue(): T,\n    getNode(count?: number): null | T,\n    getParentNode(count?: number): null | T,\n    call<U>(callback: (path: FastPath<T>) => U, ...names: Array<string | number | Symbol>): U,\n    each(callback: (path: FastPath<T>) => void, ...names: Array<string | number | Symbol>): void,\n    map<U>(callback: (path: FastPath<T>, index: number) => U, ...names: Array<string | number | Symbol>): U[],\n    ...\n  };\n\n  declare export type PrettierParserName =\n    | \"babylon\" // deprecated\n    | \"babel\"\n    | \"babel-flow\"\n    | \"flow\"\n    | \"typescript\"\n    | \"postcss\" // deprecated\n    | \"css\"\n    | \"less\"\n    | \"scss\"\n    | \"json\"\n    | \"json5\"\n    | \"json-stringify\"\n    | \"graphql\"\n    | \"markdown\"\n    | \"vue\"\n    | \"html\"\n    | \"angular\"\n    | \"mdx\"\n    | \"yaml\";\n\n  declare export type PrettierParser = {\n    [name: PrettierParserName]: (text: string, options?: { [key: string]: any, ... }) => AST,\n    ...\n  };\n\n  declare export type CustomParser = (\n    text: string,\n    parsers: PrettierParser,\n    options: Options\n  ) => AST;\n\n  declare export type Options = {|\n    printWidth?: number,\n    tabWidth?: number,\n    useTabs?: boolean,\n    semi?: boolean,\n    singleQuote?: boolean,\n    trailingComma?: \"none\" | \"es5\" | \"all\",\n    bracketSpacing?: boolean,\n    jsxBracketSameLine?: boolean,\n    arrowParens?: \"avoid\" | \"always\",\n    rangeStart?: number,\n    rangeEnd?: number,\n    parser?: PrettierParserName | CustomParser,\n    filepath?: string,\n    requirePragma?: boolean,\n    insertPragma?: boolean,\n    proseWrap?: \"always\" | \"never\" | \"preserve\",\n    plugins?: Array<string | Plugin>\n  |};\n\n  declare export type Plugin = {\n    languages: SupportLanguage,\n    parsers: { [parserName: string]: Parser, ... },\n    printers: { [astFormat: string]: Printer, ... },\n    options?: SupportOption[],\n    ...\n  };\n\n  declare export type Parser = {\n    parse: (\n      text: string,\n      parsers: { [parserName: string]: Parser, ... },\n      options: { [key: string]: any, ... }\n    ) => AST,\n    astFormat: string,\n    hasPragma?: (text: string) => boolean,\n    locStart: (node: any) => number,\n    locEnd: (node: any) => number,\n    preprocess?: (text: string, options: { [key: string]: any, ... }) => string,\n    ...\n  };\n\n  declare export type Printer = {\n    print: (\n      path: FastPath<>,\n      options: { [key: string]: any, ... },\n      print: (path: FastPath<>) => Doc\n    ) => Doc,\n    embed: (\n      path: FastPath<>,\n      print: (path: FastPath<>) => Doc,\n      textToDoc: (text: string, options: { [key: string]: any, ... }) => Doc,\n      options: { [key: string]: any, ... }\n    ) => ?Doc,\n    insertPragma?: (text: string) => string,\n    massageAstNode?: (node: any, newNode: any, parent: any) => any,\n    hasPrettierIgnore?: (path: FastPath<>) => boolean,\n    canAttachComment?: (node: any) => boolean,\n    willPrintOwnComments?: (path: FastPath<>) => boolean,\n    printComments?: (path: FastPath<>, print: (path: FastPath<>) => Doc, options: { [key: string]: any, ... }, needsSemi: boolean) => Doc,\n    handleComments?: {\n      ownLine?: (commentNode: any, text: string, options: { [key: string]: any, ... }, ast: any, isLastComment: boolean) => boolean,\n      endOfLine?: (commentNode: any, text: string, options: { [key: string]: any, ... }, ast: any, isLastComment: boolean) => boolean,\n      remaining?: (commentNode: any, text: string, options: { [key: string]: any, ... }, ast: any, isLastComment: boolean) => boolean,\n      ...\n    },\n    ...\n  };\n\n  declare export type CursorOptions = {|\n    cursorOffset: number,\n    printWidth?: $PropertyType<Options, \"printWidth\">,\n    tabWidth?: $PropertyType<Options, \"tabWidth\">,\n    useTabs?: $PropertyType<Options, \"useTabs\">,\n    semi?: $PropertyType<Options, \"semi\">,\n    singleQuote?: $PropertyType<Options, \"singleQuote\">,\n    trailingComma?: $PropertyType<Options, \"trailingComma\">,\n    bracketSpacing?: $PropertyType<Options, \"bracketSpacing\">,\n    jsxBracketSameLine?: $PropertyType<Options, \"jsxBracketSameLine\">,\n    arrowParens?: $PropertyType<Options, \"arrowParens\">,\n    parser?: $PropertyType<Options, \"parser\">,\n    filepath?: $PropertyType<Options, \"filepath\">,\n    requirePragma?: $PropertyType<Options, \"requirePragma\">,\n    insertPragma?: $PropertyType<Options, \"insertPragma\">,\n    proseWrap?: $PropertyType<Options, \"proseWrap\">,\n    plugins?: $PropertyType<Options, \"plugins\">\n  |};\n\n  declare export type CursorResult = {|\n    formatted: string,\n    cursorOffset: number\n  |};\n\n  declare export type ResolveConfigOptions = {|\n    useCache?: boolean,\n    config?: string,\n    editorconfig?: boolean\n  |};\n\n  declare export type SupportLanguage = {\n    name: string,\n    since: string,\n    parsers: Array<string>,\n    group?: string,\n    tmScope: string,\n    aceMode: string,\n    codemirrorMode: string,\n    codemirrorMimeType: string,\n    aliases?: Array<string>,\n    extensions: Array<string>,\n    filenames?: Array<string>,\n    linguistLanguageId: number,\n    vscodeLanguageIds: Array<string>,\n    ...\n  };\n\n  declare export type SupportOption = {|\n    since: string,\n    type: \"int\" | \"boolean\" | \"choice\" | \"path\",\n    deprecated?: string,\n    redirect?: SupportOptionRedirect,\n    description: string,\n    oppositeDescription?: string,\n    default: SupportOptionValue,\n    range?: SupportOptionRange,\n    choices?: SupportOptionChoice\n  |};\n\n  declare export type SupportOptionRedirect = {|\n    options: string,\n    value: SupportOptionValue\n  |};\n\n  declare export type SupportOptionRange = {|\n    start: number,\n    end: number,\n    step: number\n  |};\n\n  declare export type SupportOptionChoice = {|\n    value: boolean | string,\n    description?: string,\n    since?: string,\n    deprecated?: string,\n    redirect?: SupportOptionValue\n  |};\n\n  declare export type SupportOptionValue = number | boolean | string;\n\n  declare export type SupportInfo = {|\n    languages: Array<SupportLanguage>,\n    options: Array<SupportOption>\n  |};\n\n  declare export type Prettier = {|\n    format: (source: string, options?: Options) => string,\n    check: (source: string, options?: Options) => boolean,\n    formatWithCursor: (source: string, options: CursorOptions) => CursorResult,\n    resolveConfig: {\n      (filePath: string, options?: ResolveConfigOptions): Promise<?Options>,\n      sync(filePath: string, options?: ResolveConfigOptions): ?Options,\n      ...\n    },\n    clearConfigCache: () => void,\n    getSupportInfo: (version?: string) => SupportInfo\n  |};\n\n  declare export default Prettier;\n}\n"
  },
  {
    "path": "flow-typed/npm/react-redux_v7.x.x.js",
    "content": "// flow-typed signature: d6e8d9a72e906ae26b83c9b33a1a6e56\n// flow-typed version: c6154227d1/react-redux_v7.x.x/flow_>=v0.104.x\n\n/**\nThe order of type arguments for connect() is as follows:\n\nconnect<Props, OwnProps, StateProps, DispatchProps, State, Dispatch>(…)\n\nIn Flow v0.89 only the first two are mandatory to specify. Other 4 can be repaced with the new awesome type placeholder:\n\nconnect<Props, OwnProps, _, _, _, _>(…)\n\nBut beware, in case of weird type errors somewhere in random places\njust type everything and get to a green field and only then try to\nremove the definitions you see bogus.\n\nDecrypting the abbreviations:\n  WC = Component being wrapped\n  S = State\n  D = Dispatch\n  OP = OwnProps\n  SP = StateProps\n  DP = DispatchProps\n  MP = Merge props\n  RSP = Returned state props\n  RDP = Returned dispatch props\n  RMP = Returned merge props\n  CP = Props for returned component\n  Com = React Component\n  SS = Selected state\n  ST = Static properties of Com\n  EFO = Extra factory options (used only in connectAdvanced)\n*/\n\ndeclare module \"react-redux\" {\n  // ------------------------------------------------------------\n  // Typings for connect()\n  // ------------------------------------------------------------\n\n  declare export type Options<S, OP, SP, MP> = {|\n    pure?: boolean,\n    forwardRef?: boolean,\n    areStatesEqual?: (next: S, prev: S) => boolean,\n    areOwnPropsEqual?: (next: OP, prev: OP) => boolean,\n    areStatePropsEqual?: (next: SP, prev: SP) => boolean,\n    areMergedPropsEqual?: (next: MP, prev: MP) => boolean,\n    storeKey?: string,\n  |};\n\n  declare type MapStateToProps<-S, -OP, +SP> =\n    | ((state: S, ownProps: OP) => SP)\n    // If you want to use the factory function but get a strange error\n    // like \"function is not an object\" then just type the factory function\n    // like this:\n    // const factory: (State, OwnProps) => (State, OwnProps) => StateProps\n    // and provide the StateProps type to the SP type parameter.\n    | ((state: S, ownProps: OP) => (state: S, ownProps: OP) => SP);\n\n  declare type Bind<D> = <A, R>((...A) => R) => (...A) => $Call<D, R>;\n\n  declare type MapDispatchToPropsFn<D, -OP, +DP> =\n    | ((dispatch: D, ownProps: OP) => DP)\n    // If you want to use the factory function but get a strange error\n    // like \"function is not an object\" then just type the factory function\n    // like this:\n    // const factory: (Dispatch, OwnProps) => (Dispatch, OwnProps) => DispatchProps\n    // and provide the DispatchProps type to the DP type parameter.\n    | ((dispatch: D, ownProps: OP) => (dispatch: D, ownProps: OP) => DP);\n\n  declare class ConnectedComponent<OP, +WC> extends React$Component<OP> {\n    static +WrappedComponent: WC;\n    getWrappedInstance(): React$ElementRef<WC>;\n  }\n  // The connection of the Wrapped Component and the Connected Component\n  // happens here in `MP: P`. It means that type wise MP belongs to P,\n  // so to say MP >= P.\n  declare type Connector<P, OP, MP: P> = <WC: React$ComponentType<P>>(\n    WC,\n  ) => Class<ConnectedComponent<OP, WC>> & WC;\n\n  // No `mergeProps` argument\n\n  // Got error like inexact OwnProps is incompatible with exact object type?\n  // Just make the OP parameter for `connect()` an exact object.\n  declare type MergeOP<OP, D> = {| ...$Exact<OP>, dispatch: D |};\n  declare type MergeOPSP<OP, SP, D> = {| ...$Exact<OP>, ...SP, dispatch: D |};\n  declare type MergeOPDP<OP, DP> = {| ...$Exact<OP>, ...DP |};\n  declare type MergeOPSPDP<OP, SP, DP> = {| ...$Exact<OP>, ...SP, ...DP |};\n\n  declare export function connect<-P, -OP, -SP, -DP, -S, -D>(\n    mapStateToProps?: null | void,\n    mapDispatchToProps?: null | void,\n    mergeProps?: null | void,\n    options?: ?Options<S, OP, {||}, MergeOP<OP, D>>,\n  ): Connector<P, OP, MergeOP<OP, D>>;\n\n  declare export function connect<-P, -OP, -SP, -DP, -S, -D>(\n    // If you get error here try adding return type to your mapStateToProps function\n    mapStateToProps: MapStateToProps<S, OP, SP>,\n    mapDispatchToProps?: null | void,\n    mergeProps?: null | void,\n    options?: ?Options<S, OP, SP, MergeOPSP<OP, SP, D>>,\n  ): Connector<P, OP, MergeOPSP<OP, SP, D>>;\n\n  // In this case DP is an object of functions which has been bound to dispatch\n  // by the given mapDispatchToProps function.\n  declare export function connect<-P, -OP, -SP, -DP, S, D>(\n    mapStateToProps: null | void,\n    mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,\n    mergeProps?: null | void,\n    options?: ?Options<S, OP, {||}, MergeOPDP<OP, DP>>,\n  ): Connector<P, OP, MergeOPDP<OP, DP>>;\n\n  // In this case DP is an object of action creators not yet bound to dispatch,\n  // this difference is not important in the vanila redux,\n  // but in case of usage with redux-thunk, the return type may differ.\n  declare export function connect<-P, -OP, -SP, -DP, S, D>(\n    mapStateToProps: null | void,\n    mapDispatchToProps: DP,\n    mergeProps?: null | void,\n    options?: ?Options<S, OP, {||}, MergeOPDP<OP, DP>>,\n  ): Connector<P, OP, MergeOPDP<OP, $ObjMap<DP, Bind<D>>>>;\n\n  declare export function connect<-P, -OP, -SP, -DP, S, D>(\n    // If you get error here try adding return type to your mapStateToProps function\n    mapStateToProps: MapStateToProps<S, OP, SP>,\n    mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,\n    mergeProps?: null | void,\n    options?: ?Options<S, OP, SP, {| ...OP, ...SP, ...DP |}>,\n  ): Connector<P, OP, {| ...OP, ...SP, ...DP |}>;\n\n  declare export function connect<-P, -OP, -SP, -DP, S, D>(\n    // If you get error here try adding return type to your mapStateToProps function\n    mapStateToProps: MapStateToProps<S, OP, SP>,\n    mapDispatchToProps: DP,\n    mergeProps?: null | void,\n    options?: ?Options<S, OP, SP, MergeOPSPDP<OP, SP, DP>>,\n  ): Connector<P, OP, MergeOPSPDP<OP, SP, $ObjMap<DP, Bind<D>>>>;\n\n  // With `mergeProps` argument\n\n  declare type MergeProps<+P, -OP, -SP, -DP> = (\n    stateProps: SP,\n    dispatchProps: DP,\n    ownProps: OP,\n  ) => P;\n\n  declare export function connect<-P, -OP, -SP: {||}, -DP: {||}, S, D>(\n    mapStateToProps: null | void,\n    mapDispatchToProps: null | void,\n    // If you get error here try adding return type to you mapStateToProps function\n    mergeProps: MergeProps<P, OP, {||}, {| dispatch: D |}>,\n    options?: ?Options<S, OP, {||}, P>,\n  ): Connector<P, OP, P>;\n\n  declare export function connect<-P, -OP, -SP, -DP: {||}, S, D>(\n    mapStateToProps: MapStateToProps<S, OP, SP>,\n    mapDispatchToProps: null | void,\n    // If you get error here try adding return type to you mapStateToProps function\n    mergeProps: MergeProps<P, OP, SP, {| dispatch: D |}>,\n    options?: ?Options<S, OP, SP, P>,\n  ): Connector<P, OP, P>;\n\n  // In this case DP is an object of functions which has been bound to dispatch\n  // by the given mapDispatchToProps function.\n  declare export function connect<-P, -OP, -SP: {||}, -DP, S, D>(\n    mapStateToProps: null | void,\n    mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,\n    mergeProps: MergeProps<P, OP, {||}, DP>,\n    options?: ?Options<S, OP, {||}, P>,\n  ): Connector<P, OP, P>;\n\n  // In this case DP is an object of action creators not yet bound to dispatch,\n  // this difference is not important in the vanila redux,\n  // but in case of usage with redux-thunk, the return type may differ.\n  declare export function connect<-P, -OP, -SP: {||}, -DP, S, D>(\n    mapStateToProps: null | void,\n    mapDispatchToProps: DP,\n    mergeProps: MergeProps<P, OP, {||}, $ObjMap<DP, Bind<D>>>,\n    options?: ?Options<S, OP, {||}, P>,\n  ): Connector<P, OP, P>;\n\n  // In this case DP is an object of functions which has been bound to dispatch\n  // by the given mapDispatchToProps function.\n  declare export function connect<-P, -OP, -SP, -DP, S, D>(\n    mapStateToProps: MapStateToProps<S, OP, SP>,\n    mapDispatchToProps: MapDispatchToPropsFn<D, OP, DP>,\n    mergeProps: MergeProps<P, OP, SP, DP>,\n    options?: ?Options<S, OP, SP, P>,\n  ): Connector<P, OP, P>;\n\n  // In this case DP is an object of action creators not yet bound to dispatch,\n  // this difference is not important in the vanila redux,\n  // but in case of usage with redux-thunk, the return type may differ.\n  declare export function connect<-P, -OP, -SP, -DP, S, D>(\n    mapStateToProps: MapStateToProps<S, OP, SP>,\n    mapDispatchToProps: DP,\n    mergeProps: MergeProps<P, OP, SP, $ObjMap<DP, Bind<D>>>,\n    options?: ?Options<S, OP, SP, P>,\n  ): Connector<P, OP, P>;\n\n  // ------------------------------------------------------------\n  // Typings for Hooks\n  // ------------------------------------------------------------\n\n  declare export function useDispatch<D>(): D;\n\n  declare export function useSelector<S, SS>(\n    selector: (state: S) => SS,\n    equalityFn?: (a: SS, b: SS) => boolean,\n  ): SS;\n\n  declare export function useStore<Store>(): Store;\n\n  // ------------------------------------------------------------\n  // Typings for Provider\n  // ------------------------------------------------------------\n\n  declare export class Provider<Store> extends React$Component<{\n    store: Store,\n    children?: React$Node,\n    ...\n  }> {}\n\n  declare export function createProvider(\n    storeKey?: string,\n    subKey?: string,\n  ): Class<Provider<*>>;\n\n  // ------------------------------------------------------------\n  // Typings for connectAdvanced()\n  // ------------------------------------------------------------\n\n  declare type ConnectAdvancedOptions = {\n    getDisplayName?: (name: string) => string,\n    methodName?: string,\n    renderCountProp?: string,\n    shouldHandleStateChanges?: boolean,\n    storeKey?: string,\n    forwardRef?: boolean,\n    ...\n  };\n\n  declare type SelectorFactoryOptions<Com> = {\n    getDisplayName: (name: string) => string,\n    methodName: string,\n    renderCountProp: ?string,\n    shouldHandleStateChanges: boolean,\n    storeKey: string,\n    forwardRef: boolean,\n    displayName: string,\n    wrappedComponentName: string,\n    WrappedComponent: Com,\n    ...\n  };\n\n  declare type MapStateToPropsEx<S: Object, SP: Object, RSP: Object> = (\n    state: S,\n    props: SP,\n  ) => RSP;\n\n  declare type SelectorFactory<\n    Com: React$ComponentType<*>,\n    Dispatch,\n    S: Object,\n    OP: Object,\n    EFO: Object,\n    CP: Object,\n  > = (\n    dispatch: Dispatch,\n    factoryOptions: SelectorFactoryOptions<Com> & EFO,\n  ) => MapStateToPropsEx<S, OP, CP>;\n\n  declare export function connectAdvanced<\n    Com: React$ComponentType<*>,\n    D,\n    S: Object,\n    OP: Object,\n    CP: Object,\n    EFO: Object,\n    ST: { [_: $Keys<Com>]: any, ... },\n  >(\n    selectorFactory: SelectorFactory<Com, D, S, OP, EFO, CP>,\n    connectAdvancedOptions: ?(ConnectAdvancedOptions & EFO),\n  ): (component: Com) => React$ComponentType<OP> & $Shape<ST>;\n\n  declare export default {\n    Provider: typeof Provider,\n    createProvider: typeof createProvider,\n    connect: typeof connect,\n    connectAdvanced: typeof connectAdvanced,\n    useDispatch: typeof useDispatch,\n    useSelector: typeof useSelector,\n    useStore: typeof useStore,\n    ...\n  };\n}\n"
  },
  {
    "path": "flow-typed/npm/react-test-renderer_v16.x.x.js",
    "content": "// flow-typed signature: 1e72e585885f0d635f1583960545de71\n// flow-typed version: c6154227d1/react-test-renderer_v16.x.x/flow_>=v0.104.x\n\n// Type definitions for react-test-renderer 16.x.x\n// Ported from: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-test-renderer\n\ntype ReactComponentInstance = React$Component<any>;\n\ntype ReactTestRendererJSON = {\n  type: string,\n  props: { [propName: string]: any, ... },\n  children: null | ReactTestRendererJSON[],\n  ...\n};\n\ntype ReactTestRendererTree = ReactTestRendererJSON & {\n  nodeType: \"component\" | \"host\",\n  instance: ?ReactComponentInstance,\n  rendered: null | ReactTestRendererTree,\n  ...\n};\n\ntype ReactTestInstance = {\n  instance: ?ReactComponentInstance,\n  type: string,\n  props: { [propName: string]: any, ... },\n  parent: null | ReactTestInstance,\n  children: Array<ReactTestInstance | string>,\n  find(predicate: (node: ReactTestInstance) => boolean): ReactTestInstance,\n  findByType(type: React$ElementType): ReactTestInstance,\n  findByProps(props: { [propName: string]: any, ... }): ReactTestInstance,\n  findAll(\n    predicate: (node: ReactTestInstance) => boolean,\n    options?: { deep: boolean, ... }\n  ): ReactTestInstance[],\n  findAllByType(\n    type: React$ElementType,\n    options?: { deep: boolean, ... }\n  ): ReactTestInstance[],\n  findAllByProps(\n    props: { [propName: string]: any, ... },\n    options?: { deep: boolean, ... }\n  ): ReactTestInstance[],\n  ...\n};\n\ntype TestRendererOptions = { createNodeMock(element: React$Element<any>): any, ... };\n\ndeclare module \"react-test-renderer\" {\n  declare export type ReactTestRenderer = {\n    toJSON(): null | ReactTestRendererJSON,\n    toTree(): null | ReactTestRendererTree,\n    unmount(nextElement?: React$Element<any>): void,\n    update(nextElement: React$Element<any>): void,\n    getInstance(): ?ReactComponentInstance,\n    root: ReactTestInstance,\n    ...\n  };\n\n  declare type Thenable = { then(resolve: () => mixed, reject?: () => mixed): mixed, ... };\n\n  declare function create(\n    nextElement: React$Element<any>,\n    options?: TestRendererOptions\n  ): ReactTestRenderer;\n\n  declare function act(callback: () => void): Thenable;\n}\n\ndeclare module \"react-test-renderer/shallow\" {\n  declare export default class ShallowRenderer {\n    static createRenderer(): ShallowRenderer;\n    getMountedInstance(): ReactTestInstance;\n    getRenderOutput<E: React$Element<any>>(): E;\n    getRenderOutput(): React$Element<any>;\n    render(element: React$Element<any>, context?: any): void;\n    unmount(): void;\n  }\n}\n"
  },
  {
    "path": "flow-typed/npm/redux_v4.x.x.js",
    "content": "// flow-typed signature: f62df6dbce399d55b0f2954c5ac1bd4e\n// flow-typed version: c6154227d1/redux_v4.x.x/flow_>=v0.104.x\n\ndeclare module 'redux' {\n  /*\n\n    S = State\n    A = Action\n    D = Dispatch\n\n  */\n\n  declare export type Action<T> = { type: T, ... }\n\n  declare export type DispatchAPI<A> = (action: A) => A;\n\n  declare export type Dispatch<A: { type: *, ... }> = DispatchAPI<A>;\n\n  declare export type MiddlewareAPI<S, A, D = Dispatch<A>> = {\n    dispatch: D,\n    getState(): S,\n    ...\n  };\n\n  declare export type Store<S, A, D = Dispatch<A>> = {\n    // rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages)\n    dispatch: D,\n    getState(): S,\n    subscribe(listener: () => void): () => void,\n    replaceReducer(nextReducer: Reducer<S, A>): void,\n    ...\n  };\n\n  declare export type Reducer<S, A> = (state: S | void, action: A) => S;\n\n  declare export type CombinedReducer<S, A> = (\n    state: ($Shape<S> & {...}) | void,\n    action: A\n  ) => S;\n\n  declare export type Middleware<S, A, D = Dispatch<A>> = (\n    api: MiddlewareAPI<S, A, D>\n  ) => (next: D) => D;\n\n  declare export type StoreCreator<S, A, D = Dispatch<A>> = {\n    (reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>,\n    (\n      reducer: Reducer<S, A>,\n      preloadedState: S,\n      enhancer?: StoreEnhancer<S, A, D>\n    ): Store<S, A, D>,\n    ...\n  };\n\n  declare export type StoreEnhancer<S, A, D = Dispatch<A>> = (\n    next: StoreCreator<S, A, D>\n  ) => StoreCreator<S, A, D>;\n\n  declare export function createStore<S, A, D>(\n    reducer: Reducer<S, A>,\n    enhancer?: StoreEnhancer<S, A, D>\n  ): Store<S, A, D>;\n  declare export function createStore<S, A, D>(\n    reducer: Reducer<S, A>,\n    preloadedState?: S,\n    enhancer?: StoreEnhancer<S, A, D>\n  ): Store<S, A, D>;\n\n  declare export function applyMiddleware<S, A, D>(\n    ...middlewares: Array<Middleware<S, A, D>>\n  ): StoreEnhancer<S, A, D>;\n\n  declare export type ActionCreator<A, B> = (...args: Array<B>) => A;\n  declare export type ActionCreators<K, A> = { [key: K]: ActionCreator<A, any>, ... };\n\n  declare export function bindActionCreators<\n    A,\n    C: ActionCreator<A, any>,\n    D: DispatchAPI<A>\n  >(\n    actionCreator: C,\n    dispatch: D\n  ): C;\n  declare export function bindActionCreators<\n    A,\n    K,\n    C: ActionCreators<K, A>,\n    D: DispatchAPI<A>\n  >(\n    actionCreators: C,\n    dispatch: D\n  ): C;\n\n  declare export function combineReducers<O: {...}, A>(\n    reducers: O\n  ): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;\n\n  declare export var compose: $Compose;\n}\n"
  },
  {
    "path": "flow-typed/npm/require-from-string_vx.x.x.js",
    "content": "// flow-typed signature: ad19217fac230ec2c67d4afe3b4645d1\n// flow-typed version: <<STUB>>/require-from-string_v^2.0.2/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'require-from-string'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'require-from-string' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\n\n\n// Filename aliases\ndeclare module 'require-from-string/index' {\n  declare module.exports: $Exports<'require-from-string'>;\n}\ndeclare module 'require-from-string/index.js' {\n  declare module.exports: $Exports<'require-from-string'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rimraf_vx.x.x.js",
    "content": "// flow-typed signature: 4f9dfefdfd54d755a43c1cc3824fc488\n// flow-typed version: <<STUB>>/rimraf_v^3.0.1/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rimraf'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rimraf' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rimraf/bin' {\n  declare module.exports: any;\n}\n\ndeclare module 'rimraf/rimraf' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rimraf/bin.js' {\n  declare module.exports: $Exports<'rimraf/bin'>;\n}\ndeclare module 'rimraf/rimraf.js' {\n  declare module.exports: $Exports<'rimraf/rimraf'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rollup-plugin-babel_vx.x.x.js",
    "content": "// flow-typed signature: 9f740788e10132b6d4e34a3626d2033e\n// flow-typed version: <<STUB>>/rollup-plugin-babel_v^4.3.3/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rollup-plugin-babel'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rollup-plugin-babel' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rollup-plugin-babel/dist/rollup-plugin-babel.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-babel/dist/rollup-plugin-babel.esm' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-babel/src/constants' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-babel/src/helperPlugin' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-babel/src' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-babel/src/preflightCheck' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-babel/src/utils' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rollup-plugin-babel/dist/rollup-plugin-babel.cjs.js' {\n  declare module.exports: $Exports<'rollup-plugin-babel/dist/rollup-plugin-babel.cjs'>;\n}\ndeclare module 'rollup-plugin-babel/dist/rollup-plugin-babel.esm.js' {\n  declare module.exports: $Exports<'rollup-plugin-babel/dist/rollup-plugin-babel.esm'>;\n}\ndeclare module 'rollup-plugin-babel/src/constants.js' {\n  declare module.exports: $Exports<'rollup-plugin-babel/src/constants'>;\n}\ndeclare module 'rollup-plugin-babel/src/helperPlugin.js' {\n  declare module.exports: $Exports<'rollup-plugin-babel/src/helperPlugin'>;\n}\ndeclare module 'rollup-plugin-babel/src/index' {\n  declare module.exports: $Exports<'rollup-plugin-babel/src'>;\n}\ndeclare module 'rollup-plugin-babel/src/index.js' {\n  declare module.exports: $Exports<'rollup-plugin-babel/src'>;\n}\ndeclare module 'rollup-plugin-babel/src/preflightCheck.js' {\n  declare module.exports: $Exports<'rollup-plugin-babel/src/preflightCheck'>;\n}\ndeclare module 'rollup-plugin-babel/src/utils.js' {\n  declare module.exports: $Exports<'rollup-plugin-babel/src/utils'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rollup-plugin-commonjs_vx.x.x.js",
    "content": "// flow-typed signature: 95d2e9042cd9b561a2a980089c70713a\n// flow-typed version: <<STUB>>/rollup-plugin-commonjs_v^10.1.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rollup-plugin-commonjs'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rollup-plugin-commonjs' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rollup-plugin-commonjs/dist/rollup-plugin-commonjs.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-commonjs/dist/rollup-plugin-commonjs.es' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-commonjs/src/ast-utils' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-commonjs/src/helpers' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-commonjs/src' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-commonjs/src/is-cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-commonjs/src/resolve-id' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-commonjs/src/transform' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-commonjs/src/utils' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rollup-plugin-commonjs/dist/rollup-plugin-commonjs.cjs.js' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/dist/rollup-plugin-commonjs.cjs'>;\n}\ndeclare module 'rollup-plugin-commonjs/dist/rollup-plugin-commonjs.es.js' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/dist/rollup-plugin-commonjs.es'>;\n}\ndeclare module 'rollup-plugin-commonjs/src/ast-utils.js' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/src/ast-utils'>;\n}\ndeclare module 'rollup-plugin-commonjs/src/helpers.js' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/src/helpers'>;\n}\ndeclare module 'rollup-plugin-commonjs/src/index' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/src'>;\n}\ndeclare module 'rollup-plugin-commonjs/src/index.js' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/src'>;\n}\ndeclare module 'rollup-plugin-commonjs/src/is-cjs.js' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/src/is-cjs'>;\n}\ndeclare module 'rollup-plugin-commonjs/src/resolve-id.js' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/src/resolve-id'>;\n}\ndeclare module 'rollup-plugin-commonjs/src/transform.js' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/src/transform'>;\n}\ndeclare module 'rollup-plugin-commonjs/src/utils.js' {\n  declare module.exports: $Exports<'rollup-plugin-commonjs/src/utils'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rollup-plugin-json_vx.x.x.js",
    "content": "// flow-typed signature: 0a76354785864f7e10a2f40f3fa9f6b9\n// flow-typed version: <<STUB>>/rollup-plugin-json_v^4.0.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rollup-plugin-json'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rollup-plugin-json' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rollup-plugin-json/dist/rollup-plugin-json.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-json/dist/rollup-plugin-json.es' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-json/src' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rollup-plugin-json/dist/rollup-plugin-json.cjs.js' {\n  declare module.exports: $Exports<'rollup-plugin-json/dist/rollup-plugin-json.cjs'>;\n}\ndeclare module 'rollup-plugin-json/dist/rollup-plugin-json.es.js' {\n  declare module.exports: $Exports<'rollup-plugin-json/dist/rollup-plugin-json.es'>;\n}\ndeclare module 'rollup-plugin-json/src/index' {\n  declare module.exports: $Exports<'rollup-plugin-json/src'>;\n}\ndeclare module 'rollup-plugin-json/src/index.js' {\n  declare module.exports: $Exports<'rollup-plugin-json/src'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rollup-plugin-node-resolve_vx.x.x.js",
    "content": "// flow-typed signature: 7111a73c3efd6b6bdfd43440956fb66a\n// flow-typed version: <<STUB>>/rollup-plugin-node-resolve_v^5.1.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rollup-plugin-node-resolve'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rollup-plugin-node-resolve' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rollup-plugin-node-resolve/dist/rollup-plugin-node-resolve.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-node-resolve/dist/rollup-plugin-node-resolve.es' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-node-resolve/src' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rollup-plugin-node-resolve/dist/rollup-plugin-node-resolve.cjs.js' {\n  declare module.exports: $Exports<'rollup-plugin-node-resolve/dist/rollup-plugin-node-resolve.cjs'>;\n}\ndeclare module 'rollup-plugin-node-resolve/dist/rollup-plugin-node-resolve.es.js' {\n  declare module.exports: $Exports<'rollup-plugin-node-resolve/dist/rollup-plugin-node-resolve.es'>;\n}\ndeclare module 'rollup-plugin-node-resolve/src/index' {\n  declare module.exports: $Exports<'rollup-plugin-node-resolve/src'>;\n}\ndeclare module 'rollup-plugin-node-resolve/src/index.js' {\n  declare module.exports: $Exports<'rollup-plugin-node-resolve/src'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rollup-plugin-replace_vx.x.x.js",
    "content": "// flow-typed signature: 9e645d14383f87d85c1ae8b81bc0ac6e\n// flow-typed version: <<STUB>>/rollup-plugin-replace_v^2.2.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rollup-plugin-replace'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rollup-plugin-replace' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rollup-plugin-replace/dist/rollup-plugin-replace.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-replace/dist/rollup-plugin-replace.es' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-replace/src' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rollup-plugin-replace/dist/rollup-plugin-replace.cjs.js' {\n  declare module.exports: $Exports<'rollup-plugin-replace/dist/rollup-plugin-replace.cjs'>;\n}\ndeclare module 'rollup-plugin-replace/dist/rollup-plugin-replace.es.js' {\n  declare module.exports: $Exports<'rollup-plugin-replace/dist/rollup-plugin-replace.es'>;\n}\ndeclare module 'rollup-plugin-replace/src/index' {\n  declare module.exports: $Exports<'rollup-plugin-replace/src'>;\n}\ndeclare module 'rollup-plugin-replace/src/index.js' {\n  declare module.exports: $Exports<'rollup-plugin-replace/src'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rollup-plugin-size-snapshot_vx.x.x.js",
    "content": "// flow-typed signature: e22a2b98d6048c538a13fb6e49124ef3\n// flow-typed version: <<STUB>>/rollup-plugin-size-snapshot_v^0.11.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rollup-plugin-size-snapshot'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rollup-plugin-size-snapshot' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rollup-plugin-size-snapshot/dist' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-size-snapshot/dist/snapshot' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-size-snapshot/dist/treeshakeWithRollup' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-size-snapshot/dist/treeshakeWithWebpack' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rollup-plugin-size-snapshot/dist/index' {\n  declare module.exports: $Exports<'rollup-plugin-size-snapshot/dist'>;\n}\ndeclare module 'rollup-plugin-size-snapshot/dist/index.js' {\n  declare module.exports: $Exports<'rollup-plugin-size-snapshot/dist'>;\n}\ndeclare module 'rollup-plugin-size-snapshot/dist/snapshot.js' {\n  declare module.exports: $Exports<'rollup-plugin-size-snapshot/dist/snapshot'>;\n}\ndeclare module 'rollup-plugin-size-snapshot/dist/treeshakeWithRollup.js' {\n  declare module.exports: $Exports<'rollup-plugin-size-snapshot/dist/treeshakeWithRollup'>;\n}\ndeclare module 'rollup-plugin-size-snapshot/dist/treeshakeWithWebpack.js' {\n  declare module.exports: $Exports<'rollup-plugin-size-snapshot/dist/treeshakeWithWebpack'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rollup-plugin-strip_vx.x.x.js",
    "content": "// flow-typed signature: 259b0be9d1ffea0b96d54a9a307b8346\n// flow-typed version: <<STUB>>/rollup-plugin-strip_v^1.2.2/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rollup-plugin-strip'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rollup-plugin-strip' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rollup-plugin-strip/dist/rollup-plugin-strip.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup-plugin-strip/dist/rollup-plugin-strip.es' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rollup-plugin-strip/dist/rollup-plugin-strip.cjs.js' {\n  declare module.exports: $Exports<'rollup-plugin-strip/dist/rollup-plugin-strip.cjs'>;\n}\ndeclare module 'rollup-plugin-strip/dist/rollup-plugin-strip.es.js' {\n  declare module.exports: $Exports<'rollup-plugin-strip/dist/rollup-plugin-strip.es'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rollup-plugin-terser_vx.x.x.js",
    "content": "// flow-typed signature: a7c8c8c0d56b7a709d5d48f26d97ff9f\n// flow-typed version: <<STUB>>/rollup-plugin-terser_v^5.2.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rollup-plugin-terser'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rollup-plugin-terser' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rollup-plugin-terser/transform' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rollup-plugin-terser/index' {\n  declare module.exports: $Exports<'rollup-plugin-terser'>;\n}\ndeclare module 'rollup-plugin-terser/index.js' {\n  declare module.exports: $Exports<'rollup-plugin-terser'>;\n}\ndeclare module 'rollup-plugin-terser/transform.js' {\n  declare module.exports: $Exports<'rollup-plugin-terser/transform'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/rollup_vx.x.x.js",
    "content": "// flow-typed signature: d5a13a3e2f3eac5498d81f0313519e2b\n// flow-typed version: <<STUB>>/rollup_v^1.31.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'rollup'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'rollup' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'rollup/dist/rollup.browser.es' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup/dist/rollup.browser' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup/dist/rollup.es' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup/dist/rollup' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup/dist/shared' {\n  declare module.exports: any;\n}\n\ndeclare module 'rollup/dist/shared/node-entry' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'rollup/dist/rollup.browser.es.js' {\n  declare module.exports: $Exports<'rollup/dist/rollup.browser.es'>;\n}\ndeclare module 'rollup/dist/rollup.browser.js' {\n  declare module.exports: $Exports<'rollup/dist/rollup.browser'>;\n}\ndeclare module 'rollup/dist/rollup.es.js' {\n  declare module.exports: $Exports<'rollup/dist/rollup.es'>;\n}\ndeclare module 'rollup/dist/rollup.js' {\n  declare module.exports: $Exports<'rollup/dist/rollup'>;\n}\ndeclare module 'rollup/dist/shared/index' {\n  declare module.exports: $Exports<'rollup/dist/shared'>;\n}\ndeclare module 'rollup/dist/shared/index.js' {\n  declare module.exports: $Exports<'rollup/dist/shared'>;\n}\ndeclare module 'rollup/dist/shared/node-entry.js' {\n  declare module.exports: $Exports<'rollup/dist/shared/node-entry'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/styled-components_vx.x.x.js",
    "content": "// flow-typed signature: 0b727f6b618d1233f67311e84892f002\n// flow-typed version: <<STUB>>/styled-components_v5.0.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'styled-components'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'styled-components' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'styled-components/dist/styled-components-macro.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/dist/styled-components-macro.esm' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/dist/styled-components.browser.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/dist/styled-components.browser.esm' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/dist/styled-components.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/dist/styled-components.esm' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/dist/styled-components' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/dist/styled-components.min' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/native/dist/styled-components.native.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/native/dist/styled-components.native.esm' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/primitives/dist/styled-components-primitives.cjs' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/primitives/dist/styled-components-primitives.esm' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/scripts/generateErrorMap' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/test-utils' {\n  declare module.exports: any;\n}\n\ndeclare module 'styled-components/test-utils/setupTestFramework' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'styled-components/dist/styled-components-macro.cjs.js' {\n  declare module.exports: $Exports<'styled-components/dist/styled-components-macro.cjs'>;\n}\ndeclare module 'styled-components/dist/styled-components-macro.esm.js' {\n  declare module.exports: $Exports<'styled-components/dist/styled-components-macro.esm'>;\n}\ndeclare module 'styled-components/dist/styled-components.browser.cjs.js' {\n  declare module.exports: $Exports<'styled-components/dist/styled-components.browser.cjs'>;\n}\ndeclare module 'styled-components/dist/styled-components.browser.esm.js' {\n  declare module.exports: $Exports<'styled-components/dist/styled-components.browser.esm'>;\n}\ndeclare module 'styled-components/dist/styled-components.cjs.js' {\n  declare module.exports: $Exports<'styled-components/dist/styled-components.cjs'>;\n}\ndeclare module 'styled-components/dist/styled-components.esm.js' {\n  declare module.exports: $Exports<'styled-components/dist/styled-components.esm'>;\n}\ndeclare module 'styled-components/dist/styled-components.js' {\n  declare module.exports: $Exports<'styled-components/dist/styled-components'>;\n}\ndeclare module 'styled-components/dist/styled-components.min.js' {\n  declare module.exports: $Exports<'styled-components/dist/styled-components.min'>;\n}\ndeclare module 'styled-components/native/dist/styled-components.native.cjs.js' {\n  declare module.exports: $Exports<'styled-components/native/dist/styled-components.native.cjs'>;\n}\ndeclare module 'styled-components/native/dist/styled-components.native.esm.js' {\n  declare module.exports: $Exports<'styled-components/native/dist/styled-components.native.esm'>;\n}\ndeclare module 'styled-components/primitives/dist/styled-components-primitives.cjs.js' {\n  declare module.exports: $Exports<'styled-components/primitives/dist/styled-components-primitives.cjs'>;\n}\ndeclare module 'styled-components/primitives/dist/styled-components-primitives.esm.js' {\n  declare module.exports: $Exports<'styled-components/primitives/dist/styled-components-primitives.esm'>;\n}\ndeclare module 'styled-components/scripts/generateErrorMap.js' {\n  declare module.exports: $Exports<'styled-components/scripts/generateErrorMap'>;\n}\ndeclare module 'styled-components/test-utils/index' {\n  declare module.exports: $Exports<'styled-components/test-utils'>;\n}\ndeclare module 'styled-components/test-utils/index.js' {\n  declare module.exports: $Exports<'styled-components/test-utils'>;\n}\ndeclare module 'styled-components/test-utils/setupTestFramework.js' {\n  declare module.exports: $Exports<'styled-components/test-utils/setupTestFramework'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/stylelint-config-prettier_vx.x.x.js",
    "content": "// flow-typed signature: f7a7418c5497d0181aebfde649524c82\n// flow-typed version: <<STUB>>/stylelint-config-prettier_v^8.0.1/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'stylelint-config-prettier'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'stylelint-config-prettier' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'stylelint-config-prettier/bin/check' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-config-prettier/src/checker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-config-prettier/src' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'stylelint-config-prettier/bin/check.js' {\n  declare module.exports: $Exports<'stylelint-config-prettier/bin/check'>;\n}\ndeclare module 'stylelint-config-prettier/src/checker.js' {\n  declare module.exports: $Exports<'stylelint-config-prettier/src/checker'>;\n}\ndeclare module 'stylelint-config-prettier/src/index' {\n  declare module.exports: $Exports<'stylelint-config-prettier/src'>;\n}\ndeclare module 'stylelint-config-prettier/src/index.js' {\n  declare module.exports: $Exports<'stylelint-config-prettier/src'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/stylelint-config-recommended_vx.x.x.js",
    "content": "// flow-typed signature: 4a539e33d88cdab1af3b2186bc03cecb\n// flow-typed version: <<STUB>>/stylelint-config-recommended_v^3.0.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'stylelint-config-recommended'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'stylelint-config-recommended' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\n\n\n// Filename aliases\ndeclare module 'stylelint-config-recommended/index' {\n  declare module.exports: $Exports<'stylelint-config-recommended'>;\n}\ndeclare module 'stylelint-config-recommended/index.js' {\n  declare module.exports: $Exports<'stylelint-config-recommended'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/stylelint-config-standard_vx.x.x.js",
    "content": "// flow-typed signature: 889ab190baf52758e1e0eb8ed818929a\n// flow-typed version: <<STUB>>/stylelint-config-standard_v^19.0.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'stylelint-config-standard'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'stylelint-config-standard' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\n\n\n// Filename aliases\ndeclare module 'stylelint-config-standard/index' {\n  declare module.exports: $Exports<'stylelint-config-standard'>;\n}\ndeclare module 'stylelint-config-standard/index.js' {\n  declare module.exports: $Exports<'stylelint-config-standard'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/stylelint-config-styled-components_vx.x.x.js",
    "content": "// flow-typed signature: dd1609d786c47183d228636ef55ba6e3\n// flow-typed version: <<STUB>>/stylelint-config-styled-components_v^0.1.1/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'stylelint-config-styled-components'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'stylelint-config-styled-components' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\n\n\n// Filename aliases\ndeclare module 'stylelint-config-styled-components/index' {\n  declare module.exports: $Exports<'stylelint-config-styled-components'>;\n}\ndeclare module 'stylelint-config-styled-components/index.js' {\n  declare module.exports: $Exports<'stylelint-config-styled-components'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/stylelint-processor-styled-components_vx.x.x.js",
    "content": "// flow-typed signature: 9ca763ee126a7afa7841fa99b093bcee\n// flow-typed version: <<STUB>>/stylelint-processor-styled-components_v^1.9.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'stylelint-processor-styled-components'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'stylelint-processor-styled-components' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'stylelint-processor-styled-components/src' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/src/parsers/babylon-parser' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/src/parsers' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/src/utils/general' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/src/utils/parse' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/src/utils/result' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/src/utils/styled' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/src/utils/tagged-template-literal' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/emptyblock.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/emptycode.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/garbage-css/invalid-css' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/hard/indentation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/hard/invalid-indentation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/hard/source-maps' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/hard/valid-js-comments' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/alternating-disable-enable' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/disable-whole-file' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/mix-in-css-disables' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/use-single-line-comments' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/use-single-line-disables' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/inject-global/valid-spaces' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/inject-global/valid-tabs' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolation-tagging/invalid-custom' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolation-tagging/invalid-tag' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolation-tagging/valid' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolations/complex' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolations/invalid' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolations/valid' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/import-name' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/invalid-import-name' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/invalid-module-name' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/module-name' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/relative-module-name' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/strict' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/real-world/Circle' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/real-world/LineNumbersReportedAccurate' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/global' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/helpers' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/identify-styled' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/imports' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/invalid' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/nesting' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/other-library' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/valid' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/garbage-css.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/hard.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/ignore-rule-comments.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/inject-global.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/interpolation-tagging.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/interpolations.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/jest-setup' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/nofiles.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/options.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/real-world.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/simple.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/typescript.test' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint-processor-styled-components/test/utils.test' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'stylelint-processor-styled-components/src/index' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src'>;\n}\ndeclare module 'stylelint-processor-styled-components/src/index.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src'>;\n}\ndeclare module 'stylelint-processor-styled-components/src/parsers/babylon-parser.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src/parsers/babylon-parser'>;\n}\ndeclare module 'stylelint-processor-styled-components/src/parsers/index' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src/parsers'>;\n}\ndeclare module 'stylelint-processor-styled-components/src/parsers/index.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src/parsers'>;\n}\ndeclare module 'stylelint-processor-styled-components/src/utils/general.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src/utils/general'>;\n}\ndeclare module 'stylelint-processor-styled-components/src/utils/parse.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src/utils/parse'>;\n}\ndeclare module 'stylelint-processor-styled-components/src/utils/result.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src/utils/result'>;\n}\ndeclare module 'stylelint-processor-styled-components/src/utils/styled.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src/utils/styled'>;\n}\ndeclare module 'stylelint-processor-styled-components/src/utils/tagged-template-literal.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/src/utils/tagged-template-literal'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/emptyblock.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/emptyblock.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/emptycode.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/emptycode.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/garbage-css/invalid-css.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/garbage-css/invalid-css'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/hard/indentation.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/hard/indentation'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/hard/invalid-indentation.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/hard/invalid-indentation'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/hard/source-maps.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/hard/source-maps'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/hard/valid-js-comments.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/hard/valid-js-comments'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/alternating-disable-enable.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/alternating-disable-enable'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/disable-whole-file.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/disable-whole-file'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/mix-in-css-disables.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/mix-in-css-disables'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/use-single-line-comments.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/use-single-line-comments'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/use-single-line-disables.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/ignore-rule-comments/use-single-line-disables'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/inject-global/valid-spaces.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/inject-global/valid-spaces'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/inject-global/valid-tabs.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/inject-global/valid-tabs'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolation-tagging/invalid-custom.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/interpolation-tagging/invalid-custom'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolation-tagging/invalid-tag.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/interpolation-tagging/invalid-tag'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolation-tagging/valid.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/interpolation-tagging/valid'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolations/complex.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/interpolations/complex'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolations/invalid.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/interpolations/invalid'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/interpolations/valid.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/interpolations/valid'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/import-name.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/options/import-name'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/invalid-import-name.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/options/invalid-import-name'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/invalid-module-name.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/options/invalid-module-name'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/module-name.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/options/module-name'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/relative-module-name.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/options/relative-module-name'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/options/strict.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/options/strict'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/real-world/Circle.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/real-world/Circle'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/real-world/LineNumbersReportedAccurate.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/real-world/LineNumbersReportedAccurate'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/global.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/simple/global'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/helpers.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/simple/helpers'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/identify-styled.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/simple/identify-styled'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/imports.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/simple/imports'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/invalid.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/simple/invalid'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/nesting.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/simple/nesting'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/other-library.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/simple/other-library'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/fixtures/simple/valid.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/fixtures/simple/valid'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/garbage-css.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/garbage-css.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/hard.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/hard.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/ignore-rule-comments.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/ignore-rule-comments.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/inject-global.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/inject-global.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/interpolation-tagging.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/interpolation-tagging.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/interpolations.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/interpolations.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/jest-setup.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/jest-setup'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/nofiles.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/nofiles.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/options.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/options.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/real-world.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/real-world.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/simple.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/simple.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/typescript.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/typescript.test'>;\n}\ndeclare module 'stylelint-processor-styled-components/test/utils.test.js' {\n  declare module.exports: $Exports<'stylelint-processor-styled-components/test/utils.test'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/stylelint_vx.x.x.js",
    "content": "// flow-typed signature: bafc17d692988285c8c3487149cf7566\n// flow-typed version: <<STUB>>/stylelint_v^13.0.0/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'stylelint'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'stylelint' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'stylelint/bin/stylelint' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/assignDisabledRanges' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/augmentConfig' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/cli' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/createPlugin' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/createStylelint' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/createStylelintResult' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/dynamicRequire' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/formatters/compactFormatter' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/formatters/disableOptionsReportStringFormatter' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/formatters' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/formatters/jsonFormatter' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/formatters/stringFormatter' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/formatters/unixFormatter' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/formatters/verboseFormatter' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/getConfigForFile' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/getPostcssResult' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/invalidScopeDisables' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/isPathIgnored' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/lintSource' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/needlessDisables' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/normalizeRuleSettings' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/postcssPlugin' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/printConfig' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/reference/keywordSets' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/reference/mathFunctions' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/reference/namedColorData' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/reference/propertySets' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/reference/punctuationSets' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/reference/shorthandData' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/reportUnknownRuleNames' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/requireRule' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-empty-line-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-name-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-name-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-name-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-no-unknown' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-no-vendor-prefix' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-property-requirelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-semicolon-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-semicolon-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/at-rule-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/atRuleNameSpaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-closing-brace-empty-line-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-closing-brace-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-closing-brace-newline-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-closing-brace-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-closing-brace-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-no-empty' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-opening-brace-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-opening-brace-newline-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-opening-brace-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/block-opening-brace-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/color-hex-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/color-hex-length' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/color-named/generateColorFuncs' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/color-named' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/color-no-hex' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/color-no-invalid-hex' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/comment-empty-line-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/comment-no-empty' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/comment-whitespace-inside' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/comment-word-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/custom-media-pattern' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/custom-property-empty-line-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/custom-property-pattern' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-bang-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-bang-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-block-no-duplicate-properties' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-block-no-redundant-longhand-properties' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-block-no-shorthand-property-overrides' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-newline-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-block-single-line-max-declarations' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-block-trailing-semicolon' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-colon-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-colon-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-colon-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-empty-line-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-no-important' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-property-unit-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-property-unit-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-property-value-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declaration-property-value-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declarationBangSpaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/declarationColonSpaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/findMediaOperator' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/font-family-name-quotes' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/font-family-no-duplicate-names' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/font-family-no-missing-generic-family-keyword' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/font-weight-notation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-calc-no-invalid' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-calc-no-unspaced-operator' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-comma-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-comma-newline-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-comma-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-comma-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-max-empty-lines' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-name-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-parentheses-newline-inside' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-parentheses-space-inside' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-url-no-scheme-relative' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-url-quotes' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-url-scheme-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-url-scheme-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/function-whitespace-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/functionCommaSpaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/functionCommaSpaceFix' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/indentation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/keyframe-declaration-no-important' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/keyframes-name-pattern' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/length-zero-no-unit' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/linebreaks' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/max-empty-lines' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/max-line-length' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/max-nesting-depth' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-colon-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-colon-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-name-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-name-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-name-no-unknown' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-name-no-vendor-prefix' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-name-value-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-name-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-parentheses-space-inside' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-range-operator-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-feature-range-operator-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-query-list-comma-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-query-list-comma-newline-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-query-list-comma-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/media-query-list-comma-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/mediaFeatureColonSpaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/mediaQueryListCommaWhitespaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-descending-specificity' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-duplicate-at-import-rules' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-duplicate-selectors' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-empty-first-line' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-empty-source' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-eol-whitespace' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-extra-semicolons' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-invalid-double-slash-comments' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-missing-end-of-source-newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/no-unknown-animations' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/number-leading-zero' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/number-max-precision' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/number-no-trailing-zeros' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/property-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/property-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/property-no-unknown' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/property-no-vendor-prefix' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/property-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/rule-empty-line-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-attribute-brackets-space-inside' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-attribute-quotes' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-class-pattern' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-combinator-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-combinator-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-combinator-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-combinator-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-descendant-combinator-no-non-space' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-id-pattern' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-list-comma-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-list-comma-newline-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-list-comma-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-list-comma-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-attribute' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-class' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-combinators' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-compound-selectors' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-empty-lines' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-id' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-pseudo-class' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-specificity' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-type' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-max-universal' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-nested-pattern' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-no-qualifying-type' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-no-vendor-prefix' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-no-unknown' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-parentheses-space-inside' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-colon-notation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-no-unknown' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-type-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selector-type-no-unknown' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selectorAttributeOperatorSpaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selectorCombinatorSpaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/selectorListCommaWhitespaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/shorthand-property-no-redundant-values' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/string-no-newline' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/string-quotes' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/time-min-milliseconds' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/unicode-bom' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/unit-blacklist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/unit-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/unit-no-unknown' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/unit-whitelist' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/value-keyword-case' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/value-list-comma-newline-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/value-list-comma-newline-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/value-list-comma-space-after' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/value-list-comma-space-before' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/value-list-max-empty-lines' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/value-no-vendor-prefix' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/rules/valueListCommaWhitespaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/standalone' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/addEmptyLineAfter' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/addEmptyLineBefore' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/atRuleParamIndex' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/beforeBlockString' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/blockString' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/blurComments' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/blurFunctionArguments' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/blurInterpolation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/checkAgainstRule' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/checkInvalidCLIOptions' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/configurationError' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/containsString' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/declarationValueIndex' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/eachDeclarationBlock' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/FileCache' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/filterFilePaths' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/findAnimationName' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/findAtRuleContext' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/findFontFamily' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/findListStyleType' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/functionArgumentsSearch' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/getCacheFile' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/getFileIgnorer' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/getFormatterOptionsText' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/getModulePath' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/getNextNonSharedLineCommentNode' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/getOsEol' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/getPreviousNonSharedLineCommentNode' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/getSchemeFromUrl' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/getUnitFromValueNode' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/hasBlock' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/hasEmptyBlock' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/hasEmptyLine' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/hash' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/hasInterpolation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/hasLessInterpolation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/hasPsvInterpolation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/hasScssInterpolation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/hasTplInterpolation' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isAfterComment' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isAfterSingleLineComment' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isAfterStandardPropertyDeclaration' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isAutoprefixable' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isBlocklessAtRuleAfterBlocklessAtRule' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isBlocklessAtRuleAfterSameNameBlocklessAtRule' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isCounterIncrementCustomIdentValue' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isCounterResetCustomIdentValue' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isCustomElement' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isCustomMediaQuery' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isCustomProperty' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isCustomPropertySet' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isCustomSelector' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isFirstNested' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isFirstNodeOfRoot' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isKeyframeRule' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isKeyframeSelector' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isLessVariable' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isLogicalCombination' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isMap' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isMathFunction' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isNumbery' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isOnlyWhitespace' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isRangeContextMediaFeature' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isSharedLineComment' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isSingleLineString' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxAtRule' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxCombinator' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxDeclaration' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxFunction' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxMediaFeature' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxMediaFeatureName' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxProperty' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxRule' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxSelector' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxTypeSelector' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxUrl' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isStandardSyntaxValue' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isValidFontSize' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isValidHex' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isVariable' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/isWhitespace' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/matchesStringOrRegExp' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/nextNonCommentNode' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/nodeContextLookup' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/noFilesFoundError' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/optionsMatches' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/parseCalcExpression' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/parseCalcExpression/parser' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/parseSelector' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/rawNodeString' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/removeEmptyLinesAfter' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/removeEmptyLinesBefore' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/report' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/ruleMessages' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/transformSelector' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/typeGuards' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/validateObjectWithArrayProps' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/validateOptions' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/utils/whitespaceChecker' {\n  declare module.exports: any;\n}\n\ndeclare module 'stylelint/lib/writeOutputFile' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'stylelint/bin/stylelint.js' {\n  declare module.exports: $Exports<'stylelint/bin/stylelint'>;\n}\ndeclare module 'stylelint/lib/assignDisabledRanges.js' {\n  declare module.exports: $Exports<'stylelint/lib/assignDisabledRanges'>;\n}\ndeclare module 'stylelint/lib/augmentConfig.js' {\n  declare module.exports: $Exports<'stylelint/lib/augmentConfig'>;\n}\ndeclare module 'stylelint/lib/cli.js' {\n  declare module.exports: $Exports<'stylelint/lib/cli'>;\n}\ndeclare module 'stylelint/lib/createPlugin.js' {\n  declare module.exports: $Exports<'stylelint/lib/createPlugin'>;\n}\ndeclare module 'stylelint/lib/createStylelint.js' {\n  declare module.exports: $Exports<'stylelint/lib/createStylelint'>;\n}\ndeclare module 'stylelint/lib/createStylelintResult.js' {\n  declare module.exports: $Exports<'stylelint/lib/createStylelintResult'>;\n}\ndeclare module 'stylelint/lib/dynamicRequire.js' {\n  declare module.exports: $Exports<'stylelint/lib/dynamicRequire'>;\n}\ndeclare module 'stylelint/lib/formatters/compactFormatter.js' {\n  declare module.exports: $Exports<'stylelint/lib/formatters/compactFormatter'>;\n}\ndeclare module 'stylelint/lib/formatters/disableOptionsReportStringFormatter.js' {\n  declare module.exports: $Exports<'stylelint/lib/formatters/disableOptionsReportStringFormatter'>;\n}\ndeclare module 'stylelint/lib/formatters/index' {\n  declare module.exports: $Exports<'stylelint/lib/formatters'>;\n}\ndeclare module 'stylelint/lib/formatters/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/formatters'>;\n}\ndeclare module 'stylelint/lib/formatters/jsonFormatter.js' {\n  declare module.exports: $Exports<'stylelint/lib/formatters/jsonFormatter'>;\n}\ndeclare module 'stylelint/lib/formatters/stringFormatter.js' {\n  declare module.exports: $Exports<'stylelint/lib/formatters/stringFormatter'>;\n}\ndeclare module 'stylelint/lib/formatters/unixFormatter.js' {\n  declare module.exports: $Exports<'stylelint/lib/formatters/unixFormatter'>;\n}\ndeclare module 'stylelint/lib/formatters/verboseFormatter.js' {\n  declare module.exports: $Exports<'stylelint/lib/formatters/verboseFormatter'>;\n}\ndeclare module 'stylelint/lib/getConfigForFile.js' {\n  declare module.exports: $Exports<'stylelint/lib/getConfigForFile'>;\n}\ndeclare module 'stylelint/lib/getPostcssResult.js' {\n  declare module.exports: $Exports<'stylelint/lib/getPostcssResult'>;\n}\ndeclare module 'stylelint/lib/index' {\n  declare module.exports: $Exports<'stylelint/lib'>;\n}\ndeclare module 'stylelint/lib/index.js' {\n  declare module.exports: $Exports<'stylelint/lib'>;\n}\ndeclare module 'stylelint/lib/invalidScopeDisables.js' {\n  declare module.exports: $Exports<'stylelint/lib/invalidScopeDisables'>;\n}\ndeclare module 'stylelint/lib/isPathIgnored.js' {\n  declare module.exports: $Exports<'stylelint/lib/isPathIgnored'>;\n}\ndeclare module 'stylelint/lib/lintSource.js' {\n  declare module.exports: $Exports<'stylelint/lib/lintSource'>;\n}\ndeclare module 'stylelint/lib/needlessDisables.js' {\n  declare module.exports: $Exports<'stylelint/lib/needlessDisables'>;\n}\ndeclare module 'stylelint/lib/normalizeRuleSettings.js' {\n  declare module.exports: $Exports<'stylelint/lib/normalizeRuleSettings'>;\n}\ndeclare module 'stylelint/lib/postcssPlugin.js' {\n  declare module.exports: $Exports<'stylelint/lib/postcssPlugin'>;\n}\ndeclare module 'stylelint/lib/printConfig.js' {\n  declare module.exports: $Exports<'stylelint/lib/printConfig'>;\n}\ndeclare module 'stylelint/lib/reference/keywordSets.js' {\n  declare module.exports: $Exports<'stylelint/lib/reference/keywordSets'>;\n}\ndeclare module 'stylelint/lib/reference/mathFunctions.js' {\n  declare module.exports: $Exports<'stylelint/lib/reference/mathFunctions'>;\n}\ndeclare module 'stylelint/lib/reference/namedColorData.js' {\n  declare module.exports: $Exports<'stylelint/lib/reference/namedColorData'>;\n}\ndeclare module 'stylelint/lib/reference/propertySets.js' {\n  declare module.exports: $Exports<'stylelint/lib/reference/propertySets'>;\n}\ndeclare module 'stylelint/lib/reference/punctuationSets.js' {\n  declare module.exports: $Exports<'stylelint/lib/reference/punctuationSets'>;\n}\ndeclare module 'stylelint/lib/reference/shorthandData.js' {\n  declare module.exports: $Exports<'stylelint/lib/reference/shorthandData'>;\n}\ndeclare module 'stylelint/lib/reportUnknownRuleNames.js' {\n  declare module.exports: $Exports<'stylelint/lib/reportUnknownRuleNames'>;\n}\ndeclare module 'stylelint/lib/requireRule.js' {\n  declare module.exports: $Exports<'stylelint/lib/requireRule'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-empty-line-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-empty-line-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-name-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-name-case'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-name-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-name-case'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-name-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-name-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-name-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-name-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-name-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-name-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-name-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-name-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-no-unknown/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-no-unknown/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-no-vendor-prefix/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-no-vendor-prefix/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-property-requirelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-property-requirelist'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-property-requirelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-property-requirelist'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-semicolon-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-semicolon-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-semicolon-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-semicolon-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-semicolon-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-semicolon-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-semicolon-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-semicolon-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/at-rule-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/at-rule-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/atRuleNameSpaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/atRuleNameSpaceChecker'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-empty-line-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-empty-line-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-newline-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-newline-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/block-closing-brace-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-closing-brace-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/block-no-empty/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-no-empty'>;\n}\ndeclare module 'stylelint/lib/rules/block-no-empty/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-no-empty'>;\n}\ndeclare module 'stylelint/lib/rules/block-opening-brace-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-opening-brace-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/block-opening-brace-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-opening-brace-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/block-opening-brace-newline-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-opening-brace-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/block-opening-brace-newline-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-opening-brace-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/block-opening-brace-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-opening-brace-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/block-opening-brace-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-opening-brace-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/block-opening-brace-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-opening-brace-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/block-opening-brace-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/block-opening-brace-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/color-hex-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-hex-case'>;\n}\ndeclare module 'stylelint/lib/rules/color-hex-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-hex-case'>;\n}\ndeclare module 'stylelint/lib/rules/color-hex-length/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-hex-length'>;\n}\ndeclare module 'stylelint/lib/rules/color-hex-length/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-hex-length'>;\n}\ndeclare module 'stylelint/lib/rules/color-named/generateColorFuncs.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-named/generateColorFuncs'>;\n}\ndeclare module 'stylelint/lib/rules/color-named/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-named'>;\n}\ndeclare module 'stylelint/lib/rules/color-named/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-named'>;\n}\ndeclare module 'stylelint/lib/rules/color-no-hex/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-no-hex'>;\n}\ndeclare module 'stylelint/lib/rules/color-no-hex/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-no-hex'>;\n}\ndeclare module 'stylelint/lib/rules/color-no-invalid-hex/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-no-invalid-hex'>;\n}\ndeclare module 'stylelint/lib/rules/color-no-invalid-hex/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/color-no-invalid-hex'>;\n}\ndeclare module 'stylelint/lib/rules/comment-empty-line-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/comment-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/comment-empty-line-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/comment-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/comment-no-empty/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/comment-no-empty'>;\n}\ndeclare module 'stylelint/lib/rules/comment-no-empty/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/comment-no-empty'>;\n}\ndeclare module 'stylelint/lib/rules/comment-whitespace-inside/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/comment-whitespace-inside'>;\n}\ndeclare module 'stylelint/lib/rules/comment-whitespace-inside/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/comment-whitespace-inside'>;\n}\ndeclare module 'stylelint/lib/rules/comment-word-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/comment-word-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/comment-word-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/comment-word-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/custom-media-pattern/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/custom-media-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/custom-media-pattern/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/custom-media-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/custom-property-empty-line-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/custom-property-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/custom-property-empty-line-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/custom-property-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/custom-property-pattern/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/custom-property-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/custom-property-pattern/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/custom-property-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-bang-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-bang-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-bang-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-bang-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-bang-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-bang-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-bang-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-bang-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-no-duplicate-properties/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-no-duplicate-properties'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-no-duplicate-properties/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-no-duplicate-properties'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-no-redundant-longhand-properties/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-no-redundant-longhand-properties'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-no-redundant-longhand-properties/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-no-redundant-longhand-properties'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-no-shorthand-property-overrides/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-no-shorthand-property-overrides'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-no-shorthand-property-overrides/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-no-shorthand-property-overrides'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-semicolon-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-semicolon-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-newline-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-semicolon-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-newline-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-semicolon-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-semicolon-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-semicolon-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-semicolon-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-semicolon-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-semicolon-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-single-line-max-declarations/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-single-line-max-declarations'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-single-line-max-declarations/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-single-line-max-declarations'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-trailing-semicolon/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-trailing-semicolon'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-block-trailing-semicolon/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-block-trailing-semicolon'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-colon-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-colon-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-colon-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-colon-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-colon-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-colon-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-colon-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-colon-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-colon-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-colon-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-colon-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-colon-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-empty-line-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-empty-line-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-no-important/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-no-important'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-no-important/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-no-important'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-property-unit-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-property-unit-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-property-unit-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-property-unit-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-property-unit-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-property-unit-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-property-unit-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-property-unit-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-property-value-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-property-value-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-property-value-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-property-value-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-property-value-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-property-value-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/declaration-property-value-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declaration-property-value-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/declarationBangSpaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declarationBangSpaceChecker'>;\n}\ndeclare module 'stylelint/lib/rules/declarationColonSpaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/declarationColonSpaceChecker'>;\n}\ndeclare module 'stylelint/lib/rules/findMediaOperator.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/findMediaOperator'>;\n}\ndeclare module 'stylelint/lib/rules/font-family-name-quotes/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/font-family-name-quotes'>;\n}\ndeclare module 'stylelint/lib/rules/font-family-name-quotes/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/font-family-name-quotes'>;\n}\ndeclare module 'stylelint/lib/rules/font-family-no-duplicate-names/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/font-family-no-duplicate-names'>;\n}\ndeclare module 'stylelint/lib/rules/font-family-no-duplicate-names/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/font-family-no-duplicate-names'>;\n}\ndeclare module 'stylelint/lib/rules/font-family-no-missing-generic-family-keyword/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/font-family-no-missing-generic-family-keyword'>;\n}\ndeclare module 'stylelint/lib/rules/font-family-no-missing-generic-family-keyword/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/font-family-no-missing-generic-family-keyword'>;\n}\ndeclare module 'stylelint/lib/rules/font-weight-notation/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/font-weight-notation'>;\n}\ndeclare module 'stylelint/lib/rules/font-weight-notation/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/font-weight-notation'>;\n}\ndeclare module 'stylelint/lib/rules/function-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/function-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/function-calc-no-invalid/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-calc-no-invalid'>;\n}\ndeclare module 'stylelint/lib/rules/function-calc-no-invalid/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-calc-no-invalid'>;\n}\ndeclare module 'stylelint/lib/rules/function-calc-no-unspaced-operator/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-calc-no-unspaced-operator'>;\n}\ndeclare module 'stylelint/lib/rules/function-calc-no-unspaced-operator/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-calc-no-unspaced-operator'>;\n}\ndeclare module 'stylelint/lib/rules/function-comma-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-comma-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/function-comma-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-comma-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/function-comma-newline-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-comma-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/function-comma-newline-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-comma-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/function-comma-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-comma-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/function-comma-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-comma-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/function-comma-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-comma-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/function-comma-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-comma-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction'>;\n}\ndeclare module 'stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-linear-gradient-no-nonstandard-direction'>;\n}\ndeclare module 'stylelint/lib/rules/function-max-empty-lines/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-max-empty-lines'>;\n}\ndeclare module 'stylelint/lib/rules/function-max-empty-lines/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-max-empty-lines'>;\n}\ndeclare module 'stylelint/lib/rules/function-name-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-name-case'>;\n}\ndeclare module 'stylelint/lib/rules/function-name-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-name-case'>;\n}\ndeclare module 'stylelint/lib/rules/function-parentheses-newline-inside/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-parentheses-newline-inside'>;\n}\ndeclare module 'stylelint/lib/rules/function-parentheses-newline-inside/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-parentheses-newline-inside'>;\n}\ndeclare module 'stylelint/lib/rules/function-parentheses-space-inside/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-parentheses-space-inside'>;\n}\ndeclare module 'stylelint/lib/rules/function-parentheses-space-inside/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-parentheses-space-inside'>;\n}\ndeclare module 'stylelint/lib/rules/function-url-no-scheme-relative/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-url-no-scheme-relative'>;\n}\ndeclare module 'stylelint/lib/rules/function-url-no-scheme-relative/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-url-no-scheme-relative'>;\n}\ndeclare module 'stylelint/lib/rules/function-url-quotes/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-url-quotes'>;\n}\ndeclare module 'stylelint/lib/rules/function-url-quotes/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-url-quotes'>;\n}\ndeclare module 'stylelint/lib/rules/function-url-scheme-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-url-scheme-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/function-url-scheme-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-url-scheme-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/function-url-scheme-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-url-scheme-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/function-url-scheme-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-url-scheme-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/function-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/function-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/function-whitespace-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-whitespace-after'>;\n}\ndeclare module 'stylelint/lib/rules/function-whitespace-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/function-whitespace-after'>;\n}\ndeclare module 'stylelint/lib/rules/functionCommaSpaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/functionCommaSpaceChecker'>;\n}\ndeclare module 'stylelint/lib/rules/functionCommaSpaceFix.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/functionCommaSpaceFix'>;\n}\ndeclare module 'stylelint/lib/rules/indentation/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/indentation'>;\n}\ndeclare module 'stylelint/lib/rules/indentation/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/indentation'>;\n}\ndeclare module 'stylelint/lib/rules/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules'>;\n}\ndeclare module 'stylelint/lib/rules/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules'>;\n}\ndeclare module 'stylelint/lib/rules/keyframe-declaration-no-important/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/keyframe-declaration-no-important'>;\n}\ndeclare module 'stylelint/lib/rules/keyframe-declaration-no-important/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/keyframe-declaration-no-important'>;\n}\ndeclare module 'stylelint/lib/rules/keyframes-name-pattern/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/keyframes-name-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/keyframes-name-pattern/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/keyframes-name-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/length-zero-no-unit/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/length-zero-no-unit'>;\n}\ndeclare module 'stylelint/lib/rules/length-zero-no-unit/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/length-zero-no-unit'>;\n}\ndeclare module 'stylelint/lib/rules/linebreaks/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/linebreaks'>;\n}\ndeclare module 'stylelint/lib/rules/linebreaks/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/linebreaks'>;\n}\ndeclare module 'stylelint/lib/rules/max-empty-lines/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/max-empty-lines'>;\n}\ndeclare module 'stylelint/lib/rules/max-empty-lines/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/max-empty-lines'>;\n}\ndeclare module 'stylelint/lib/rules/max-line-length/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/max-line-length'>;\n}\ndeclare module 'stylelint/lib/rules/max-line-length/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/max-line-length'>;\n}\ndeclare module 'stylelint/lib/rules/max-nesting-depth/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/max-nesting-depth'>;\n}\ndeclare module 'stylelint/lib/rules/max-nesting-depth/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/max-nesting-depth'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-colon-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-colon-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-colon-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-colon-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-colon-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-colon-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-colon-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-colon-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-case'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-case'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-no-unknown/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-no-unknown/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-no-vendor-prefix/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-no-vendor-prefix/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-value-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-value-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-value-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-value-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-name-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-name-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-parentheses-space-inside/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-parentheses-space-inside'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-parentheses-space-inside/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-parentheses-space-inside'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-range-operator-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-range-operator-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-range-operator-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-range-operator-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-range-operator-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-range-operator-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/media-feature-range-operator-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-feature-range-operator-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/media-query-list-comma-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-query-list-comma-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/media-query-list-comma-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-query-list-comma-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/media-query-list-comma-newline-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-query-list-comma-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/media-query-list-comma-newline-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-query-list-comma-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/media-query-list-comma-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-query-list-comma-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/media-query-list-comma-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-query-list-comma-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/media-query-list-comma-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-query-list-comma-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/media-query-list-comma-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/media-query-list-comma-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/mediaFeatureColonSpaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/mediaFeatureColonSpaceChecker'>;\n}\ndeclare module 'stylelint/lib/rules/mediaQueryListCommaWhitespaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/mediaQueryListCommaWhitespaceChecker'>;\n}\ndeclare module 'stylelint/lib/rules/no-descending-specificity/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-descending-specificity'>;\n}\ndeclare module 'stylelint/lib/rules/no-descending-specificity/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-descending-specificity'>;\n}\ndeclare module 'stylelint/lib/rules/no-duplicate-at-import-rules/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-duplicate-at-import-rules'>;\n}\ndeclare module 'stylelint/lib/rules/no-duplicate-at-import-rules/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-duplicate-at-import-rules'>;\n}\ndeclare module 'stylelint/lib/rules/no-duplicate-selectors/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-duplicate-selectors'>;\n}\ndeclare module 'stylelint/lib/rules/no-duplicate-selectors/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-duplicate-selectors'>;\n}\ndeclare module 'stylelint/lib/rules/no-empty-first-line/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-empty-first-line'>;\n}\ndeclare module 'stylelint/lib/rules/no-empty-first-line/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-empty-first-line'>;\n}\ndeclare module 'stylelint/lib/rules/no-empty-source/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-empty-source'>;\n}\ndeclare module 'stylelint/lib/rules/no-empty-source/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-empty-source'>;\n}\ndeclare module 'stylelint/lib/rules/no-eol-whitespace/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-eol-whitespace'>;\n}\ndeclare module 'stylelint/lib/rules/no-eol-whitespace/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-eol-whitespace'>;\n}\ndeclare module 'stylelint/lib/rules/no-extra-semicolons/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-extra-semicolons'>;\n}\ndeclare module 'stylelint/lib/rules/no-extra-semicolons/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-extra-semicolons'>;\n}\ndeclare module 'stylelint/lib/rules/no-invalid-double-slash-comments/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-invalid-double-slash-comments'>;\n}\ndeclare module 'stylelint/lib/rules/no-invalid-double-slash-comments/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-invalid-double-slash-comments'>;\n}\ndeclare module 'stylelint/lib/rules/no-missing-end-of-source-newline/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-missing-end-of-source-newline'>;\n}\ndeclare module 'stylelint/lib/rules/no-missing-end-of-source-newline/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-missing-end-of-source-newline'>;\n}\ndeclare module 'stylelint/lib/rules/no-unknown-animations/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-unknown-animations'>;\n}\ndeclare module 'stylelint/lib/rules/no-unknown-animations/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/no-unknown-animations'>;\n}\ndeclare module 'stylelint/lib/rules/number-leading-zero/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/number-leading-zero'>;\n}\ndeclare module 'stylelint/lib/rules/number-leading-zero/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/number-leading-zero'>;\n}\ndeclare module 'stylelint/lib/rules/number-max-precision/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/number-max-precision'>;\n}\ndeclare module 'stylelint/lib/rules/number-max-precision/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/number-max-precision'>;\n}\ndeclare module 'stylelint/lib/rules/number-no-trailing-zeros/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/number-no-trailing-zeros'>;\n}\ndeclare module 'stylelint/lib/rules/number-no-trailing-zeros/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/number-no-trailing-zeros'>;\n}\ndeclare module 'stylelint/lib/rules/property-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/property-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/property-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-case'>;\n}\ndeclare module 'stylelint/lib/rules/property-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-case'>;\n}\ndeclare module 'stylelint/lib/rules/property-no-unknown/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/property-no-unknown/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/property-no-vendor-prefix/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/property-no-vendor-prefix/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/property-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/property-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/property-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/rule-empty-line-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/rule-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/rule-empty-line-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/rule-empty-line-before'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-brackets-space-inside/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-brackets-space-inside'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-brackets-space-inside/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-brackets-space-inside'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-operator-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-operator-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-operator-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-operator-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-operator-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-operator-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-operator-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-operator-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-operator-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-quotes/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-quotes'>;\n}\ndeclare module 'stylelint/lib/rules/selector-attribute-quotes/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-attribute-quotes'>;\n}\ndeclare module 'stylelint/lib/rules/selector-class-pattern/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-class-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/selector-class-pattern/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-class-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/selector-combinator-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-combinator-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-combinator-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-combinator-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-combinator-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-combinator-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/selector-combinator-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-combinator-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/selector-combinator-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-combinator-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/selector-combinator-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-combinator-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/selector-combinator-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-combinator-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-combinator-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-combinator-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-descendant-combinator-no-non-space/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-descendant-combinator-no-non-space'>;\n}\ndeclare module 'stylelint/lib/rules/selector-descendant-combinator-no-non-space/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-descendant-combinator-no-non-space'>;\n}\ndeclare module 'stylelint/lib/rules/selector-id-pattern/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-id-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/selector-id-pattern/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-id-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/selector-list-comma-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-list-comma-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/selector-list-comma-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-list-comma-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/selector-list-comma-newline-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-list-comma-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/selector-list-comma-newline-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-list-comma-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/selector-list-comma-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-list-comma-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/selector-list-comma-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-list-comma-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/selector-list-comma-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-list-comma-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/selector-list-comma-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-list-comma-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-attribute/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-attribute'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-attribute/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-attribute'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-class/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-class'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-class/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-class'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-combinators/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-combinators'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-combinators/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-combinators'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-compound-selectors/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-compound-selectors'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-compound-selectors/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-compound-selectors'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-empty-lines/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-empty-lines'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-empty-lines/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-empty-lines'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-id/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-id'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-id/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-id'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-pseudo-class/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-pseudo-class'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-pseudo-class/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-pseudo-class'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-specificity/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-specificity'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-specificity/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-specificity'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-type/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-type'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-type/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-type'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-universal/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-universal'>;\n}\ndeclare module 'stylelint/lib/rules/selector-max-universal/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-max-universal'>;\n}\ndeclare module 'stylelint/lib/rules/selector-nested-pattern/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-nested-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/selector-nested-pattern/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-nested-pattern'>;\n}\ndeclare module 'stylelint/lib/rules/selector-no-qualifying-type/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-no-qualifying-type'>;\n}\ndeclare module 'stylelint/lib/rules/selector-no-qualifying-type/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-no-qualifying-type'>;\n}\ndeclare module 'stylelint/lib/rules/selector-no-vendor-prefix/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/selector-no-vendor-prefix/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-case'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-case'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-no-unknown/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-no-unknown/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-parentheses-space-inside/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-parentheses-space-inside'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-parentheses-space-inside/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-parentheses-space-inside'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-class-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-class-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-case'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-case'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-colon-notation/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-colon-notation'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-colon-notation/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-colon-notation'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-no-unknown/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-no-unknown/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-pseudo-element-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-pseudo-element-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/selector-type-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-type-case'>;\n}\ndeclare module 'stylelint/lib/rules/selector-type-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-type-case'>;\n}\ndeclare module 'stylelint/lib/rules/selector-type-no-unknown/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-type-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/selector-type-no-unknown/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selector-type-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/selectorAttributeOperatorSpaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selectorAttributeOperatorSpaceChecker'>;\n}\ndeclare module 'stylelint/lib/rules/selectorCombinatorSpaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selectorCombinatorSpaceChecker'>;\n}\ndeclare module 'stylelint/lib/rules/selectorListCommaWhitespaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/selectorListCommaWhitespaceChecker'>;\n}\ndeclare module 'stylelint/lib/rules/shorthand-property-no-redundant-values/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/shorthand-property-no-redundant-values'>;\n}\ndeclare module 'stylelint/lib/rules/shorthand-property-no-redundant-values/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/shorthand-property-no-redundant-values'>;\n}\ndeclare module 'stylelint/lib/rules/string-no-newline/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/string-no-newline'>;\n}\ndeclare module 'stylelint/lib/rules/string-no-newline/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/string-no-newline'>;\n}\ndeclare module 'stylelint/lib/rules/string-quotes/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/string-quotes'>;\n}\ndeclare module 'stylelint/lib/rules/string-quotes/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/string-quotes'>;\n}\ndeclare module 'stylelint/lib/rules/time-min-milliseconds/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/time-min-milliseconds'>;\n}\ndeclare module 'stylelint/lib/rules/time-min-milliseconds/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/time-min-milliseconds'>;\n}\ndeclare module 'stylelint/lib/rules/unicode-bom/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unicode-bom'>;\n}\ndeclare module 'stylelint/lib/rules/unicode-bom/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unicode-bom'>;\n}\ndeclare module 'stylelint/lib/rules/unit-blacklist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unit-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/unit-blacklist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unit-blacklist'>;\n}\ndeclare module 'stylelint/lib/rules/unit-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unit-case'>;\n}\ndeclare module 'stylelint/lib/rules/unit-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unit-case'>;\n}\ndeclare module 'stylelint/lib/rules/unit-no-unknown/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unit-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/unit-no-unknown/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unit-no-unknown'>;\n}\ndeclare module 'stylelint/lib/rules/unit-whitelist/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unit-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/unit-whitelist/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/unit-whitelist'>;\n}\ndeclare module 'stylelint/lib/rules/value-keyword-case/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-keyword-case'>;\n}\ndeclare module 'stylelint/lib/rules/value-keyword-case/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-keyword-case'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-comma-newline-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-comma-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-comma-newline-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-comma-newline-after'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-comma-newline-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-comma-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-comma-newline-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-comma-newline-before'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-comma-space-after/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-comma-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-comma-space-after/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-comma-space-after'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-comma-space-before/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-comma-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-comma-space-before/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-comma-space-before'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-max-empty-lines/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-max-empty-lines'>;\n}\ndeclare module 'stylelint/lib/rules/value-list-max-empty-lines/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-list-max-empty-lines'>;\n}\ndeclare module 'stylelint/lib/rules/value-no-vendor-prefix/index' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/value-no-vendor-prefix/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/value-no-vendor-prefix'>;\n}\ndeclare module 'stylelint/lib/rules/valueListCommaWhitespaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/rules/valueListCommaWhitespaceChecker'>;\n}\ndeclare module 'stylelint/lib/standalone.js' {\n  declare module.exports: $Exports<'stylelint/lib/standalone'>;\n}\ndeclare module 'stylelint/lib/utils/addEmptyLineAfter.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/addEmptyLineAfter'>;\n}\ndeclare module 'stylelint/lib/utils/addEmptyLineBefore.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/addEmptyLineBefore'>;\n}\ndeclare module 'stylelint/lib/utils/atRuleParamIndex.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/atRuleParamIndex'>;\n}\ndeclare module 'stylelint/lib/utils/beforeBlockString.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/beforeBlockString'>;\n}\ndeclare module 'stylelint/lib/utils/blockString.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/blockString'>;\n}\ndeclare module 'stylelint/lib/utils/blurComments.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/blurComments'>;\n}\ndeclare module 'stylelint/lib/utils/blurFunctionArguments.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/blurFunctionArguments'>;\n}\ndeclare module 'stylelint/lib/utils/blurInterpolation.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/blurInterpolation'>;\n}\ndeclare module 'stylelint/lib/utils/checkAgainstRule.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/checkAgainstRule'>;\n}\ndeclare module 'stylelint/lib/utils/checkInvalidCLIOptions.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/checkInvalidCLIOptions'>;\n}\ndeclare module 'stylelint/lib/utils/configurationError.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/configurationError'>;\n}\ndeclare module 'stylelint/lib/utils/containsString.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/containsString'>;\n}\ndeclare module 'stylelint/lib/utils/declarationValueIndex.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/declarationValueIndex'>;\n}\ndeclare module 'stylelint/lib/utils/eachDeclarationBlock.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/eachDeclarationBlock'>;\n}\ndeclare module 'stylelint/lib/utils/FileCache.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/FileCache'>;\n}\ndeclare module 'stylelint/lib/utils/filterFilePaths.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/filterFilePaths'>;\n}\ndeclare module 'stylelint/lib/utils/findAnimationName.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/findAnimationName'>;\n}\ndeclare module 'stylelint/lib/utils/findAtRuleContext.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/findAtRuleContext'>;\n}\ndeclare module 'stylelint/lib/utils/findFontFamily.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/findFontFamily'>;\n}\ndeclare module 'stylelint/lib/utils/findListStyleType.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/findListStyleType'>;\n}\ndeclare module 'stylelint/lib/utils/functionArgumentsSearch.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/functionArgumentsSearch'>;\n}\ndeclare module 'stylelint/lib/utils/getCacheFile.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/getCacheFile'>;\n}\ndeclare module 'stylelint/lib/utils/getFileIgnorer.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/getFileIgnorer'>;\n}\ndeclare module 'stylelint/lib/utils/getFormatterOptionsText.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/getFormatterOptionsText'>;\n}\ndeclare module 'stylelint/lib/utils/getModulePath.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/getModulePath'>;\n}\ndeclare module 'stylelint/lib/utils/getNextNonSharedLineCommentNode.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/getNextNonSharedLineCommentNode'>;\n}\ndeclare module 'stylelint/lib/utils/getOsEol.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/getOsEol'>;\n}\ndeclare module 'stylelint/lib/utils/getPreviousNonSharedLineCommentNode.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/getPreviousNonSharedLineCommentNode'>;\n}\ndeclare module 'stylelint/lib/utils/getSchemeFromUrl.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/getSchemeFromUrl'>;\n}\ndeclare module 'stylelint/lib/utils/getUnitFromValueNode.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/getUnitFromValueNode'>;\n}\ndeclare module 'stylelint/lib/utils/hasBlock.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/hasBlock'>;\n}\ndeclare module 'stylelint/lib/utils/hasEmptyBlock.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/hasEmptyBlock'>;\n}\ndeclare module 'stylelint/lib/utils/hasEmptyLine.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/hasEmptyLine'>;\n}\ndeclare module 'stylelint/lib/utils/hash.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/hash'>;\n}\ndeclare module 'stylelint/lib/utils/hasInterpolation.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/hasInterpolation'>;\n}\ndeclare module 'stylelint/lib/utils/hasLessInterpolation.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/hasLessInterpolation'>;\n}\ndeclare module 'stylelint/lib/utils/hasPsvInterpolation.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/hasPsvInterpolation'>;\n}\ndeclare module 'stylelint/lib/utils/hasScssInterpolation.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/hasScssInterpolation'>;\n}\ndeclare module 'stylelint/lib/utils/hasTplInterpolation.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/hasTplInterpolation'>;\n}\ndeclare module 'stylelint/lib/utils/isAfterComment.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isAfterComment'>;\n}\ndeclare module 'stylelint/lib/utils/isAfterSingleLineComment.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isAfterSingleLineComment'>;\n}\ndeclare module 'stylelint/lib/utils/isAfterStandardPropertyDeclaration.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isAfterStandardPropertyDeclaration'>;\n}\ndeclare module 'stylelint/lib/utils/isAutoprefixable.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isAutoprefixable'>;\n}\ndeclare module 'stylelint/lib/utils/isBlocklessAtRuleAfterBlocklessAtRule.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isBlocklessAtRuleAfterBlocklessAtRule'>;\n}\ndeclare module 'stylelint/lib/utils/isBlocklessAtRuleAfterSameNameBlocklessAtRule.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isBlocklessAtRuleAfterSameNameBlocklessAtRule'>;\n}\ndeclare module 'stylelint/lib/utils/isCounterIncrementCustomIdentValue.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isCounterIncrementCustomIdentValue'>;\n}\ndeclare module 'stylelint/lib/utils/isCounterResetCustomIdentValue.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isCounterResetCustomIdentValue'>;\n}\ndeclare module 'stylelint/lib/utils/isCustomElement.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isCustomElement'>;\n}\ndeclare module 'stylelint/lib/utils/isCustomMediaQuery.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isCustomMediaQuery'>;\n}\ndeclare module 'stylelint/lib/utils/isCustomProperty.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isCustomProperty'>;\n}\ndeclare module 'stylelint/lib/utils/isCustomPropertySet.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isCustomPropertySet'>;\n}\ndeclare module 'stylelint/lib/utils/isCustomSelector.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isCustomSelector'>;\n}\ndeclare module 'stylelint/lib/utils/isFirstNested.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isFirstNested'>;\n}\ndeclare module 'stylelint/lib/utils/isFirstNodeOfRoot.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isFirstNodeOfRoot'>;\n}\ndeclare module 'stylelint/lib/utils/isKeyframeRule.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isKeyframeRule'>;\n}\ndeclare module 'stylelint/lib/utils/isKeyframeSelector.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isKeyframeSelector'>;\n}\ndeclare module 'stylelint/lib/utils/isLessVariable.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isLessVariable'>;\n}\ndeclare module 'stylelint/lib/utils/isLogicalCombination.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isLogicalCombination'>;\n}\ndeclare module 'stylelint/lib/utils/isMap.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isMap'>;\n}\ndeclare module 'stylelint/lib/utils/isMathFunction.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isMathFunction'>;\n}\ndeclare module 'stylelint/lib/utils/isNumbery.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isNumbery'>;\n}\ndeclare module 'stylelint/lib/utils/isOnlyWhitespace.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isOnlyWhitespace'>;\n}\ndeclare module 'stylelint/lib/utils/isRangeContextMediaFeature.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isRangeContextMediaFeature'>;\n}\ndeclare module 'stylelint/lib/utils/isSharedLineComment.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isSharedLineComment'>;\n}\ndeclare module 'stylelint/lib/utils/isSingleLineString.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isSingleLineString'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxAtRule.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxAtRule'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxCombinator.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxCombinator'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxDeclaration.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxDeclaration'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxFunction.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxFunction'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxMediaFeature.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxMediaFeature'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxMediaFeatureName.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxMediaFeatureName'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxProperty.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxProperty'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxRule.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxRule'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxSelector.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxSelector'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxTypeSelector.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxTypeSelector'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxUrl.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxUrl'>;\n}\ndeclare module 'stylelint/lib/utils/isStandardSyntaxValue.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isStandardSyntaxValue'>;\n}\ndeclare module 'stylelint/lib/utils/isValidFontSize.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isValidFontSize'>;\n}\ndeclare module 'stylelint/lib/utils/isValidHex.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isValidHex'>;\n}\ndeclare module 'stylelint/lib/utils/isVariable.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isVariable'>;\n}\ndeclare module 'stylelint/lib/utils/isWhitespace.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/isWhitespace'>;\n}\ndeclare module 'stylelint/lib/utils/matchesStringOrRegExp.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/matchesStringOrRegExp'>;\n}\ndeclare module 'stylelint/lib/utils/nextNonCommentNode.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/nextNonCommentNode'>;\n}\ndeclare module 'stylelint/lib/utils/nodeContextLookup.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/nodeContextLookup'>;\n}\ndeclare module 'stylelint/lib/utils/noFilesFoundError.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/noFilesFoundError'>;\n}\ndeclare module 'stylelint/lib/utils/optionsMatches.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/optionsMatches'>;\n}\ndeclare module 'stylelint/lib/utils/parseCalcExpression/index' {\n  declare module.exports: $Exports<'stylelint/lib/utils/parseCalcExpression'>;\n}\ndeclare module 'stylelint/lib/utils/parseCalcExpression/index.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/parseCalcExpression'>;\n}\ndeclare module 'stylelint/lib/utils/parseCalcExpression/parser.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/parseCalcExpression/parser'>;\n}\ndeclare module 'stylelint/lib/utils/parseSelector.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/parseSelector'>;\n}\ndeclare module 'stylelint/lib/utils/rawNodeString.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/rawNodeString'>;\n}\ndeclare module 'stylelint/lib/utils/removeEmptyLinesAfter.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/removeEmptyLinesAfter'>;\n}\ndeclare module 'stylelint/lib/utils/removeEmptyLinesBefore.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/removeEmptyLinesBefore'>;\n}\ndeclare module 'stylelint/lib/utils/report.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/report'>;\n}\ndeclare module 'stylelint/lib/utils/ruleMessages.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/ruleMessages'>;\n}\ndeclare module 'stylelint/lib/utils/transformSelector.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/transformSelector'>;\n}\ndeclare module 'stylelint/lib/utils/typeGuards.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/typeGuards'>;\n}\ndeclare module 'stylelint/lib/utils/validateObjectWithArrayProps.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/validateObjectWithArrayProps'>;\n}\ndeclare module 'stylelint/lib/utils/validateOptions.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/validateOptions'>;\n}\ndeclare module 'stylelint/lib/utils/whitespaceChecker.js' {\n  declare module.exports: $Exports<'stylelint/lib/utils/whitespaceChecker'>;\n}\ndeclare module 'stylelint/lib/writeOutputFile.js' {\n  declare module.exports: $Exports<'stylelint/lib/writeOutputFile'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/wait-port_vx.x.x.js",
    "content": "// flow-typed signature: 0601d74e6ea494c18446643c47a59c83\n// flow-typed version: <<STUB>>/wait-port_v^0.2.7/flow_v0.110.1\n\n/**\n * This is an autogenerated libdef stub for:\n *\n *   'wait-port'\n *\n * Fill this stub out by replacing all the `any` types.\n *\n * Once filled out, we encourage you to share your work with the\n * community by sending a pull request to:\n * https://github.com/flowtype/flow-typed\n */\n\ndeclare module 'wait-port' {\n  declare module.exports: any;\n}\n\n/**\n * We include stubs for each file inside this npm package in case you need to\n * require those files directly. Feel free to delete any files that aren't\n * needed.\n */\ndeclare module 'wait-port/bin/wait-port' {\n  declare module.exports: any;\n}\n\ndeclare module 'wait-port/lib/errors/connection-error' {\n  declare module.exports: any;\n}\n\ndeclare module 'wait-port/lib/errors/target-error' {\n  declare module.exports: any;\n}\n\ndeclare module 'wait-port/lib/errors/validation-error' {\n  declare module.exports: any;\n}\n\ndeclare module 'wait-port/lib/extract-target' {\n  declare module.exports: any;\n}\n\ndeclare module 'wait-port/lib/output-functions/dots' {\n  declare module.exports: any;\n}\n\ndeclare module 'wait-port/lib/output-functions' {\n  declare module.exports: any;\n}\n\ndeclare module 'wait-port/lib/output-functions/silent' {\n  declare module.exports: any;\n}\n\ndeclare module 'wait-port/lib/validate-parameters' {\n  declare module.exports: any;\n}\n\ndeclare module 'wait-port/lib/wait-port' {\n  declare module.exports: any;\n}\n\n// Filename aliases\ndeclare module 'wait-port/bin/wait-port.js' {\n  declare module.exports: $Exports<'wait-port/bin/wait-port'>;\n}\ndeclare module 'wait-port/lib/errors/connection-error.js' {\n  declare module.exports: $Exports<'wait-port/lib/errors/connection-error'>;\n}\ndeclare module 'wait-port/lib/errors/target-error.js' {\n  declare module.exports: $Exports<'wait-port/lib/errors/target-error'>;\n}\ndeclare module 'wait-port/lib/errors/validation-error.js' {\n  declare module.exports: $Exports<'wait-port/lib/errors/validation-error'>;\n}\ndeclare module 'wait-port/lib/extract-target.js' {\n  declare module.exports: $Exports<'wait-port/lib/extract-target'>;\n}\ndeclare module 'wait-port/lib/output-functions/dots.js' {\n  declare module.exports: $Exports<'wait-port/lib/output-functions/dots'>;\n}\ndeclare module 'wait-port/lib/output-functions/index' {\n  declare module.exports: $Exports<'wait-port/lib/output-functions'>;\n}\ndeclare module 'wait-port/lib/output-functions/index.js' {\n  declare module.exports: $Exports<'wait-port/lib/output-functions'>;\n}\ndeclare module 'wait-port/lib/output-functions/silent.js' {\n  declare module.exports: $Exports<'wait-port/lib/output-functions/silent'>;\n}\ndeclare module 'wait-port/lib/validate-parameters.js' {\n  declare module.exports: $Exports<'wait-port/lib/validate-parameters'>;\n}\ndeclare module 'wait-port/lib/wait-port.js' {\n  declare module.exports: $Exports<'wait-port/lib/wait-port'>;\n}\n"
  },
  {
    "path": "flow-typed/npm/webpack_v4.x.x.js",
    "content": "// flow-typed signature: a11323c6900f44e506402540d33781c2\n// flow-typed version: 7448070196/webpack_v4.x.x/flow_>=v0.104.x\n\nimport * as http from 'http';\nimport fs from 'fs';\n\ndeclare module 'webpack' {\n  declare class $WebpackError extends Error {\n    constructor(message: string): WebpackError;\n    inspect(): string;\n    details: string;\n  }\n\n  declare type WebpackError = $WebpackError;\n\n  declare interface Stats {\n    hasErrors(): boolean;\n    hasWarnings(): boolean;\n    toJson(options?: StatsOptions): any;\n    toString(options?: { ...StatsOptions, colors?: boolean, ... }): string;\n  }\n\n  declare type Callback = (error: WebpackError, stats: Stats) => void;\n  declare type WatchHandler = (error: WebpackError, stats: Stats) => void;\n\n  declare type Watching = {\n    close(): void,\n    invalidate(): void,\n    ...\n  };\n\n  declare type WebpackCompiler = {\n    run(callback: Callback): void,\n    watch(options: WatchOptions, handler: WatchHandler): Watching,\n    ...\n  };\n\n  declare type WebpackMultiCompiler = {\n    run(callback: Callback): void,\n    watch(options: WatchOptions, handler: WatchHandler): Watching,\n    ...\n  };\n\n  declare class WebpackCompilation {\n    constructor(compiler: WebpackCompiler): WebpackCompilation;\n    // <...>\n  }\n\n  declare class WebpackStats {\n    constructor(compilation: WebpackCompilation): WebpackStats;\n    // <...>\n  }\n\n  declare type NonEmptyArrayOfUniqueStringValues = Array<string>;\n\n  declare type EntryObject = { [k: string]: string | NonEmptyArrayOfUniqueStringValues, ... };\n\n  declare type EntryItem = string | NonEmptyArrayOfUniqueStringValues;\n\n  declare type EntryStatic = EntryObject | EntryItem;\n\n  declare type EntryDynamic = () => EntryStatic | Promise<EntryStatic>;\n\n  declare type Entry = EntryDynamic | EntryStatic;\n\n  declare type ArrayOfStringValues = Array<string>;\n\n  declare type ExternalItem =\n    | string\n    | { [k: string]:\n    | string\n    | { [k: string]: any, ... }\n    | ArrayOfStringValues\n    | boolean, ... }\n    | RegExp;\n\n  declare type Externals =\n    | ((\n        context: string,\n        request: string,\n        callback: (err?: Error, result?: string) => void\n      ) => void)\n    | ExternalItem\n    | Array<\n        | ((\n            context: string,\n            request: string,\n            callback: (err?: Error, result?: string) => void\n          ) => void)\n        | ExternalItem\n      >;\n\n  declare type RuleSetCondition =\n    | RegExp\n    | string\n    | ((value: string) => boolean)\n    | RuleSetConditions\n    | {\n    and?: RuleSetConditions,\n    exclude?: RuleSetConditionOrConditions,\n    include?: RuleSetConditionOrConditions,\n    not?: RuleSetConditions,\n    or?: RuleSetConditions,\n    test?: RuleSetConditionOrConditions,\n    ...\n  };\n\n  declare type RuleSetConditions = Array<RuleSetCondition>;\n\n  declare type RuleSetConditionOrConditions =\n    | RuleSetCondition\n    | RuleSetConditions;\n\n  declare type RuleSetLoader = string;\n\n  declare type RuleSetQuery = { [k: string]: any, ... } | string;\n\n  declare type RuleSetUseItem =\n    | RuleSetLoader\n    | Function\n    | {\n    ident?: string,\n    loader?: RuleSetLoader,\n    options?: RuleSetQuery,\n    query?: RuleSetQuery,\n    ...\n  };\n\n  declare type RuleSetUse = RuleSetUseItem | Function | Array<RuleSetUseItem>;\n\n  declare type RuleSetRule = {\n    compiler?: RuleSetConditionOrConditions,\n    enforce?: 'pre' | 'post',\n    exclude?: RuleSetConditionOrConditions,\n    include?: RuleSetConditionOrConditions,\n    issuer?: RuleSetConditionOrConditions,\n    loader?: RuleSetLoader | RuleSetUse,\n    loaders?: RuleSetUse,\n    oneOf?: RuleSetRules,\n    options?: RuleSetQuery,\n    parser?: { [k: string]: any, ... },\n    query?: RuleSetQuery,\n    resolve?: ResolveOptions,\n    resource?: RuleSetConditionOrConditions,\n    resourceQuery?: RuleSetConditionOrConditions,\n    rules?: RuleSetRules,\n    sideEffects?: boolean,\n    test?: RuleSetConditionOrConditions,\n    type?:\n      | 'javascript/auto'\n      | 'javascript/dynamic'\n      | 'javascript/esm'\n      | 'json'\n      | 'webassembly/experimental',\n    use?: RuleSetUse,\n    ...\n  };\n\n  declare type RuleSetRules = Array<RuleSetRule>;\n\n  declare type ModuleOptions = {\n    defaultRules?: RuleSetRules,\n    exprContextCritical?: boolean,\n    exprContextRecursive?: boolean,\n    exprContextRegExp?: boolean | RegExp,\n    exprContextRequest?: string,\n    noParse?: Array<RegExp> | RegExp | Function | Array<string> | string,\n    rules?: RuleSetRules,\n    strictExportPresence?: boolean,\n    strictThisContextOnImports?: boolean,\n    unknownContextCritical?: boolean,\n    unknownContextRecursive?: boolean,\n    unknownContextRegExp?: boolean | RegExp,\n    unknownContextRequest?: string,\n    unsafeCache?: boolean | Function,\n    wrappedContextCritical?: boolean,\n    wrappedContextRecursive?: boolean,\n    wrappedContextRegExp?: RegExp,\n    ...\n  };\n\n  declare type NodeOptions = {\n    [k: string]: false | true | 'mock' | 'empty',\n    Buffer?: false | true | 'mock',\n    __dirname?: false | true | 'mock',\n    __filename?: false | true | 'mock',\n    console?: false | true | 'mock',\n    global?: boolean,\n    process?: false | true | 'mock',\n    ...\n  };\n\n  declare type WebpackPluginFunction = (compiler: WebpackCompiler) => void;\n\n  declare type WebpackPluginInstance = {\n    [k: string]: any,\n    apply: WebpackPluginFunction,\n    ...\n  };\n\n  declare type OptimizationSplitChunksOptions = {\n    automaticNameDelimiter?: string,\n    cacheGroups?: { [k: string]:\n      | false\n      | Function\n      | string\n      | RegExp\n      | {\n      automaticNameDelimiter?: string,\n      automaticNamePrefix?: string,\n      chunks?: ('initial' | 'async' | 'all') | Function,\n      enforce?: boolean,\n      filename?: string,\n      maxAsyncRequests?: number,\n      maxInitialRequests?: number,\n      maxSize?: number,\n      minChunks?: number,\n      minSize?: number,\n      name?: boolean | Function | string,\n      priority?: number,\n      reuseExistingChunk?: boolean,\n      test?: Function | string | RegExp,\n      ...\n    }, ... },\n    chunks?: ('initial' | 'async' | 'all') | Function,\n    fallbackCacheGroup?: {\n      automaticNameDelimiter?: string,\n      maxSize?: number,\n      minSize?: number,\n      ...\n    },\n    filename?: string,\n    hidePathInfo?: boolean,\n    maxAsyncRequests?: number,\n    maxInitialRequests?: number,\n    maxSize?: number,\n    minChunks?: number,\n    minSize?: number,\n    name?: boolean | Function | string,\n    ...\n  };\n\n  declare type OptimizationOptions = {\n    checkWasmTypes?: boolean,\n    chunkIds?: 'natural' | 'named' | 'size' | 'total-size' | false,\n    concatenateModules?: boolean,\n    flagIncludedChunks?: boolean,\n    hashedModuleIds?: boolean,\n    mangleWasmImports?: boolean,\n    mergeDuplicateChunks?: boolean,\n    minimize?: boolean,\n    minimizer?: Array<WebpackPluginInstance | WebpackPluginFunction>,\n    moduleIds?: 'natural' | 'named' | 'hashed' | 'size' | 'total-size' | false,\n    namedChunks?: boolean,\n    namedModules?: boolean,\n    noEmitOnErrors?: boolean,\n    nodeEnv?: false | string,\n    occurrenceOrder?: boolean,\n    portableRecords?: boolean,\n    providedExports?: boolean,\n    removeAvailableModules?: boolean,\n    removeEmptyChunks?: boolean,\n    runtimeChunk?:\n      | boolean\n      | ('single' | 'multiple')\n      | { name?: string | Function, ... },\n    sideEffects?: boolean,\n    splitChunks?: false | OptimizationSplitChunksOptions,\n    usedExports?: boolean,\n    ...\n  };\n\n  declare type LibraryCustomUmdObject = {\n    amd?: string,\n    commonjs?: string,\n    root?: string | ArrayOfStringValues,\n    ...\n  };\n\n  declare type OutputOptions = {\n    auxiliaryComment?:\n      | string\n      | {\n      amd?: string,\n      commonjs?: string,\n      commonjs2?: string,\n      root?: string,\n      ...\n    },\n    chunkCallbackName?: string,\n    chunkFilename?: string,\n    chunkLoadTimeout?: number,\n    crossOriginLoading?: false | 'anonymous' | 'use-credentials',\n    devtoolFallbackModuleFilenameTemplate?: string | Function,\n    devtoolLineToLine?: boolean | { [k: string]: any, ... },\n    devtoolModuleFilenameTemplate?: string | Function,\n    devtoolNamespace?: string,\n    filename?: string | Function,\n    globalObject?: string,\n    hashDigest?: string,\n    hashDigestLength?: number,\n    hashFunction?: string | Function,\n    hashSalt?: string,\n    hotUpdateChunkFilename?: string | Function,\n    hotUpdateFunction?: string,\n    hotUpdateMainFilename?: string | Function,\n    jsonpFunction?: string,\n    jsonpScriptType?: false | 'text/javascript' | 'module',\n    library?: string | Array<string> | LibraryCustomUmdObject,\n    libraryExport?: string | ArrayOfStringValues,\n    libraryTarget?:\n      | 'var'\n      | 'assign'\n      | 'this'\n      | 'window'\n      | 'self'\n      | 'global'\n      | 'commonjs'\n      | 'commonjs2'\n      | 'commonjs-module'\n      | 'amd'\n      | 'amd-require'\n      | 'umd'\n      | 'umd2'\n      | 'jsonp',\n    path?: string,\n    pathinfo?: boolean,\n    publicPath?: string | Function,\n    sourceMapFilename?: string,\n    sourcePrefix?: string,\n    strictModuleExceptionHandling?: boolean,\n    umdNamedDefine?: boolean,\n    webassemblyModuleFilename?: string,\n    ...\n  };\n\n  declare type PerformanceOptions = {\n    assetFilter?: Function,\n    hints?: false | 'warning' | 'error',\n    maxAssetSize?: number,\n    maxEntrypointSize?: number,\n    ...\n  };\n\n  declare type ArrayOfStringOrStringArrayValues = Array<string | Array<string>>;\n\n  declare type ResolveOptions = {\n    alias?:\n      | { [k: string]: string, ... }\n      | Array<{\n      alias?: string,\n      name?: string,\n      onlyModule?: boolean,\n      ...\n    }>,\n    aliasFields?: ArrayOfStringOrStringArrayValues,\n    cachePredicate?: Function,\n    cacheWithContext?: boolean,\n    concord?: boolean,\n    descriptionFiles?: ArrayOfStringValues,\n    enforceExtension?: boolean,\n    enforceModuleExtension?: boolean,\n    extensions?: ArrayOfStringValues,\n    fileSystem?: { [k: string]: any, ... },\n    mainFields?: ArrayOfStringOrStringArrayValues,\n    mainFiles?: ArrayOfStringValues,\n    moduleExtensions?: ArrayOfStringValues,\n    modules?: ArrayOfStringValues,\n    plugins?: Array<WebpackPluginInstance | WebpackPluginFunction>,\n    resolver?: { [k: string]: any, ... },\n    symlinks?: boolean,\n    unsafeCache?: boolean | { [k: string]: any, ... },\n    useSyncFileSystemCalls?: boolean,\n    ...\n  };\n\n  declare type FilterItemTypes = RegExp | string | Function;\n\n  declare type FilterTypes = FilterItemTypes | Array<FilterItemTypes>;\n\n  declare type StatsOptions =\n    | boolean\n    | ('none' | 'errors-only' | 'minimal' | 'normal' | 'detailed' | 'verbose')\n    | {\n    all?: boolean,\n    assets?: boolean,\n    assetsSort?: string,\n    builtAt?: boolean,\n    cached?: boolean,\n    cachedAssets?: boolean,\n    children?: boolean,\n    chunkGroups?: boolean,\n    chunkModules?: boolean,\n    chunkOrigins?: boolean,\n    chunks?: boolean,\n    chunksSort?: string,\n    colors?:\n      | boolean\n      | {\n      bold?: string,\n      cyan?: string,\n      green?: string,\n      magenta?: string,\n      red?: string,\n      yellow?: string,\n      ...\n    },\n    context?: string,\n    depth?: boolean,\n    entrypoints?: boolean,\n    env?: boolean,\n    errorDetails?: boolean,\n    errors?: boolean,\n    exclude?: FilterTypes | boolean,\n    excludeAssets?: FilterTypes,\n    excludeModules?: FilterTypes | boolean,\n    hash?: boolean,\n    maxModules?: number,\n    moduleAssets?: boolean,\n    moduleTrace?: boolean,\n    modules?: boolean,\n    modulesSort?: string,\n    nestedModules?: boolean,\n    optimizationBailout?: boolean,\n    outputPath?: boolean,\n    performance?: boolean,\n    providedExports?: boolean,\n    publicPath?: boolean,\n    reasons?: boolean,\n    source?: boolean,\n    timings?: boolean,\n    usedExports?: boolean,\n    version?: boolean,\n    warnings?: boolean,\n    warningsFilter?: FilterTypes,\n    ...\n  };\n\n  declare type WatchOptions = {\n    aggregateTimeout?: number,\n    ignored?: { [k: string]: any, ... },\n    poll?: boolean | number,\n    stdin?: boolean,\n    ...\n  };\n\n  declare type WebpackOptions = {\n    amd?: { [k: string]: any, ... },\n    bail?: boolean,\n    cache?: boolean | { [k: string]: any, ... },\n    context?: string,\n    dependencies?: Array<string>,\n    devServer?: {\n      after?: (app: any, server: http.Server) => void,\n      allowedHosts?: string[],\n      before?: (app: any, server: http.Server) => void,\n      bonjour?: boolean,\n      clientLogLevel?: 'none' | 'info' | 'error' | 'warning',\n      compress?: boolean,\n      contentBase?: false | string | string[] | number,\n      disableHostCheck?: boolean,\n      filename?: string,\n      headers?: { [key: string]: string, ... },\n      historyApiFallback?:\n        | boolean\n        | {\n        rewrites?: Array<{\n          from: string,\n          to: string,\n          ...\n        }>,\n        disableDotRule?: boolean,\n        ...\n      },\n      host?: string,\n      hot?: boolean,\n      hotOnly?: boolean,\n      https?:\n        | boolean\n        | {\n        key: string,\n        cert: string,\n        ca?: string,\n        ...\n      },\n      index?: string,\n      inline?: boolean,\n      lazy?: boolean,\n      noInfo?: boolean,\n      open?: boolean | string,\n      openPage?: string,\n      overlay?:\n        | boolean\n        | {\n        errors?: boolean,\n        warnings?: boolean,\n        ...\n      },\n      pfx?: string,\n      pfxPassphrase?: string,\n      port?: number,\n      proxy?: Object | Array<Object | Function>,\n      public?: string,\n      publicPath?: string,\n      quiet?: boolean,\n      socket?: string,\n      staticOptions?: {\n        dotfiles?: string,\n        etag?: boolean,\n        extensions?: false | string[],\n        fallthrough?: boolean,\n        immutable?: boolean,\n        index?: false | string,\n        lastModified?: boolean,\n        maxAge?: number,\n        redirect?: boolean,\n        setHeaders?: (\n          res: http.OutgoingMessage,\n          path: string,\n          stat: fs.Stat\n        ) => void,\n        ...\n      },\n      stats?: StatsOptions,\n      useLocalIp?: boolean,\n      watchContentBase?: boolean,\n      watchOptions?: WatchOptions,\n      publicPath?: string,\n      ...\n    },\n    devtool?:\n      | '@cheap-eval-source-map'\n      | '@cheap-module-eval-source-map'\n      | '@cheap-module-source-map'\n      | '@cheap-source-map'\n      | '@eval-source-map'\n      | '@eval'\n      | '@hidden-source-map'\n      | '@inline-source-map'\n      | '@nosources-source-map'\n      | '@source-map'\n      | '#@cheap-eval-source-map'\n      | '#@cheap-module-eval-source-map'\n      | '#@cheap-module-source-map'\n      | '#@cheap-source-map'\n      | '#@eval-source-map'\n      | '#@eval'\n      | '#@hidden-source-map'\n      | '#@inline-source-map'\n      | '#@nosources-source-map'\n      | '#@source-map'\n      | '#cheap-eval-source-map'\n      | '#cheap-module-eval-source-map'\n      | '#cheap-module-source-map'\n      | '#cheap-source-map'\n      | '#eval-source-map'\n      | '#eval'\n      | '#hidden-source-map'\n      | '#inline-source-map'\n      | '#nosources-source-map'\n      | '#source-map'\n      | 'cheap-eval-source-map'\n      | 'cheap-module-eval-source-map'\n      | 'cheap-module-source-map'\n      | 'cheap-source-map'\n      | 'eval-source-map'\n      | 'eval'\n      | 'hidden-source-map'\n      | 'inline-source-map'\n      | 'nosources-source-map'\n      | 'source-map'\n      | false,\n    entry?: Entry,\n    externals?: Externals,\n    loader?: { [k: string]: any, ... },\n    mode?: 'development' | 'production' | 'none',\n    module?: ModuleOptions,\n    name?: string,\n    node?: false | NodeOptions,\n    optimization?: OptimizationOptions,\n    output?: OutputOptions,\n    parallelism?: number,\n    performance?: false | PerformanceOptions,\n    plugins?: Array<WebpackPluginInstance | WebpackPluginFunction>,\n    profile?: boolean,\n    recordsInputPath?: string,\n    recordsOutputPath?: string,\n    recordsPath?: string,\n    resolve?: ResolveOptions,\n    resolveLoader?: ResolveOptions,\n    serve?: { [k: string]: any, ... },\n    stats?: StatsOptions,\n    target?:\n      | 'web'\n      | 'webworker'\n      | 'node'\n      | 'async-node'\n      | 'node-webkit'\n      | 'electron-main'\n      | 'electron-renderer'\n      | ((compiler: WebpackCompiler) => void),\n    watch?: boolean,\n    watchOptions?: WatchOptions,\n    ...\n  };\n\n  declare class EnvironmentPlugin {\n    constructor(env: { [string]: mixed, ... } | string[]): $ElementType<\n      $NonMaybeType<$PropertyType<ResolveOptions, 'plugins'>>,\n      number\n    >;\n  }\n\n  declare class DefinePlugin {\n    constructor({ [string]: string, ... }): $ElementType<\n      $NonMaybeType<$PropertyType<ResolveOptions, 'plugins'>>,\n      number\n    >;\n  }\n\n  declare class IgnorePlugin {\n    constructor(RegExp | {|\n      resourceRegExp: RegExp,\n      contextRegExp?: RegExp,\n    |}, void | RegExp): $ElementType<\n      $NonMaybeType<$PropertyType<ResolveOptions, 'plugins'>>,\n      number\n    >;\n  }\n\n  declare class SourceMapDevToolPlugin {\n    constructor({|\n      test?: ?(string | RegExp | Array<string | RegExp>),\n      include?: ?(string | RegExp | Array<string | RegExp>),\n      exclude?: ?(string | RegExp | Array<string | RegExp>),\n      filename?: ?string,\n      append?: ?(string | false),\n      moduleFilenameTemplate?: ?string,\n      fallbackModuleFilenameTemplate?: ?string,\n      namespace?: ?string,\n      module?: ?boolean,\n      columns?: ?boolean,\n      lineToLine?: ?(boolean | {|\n        test?: ?(string | RegExp | Array<string | RegExp>),\n        include?: ?(string | RegExp | Array<string | RegExp>),\n        exclude?: ?(string | RegExp | Array<string | RegExp>),\n      |}),\n      noSources?: ?boolean,\n      publicPath?: ?string,\n      fileContext?: ?string,\n    |}): $ElementType<\n      $NonMaybeType<$PropertyType<ResolveOptions, 'plugins'>>,\n      number\n    >;\n  }\n\n  declare class HotModuleReplacementPlugin {\n    constructor(): $ElementType<\n      $NonMaybeType<$PropertyType<ResolveOptions, 'plugins'>>,\n      number\n    >;\n  }\n\n  declare class ContextReplacementPlugin {\n    constructor(\n      resourceRegExp: RegExp,\n      newContentRegExp?: RegExp\n    ): $ElementType<\n      $NonMaybeType<$PropertyType<ResolveOptions, 'plugins'>>,\n      number\n    >;\n  }\n\n  declare function builder(\n    options: WebpackOptions,\n    callback?: Callback\n  ): WebpackCompiler;\n  declare function builder(\n    options: WebpackOptions[],\n    callback?: Callback\n  ): WebpackMultiCompiler;\n\n  declare module.exports: typeof builder & {\n    EnvironmentPlugin: typeof EnvironmentPlugin,\n    DefinePlugin: typeof DefinePlugin,\n    IgnorePlugin: typeof IgnorePlugin,\n    SourceMapDevToolPlugin: typeof SourceMapDevToolPlugin,\n    HotModuleReplacementPlugin: typeof HotModuleReplacementPlugin,\n    ContextReplacementPlugin: typeof ContextReplacementPlugin,\n    ...\n  };\n}\n"
  },
  {
    "path": "jest.config.js",
    "content": "/* eslint-disable flowtype/require-valid-file-annotation */\n\nmodule.exports = {\n  setupFiles: [\n    // for some painful reason this is needed for our 'async' usage\n    // in drop-dev-warnings-for-prod.spec.js\n    require.resolve('regenerator-runtime/runtime'),\n    './test/env-setup.js',\n  ],\n  setupFilesAfterEnv: ['./test/test-setup.js'],\n  // node_modules is default.\n  testPathIgnorePatterns: ['/node_modules/', '/cypress/'],\n  modulePathIgnorePatterns: ['/dist/'],\n  watchPlugins: [\n    'jest-watch-typeahead/filename',\n    'jest-watch-typeahead/testname',\n  ],\n  verbose: true,\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-beautiful-dnd\",\n  \"version\": \"13.1.1\",\n  \"description\": \"Beautiful and accessible drag and drop for lists with React\",\n  \"author\": \"Alex Reardon <areardon@atlassian.com>\",\n  \"keywords\": [\n    \"drag and drop\",\n    \"dnd\",\n    \"sortable\",\n    \"reorder\",\n    \"reorderable\",\n    \"react\",\n    \"react.js\",\n    \"natural\",\n    \"beautiful\",\n    \"accessible\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/atlassian/react-beautiful-dnd.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/atlassian/react-beautiful-dnd/issues\"\n  },\n  \"main\": \"dist/react-beautiful-dnd.cjs.js\",\n  \"module\": \"dist/react-beautiful-dnd.esm.js\",\n  \"sideEffects\": false,\n  \"files\": [\n    \"/dist\",\n    \"/src\"\n  ],\n  \"config\": {\n    \"prettier_target\": \"*.{js,jsx,md,json} src/**/*.{js,jsx,md,json} test/**/*.{js,jsx,md,json} docs/**/*.{js,jsx,md,json} stories/**/*.{js,jsx,md,json} cypress/**/*.{js,jsx,md,json} csp-server/**/*.{js,jsx,md,json}\"\n  },\n  \"scripts\": {\n    \"test:accessibility\": \"lighthouse http://localhost:9002/iframe.html?id=single-vertical-list--basic --chrome-flags='--headless' --output=json --startServerReadyTimeout=60000 --output-path=./test-reports/lighthouse/a11y.json && node a11y-audit-parse.js\",\n    \"test\": \"jest --config ./jest.config.js\",\n    \"test:ci\": \"jest test --maxWorkers=2\",\n    \"test:browser\": \"cypress open\",\n    \"test:browser:ci\": \"cypress run\",\n    \"test:coverage\": \"yarn test --coverage --coveragePathIgnorePatterns=/debug\",\n    \"validate\": \"yarn prettier:check && yarn lint:eslint && yarn lint:css && yarn typecheck\",\n    \"prettier:check\": \"yarn prettier --debug-check $npm_package_config_prettier_target\",\n    \"prettier:write\": \"yarn prettier --write $npm_package_config_prettier_target\",\n    \"lint:eslint\": \"yarn eslint \\\"./**/*.{js,jsx}\\\"\",\n    \"lint:css\": \"stylelint \\\"stories/**/*.{js,jsx}\\\"\",\n    \"typecheck\": \"flow check --max-warnings=0\",\n    \"bundle-size:check\": \"cross-env SNAPSHOT=match yarn bundle-size:update\",\n    \"bundle-size:update\": \"yarn build:clean && yarn build:dist && yarn build:clean\",\n    \"build\": \"yarn build:clean && yarn build:dist && yarn build:flow\",\n    \"build:clean\": \"rimraf dist\",\n    \"build:dist\": \"rollup -c\",\n    \"build:flow\": \"echo \\\"// @flow\\n\\nexport * from '../src';\\\" > dist/react-beautiful-dnd.cjs.js.flow\",\n    \"storybook\": \"start-storybook -p 9002\",\n    \"build-storybook\": \"build-storybook -c .storybook -o site\",\n    \"prepublishOnly\": \"yarn build\"\n  },\n  \"dependencies\": {\n    \"@babel/runtime\": \"^7.9.2\",\n    \"css-box-model\": \"^1.2.0\",\n    \"memoize-one\": \"^5.1.1\",\n    \"raf-schd\": \"^4.0.2\",\n    \"react-redux\": \"^7.2.0\",\n    \"redux\": \"^4.0.4\",\n    \"use-memo-one\": \"^1.1.1\"\n  },\n  \"devDependencies\": {\n    \"@atlaskit/css-reset\": \"5.0.12\",\n    \"@atlaskit/theme\": \"9.5.6\",\n    \"@babel/core\": \"7.9.0\",\n    \"@babel/plugin-proposal-class-properties\": \"7.8.3\",\n    \"@babel/plugin-transform-modules-commonjs\": \"7.9.0\",\n    \"@babel/plugin-transform-object-assign\": \"7.8.3\",\n    \"@babel/plugin-transform-runtime\": \"7.9.0\",\n    \"@babel/preset-env\": \"7.9.5\",\n    \"@babel/preset-flow\": \"7.9.0\",\n    \"@babel/preset-react\": \"7.9.4\",\n    \"@emotion/babel-preset-css-prop\": \"10.0.27\",\n    \"@emotion/core\": \"10.0.28\",\n    \"@emotion/styled\": \"10.0.27\",\n    \"@storybook/addon-storysource\": \"5.3.21\",\n    \"@storybook/react\": \"5.3.21\",\n    \"@storybook/theming\": \"5.3.21\",\n    \"@testing-library/react\": \"10.4.9\",\n    \"babel-core\": \"7.0.0-bridge.0\",\n    \"babel-eslint\": \"10.1.0\",\n    \"babel-jest\": \"25.5.1\",\n    \"babel-loader\": \"8.1.0\",\n    \"babel-plugin-dev-expression\": \"0.2.2\",\n    \"babel-plugin-emotion\": \"10.0.33\",\n    \"cross-env\": \"7.0.3\",\n    \"cypress\": \"4.4.0\",\n    \"emotion-theming\": \"10.0.27\",\n    \"enzyme\": \"3.11.0\",\n    \"enzyme-adapter-react-16\": \"1.15.2\",\n    \"eslint\": \"6.8.0\",\n    \"eslint-config-airbnb\": \"18.1.0\",\n    \"eslint-config-prettier\": \"6.15.0\",\n    \"eslint-plugin-cypress\": \"2.11.3\",\n    \"eslint-plugin-emotion\": \"10.0.27\",\n    \"eslint-plugin-es5\": \"1.5.0\",\n    \"eslint-plugin-flowtype\": \"4.7.0\",\n    \"eslint-plugin-import\": \"2.22.1\",\n    \"eslint-plugin-jest\": \"23.20.0\",\n    \"eslint-plugin-jsx-a11y\": \"6.4.1\",\n    \"eslint-plugin-prettier\": \"3.3.1\",\n    \"eslint-plugin-react\": \"7.19.0\",\n    \"eslint-plugin-react-hooks\": \"3.0.0\",\n    \"flow-bin\": \"0.110.1\",\n    \"fs-extra\": \"9.1.0\",\n    \"globby\": \"11.0.3\",\n    \"jest\": \"25.5.4\",\n    \"jest-axe\": \"3.5.0\",\n    \"jest-junit\": \"10.0.0\",\n    \"jest-watch-typeahead\": \"0.6.1\",\n    \"lighthouse\": \"5.6.0\",\n    \"markdown-it\": \"10.0.0\",\n    \"picocolors\": \"^1.0.0\",\n    \"prettier\": \"2.0.4\",\n    \"raf-stub\": \"3.0.0\",\n    \"react\": \"16.13.1\",\n    \"react-dom\": \"16.13.1\",\n    \"react-test-renderer\": \"16.13.1\",\n    \"react-virtualized\": \"9.21.2\",\n    \"react-window\": \"1.8.6\",\n    \"require-from-string\": \"2.0.2\",\n    \"rimraf\": \"3.0.2\",\n    \"rollup\": \"2.6.1\",\n    \"rollup-plugin-babel\": \"4.4.0\",\n    \"rollup-plugin-commonjs\": \"10.1.0\",\n    \"rollup-plugin-json\": \"4.0.0\",\n    \"rollup-plugin-node-resolve\": \"5.2.0\",\n    \"rollup-plugin-replace\": \"2.2.0\",\n    \"rollup-plugin-size-snapshot\": \"0.11.0\",\n    \"rollup-plugin-strip\": \"1.2.2\",\n    \"rollup-plugin-terser\": \"5.3.1\",\n    \"storybook-addon-performance\": \"0.9.0\",\n    \"styled-components\": \"5.1.0\",\n    \"stylelint\": \"13.13.1\",\n    \"stylelint-config-prettier\": \"8.0.2\",\n    \"stylelint-config-recommended\": \"3.0.0\",\n    \"stylelint-config-standard\": \"20.0.0\",\n    \"stylelint-config-styled-components\": \"0.1.1\",\n    \"stylelint-processor-styled-components\": \"1.10.0\",\n    \"wait-port\": \"0.2.9\",\n    \"webpack\": \"4.42.1\"\n  },\n  \"peerDependencies\": {\n    \"react\": \"^16.8.5 || ^17.0.0 || ^18.0.0\",\n    \"react-dom\": \"^16.8.5 || ^17.0.0 || ^18.0.0\"\n  },\n  \"license\": \"Apache-2.0\",\n  \"jest-junit\": {\n    \"output\": \"test-reports/junit/js-test-results.xml\"\n  }\n}\n"
  },
  {
    "path": "renovate.json",
    "content": "{\n  \"extends\": [\n    \"config:base\"\n  ]\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "/* eslint-disable flowtype/require-valid-file-annotation */\n\nimport resolve from 'rollup-plugin-node-resolve';\nimport commonjs from 'rollup-plugin-commonjs';\nimport babel from 'rollup-plugin-babel';\nimport replace from 'rollup-plugin-replace';\nimport strip from 'rollup-plugin-strip';\nimport { terser } from 'rollup-plugin-terser';\nimport { sizeSnapshot } from 'rollup-plugin-size-snapshot';\nimport json from 'rollup-plugin-json';\nimport pkg from './package.json';\n\nconst input = './src/index.js';\nconst extensions = ['.js', '.jsx'];\n\n// Treat as externals all not relative and not absolute paths\n// e.g. 'react'\nconst excludeAllExternals = (id) => !id.startsWith('.') && !id.startsWith('/');\n\nconst getBabelOptions = ({ useESModules }) => ({\n  exclude: 'node_modules/**',\n  runtimeHelpers: true,\n  plugins: [['@babel/transform-runtime', { useESModules }]],\n});\n\nconst snapshotArgs =\n  process.env.SNAPSHOT === 'match'\n    ? {\n        matchSnapshot: true,\n        threshold: 1000,\n      }\n    : {};\n\nconst commonjsArgs = {\n  include: 'node_modules/**',\n  // needed for react-is via react-redux\n  // https://stackoverflow.com/questions/50080893/rollup-error-isvalidelementtype-is-not-exported-by-node-modules-react-is-inde/50098540\n  namedExports: {\n    'node_modules/react-is/index.js': [\n      'isValidElementType',\n      'isContextConsumer',\n    ],\n  },\n};\n\nexport default [\n  // Universal module definition (UMD) build\n  // - including console.* statements\n  // - conditionally used to match snapshot size\n  {\n    input,\n    output: {\n      file: 'dist/react-beautiful-dnd.js',\n      format: 'umd',\n      name: 'ReactBeautifulDnd',\n      globals: { react: 'React', 'react-dom': 'ReactDOM' },\n    },\n    // Only deep dependency required is React\n    external: ['react', 'react-dom'],\n    plugins: [\n      json(),\n      babel(getBabelOptions({ useESModules: true })),\n      resolve({ extensions }),\n      commonjs(commonjsArgs),\n      replace({ 'process.env.NODE_ENV': JSON.stringify('development') }),\n      sizeSnapshot(snapshotArgs),\n    ],\n  },\n\n  // Minified UMD build\n  {\n    input,\n    output: {\n      file: 'dist/react-beautiful-dnd.min.js',\n      format: 'umd',\n      name: 'ReactBeautifulDnd',\n      globals: { react: 'React', 'react-dom': 'ReactDOM' },\n    },\n    // Only deep dependency required is React\n    external: ['react', 'react-dom'],\n    plugins: [\n      json(),\n      babel(getBabelOptions({ useESModules: true })),\n      resolve({ extensions }),\n      commonjs(commonjsArgs),\n      strip(),\n      replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),\n      sizeSnapshot(snapshotArgs),\n      terser(),\n      // Useful for debugging: you can see what code is dropped\n      // terser({\n      //   mangle: false,\n      //   compress: false,\n      //   keep_fnames: true,\n      //   output: { beautify: true },\n      // }),\n    ],\n  },\n\n  // CommonJS (cjs) build\n  // - Keeping console.log statements\n  // - All external packages are not bundled\n  {\n    input,\n    output: { file: pkg.main, format: 'cjs' },\n    external: excludeAllExternals,\n    plugins: [\n      json(),\n      resolve({ extensions }),\n      babel(getBabelOptions({ useESModules: false })),\n    ],\n  },\n\n  // EcmaScript Module (esm) build\n  // - Keeping console.log statements\n  // - All external packages are not bundled\n  {\n    input,\n    output: { file: pkg.module, format: 'esm' },\n    external: excludeAllExternals,\n    plugins: [\n      json(),\n      resolve({ extensions }),\n      babel(getBabelOptions({ useESModules: true })),\n      sizeSnapshot(snapshotArgs),\n    ],\n  },\n];\n"
  },
  {
    "path": "server-ports.js",
    "content": "// @flow\nconst ports = {\n  storybook: 9002,\n  cspServer: 9003,\n};\n\nmodule.exports = ports;\n"
  },
  {
    "path": "src/animation.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { isEqual, origin } from './state/position';\n\nexport const curves = {\n  outOfTheWay: 'cubic-bezier(0.2, 0, 0, 1)',\n  drop: 'cubic-bezier(.2,1,.1,1)',\n};\n\nexport const combine = {\n  opacity: {\n    // while dropping: fade out totally\n    drop: 0,\n    // while dragging: fade out partially\n    combining: 0.7,\n  },\n  scale: {\n    drop: 0.75,\n  },\n};\n\nexport const timings = {\n  outOfTheWay: 0.2,\n  // greater than the out of the way time\n  // so that when the drop ends everything will\n  // have to be out of the way\n  minDropTime: 0.33,\n  maxDropTime: 0.55,\n};\n\n// slow timings\n// uncomment to use\n// export const timings = {\n//   outOfTheWay: 2,\n//   // greater than the out of the way time\n//   // so that when the drop ends everything will\n//   // have to be out of the way\n//   minDropTime: 3,\n//   maxDropTime: 4,\n// };\n\nconst outOfTheWayTiming: string = `${timings.outOfTheWay}s ${curves.outOfTheWay}`;\nexport const placeholderTransitionDelayTime: number = 0.1;\n\nexport const transitions = {\n  fluid: `opacity ${outOfTheWayTiming}`,\n  snap: `transform ${outOfTheWayTiming}, opacity ${outOfTheWayTiming}`,\n  drop: (duration: number): string => {\n    const timing: string = `${duration}s ${curves.drop}`;\n    return `transform ${timing}, opacity ${timing}`;\n  },\n  outOfTheWay: `transform ${outOfTheWayTiming}`,\n  placeholder: `height ${outOfTheWayTiming}, width ${outOfTheWayTiming}, margin ${outOfTheWayTiming}`,\n};\n\nconst moveTo = (offset: Position): ?string =>\n  isEqual(offset, origin) ? null : `translate(${offset.x}px, ${offset.y}px)`;\n\nexport const transforms = {\n  moveTo,\n  drop: (offset: Position, isCombining: boolean) => {\n    const translate: ?string = moveTo(offset);\n    if (!translate) {\n      return null;\n    }\n\n    // only transforming the translate\n    if (!isCombining) {\n      return translate;\n    }\n\n    // when dropping while combining we also update the scale\n    return `${translate} scale(${combine.scale.drop})`;\n  },\n};\n"
  },
  {
    "path": "src/debug/middleware/action-timing-average.js",
    "content": "// @flow\n/* eslint-disable no-console */\nimport type { Action } from '../../state/store-types';\n\ntype Bucket = {\n  [key: string]: number[],\n};\n\nconst average = (values: number[]): number => {\n  const sum: number = values.reduce(\n    (previous: number, current: number) => previous + current,\n    0,\n  );\n  return sum / values.length;\n};\n\nexport default (groupSize: number) => {\n  console.log('Starting average action timer middleware');\n  console.log(`Will take an average every ${groupSize} actions`);\n  const bucket: Bucket = {};\n\n  return () => (next: (Action) => mixed) => (action: Action): any => {\n    const start: number = performance.now();\n\n    const result: mixed = next(action);\n\n    const end: number = performance.now();\n\n    const duration: number = end - start;\n\n    if (!bucket[action.type]) {\n      bucket[action.type] = [duration];\n      return result;\n    }\n\n    bucket[action.type].push(duration);\n\n    if (bucket[action.type].length < groupSize) {\n      return result;\n    }\n\n    console.warn(\n      `Average time for ${action.type}`,\n      average(bucket[action.type]),\n    );\n\n    // reset\n    bucket[action.type] = [];\n\n    return result;\n  };\n};\n"
  },
  {
    "path": "src/debug/middleware/action-timing.js",
    "content": "// @flow\n/* eslint-disable no-console */\nimport * as timings from '../timings';\nimport type { Action } from '../../state/store-types';\n\nexport default () => (next: (Action) => mixed) => (action: Action): any => {\n  timings.forceEnable();\n  const key = `redux action: ${action.type}`;\n  timings.start(key);\n\n  const result: mixed = next(action);\n\n  timings.finish(key);\n\n  return result;\n};\n"
  },
  {
    "path": "src/debug/middleware/log.js",
    "content": "// @flow\n/* eslint-disable no-console */\nimport type { Action, Store } from '../../state/store-types';\n\ntype Mode = 'verbose' | 'light';\n\nexport default (mode?: Mode = 'verbose') => (store: Store) => (\n  next: (Action) => mixed,\n) => (action: Action): any => {\n  if (mode === 'light') {\n    console.log('🏃‍ Action:', action.type);\n    return next(action);\n  }\n\n  console.group(`action: ${action.type}`);\n  console.log('action payload', action.payload);\n\n  console.log('state before', store.getState());\n\n  const result: mixed = next(action);\n\n  console.log('state after', store.getState());\n  console.groupEnd();\n\n  return result;\n};\n"
  },
  {
    "path": "src/debug/middleware/user-timing.js",
    "content": "// @flow\nimport type { Action } from '../../state/store-types';\n\nexport default () => (next: (Action) => mixed) => (action: Action): any => {\n  const title: string = `👾 redux (action): ${action.type}`;\n  const startMark: string = `${action.type}:start`;\n  const endMark: string = `${action.type}:end`;\n\n  performance.mark(startMark);\n  const result: mixed = next(action);\n  performance.mark(endMark);\n\n  performance.measure(title, startMark, endMark);\n\n  return result;\n};\n"
  },
  {
    "path": "src/debug/timings.js",
    "content": "// @flow\ntype Records = {\n  [key: string]: number,\n};\n\nconst records: Records = {};\nlet isEnabled: boolean = false;\n\nconst isTimingsEnabled = (): boolean => isEnabled;\n\nexport const forceEnable = () => {\n  isEnabled = true;\n};\n\n// Debug: uncomment to enable\n// forceEnable();\n\nexport const start = (key: string) => {\n  // we want to strip all the code out for production builds\n  // draw back: can only do timings in dev env (which seems to be fine for now)\n  if (process.env.NODE_ENV !== 'production') {\n    if (!isTimingsEnabled()) {\n      return;\n    }\n    const now: number = performance.now();\n\n    records[key] = now;\n  }\n};\n\ntype Style = {|\n  textColor: string,\n  symbol: string,\n|};\n\nexport const finish = (key: string) => {\n  if (process.env.NODE_ENV !== 'production') {\n    if (!isTimingsEnabled()) {\n      return;\n    }\n    const now: number = performance.now();\n\n    const previous: ?number = records[key];\n\n    if (!previous) {\n      // eslint-disable-next-line no-console\n      console.warn('cannot finish timing as no previous time found', key);\n      return;\n    }\n\n    const result: number = now - previous;\n    const rounded: string = result.toFixed(2);\n\n    const style: Style = (() => {\n      if (result < 12) {\n        return {\n          textColor: 'green',\n          symbol: '✅',\n        };\n      }\n      if (result < 40) {\n        return {\n          textColor: 'orange',\n          symbol: '⚠️',\n        };\n      }\n      return {\n        textColor: 'red',\n        symbol: '❌',\n      };\n    })();\n\n    // eslint-disable-next-line no-console\n    console.log(\n      `${style.symbol} %cTiming %c${rounded} %cms %c${key}`,\n      // title\n      'color: blue; font-weight: bold;',\n      // result\n      `color: ${style.textColor}; font-size: 1.1em;`,\n      // ms\n      'color: grey;',\n      // key\n      'color: purple; font-weight: bold;',\n    );\n  }\n};\n"
  },
  {
    "path": "src/dev-warning.js",
    "content": "// @flow\n\nconst isProduction: boolean = process.env.NODE_ENV === 'production';\n\n// not replacing newlines (which \\s does)\nconst spacesAndTabs: RegExp = /[ \\t]{2,}/g;\nconst lineStartWithSpaces: RegExp = /^[ \\t]*/gm;\n\n// using .trim() to clear the any newlines before the first text and after last text\nconst clean = (value: string): string =>\n  value.replace(spacesAndTabs, ' ').replace(lineStartWithSpaces, '').trim();\n\nconst getDevMessage = (message: string): string =>\n  clean(`\n  %creact-beautiful-dnd\n\n  %c${clean(message)}\n\n  %c👷‍ This is a development only message. It will be removed in production builds.\n`);\n\nexport const getFormattedMessage = (message: string): string[] => [\n  getDevMessage(message),\n  // title (green400)\n  'color: #00C584; font-size: 1.2em; font-weight: bold;',\n  // message\n  'line-height: 1.5',\n  // footer (purple300)\n  'color: #723874;',\n];\n\nconst isDisabledFlag: string = '__react-beautiful-dnd-disable-dev-warnings';\n\nexport function log(type: 'error' | 'warn', message: string) {\n  // no warnings in production\n  if (isProduction) {\n    return;\n  }\n\n  // manual opt out of warnings\n  if (typeof window !== 'undefined' && window[isDisabledFlag]) {\n    return;\n  }\n\n  // eslint-disable-next-line no-console\n  console[type](...getFormattedMessage(message));\n}\n\nexport const warning = log.bind(null, 'warn');\nexport const error = log.bind(null, 'error');\n"
  },
  {
    "path": "src/empty.js",
    "content": "// @flow\nexport function noop(): void {}\n\nexport function identity<T>(value: T): T {\n  return value;\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "// @flow\n\n// Components\n\nexport { default as DragDropContext } from './view/drag-drop-context';\nexport { default as Droppable } from './view/droppable';\nexport { default as Draggable } from './view/draggable';\n\n// Default sensors\n\nexport {\n  useMouseSensor,\n  useTouchSensor,\n  useKeyboardSensor,\n} from './view/use-sensor-marshal';\n\n// Utils\n\nexport { resetServerContext } from './view/drag-drop-context';\n\n// Public flow types\n\nexport type {\n  Id,\n  TypeId,\n  DraggableId,\n  DroppableId,\n  DraggableRubric,\n  MovementMode,\n  BeforeCapture,\n  DragStart,\n  DragUpdate,\n  DropResult,\n  Direction,\n  ResponderProvided,\n  Announce,\n  DraggableLocation,\n  OnBeforeCaptureResponder,\n  OnBeforeDragStartResponder,\n  OnDragStartResponder,\n  OnDragUpdateResponder,\n  OnDragEndResponder,\n  SensorAPI,\n  Sensor,\n  TryGetLock,\n  TryGetLockOptions,\n} from './types';\n\n// Droppable types\nexport type {\n  Provided as DroppableProvided,\n  StateSnapshot as DroppableStateSnapshot,\n  DroppableProps,\n} from './view/droppable/droppable-types';\n\n// Draggable types\nexport type {\n  Provided as DraggableProvided,\n  StateSnapshot as DraggableStateSnapshot,\n  DragHandleProps,\n  DropAnimation,\n  DraggableProps,\n  DraggableStyle,\n  DraggingStyle,\n  NotDraggingStyle,\n  ChildrenFn as DraggableChildrenFn,\n} from './view/draggable/draggable-types';\n"
  },
  {
    "path": "src/invariant.js",
    "content": "// @flow\n/* eslint-disable no-restricted-syntax */\nconst isProduction: boolean = process.env.NODE_ENV === 'production';\nconst prefix: string = 'Invariant failed';\n\n// Want to use this:\n// export class RbdInvariant extends Error { }\n// But it causes babel to bring in a lot of code\n\nexport function RbdInvariant(message: string) {\n  this.message = message;\n}\n// $FlowFixMe\nRbdInvariant.prototype.toString = function toString() {\n  return this.message;\n};\n\n// A copy-paste of tiny-invariant but with a custom error type\n// Throw an error if the condition fails\nexport function invariant(condition: mixed, message?: string) {\n  if (condition) {\n    return;\n  }\n\n  if (isProduction) {\n    // In production we strip the message but still throw\n    throw new RbdInvariant(prefix);\n  } else {\n    // When not in production we allow the message to pass through\n    // *This block will be removed in production builds*\n    throw new RbdInvariant(`${prefix}: ${message || ''}`);\n  }\n}\n"
  },
  {
    "path": "src/native-with-fallback.js",
    "content": "// @flow\n/* eslint-disable es5/no-es6-methods */\n/* eslint-disable es5/no-es6-static-methods */\n/* eslint-disable no-restricted-globals */\n\ntype Map<T> = {\n  [key: string]: T,\n};\n\nexport function isInteger(value: mixed): boolean {\n  if (Number.isInteger) {\n    return Number.isInteger(value);\n  }\n  return (\n    typeof value === 'number' && isFinite(value) && Math.floor(value) === value\n  );\n}\n\n// Using this helper to ensure there are correct flow types\n// https://github.com/facebook/flow/issues/2221\nexport function values<T>(map: Map<T>): T[] {\n  if (Object.values) {\n    // $FlowFixMe - Object.values currently does not have good flow support\n    return Object.values(map);\n  }\n\n  return Object.keys(map).map((key) => map[key]);\n}\n\n// Could also extend to pass index and list\ntype PredicateFn<T> = (value: T) => boolean;\n\n// TODO: swap order\nexport function findIndex<T>(\n  list: Array<T>,\n  predicate: PredicateFn<T>,\n): number {\n  if (list.findIndex) {\n    return list.findIndex(predicate);\n  }\n\n  // Using a for loop so that we can exit early\n  for (let i = 0; i < list.length; i++) {\n    if (predicate(list[i])) {\n      return i;\n    }\n  }\n  // Array.prototype.find returns -1 when nothing is found\n  return -1;\n}\n\nexport function find<T>(list: Array<T>, predicate: PredicateFn<T>): ?T {\n  if (list.find) {\n    return list.find(predicate);\n  }\n  const index: number = findIndex(list, predicate);\n  if (index !== -1) {\n    return list[index];\n  }\n  // Array.prototype.find returns undefined when nothing is found\n  return undefined;\n}\n\n// Using this rather than Array.from as Array.from adds 2kb to the gzip\n// document.querySelector actually returns Element[], but flow thinks it is HTMLElement[]\n// So we downcast the result to Element[]\nexport function toArray(list: NodeList<HTMLElement>): Element[] {\n  return Array.prototype.slice.call(list);\n}\n"
  },
  {
    "path": "src/screen-reader-message-preset.js",
    "content": "// @flow\nimport type {\n  DraggableId,\n  DragStart,\n  DragUpdate,\n  DropResult,\n  DraggableLocation,\n  Combine,\n} from './types';\n\nexport type MessagePreset = {|\n  dragHandleUsageInstructions: string,\n  onDragStart: (start: DragStart) => string,\n  onDragUpdate: (update: DragUpdate) => string,\n  onDragEnd: (result: DropResult) => string,\n|};\n\nconst dragHandleUsageInstructions: string = `\n  Press space bar to start a drag.\n  When dragging you can use the arrow keys to move the item around and escape to cancel.\n  Some screen readers may require you to be in focus mode or to use your pass through key\n`;\n\nconst position = (index: number): number => index + 1;\n\n// We cannot list what index the Droppable is in automatically as we are not sure how\n// the Droppable's have been configured\nconst onDragStart = (start: DragStart): string => `\n  You have lifted an item in position ${position(start.source.index)}\n`;\n\nconst withLocation = (\n  source: DraggableLocation,\n  destination: DraggableLocation,\n) => {\n  const isInHomeList: boolean = source.droppableId === destination.droppableId;\n\n  const startPosition: number = position(source.index);\n  const endPosition: number = position(destination.index);\n\n  if (isInHomeList) {\n    return `\n      You have moved the item from position ${startPosition}\n      to position ${endPosition}\n    `;\n  }\n\n  return `\n    You have moved the item from position ${startPosition}\n    in list ${source.droppableId}\n    to list ${destination.droppableId}\n    in position ${endPosition}\n  `;\n};\n\nconst withCombine = (\n  id: DraggableId,\n  source: DraggableLocation,\n  combine: Combine,\n): string => {\n  const inHomeList: boolean = source.droppableId === combine.droppableId;\n\n  if (inHomeList) {\n    return `\n      The item ${id}\n      has been combined with ${combine.draggableId}`;\n  }\n\n  return `\n      The item ${id}\n      in list ${source.droppableId}\n      has been combined with ${combine.draggableId}\n      in list ${combine.droppableId}\n    `;\n};\n\nconst onDragUpdate = (update: DragUpdate): string => {\n  const location: ?DraggableLocation = update.destination;\n  if (location) {\n    return withLocation(update.source, location);\n  }\n\n  const combine: ?Combine = update.combine;\n  if (combine) {\n    return withCombine(update.draggableId, update.source, combine);\n  }\n\n  return 'You are over an area that cannot be dropped on';\n};\n\nconst returnedToStart = (source: DraggableLocation): string => `\n  The item has returned to its starting position\n  of ${position(source.index)}\n`;\n\nconst onDragEnd = (result: DropResult): string => {\n  if (result.reason === 'CANCEL') {\n    return `\n      Movement cancelled.\n      ${returnedToStart(result.source)}\n    `;\n  }\n\n  const location: ?DraggableLocation = result.destination;\n  const combine: ?Combine = result.combine;\n\n  if (location) {\n    return `\n      You have dropped the item.\n      ${withLocation(result.source, location)}\n    `;\n  }\n\n  if (combine) {\n    return `\n      You have dropped the item.\n      ${withCombine(result.draggableId, result.source, combine)}\n    `;\n  }\n\n  return `\n    The item has been dropped while not over a drop area.\n    ${returnedToStart(result.source)}\n  `;\n};\n\nconst preset: MessagePreset = {\n  dragHandleUsageInstructions,\n  onDragStart,\n  onDragUpdate,\n  onDragEnd,\n};\n\nexport default preset;\n"
  },
  {
    "path": "src/state/action-creators.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Critical,\n  DraggableId,\n  DroppableId,\n  CompletedDrag,\n  MovementMode,\n  Viewport,\n  DimensionMap,\n  DropReason,\n  Published,\n} from '../types';\n\nexport type BeforeInitialCaptureArgs = {|\n  draggableId: DraggableId,\n  movementMode: MovementMode,\n|};\n\nexport type BeforeInitialCaptureAction = {|\n  type: 'BEFORE_INITIAL_CAPTURE',\n  payload: BeforeInitialCaptureArgs,\n|};\n\nexport const beforeInitialCapture = (\n  args: BeforeInitialCaptureArgs,\n): BeforeInitialCaptureAction => ({\n  type: 'BEFORE_INITIAL_CAPTURE',\n  payload: args,\n});\n\nexport type LiftArgs = {|\n  // lifting with DraggableId rather than descriptor\n  // as the descriptor might change after a drop is flushed\n  id: DraggableId,\n  clientSelection: Position,\n  movementMode: MovementMode,\n|};\n\nexport type LiftAction = {|\n  type: 'LIFT',\n  payload: LiftArgs,\n|};\n\nexport const lift = (args: LiftArgs): LiftAction => ({\n  type: 'LIFT',\n  payload: args,\n});\n\nexport type InitialPublishArgs = {|\n  critical: Critical,\n  dimensions: DimensionMap,\n  clientSelection: Position,\n  viewport: Viewport,\n  movementMode: MovementMode,\n|};\n\nexport type InitialPublishAction = {|\n  type: 'INITIAL_PUBLISH',\n  payload: InitialPublishArgs,\n|};\n\nexport const initialPublish = (\n  args: InitialPublishArgs,\n): InitialPublishAction => ({\n  type: 'INITIAL_PUBLISH',\n  payload: args,\n});\n\nexport type WhileDraggingPublishAction = {|\n  type: 'PUBLISH_WHILE_DRAGGING',\n  payload: Published,\n|};\n\nexport const publishWhileDragging = (\n  args: Published,\n): WhileDraggingPublishAction => ({\n  type: 'PUBLISH_WHILE_DRAGGING',\n  payload: args,\n});\n\nexport type CollectionStartingAction = {|\n  type: 'COLLECTION_STARTING',\n  payload: null,\n|};\n\nexport const collectionStarting = (): CollectionStartingAction => ({\n  type: 'COLLECTION_STARTING',\n  payload: null,\n});\n\nexport type UpdateDroppableScrollArgs = {\n  id: DroppableId,\n  newScroll: Position,\n};\n\nexport type UpdateDroppableScrollAction = {|\n  type: 'UPDATE_DROPPABLE_SCROLL',\n  payload: UpdateDroppableScrollArgs,\n|};\n\nexport const updateDroppableScroll = (\n  args: UpdateDroppableScrollArgs,\n): UpdateDroppableScrollAction => ({\n  type: 'UPDATE_DROPPABLE_SCROLL',\n  payload: args,\n});\n\nexport type UpdateDroppableIsEnabledArgs = {|\n  id: DroppableId,\n  isEnabled: boolean,\n|};\n\nexport type UpdateDroppableIsEnabledAction = {|\n  type: 'UPDATE_DROPPABLE_IS_ENABLED',\n  payload: UpdateDroppableIsEnabledArgs,\n|};\n\nexport const updateDroppableIsEnabled = (\n  args: UpdateDroppableIsEnabledArgs,\n): UpdateDroppableIsEnabledAction => ({\n  type: 'UPDATE_DROPPABLE_IS_ENABLED',\n  payload: args,\n});\n\nexport type UpdateDroppableIsCombineEnabledArgs = {|\n  id: DroppableId,\n  isCombineEnabled: boolean,\n|};\n\nexport type UpdateDroppableIsCombineEnabledAction = {|\n  type: 'UPDATE_DROPPABLE_IS_COMBINE_ENABLED',\n  payload: UpdateDroppableIsCombineEnabledArgs,\n|};\n\nexport const updateDroppableIsCombineEnabled = (\n  args: UpdateDroppableIsCombineEnabledArgs,\n): UpdateDroppableIsCombineEnabledAction => ({\n  type: 'UPDATE_DROPPABLE_IS_COMBINE_ENABLED',\n  payload: args,\n});\n\nexport type MoveArgs = {|\n  client: Position,\n|};\n\nexport type MoveAction = {|\n  type: 'MOVE',\n  payload: MoveArgs,\n|};\n\nexport const move = (args: MoveArgs): MoveAction => ({\n  type: 'MOVE',\n  payload: args,\n});\n\ntype MoveByWindowScrollArgs = {|\n  newScroll: Position,\n|};\n\nexport type MoveByWindowScrollAction = {|\n  type: 'MOVE_BY_WINDOW_SCROLL',\n  payload: MoveByWindowScrollArgs,\n|};\n\nexport const moveByWindowScroll = (\n  args: MoveByWindowScrollArgs,\n): MoveByWindowScrollAction => ({\n  type: 'MOVE_BY_WINDOW_SCROLL',\n  payload: args,\n});\n\nexport type UpdateViewportMaxScrollArgs = {|\n  maxScroll: Position,\n|};\n\ntype UpdateViewportMaxScrollAction = {|\n  type: 'UPDATE_VIEWPORT_MAX_SCROLL',\n  payload: UpdateViewportMaxScrollArgs,\n|};\n\nexport const updateViewportMaxScroll = (\n  args: UpdateViewportMaxScrollArgs,\n): UpdateViewportMaxScrollAction => ({\n  type: 'UPDATE_VIEWPORT_MAX_SCROLL',\n  payload: args,\n});\n\nexport type MoveUpAction = {|\n  type: 'MOVE_UP',\n  payload: null,\n|};\n\nexport const moveUp = (): MoveUpAction => ({\n  type: 'MOVE_UP',\n  payload: null,\n});\n\nexport type MoveDownAction = {|\n  type: 'MOVE_DOWN',\n  payload: null,\n|};\n\nexport const moveDown = (): MoveDownAction => ({\n  type: 'MOVE_DOWN',\n  payload: null,\n});\n\nexport type MoveRightAction = {|\n  type: 'MOVE_RIGHT',\n  payload: null,\n|};\n\nexport const moveRight = (): MoveRightAction => ({\n  type: 'MOVE_RIGHT',\n  payload: null,\n});\n\nexport type MoveLeftAction = {|\n  type: 'MOVE_LEFT',\n  payload: null,\n|};\n\nexport const moveLeft = (): MoveLeftAction => ({\n  type: 'MOVE_LEFT',\n  payload: null,\n});\n\ntype FlushAction = {|\n  type: 'FLUSH',\n  payload: null,\n|};\n\nexport const flush = (): FlushAction => ({\n  type: 'FLUSH',\n  payload: null,\n});\n\nexport type AnimateDropArgs = {|\n  completed: CompletedDrag,\n  newHomeClientOffset: Position,\n  dropDuration: number,\n|};\n\nexport type DropAnimateAction = {\n  type: 'DROP_ANIMATE',\n  payload: AnimateDropArgs,\n};\n\nexport const animateDrop = (args: AnimateDropArgs): DropAnimateAction => ({\n  type: 'DROP_ANIMATE',\n  payload: args,\n});\n\nexport type DropCompleteArgs = {|\n  completed: CompletedDrag,\n|};\n\nexport type DropCompleteAction = {\n  type: 'DROP_COMPLETE',\n  payload: DropCompleteArgs,\n};\n\nexport const completeDrop = (args: DropCompleteArgs): DropCompleteAction => ({\n  type: 'DROP_COMPLETE',\n  payload: args,\n});\n\ntype DropArgs = {|\n  reason: DropReason,\n|};\n\nexport type DropAction = {|\n  type: 'DROP',\n  payload: DropArgs,\n|};\n\nexport const drop = (args: DropArgs) => ({\n  type: 'DROP',\n  payload: args,\n});\n\nexport const cancel = () => drop({ reason: 'CANCEL' });\n\nexport type DropPendingAction = {|\n  type: 'DROP_PENDING',\n  payload: DropArgs,\n|};\n\nexport const dropPending = (args: DropArgs): DropPendingAction => ({\n  type: 'DROP_PENDING',\n  payload: args,\n});\n\nexport type DropAnimationFinishedAction = {|\n  type: 'DROP_ANIMATION_FINISHED',\n  payload: null,\n|};\n\nexport const dropAnimationFinished = (): DropAnimationFinishedAction => ({\n  type: 'DROP_ANIMATION_FINISHED',\n  payload: null,\n});\n\nexport type Action =\n  | BeforeInitialCaptureAction\n  | LiftAction\n  | InitialPublishAction\n  | WhileDraggingPublishAction\n  | CollectionStartingAction\n  | UpdateDroppableScrollAction\n  | UpdateDroppableIsEnabledAction\n  | UpdateDroppableIsCombineEnabledAction\n  | MoveByWindowScrollAction\n  | UpdateViewportMaxScrollAction\n  // | PostJumpScrollAction\n  // | PostSnapDestinationChangeAction\n  | MoveAction\n  | MoveUpAction\n  | MoveDownAction\n  | MoveRightAction\n  | MoveLeftAction\n  | DropPendingAction\n  | DropAction\n  | DropAnimateAction\n  | DropAnimationFinishedAction\n  | DropCompleteAction\n  | FlushAction;\n"
  },
  {
    "path": "src/state/auto-scroller/auto-scroller-types.js",
    "content": "// @flow\nimport type { State, DraggingState } from '../../types';\n\nexport type AutoScroller = {|\n  start: (state: DraggingState) => void,\n  stop: () => void,\n  scroll: (state: State) => void,\n|};\n"
  },
  {
    "path": "src/state/auto-scroller/can-scroll.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { add, apply, isEqual, origin } from '../position';\nimport type { DroppableDimension, Viewport, Scrollable } from '../../types';\n\ntype CanPartiallyScrollArgs = {|\n  max: Position,\n  current: Position,\n  change: Position,\n|};\n\nconst smallestSigned = apply((value: number) => {\n  if (value === 0) {\n    return 0;\n  }\n  return value > 0 ? 1 : -1;\n});\n\ntype GetRemainderArgs = {|\n  current: Position,\n  max: Position,\n  change: Position,\n|};\n\n// We need to figure out how much of the movement\n// cannot be done with a scroll\nexport const getOverlap = (() => {\n  const getRemainder = (target: number, max: number): number => {\n    if (target < 0) {\n      return target;\n    }\n    if (target > max) {\n      return target - max;\n    }\n    return 0;\n  };\n\n  return ({ current, max, change }: GetRemainderArgs): ?Position => {\n    const targetScroll: Position = add(current, change);\n\n    const overlap: Position = {\n      x: getRemainder(targetScroll.x, max.x),\n      y: getRemainder(targetScroll.y, max.y),\n    };\n\n    if (isEqual(overlap, origin)) {\n      return null;\n    }\n\n    return overlap;\n  };\n})();\n\nexport const canPartiallyScroll = ({\n  max: rawMax,\n  current,\n  change,\n}: CanPartiallyScrollArgs): boolean => {\n  // It is possible for the max scroll to be greater than the current scroll\n  // when there are scrollbars on the cross axis. We adjust for this by\n  // increasing the max scroll point if needed\n  // This will allow movements backwards even if the current scroll is greater than the max scroll\n  const max: Position = {\n    x: Math.max(current.x, rawMax.x),\n    y: Math.max(current.y, rawMax.y),\n  };\n\n  // Only need to be able to move the smallest amount in the desired direction\n  const smallestChange: Position = smallestSigned(change);\n\n  const overlap: ?Position = getOverlap({\n    max,\n    current,\n    change: smallestChange,\n  });\n\n  // no overlap at all - we can move there!\n  if (!overlap) {\n    return true;\n  }\n\n  // if there was an x value, but there is no x overlap - then we can scroll on the x!\n  if (smallestChange.x !== 0 && overlap.x === 0) {\n    return true;\n  }\n\n  // if there was an y value, but there is no y overlap - then we can scroll on the y!\n  if (smallestChange.y !== 0 && overlap.y === 0) {\n    return true;\n  }\n\n  return false;\n};\n\nexport const canScrollWindow = (\n  viewport: Viewport,\n  change: Position,\n): boolean =>\n  canPartiallyScroll({\n    current: viewport.scroll.current,\n    max: viewport.scroll.max,\n    change,\n  });\n\nexport const getWindowOverlap = (\n  viewport: Viewport,\n  change: Position,\n): ?Position => {\n  if (!canScrollWindow(viewport, change)) {\n    return null;\n  }\n\n  const max: Position = viewport.scroll.max;\n  const current: Position = viewport.scroll.current;\n\n  return getOverlap({\n    current,\n    max,\n    change,\n  });\n};\n\nexport const canScrollDroppable = (\n  droppable: DroppableDimension,\n  change: Position,\n): boolean => {\n  const frame: ?Scrollable = droppable.frame;\n\n  // Cannot scroll when there is no scrollable\n  if (!frame) {\n    return false;\n  }\n\n  return canPartiallyScroll({\n    current: frame.scroll.current,\n    max: frame.scroll.max,\n    change,\n  });\n};\n\nexport const getDroppableOverlap = (\n  droppable: DroppableDimension,\n  change: Position,\n): ?Position => {\n  const frame: ?Scrollable = droppable.frame;\n\n  if (!frame) {\n    return null;\n  }\n\n  if (!canScrollDroppable(droppable, change)) {\n    return null;\n  }\n\n  return getOverlap({\n    current: frame.scroll.current,\n    max: frame.scroll.max,\n    change,\n  });\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/config.js",
    "content": "// @flow\n\n// Values used to control how the fluid auto scroll feels\nconst config = {\n  // percentage distance from edge of container:\n  startFromPercentage: 0.25,\n  maxScrollAtPercentage: 0.05,\n  // pixels per frame\n  maxPixelScroll: 28,\n\n  // A function used to ease a percentage value\n  // A simple linear function would be: (percentage) => percentage;\n  // percentage is between 0 and 1\n  // result must be between 0 and 1\n  ease: (percentage: number): number => Math.pow(percentage, 2),\n\n  durationDampening: {\n    // ms: how long to dampen the speed of an auto scroll from the start of a drag\n    stopDampeningAt: 1200,\n    // ms: when to start accelerating the reduction of duration dampening\n    accelerateAt: 360,\n  },\n};\n\nexport default config;\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/did-start-in-scrollable-area.js",
    "content": "// @flow\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-best-scrollable-droppable.js",
    "content": "// @flow\nimport memoizeOne from 'memoize-one';\nimport { type Position } from 'css-box-model';\nimport type {\n  DroppableDimension,\n  DroppableDimensionMap,\n  DroppableId,\n} from '../../../types';\nimport { invariant } from '../../../invariant';\nimport isPositionInFrame from '../../visibility/is-position-in-frame';\nimport { toDroppableList } from '../../dimension-structures';\nimport { find } from '../../../native-with-fallback';\n\nconst getScrollableDroppables = memoizeOne(\n  (droppables: DroppableDimensionMap): DroppableDimension[] =>\n    toDroppableList(droppables).filter(\n      (droppable: DroppableDimension): boolean => {\n        // exclude disabled droppables\n        if (!droppable.isEnabled) {\n          return false;\n        }\n\n        // only want droppables that are scrollable\n        if (!droppable.frame) {\n          return false;\n        }\n\n        return true;\n      },\n    ),\n);\n\nconst getScrollableDroppableOver = (\n  target: Position,\n  droppables: DroppableDimensionMap,\n): ?DroppableDimension => {\n  const maybe: ?DroppableDimension = find(\n    getScrollableDroppables(droppables),\n    (droppable: DroppableDimension): boolean => {\n      invariant(droppable.frame, 'Invalid result');\n      return isPositionInFrame(droppable.frame.pageMarginBox)(target);\n    },\n  );\n\n  return maybe;\n};\n\ntype Api = {|\n  center: Position,\n  destination: ?DroppableId,\n  droppables: DroppableDimensionMap,\n|};\n\nexport default ({\n  center,\n  destination,\n  droppables,\n}: Api): ?DroppableDimension => {\n  // We need to scroll the best droppable frame we can so that the\n  // placeholder buffer logic works correctly\n\n  if (destination) {\n    const dimension: DroppableDimension = droppables[destination];\n    if (!dimension.frame) {\n      return null;\n    }\n    return dimension;\n  }\n\n  // 2. If we are not over a droppable - are we over a droppable frame?\n  const dimension: ?DroppableDimension = getScrollableDroppableOver(\n    center,\n    droppables,\n  );\n\n  return dimension;\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-droppable-scroll-change.js",
    "content": "// @flow\nimport type { Position, Rect } from 'css-box-model';\nimport type { Scrollable, DroppableDimension } from '../../../types';\nimport getScroll from './get-scroll';\nimport { canScrollDroppable } from '../can-scroll';\n\ntype Args = {|\n  droppable: DroppableDimension,\n  subject: Rect,\n  center: Position,\n  dragStartTime: number,\n  shouldUseTimeDampening: boolean,\n|};\n\nexport default ({\n  droppable,\n  subject,\n  center,\n  dragStartTime,\n  shouldUseTimeDampening,\n}: Args): ?Position => {\n  // We know this has a closestScrollable\n  const frame: ?Scrollable = droppable.frame;\n\n  // this should never happen - just being safe\n  if (!frame) {\n    return null;\n  }\n\n  const scroll: ?Position = getScroll({\n    dragStartTime,\n    container: frame.pageMarginBox,\n    subject,\n    center,\n    shouldUseTimeDampening,\n  });\n\n  return scroll && canScrollDroppable(droppable, scroll) ? scroll : null;\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-percentage.js",
    "content": "// @flow\nimport { warning } from '../../../dev-warning';\n\ntype Args = {|\n  startOfRange: number,\n  endOfRange: number,\n  current: number,\n|};\n\nexport default ({ startOfRange, endOfRange, current }: Args): number => {\n  const range: number = endOfRange - startOfRange;\n\n  if (range === 0) {\n    warning(`\n      Detected distance range of 0 in the fluid auto scroller\n      This is unexpected and would cause a divide by 0 issue.\n      Not allowing an auto scroll\n    `);\n    return 0;\n  }\n\n  const currentInRange: number = current - startOfRange;\n  const percentage: number = currentInRange / range;\n  return percentage;\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-scroll/adjust-for-size-limits.js",
    "content": "// @flow\nimport type { Rect, Position } from 'css-box-model';\n\ntype Args = {|\n  container: Rect,\n  subject: Rect,\n  proposedScroll: Position,\n|};\n\nexport default ({ container, subject, proposedScroll }: Args): ?Position => {\n  const isTooBigVertically: boolean = subject.height > container.height;\n  const isTooBigHorizontally: boolean = subject.width > container.width;\n\n  // not too big on any axis\n  if (!isTooBigHorizontally && !isTooBigVertically) {\n    return proposedScroll;\n  }\n\n  // too big on both axis\n  if (isTooBigHorizontally && isTooBigVertically) {\n    return null;\n  }\n\n  // Only too big on one axis\n  // Exclude the axis that we cannot scroll on\n  return {\n    x: isTooBigHorizontally ? 0 : proposedScroll.x,\n    y: isTooBigVertically ? 0 : proposedScroll.y,\n  };\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/dampen-value-by-time.js",
    "content": "// @flow\nimport getPercentage from '../../get-percentage';\nimport config from '../../config';\nimport minScroll from './min-scroll';\n\nconst accelerateAt: number = config.durationDampening.accelerateAt;\nconst stopAt: number = config.durationDampening.stopDampeningAt;\n\nexport default (proposedScroll: number, dragStartTime: number): number => {\n  const startOfRange: number = dragStartTime;\n  const endOfRange: number = stopAt;\n  const now: number = Date.now();\n  const runTime: number = now - startOfRange;\n\n  // we have finished the time dampening period\n  if (runTime >= stopAt) {\n    return proposedScroll;\n  }\n\n  // Up to this point we know there is a proposed scroll\n  // but we have not reached our accelerate point\n  // Return the minimum amount of scroll\n  if (runTime < accelerateAt) {\n    return minScroll;\n  }\n\n  const betweenAccelerateAtAndStopAtPercentage: number = getPercentage({\n    startOfRange: accelerateAt,\n    endOfRange,\n    current: runTime,\n  });\n\n  const scroll: number =\n    proposedScroll * config.ease(betweenAccelerateAtAndStopAtPercentage);\n\n  return Math.ceil(scroll);\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-distance-thresholds.js",
    "content": "// @flow\nimport type { Rect } from 'css-box-model';\nimport config from '../../config';\nimport type { Axis } from '../../../../../types';\n\n// all in pixels\nexport type DistanceThresholds = {|\n  startScrollingFrom: number,\n  maxScrollValueAt: number,\n|};\n\n// converts the percentages in the config into actual pixel values\nexport default (container: Rect, axis: Axis): DistanceThresholds => {\n  const startScrollingFrom: number =\n    container[axis.size] * config.startFromPercentage;\n  const maxScrollValueAt: number =\n    container[axis.size] * config.maxScrollAtPercentage;\n\n  const thresholds: DistanceThresholds = {\n    startScrollingFrom,\n    maxScrollValueAt,\n  };\n\n  return thresholds;\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-value-from-distance.js",
    "content": "// @flow\nimport { type DistanceThresholds } from './get-distance-thresholds';\nimport getPercentage from '../../get-percentage';\nimport config from '../../config';\nimport minScroll from './min-scroll';\n\nexport default (\n  distanceToEdge: number,\n  thresholds: DistanceThresholds,\n): number => {\n  /*\n  // This function only looks at the distance to one edge\n  // Example: looking at bottom edge\n  |----------------------------------|\n  |                                  |\n  |                                  |\n  |                                  |\n  |                                  |\n  |                                  | => no scroll in this range\n  |                                  |\n  |                                  |\n  |  startScrollingFrom (eg 100px)   |\n  |                                  |\n  |                                  | => increased scroll value the closer to maxScrollValueAt\n  |  maxScrollValueAt (eg 10px)      |\n  |                                  | => max scroll value in this range\n  |----------------------------------|\n  */\n\n  // too far away to auto scroll\n  if (distanceToEdge > thresholds.startScrollingFrom) {\n    return 0;\n  }\n\n  // use max speed when on or over boundary\n  if (distanceToEdge <= thresholds.maxScrollValueAt) {\n    return config.maxPixelScroll;\n  }\n\n  // when just going on the boundary return the minimum integer\n  if (distanceToEdge === thresholds.startScrollingFrom) {\n    return minScroll;\n  }\n\n  // to get the % past startScrollingFrom we will calculate\n  // the % the value is from maxScrollValueAt and then invert it\n  const percentageFromMaxScrollValueAt: number = getPercentage({\n    startOfRange: thresholds.maxScrollValueAt,\n    endOfRange: thresholds.startScrollingFrom,\n    current: distanceToEdge,\n  });\n\n  const percentageFromStartScrollingFrom: number =\n    1 - percentageFromMaxScrollValueAt;\n\n  const scroll: number =\n    config.maxPixelScroll * config.ease(percentageFromStartScrollingFrom);\n\n  // scroll will always be a positive integer\n  return Math.ceil(scroll);\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-value.js",
    "content": "// @flow\nimport { type DistanceThresholds } from './get-distance-thresholds';\nimport getValueFromDistance from './get-value-from-distance';\nimport dampenValueByTime from './dampen-value-by-time';\nimport minScroll from './min-scroll';\n\ntype Args = {|\n  distanceToEdge: number,\n  thresholds: DistanceThresholds,\n  dragStartTime: number,\n  shouldUseTimeDampening: boolean,\n|};\n\nexport default ({\n  distanceToEdge,\n  thresholds,\n  dragStartTime,\n  shouldUseTimeDampening,\n}: Args): number => {\n  const scroll: number = getValueFromDistance(distanceToEdge, thresholds);\n\n  // not enough distance to trigger a minimum scroll\n  // we can bail here\n  if (scroll === 0) {\n    return 0;\n  }\n\n  // Dampen an auto scroll speed based on duration of drag\n\n  if (!shouldUseTimeDampening) {\n    return scroll;\n  }\n\n  // Once we know an auto scroll should occur based on distance,\n  // we must let at least 1px through to trigger a scroll event an\n  // another auto scroll call\n\n  return Math.max(dampenValueByTime(scroll, dragStartTime), minScroll);\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/index.js",
    "content": "// @flow\nimport type { Rect, Spacing } from 'css-box-model';\nimport getDistanceThresholds, {\n  type DistanceThresholds,\n} from './get-distance-thresholds';\nimport type { Axis } from '../../../../../types';\nimport getValue from './get-value';\n\ntype GetOnAxisArgs = {|\n  container: Rect,\n  distanceToEdges: Spacing,\n  dragStartTime: number,\n  axis: Axis,\n  shouldUseTimeDampening: boolean,\n|};\n\nexport default ({\n  container,\n  distanceToEdges,\n  dragStartTime,\n  axis,\n  shouldUseTimeDampening,\n}: GetOnAxisArgs): number => {\n  const thresholds: DistanceThresholds = getDistanceThresholds(container, axis);\n  const isCloserToEnd: boolean =\n    distanceToEdges[axis.end] < distanceToEdges[axis.start];\n\n  if (isCloserToEnd) {\n    return getValue({\n      distanceToEdge: distanceToEdges[axis.end],\n      thresholds,\n      dragStartTime,\n      shouldUseTimeDampening,\n    });\n  }\n\n  return (\n    -1 *\n    getValue({\n      distanceToEdge: distanceToEdges[axis.start],\n      thresholds,\n      dragStartTime,\n      shouldUseTimeDampening,\n    })\n  );\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/min-scroll.js",
    "content": "// @flow\n\n// A scroll event will only be triggered when there is a value of at least 1px change\nexport default 1;\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-scroll/index.js",
    "content": "// @flow\nimport type { Position, Rect, Spacing } from 'css-box-model';\nimport { apply, isEqual, origin } from '../../../position';\nimport getScrollOnAxis from './get-scroll-on-axis';\nimport adjustForSizeLimits from './adjust-for-size-limits';\nimport { horizontal, vertical } from '../../../axis';\n\n// will replace -0 and replace with +0\nconst clean = apply((value: number) => (value === 0 ? 0 : value));\n\ntype Args = {|\n  dragStartTime: number,\n  container: Rect,\n  subject: Rect,\n  center: Position,\n  shouldUseTimeDampening: boolean,\n|};\n\nexport default ({\n  dragStartTime,\n  container,\n  subject,\n  center,\n  shouldUseTimeDampening,\n}: Args): ?Position => {\n  // get distance to each edge\n  const distanceToEdges: Spacing = {\n    top: center.y - container.top,\n    right: container.right - center.x,\n    bottom: container.bottom - center.y,\n    left: center.x - container.left,\n  };\n\n  // 1. Figure out which x,y values are the best target\n  // 2. Can the container scroll in that direction at all?\n  // If no for both directions, then return null\n  // 3. Is the center close enough to a edge to start a drag?\n  // 4. Based on the distance, calculate the speed at which a scroll should occur\n  // The lower distance value the faster the scroll should be.\n  // Maximum speed value should be hit before the distance is 0\n  // Negative values to not continue to increase the speed\n  const y: number = getScrollOnAxis({\n    container,\n    distanceToEdges,\n    dragStartTime,\n    axis: vertical,\n    shouldUseTimeDampening,\n  });\n  const x: number = getScrollOnAxis({\n    container,\n    distanceToEdges,\n    dragStartTime,\n    axis: horizontal,\n    shouldUseTimeDampening,\n  });\n\n  const required: Position = clean({ x, y });\n\n  // nothing required\n  if (isEqual(required, origin)) {\n    return null;\n  }\n\n  // need to not scroll in a direction that we are too big to scroll in\n  const limited: ?Position = adjustForSizeLimits({\n    container,\n    subject,\n    proposedScroll: required,\n  });\n\n  if (!limited) {\n    return null;\n  }\n\n  return isEqual(limited, origin) ? null : limited;\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/get-window-scroll-change.js",
    "content": "// @flow\nimport type { Position, Rect } from 'css-box-model';\nimport type { Viewport } from '../../../types';\nimport getScroll from './get-scroll';\nimport { canScrollWindow } from '../can-scroll';\n\ntype Args = {|\n  viewport: Viewport,\n  subject: Rect,\n  center: Position,\n  dragStartTime: number,\n  shouldUseTimeDampening: boolean,\n|};\n\nexport default ({\n  viewport,\n  subject,\n  center,\n  dragStartTime,\n  shouldUseTimeDampening,\n}: Args): ?Position => {\n  const scroll: ?Position = getScroll({\n    dragStartTime,\n    container: viewport.frame,\n    subject,\n    center,\n    shouldUseTimeDampening,\n  });\n\n  return scroll && canScrollWindow(viewport, scroll) ? scroll : null;\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/index.js",
    "content": "// @flow\nimport rafSchd from 'raf-schd';\nimport { type Position } from 'css-box-model';\nimport type { DraggingState, DroppableId } from '../../../types';\nimport scroll from './scroll';\nimport { invariant } from '../../../invariant';\nimport * as timings from '../../../debug/timings';\n\nexport type PublicArgs = {|\n  scrollWindow: (change: Position) => void,\n  scrollDroppable: (id: DroppableId, change: Position) => void,\n|};\n\nexport type FluidScroller = {|\n  scroll: (state: DraggingState) => void,\n  start: (state: DraggingState) => void,\n  stop: () => void,\n|};\n\ntype WhileDragging = {|\n  dragStartTime: number,\n  shouldUseTimeDampening: boolean,\n|};\n\nexport default ({\n  scrollWindow,\n  scrollDroppable,\n}: PublicArgs): FluidScroller => {\n  const scheduleWindowScroll = rafSchd(scrollWindow);\n  const scheduleDroppableScroll = rafSchd(scrollDroppable);\n  let dragging: ?WhileDragging = null;\n\n  const tryScroll = (state: DraggingState): void => {\n    invariant(dragging, 'Cannot fluid scroll if not dragging');\n    const { shouldUseTimeDampening, dragStartTime } = dragging;\n\n    scroll({\n      state,\n      scrollWindow: scheduleWindowScroll,\n      scrollDroppable: scheduleDroppableScroll,\n      dragStartTime,\n      shouldUseTimeDampening,\n    });\n  };\n\n  const start = (state: DraggingState) => {\n    timings.start('starting fluid scroller');\n    invariant(!dragging, 'Cannot start auto scrolling when already started');\n    const dragStartTime: number = Date.now();\n\n    let wasScrollNeeded: boolean = false;\n    const fakeScrollCallback = () => {\n      wasScrollNeeded = true;\n    };\n    scroll({\n      state,\n      dragStartTime: 0,\n      shouldUseTimeDampening: false,\n      scrollWindow: fakeScrollCallback,\n      scrollDroppable: fakeScrollCallback,\n    });\n\n    dragging = {\n      dragStartTime,\n      shouldUseTimeDampening: wasScrollNeeded,\n    };\n    timings.finish('starting fluid scroller');\n\n    // we know an auto scroll is needed - let's do it!\n    if (wasScrollNeeded) {\n      tryScroll(state);\n    }\n  };\n\n  const stop = () => {\n    // can be called defensively\n    if (!dragging) {\n      return;\n    }\n    scheduleWindowScroll.cancel();\n    scheduleDroppableScroll.cancel();\n    dragging = null;\n  };\n\n  return {\n    start,\n    stop,\n    scroll: tryScroll,\n  };\n};\n"
  },
  {
    "path": "src/state/auto-scroller/fluid-scroller/scroll.js",
    "content": "// @flow\nimport { type Position, type Rect } from 'css-box-model';\nimport type {\n  DraggingState,\n  DroppableId,\n  DraggableDimension,\n  DroppableDimension,\n  Viewport,\n} from '../../../types';\nimport getBestScrollableDroppable from './get-best-scrollable-droppable';\nimport whatIsDraggedOver from '../../droppable/what-is-dragged-over';\nimport getWindowScrollChange from './get-window-scroll-change';\nimport getDroppableScrollChange from './get-droppable-scroll-change';\n\ntype Args = {|\n  state: DraggingState,\n  dragStartTime: number,\n  shouldUseTimeDampening: boolean,\n  scrollWindow: (scroll: Position) => void,\n  scrollDroppable: (id: DroppableId, scroll: Position) => void,\n|};\n\nexport default ({\n  state,\n  dragStartTime,\n  shouldUseTimeDampening,\n  scrollWindow,\n  scrollDroppable,\n}: Args): void => {\n  const center: Position = state.current.page.borderBoxCenter;\n  const draggable: DraggableDimension =\n    state.dimensions.draggables[state.critical.draggable.id];\n  const subject: Rect = draggable.page.marginBox;\n  // 1. Can we scroll the viewport?\n  if (state.isWindowScrollAllowed) {\n    const viewport: Viewport = state.viewport;\n    const change: ?Position = getWindowScrollChange({\n      dragStartTime,\n      viewport,\n      subject,\n      center,\n      shouldUseTimeDampening,\n    });\n\n    if (change) {\n      scrollWindow(change);\n      return;\n    }\n  }\n\n  const droppable: ?DroppableDimension = getBestScrollableDroppable({\n    center,\n    destination: whatIsDraggedOver(state.impact),\n    droppables: state.dimensions.droppables,\n  });\n\n  if (!droppable) {\n    return;\n  }\n\n  const change: ?Position = getDroppableScrollChange({\n    dragStartTime,\n    droppable,\n    subject,\n    center,\n    shouldUseTimeDampening,\n  });\n\n  if (change) {\n    scrollDroppable(droppable.descriptor.id, change);\n  }\n};\n"
  },
  {
    "path": "src/state/auto-scroller/index.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport createFluidScroller, { type FluidScroller } from './fluid-scroller';\nimport createJumpScroller, { type JumpScroller } from './jump-scroller';\nimport type { AutoScroller } from './auto-scroller-types';\nimport type { DroppableId, State } from '../../types';\nimport type { MoveArgs } from '../action-creators';\n\nexport type Args = {|\n  scrollWindow: (offset: Position) => void,\n  scrollDroppable: (id: DroppableId, change: Position) => void,\n  move: (args: MoveArgs) => mixed,\n|};\n\nexport default ({\n  scrollDroppable,\n  scrollWindow,\n  move,\n}: Args): AutoScroller => {\n  const fluidScroller: FluidScroller = createFluidScroller({\n    scrollWindow,\n    scrollDroppable,\n  });\n\n  const jumpScroll: JumpScroller = createJumpScroller({\n    move,\n    scrollWindow,\n    scrollDroppable,\n  });\n\n  const scroll = (state: State) => {\n    // Only allowing auto scrolling in the DRAGGING phase\n    if (state.phase !== 'DRAGGING') {\n      return;\n    }\n\n    if (state.movementMode === 'FLUID') {\n      fluidScroller.scroll(state);\n      return;\n    }\n\n    if (!state.scrollJumpRequest) {\n      return;\n    }\n\n    jumpScroll(state);\n  };\n\n  const scroller: AutoScroller = {\n    scroll,\n    start: fluidScroller.start,\n    stop: fluidScroller.stop,\n  };\n\n  return scroller;\n};\n"
  },
  {
    "path": "src/state/auto-scroller/jump-scroller.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { invariant } from '../../invariant';\nimport { add, subtract } from '../position';\nimport {\n  canScrollWindow,\n  canScrollDroppable,\n  getWindowOverlap,\n  getDroppableOverlap,\n} from './can-scroll';\nimport whatIsDraggedOver from '../droppable/what-is-dragged-over';\nimport { type MoveArgs } from '../action-creators';\nimport type {\n  DroppableDimension,\n  Viewport,\n  DraggingState,\n  DroppableId,\n} from '../../types';\n\ntype Args = {|\n  scrollDroppable: (id: DroppableId, change: Position) => void,\n  scrollWindow: (offset: Position) => void,\n  move: (args: MoveArgs) => mixed,\n|};\n\nexport type JumpScroller = (state: DraggingState) => void;\n\ntype Remainder = Position;\n\nexport default ({\n  move,\n  scrollDroppable,\n  scrollWindow,\n}: Args): JumpScroller => {\n  const moveByOffset = (state: DraggingState, offset: Position) => {\n    const client: Position = add(state.current.client.selection, offset);\n    move({ client });\n  };\n\n  const scrollDroppableAsMuchAsItCan = (\n    droppable: DroppableDimension,\n    change: Position,\n  ): ?Remainder => {\n    // Droppable cannot absorb any of the scroll\n    if (!canScrollDroppable(droppable, change)) {\n      return change;\n    }\n\n    const overlap: ?Position = getDroppableOverlap(droppable, change);\n\n    // Droppable can absorb the entire change\n    if (!overlap) {\n      scrollDroppable(droppable.descriptor.id, change);\n      return null;\n    }\n\n    // Droppable can only absorb a part of the change\n    const whatTheDroppableCanScroll: Position = subtract(change, overlap);\n    scrollDroppable(droppable.descriptor.id, whatTheDroppableCanScroll);\n\n    const remainder: Position = subtract(change, whatTheDroppableCanScroll);\n    return remainder;\n  };\n\n  const scrollWindowAsMuchAsItCan = (\n    isWindowScrollAllowed: boolean,\n    viewport: Viewport,\n    change: Position,\n  ): ?Position => {\n    if (!isWindowScrollAllowed) {\n      return change;\n    }\n\n    if (!canScrollWindow(viewport, change)) {\n      // window cannot absorb any of the scroll\n      return change;\n    }\n\n    const overlap: ?Position = getWindowOverlap(viewport, change);\n\n    // window can absorb entire scroll\n    if (!overlap) {\n      scrollWindow(change);\n      return null;\n    }\n\n    // window can only absorb a part of the scroll\n    const whatTheWindowCanScroll: Position = subtract(change, overlap);\n    scrollWindow(whatTheWindowCanScroll);\n\n    const remainder: Position = subtract(change, whatTheWindowCanScroll);\n    return remainder;\n  };\n\n  const jumpScroller: JumpScroller = (state: DraggingState) => {\n    const request: ?Position = state.scrollJumpRequest;\n\n    if (!request) {\n      return;\n    }\n\n    const destination: ?DroppableId = whatIsDraggedOver(state.impact);\n    invariant(\n      destination,\n      'Cannot perform a jump scroll when there is no destination',\n    );\n\n    // 1. We scroll the droppable first if we can to avoid the draggable\n    // leaving the list\n\n    const droppableRemainder: ?Position = scrollDroppableAsMuchAsItCan(\n      state.dimensions.droppables[destination],\n      request,\n    );\n\n    // droppable absorbed the entire scroll\n    if (!droppableRemainder) {\n      return;\n    }\n\n    const viewport: Viewport = state.viewport;\n    const windowRemainder: ?Position = scrollWindowAsMuchAsItCan(\n      state.isWindowScrollAllowed,\n      viewport,\n      droppableRemainder,\n    );\n\n    // window could absorb all the droppable remainder\n    if (!windowRemainder) {\n      return;\n    }\n\n    // The entire scroll could not be absorbed by the droppable and window\n    // so we manually move whatever is left\n    moveByOffset(state, windowRemainder);\n  };\n\n  return jumpScroller;\n};\n"
  },
  {
    "path": "src/state/axis.js",
    "content": "// @flow\nimport type { HorizontalAxis, VerticalAxis } from '../types';\n\nexport const vertical: VerticalAxis = {\n  direction: 'vertical',\n  line: 'y',\n  crossAxisLine: 'x',\n  start: 'top',\n  end: 'bottom',\n  size: 'height',\n  crossAxisStart: 'left',\n  crossAxisEnd: 'right',\n  crossAxisSize: 'width',\n};\n\nexport const horizontal: HorizontalAxis = {\n  direction: 'horizontal',\n  line: 'x',\n  crossAxisLine: 'y',\n  start: 'left',\n  end: 'right',\n  size: 'width',\n  crossAxisStart: 'top',\n  crossAxisEnd: 'bottom',\n  crossAxisSize: 'height',\n};\n"
  },
  {
    "path": "src/state/calculate-drag-impact/calculate-reorder-impact.js",
    "content": "// @flow\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n  DragImpact,\n  DisplacementGroups,\n  Viewport,\n  DisplacedBy,\n} from '../../types';\nimport removeDraggableFromList from '../remove-draggable-from-list';\nimport isHomeOf from '../droppable/is-home-of';\nimport { emptyGroups } from '../no-impact';\nimport { find } from '../../native-with-fallback';\nimport getDisplacementGroups from '../get-displacement-groups';\n\ntype Args = {|\n  draggable: DraggableDimension,\n  insideDestination: DraggableDimension[],\n  destination: DroppableDimension,\n  viewport: Viewport,\n  displacedBy: DisplacedBy,\n  last: DisplacementGroups,\n  index: ?number,\n  forceShouldAnimate?: boolean,\n|};\n\nfunction getIndexOfLastItem(\n  draggables: DraggableDimension[],\n  options: {| inHomeList: boolean |},\n): number {\n  if (!draggables.length) {\n    return 0;\n  }\n\n  const indexOfLastItem: number =\n    draggables[draggables.length - 1].descriptor.index;\n\n  // When in a foreign list there will be an additional one item in the list\n  return options.inHomeList ? indexOfLastItem : indexOfLastItem + 1;\n}\n\ntype GoAtEndArgs = {|\n  insideDestination: DraggableDimension[],\n  inHomeList: boolean,\n  displacedBy: DisplacedBy,\n  destination: DroppableDimension,\n|};\n\nfunction goAtEnd({\n  insideDestination,\n  inHomeList,\n  displacedBy,\n  destination,\n}: GoAtEndArgs): DragImpact {\n  const newIndex: number = getIndexOfLastItem(insideDestination, {\n    inHomeList,\n  });\n\n  return {\n    displaced: emptyGroups,\n    displacedBy,\n    at: {\n      type: 'REORDER',\n      destination: {\n        droppableId: destination.descriptor.id,\n        index: newIndex,\n      },\n    },\n  };\n}\n\nexport default function calculateReorderImpact({\n  draggable,\n  insideDestination,\n  destination,\n  viewport,\n  displacedBy,\n  last,\n  index,\n  forceShouldAnimate,\n}: Args): DragImpact {\n  const inHomeList: boolean = isHomeOf(draggable, destination);\n\n  // Go into last spot of list\n  if (index == null) {\n    return goAtEnd({\n      insideDestination,\n      inHomeList,\n      displacedBy,\n      destination,\n    });\n  }\n\n  // this might be the dragging item\n  const match: ?DraggableDimension = find(\n    insideDestination,\n    (item: DraggableDimension) => item.descriptor.index === index,\n  );\n\n  if (!match) {\n    return goAtEnd({\n      insideDestination,\n      inHomeList,\n      displacedBy,\n      destination,\n    });\n  }\n  const withoutDragging: DraggableDimension[] = removeDraggableFromList(\n    draggable,\n    insideDestination,\n  );\n\n  const sliceFrom: number = insideDestination.indexOf(match);\n  const impacted: DraggableDimension[] = withoutDragging.slice(sliceFrom);\n\n  const displaced: DisplacementGroups = getDisplacementGroups({\n    afterDragging: impacted,\n    destination,\n    displacedBy,\n    last,\n    viewport: viewport.frame,\n    forceShouldAnimate,\n  });\n\n  return {\n    displaced,\n    displacedBy,\n    at: {\n      type: 'REORDER',\n      destination: {\n        droppableId: destination.descriptor.id,\n        index,\n      },\n    },\n  };\n}\n"
  },
  {
    "path": "src/state/can-start-drag.js",
    "content": "// @flow\nimport type { State, DraggableId } from '../types';\n\nexport default (state: State, id: DraggableId): boolean => {\n  // Ready to go!\n  if (state.phase === 'IDLE') {\n    return true;\n  }\n\n  // Can lift depending on the type of drop animation\n  if (state.phase !== 'DROP_ANIMATING') {\n    return false;\n  }\n\n  // - For a user drop we allow the user to drag other Draggables\n  //   immediately as items are most likely already in their home\n  // - For a cancel items will be moving back to their original position\n  //   as such it is a cleaner experience to block them from dragging until\n  //   the drop animation is complete. Otherwise they will be grabbing\n  //   items not in their original position which can lead to bad visuals\n  // Not allowing dragging of the dropping draggable\n  if (state.completed.result.draggableId === id) {\n    return false;\n  }\n\n  // if dropping - allow lifting\n  // if cancelling - disallow lifting\n  return state.completed.result.reason === 'DROP';\n};\n"
  },
  {
    "path": "src/state/create-store.js",
    "content": "// @flow\n/* eslint-disable no-underscore-dangle */\nimport { applyMiddleware, createStore, compose } from 'redux';\nimport reducer from './reducer';\nimport lift from './middleware/lift';\nimport style from './middleware/style';\nimport drop from './middleware/drop/drop-middleware';\nimport scrollListener from './middleware/scroll-listener';\nimport responders from './middleware/responders/responders-middleware';\nimport dropAnimationFinish from './middleware/drop/drop-animation-finish-middleware';\nimport dropAnimationFlushOnScroll from './middleware/drop/drop-animation-flush-on-scroll-middleware';\nimport dimensionMarshalStopper from './middleware/dimension-marshal-stopper';\nimport focus from './middleware/focus';\nimport autoScroll from './middleware/auto-scroll';\nimport pendingDrop from './middleware/pending-drop';\nimport type { DimensionMarshal } from './dimension-marshal/dimension-marshal-types';\nimport type { FocusMarshal } from '../view/use-focus-marshal/focus-marshal-types';\nimport type { StyleMarshal } from '../view/use-style-marshal/style-marshal-types';\nimport type { AutoScroller } from './auto-scroller/auto-scroller-types';\nimport type { Responders, Announce } from '../types';\nimport type { Store } from './store-types';\n\n// We are checking if window is available before using it.\n// This is needed for universal apps that render the component server side.\n// Details: https://github.com/zalmoxisus/redux-devtools-extension#12-advanced-store-setup\nconst composeEnhancers =\n  process.env.NODE_ENV !== 'production' &&\n  typeof window !== 'undefined' &&\n  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__\n    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({\n        name: 'react-beautiful-dnd',\n      })\n    : compose;\n\ntype Args = {|\n  dimensionMarshal: DimensionMarshal,\n  focusMarshal: FocusMarshal,\n  styleMarshal: StyleMarshal,\n  getResponders: () => Responders,\n  announce: Announce,\n  autoScroller: AutoScroller,\n|};\n\nexport default ({\n  dimensionMarshal,\n  focusMarshal,\n  styleMarshal,\n  getResponders,\n  announce,\n  autoScroller,\n}: Args): Store =>\n  createStore(\n    reducer,\n    composeEnhancers(\n      applyMiddleware(\n        // ## Debug middleware\n\n        // > uncomment to use\n        // debugging logger\n        // require('../debug/middleware/log').default('light'),\n        // // user timing api\n        // require('../debug/middleware/user-timing').default,\n        // debugging timer\n        // require('../debug/middleware/action-timing').default,\n        // average action timer\n        // require('../debug/middleware/action-timing-average').default(200),\n\n        // ## Application middleware\n\n        // Style updates do not cause more actions. It is important to update styles\n        // before responders are called: specifically the onDragEnd responder. We need to clear\n        // the transition styles off the elements before a reorder to prevent strange\n        // post drag animations in firefox. Even though we clear the transition off\n        // a Draggable - if it is done after a reorder firefox will still apply the\n        // transition.\n        // Must be called before dimension marshal for lifting to apply collecting styles\n        style(styleMarshal),\n        // Stop the dimension marshal collecting anything\n        // when moving into a phase where collection is no longer needed.\n        // We need to stop the marshal before responders fire as responders can cause\n        // dimension registration changes in response to reordering\n        dimensionMarshalStopper(dimensionMarshal),\n        // Fire application responders in response to drag changes\n        lift(dimensionMarshal),\n        drop,\n        // When a drop animation finishes - fire a drop complete\n        dropAnimationFinish,\n        dropAnimationFlushOnScroll,\n        pendingDrop,\n        autoScroll(autoScroller),\n        scrollListener,\n        focus(focusMarshal),\n        // Fire responders for consumers (after update to store)\n        responders(getResponders, announce),\n      ),\n    ),\n  );\n"
  },
  {
    "path": "src/state/did-start-after-critical.js",
    "content": "// @flow\nimport type { DraggableId, LiftEffect } from '../types';\n\nexport default function didStartAfterCritical(\n  draggableId: DraggableId,\n  afterCritical: LiftEffect,\n): boolean {\n  return Boolean(afterCritical.effected[draggableId]);\n}\n"
  },
  {
    "path": "src/state/dimension-marshal/dimension-marshal-types.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  UpdateDroppableScrollArgs,\n  UpdateDroppableIsEnabledArgs,\n  UpdateDroppableIsCombineEnabledArgs,\n} from '../action-creators';\nimport type {\n  DroppableId,\n  Critical,\n  DimensionMap,\n  LiftRequest,\n  Published,\n  Viewport,\n} from '../../types';\n\nexport type StartPublishingResult = {|\n  critical: Critical,\n  dimensions: DimensionMap,\n  viewport: Viewport,\n|};\n\nexport type DimensionMarshal = {|\n  // it is possible for a droppable to change whether it is enabled during a drag\n  updateDroppableIsEnabled: (id: DroppableId, isEnabled: boolean) => void,\n  // it is also possible to update whether combining is enabled\n  updateDroppableIsCombineEnabled: (\n    id: DroppableId,\n    isEnabled: boolean,\n  ) => void,\n  updateDroppableScroll: (id: DroppableId, newScroll: Position) => void,\n  scrollDroppable: (id: DroppableId, change: Position) => void,\n  // Entry\n  startPublishing: (request: LiftRequest) => StartPublishingResult,\n  stopPublishing: () => void,\n|};\n\nexport type Callbacks = {|\n  collectionStarting: () => mixed,\n  publishWhileDragging: (args: Published) => mixed,\n  updateDroppableScroll: (args: UpdateDroppableScrollArgs) => mixed,\n  updateDroppableIsEnabled: (args: UpdateDroppableIsEnabledArgs) => mixed,\n  updateDroppableIsCombineEnabled: (\n    args: UpdateDroppableIsCombineEnabledArgs,\n  ) => mixed,\n|};\n"
  },
  {
    "path": "src/state/dimension-marshal/dimension-marshal.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { invariant } from '../../invariant';\nimport type {\n  DimensionMarshal,\n  Callbacks,\n  StartPublishingResult,\n} from './dimension-marshal-types';\nimport createPublisher, {\n  type WhileDraggingPublisher,\n} from './while-dragging-publisher';\nimport getInitialPublish from './get-initial-publish';\nimport type {\n  Registry,\n  DroppableEntry,\n  DraggableEntry,\n  Subscriber,\n  Unsubscribe,\n  RegistryEvent,\n} from '../registry/registry-types';\nimport type {\n  DroppableId,\n  DroppableDescriptor,\n  LiftRequest,\n  Critical,\n  DraggableDescriptor,\n} from '../../types';\nimport { warning } from '../../dev-warning';\n\ntype Collection = {|\n  critical: Critical,\n  unsubscribe: Unsubscribe,\n|};\n\nfunction shouldPublishUpdate(\n  registry: Registry,\n  dragging: DraggableDescriptor,\n  entry: DraggableEntry,\n): boolean {\n  // do not publish updates for the critical draggable\n  if (entry.descriptor.id === dragging.id) {\n    return false;\n  }\n  // do not publish updates for draggables that are not of a type that we care about\n  if (entry.descriptor.type !== dragging.type) {\n    return false;\n  }\n\n  const home: DroppableEntry = registry.droppable.getById(\n    entry.descriptor.droppableId,\n  );\n\n  if (home.descriptor.mode !== 'virtual') {\n    warning(`\n      You are attempting to add or remove a Draggable [id: ${entry.descriptor.id}]\n      while a drag is occurring. This is only supported for virtual lists.\n\n      See https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/patterns/virtual-lists.md\n    `);\n    return false;\n  }\n\n  return true;\n}\n\nexport default (registry: Registry, callbacks: Callbacks) => {\n  let collection: ?Collection = null;\n\n  const publisher: WhileDraggingPublisher = createPublisher({\n    callbacks: {\n      publish: callbacks.publishWhileDragging,\n      collectionStarting: callbacks.collectionStarting,\n    },\n    registry,\n  });\n\n  const updateDroppableIsEnabled = (id: DroppableId, isEnabled: boolean) => {\n    invariant(\n      registry.droppable.exists(id),\n      `Cannot update is enabled flag of Droppable ${id} as it is not registered`,\n    );\n\n    // no need to update the application state if a collection is not occurring\n    if (!collection) {\n      return;\n    }\n\n    // At this point a non primary droppable dimension might not yet be published\n    // but may have its enabled state changed. For now we still publish this change\n    // and let the reducer exit early if it cannot find the dimension in the state.\n    callbacks.updateDroppableIsEnabled({ id, isEnabled });\n  };\n\n  const updateDroppableIsCombineEnabled = (\n    id: DroppableId,\n    isCombineEnabled: boolean,\n  ) => {\n    // no need to update\n    if (!collection) {\n      return;\n    }\n\n    invariant(\n      registry.droppable.exists(id),\n      `Cannot update isCombineEnabled flag of Droppable ${id} as it is not registered`,\n    );\n\n    callbacks.updateDroppableIsCombineEnabled({ id, isCombineEnabled });\n  };\n\n  const updateDroppableScroll = (id: DroppableId, newScroll: Position) => {\n    // no need to update the application state if a collection is not occurring\n    if (!collection) {\n      return;\n    }\n\n    invariant(\n      registry.droppable.exists(id),\n      `Cannot update the scroll on Droppable ${id} as it is not registered`,\n    );\n\n    callbacks.updateDroppableScroll({ id, newScroll });\n  };\n\n  const scrollDroppable = (id: DroppableId, change: Position) => {\n    if (!collection) {\n      return;\n    }\n    registry.droppable.getById(id).callbacks.scroll(change);\n  };\n\n  const stopPublishing = () => {\n    // This function can be called defensively\n    if (!collection) {\n      return;\n    }\n    // Stop any pending dom collections or publish\n    publisher.stop();\n\n    // Tell all droppables to stop watching scroll\n    // all good if they where not already listening\n    const home: DroppableDescriptor = collection.critical.droppable;\n    registry.droppable\n      .getAllByType(home.type)\n      .forEach((entry: DroppableEntry) => entry.callbacks.dragStopped());\n\n    // Unsubscribe from registry updates\n    collection.unsubscribe();\n    // Finally - clear our collection\n    collection = null;\n  };\n\n  const subscriber: Subscriber = (event: RegistryEvent) => {\n    invariant(\n      collection,\n      'Should only be subscribed when a collection is occurring',\n    );\n    // The dragging item can be add and removed when using a clone\n    // We do not publish updates for the critical item\n    const dragging: DraggableDescriptor = collection.critical.draggable;\n\n    if (event.type === 'ADDITION') {\n      if (shouldPublishUpdate(registry, dragging, event.value)) {\n        publisher.add(event.value);\n      }\n    }\n    if (event.type === 'REMOVAL') {\n      if (shouldPublishUpdate(registry, dragging, event.value)) {\n        publisher.remove(event.value);\n      }\n    }\n  };\n\n  const startPublishing = (request: LiftRequest): StartPublishingResult => {\n    invariant(\n      !collection,\n      'Cannot start capturing critical dimensions as there is already a collection',\n    );\n    const entry: DraggableEntry = registry.draggable.getById(\n      request.draggableId,\n    );\n    const home: DroppableEntry = registry.droppable.getById(\n      entry.descriptor.droppableId,\n    );\n\n    const critical: Critical = {\n      draggable: entry.descriptor,\n      droppable: home.descriptor,\n    };\n\n    const unsubscribe = registry.subscribe(subscriber);\n\n    collection = {\n      critical,\n      unsubscribe,\n    };\n\n    return getInitialPublish({\n      critical,\n      registry,\n      scrollOptions: request.scrollOptions,\n    });\n  };\n\n  const marshal: DimensionMarshal = {\n    // Droppable changes\n    updateDroppableIsEnabled,\n    updateDroppableIsCombineEnabled,\n    scrollDroppable,\n    updateDroppableScroll,\n\n    // Entry\n    startPublishing,\n    stopPublishing,\n  };\n\n  return marshal;\n};\n"
  },
  {
    "path": "src/state/dimension-marshal/get-initial-publish.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport * as timings from '../../debug/timings';\nimport type { StartPublishingResult } from './dimension-marshal-types';\nimport type {\n  Registry,\n  DraggableEntry,\n  DroppableEntry,\n} from '../registry/registry-types';\nimport { toDraggableMap, toDroppableMap } from '../dimension-structures';\nimport type {\n  DroppableDescriptor,\n  DroppableDimension,\n  DraggableDimension,\n  DimensionMap,\n  ScrollOptions,\n  Critical,\n  Viewport,\n} from '../../types';\nimport getViewport from '../../view/window/get-viewport';\n\ntype Args = {|\n  critical: Critical,\n  scrollOptions: ScrollOptions,\n  registry: Registry,\n|};\n\nexport default ({\n  critical,\n  scrollOptions,\n  registry,\n}: Args): StartPublishingResult => {\n  const timingKey: string = 'Initial collection from DOM';\n  timings.start(timingKey);\n  const viewport: Viewport = getViewport();\n  const windowScroll: Position = viewport.scroll.current;\n\n  const home: DroppableDescriptor = critical.droppable;\n\n  const droppables: DroppableDimension[] = registry.droppable\n    .getAllByType(home.type)\n    .map((entry: DroppableEntry): DroppableDimension =>\n      entry.callbacks.getDimensionAndWatchScroll(windowScroll, scrollOptions),\n    );\n\n  const draggables: DraggableDimension[] = registry.draggable\n    .getAllByType(critical.draggable.type)\n    .map((entry: DraggableEntry): DraggableDimension =>\n      entry.getDimension(windowScroll),\n    );\n\n  const dimensions: DimensionMap = {\n    draggables: toDraggableMap(draggables),\n    droppables: toDroppableMap(droppables),\n  };\n\n  timings.finish(timingKey);\n\n  const result: StartPublishingResult = {\n    dimensions,\n    critical,\n    viewport,\n  };\n\n  return result;\n};\n"
  },
  {
    "path": "src/state/dimension-marshal/while-dragging-publisher.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DraggableId,\n  DroppableId,\n  DraggableDescriptor,\n  Published,\n  DraggableDimension,\n  DroppablePublish,\n  DroppableIdMap,\n  DraggableIdMap,\n} from '../../types';\nimport type {\n  DroppableEntry,\n  Registry,\n  DraggableEntry,\n  DraggableEntryMap,\n} from '../registry/registry-types';\nimport * as timings from '../../debug/timings';\nimport { origin } from '../position';\n\nexport type WhileDraggingPublisher = {|\n  add: (entry: DraggableEntry) => void,\n  remove: (entry: DraggableEntry) => void,\n  stop: () => void,\n|};\n\ntype Staging = {|\n  additions: DraggableEntryMap,\n  removals: DraggableIdMap,\n  modified: DroppableIdMap,\n|};\n\ntype Callbacks = {|\n  publish: (args: Published) => mixed,\n  collectionStarting: () => mixed,\n|};\n\ntype Args = {|\n  registry: Registry,\n  callbacks: Callbacks,\n|};\n\nconst clean = (): Staging => ({\n  additions: {},\n  removals: {},\n  modified: {},\n});\n\nconst timingKey: string = 'Publish collection from DOM';\n\nexport default function createPublisher({\n  registry,\n  callbacks,\n}: Args): WhileDraggingPublisher {\n  let staging: Staging = clean();\n  let frameId: ?AnimationFrameID = null;\n\n  const collect = () => {\n    if (frameId) {\n      return;\n    }\n\n    callbacks.collectionStarting();\n    frameId = requestAnimationFrame(() => {\n      frameId = null;\n      timings.start(timingKey);\n\n      const { additions, removals, modified } = staging;\n\n      const added: DraggableDimension[] = Object.keys(additions)\n        .map(\n          // Using the origin as the window scroll. This will be adjusted when processing the published values\n          (id: DraggableId): DraggableDimension =>\n            registry.draggable.getById(id).getDimension(origin),\n        )\n        // Dimensions are not guarenteed to be ordered in the same order as keys\n        // So we need to sort them so they are in the correct order\n        .sort(\n          (a: DraggableDimension, b: DraggableDimension): number =>\n            a.descriptor.index - b.descriptor.index,\n        );\n\n      const updated: DroppablePublish[] = Object.keys(modified).map(\n        (id: DroppableId) => {\n          const entry: DroppableEntry = registry.droppable.getById(id);\n\n          const scroll: Position = entry.callbacks.getScrollWhileDragging();\n          return {\n            droppableId: id,\n            scroll,\n          };\n        },\n      );\n\n      const result: Published = {\n        additions: added,\n        removals: Object.keys(removals),\n        modified: updated,\n      };\n\n      staging = clean();\n\n      timings.finish(timingKey);\n      callbacks.publish(result);\n    });\n  };\n\n  const add = (entry: DraggableEntry) => {\n    const id: DraggableId = entry.descriptor.id;\n    staging.additions[id] = entry;\n    staging.modified[entry.descriptor.droppableId] = true;\n\n    if (staging.removals[id]) {\n      delete staging.removals[id];\n    }\n    collect();\n  };\n\n  const remove = (entry: DraggableEntry) => {\n    const descriptor: DraggableDescriptor = entry.descriptor;\n    staging.removals[descriptor.id] = true;\n    staging.modified[descriptor.droppableId] = true;\n\n    if (staging.additions[descriptor.id]) {\n      delete staging.additions[descriptor.id];\n    }\n    collect();\n  };\n\n  const stop = () => {\n    if (!frameId) {\n      return;\n    }\n\n    cancelAnimationFrame(frameId);\n    frameId = null;\n    staging = clean();\n  };\n\n  return {\n    add,\n    remove,\n    stop,\n  };\n}\n"
  },
  {
    "path": "src/state/dimension-structures.js",
    "content": "// @flow\nimport memoizeOne from 'memoize-one';\nimport { values } from '../native-with-fallback';\nimport type {\n  DroppableDimension,\n  DroppableDimensionMap,\n  DraggableDimension,\n  DraggableDimensionMap,\n} from '../types';\n\nexport const toDroppableMap = memoizeOne(\n  (droppables: DroppableDimension[]): DroppableDimensionMap =>\n    droppables.reduce((previous, current) => {\n      previous[current.descriptor.id] = current;\n      return previous;\n    }, {}),\n);\n\nexport const toDraggableMap = memoizeOne(\n  (draggables: DraggableDimension[]): DraggableDimensionMap =>\n    draggables.reduce((previous, current) => {\n      previous[current.descriptor.id] = current;\n      return previous;\n    }, {}),\n);\n\nexport const toDroppableList = memoizeOne(\n  (droppables: DroppableDimensionMap): DroppableDimension[] =>\n    values(droppables),\n);\n\nexport const toDraggableList = memoizeOne(\n  (draggables: DraggableDimensionMap): DraggableDimension[] =>\n    values(draggables),\n);\n"
  },
  {
    "path": "src/state/droppable/get-droppable.js",
    "content": "// @flow\nimport { type BoxModel, type Position } from 'css-box-model';\nimport type {\n  Axis,\n  DroppableDimension,\n  DroppableDescriptor,\n  Scrollable,\n  DroppableSubject,\n  ScrollSize,\n} from '../../types';\nimport { vertical, horizontal } from '../axis';\nimport { origin } from '../position';\nimport getMaxScroll from '../get-max-scroll';\nimport getSubject from './util/get-subject';\n\nexport type Closest = {|\n  client: BoxModel,\n  page: BoxModel,\n  scroll: Position,\n  scrollSize: ScrollSize,\n  shouldClipSubject: boolean,\n|};\n\ntype Args = {|\n  descriptor: DroppableDescriptor,\n  isEnabled: boolean,\n  isCombineEnabled: boolean,\n  isFixedOnPage: boolean,\n  direction: 'vertical' | 'horizontal',\n  client: BoxModel,\n  // is null when in a fixed container\n  page: BoxModel,\n  closest?: ?Closest,\n|};\n\nexport default ({\n  descriptor,\n  isEnabled,\n  isCombineEnabled,\n  isFixedOnPage,\n  direction,\n  client,\n  page,\n  closest,\n}: Args): DroppableDimension => {\n  const frame: ?Scrollable = (() => {\n    if (!closest) {\n      return null;\n    }\n\n    const { scrollSize, client: frameClient } = closest;\n\n    // scrollHeight and scrollWidth are based on the padding box\n    // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight\n    const maxScroll: Position = getMaxScroll({\n      scrollHeight: scrollSize.scrollHeight,\n      scrollWidth: scrollSize.scrollWidth,\n      height: frameClient.paddingBox.height,\n      width: frameClient.paddingBox.width,\n    });\n\n    return {\n      pageMarginBox: closest.page.marginBox,\n      frameClient,\n      scrollSize,\n      shouldClipSubject: closest.shouldClipSubject,\n      scroll: {\n        initial: closest.scroll,\n        current: closest.scroll,\n        max: maxScroll,\n        diff: {\n          value: origin,\n          displacement: origin,\n        },\n      },\n    };\n  })();\n\n  const axis: Axis = direction === 'vertical' ? vertical : horizontal;\n\n  const subject: DroppableSubject = getSubject({\n    page,\n    withPlaceholder: null,\n    axis,\n    frame,\n  });\n\n  const dimension: DroppableDimension = {\n    descriptor,\n    isCombineEnabled,\n    isFixedOnPage,\n    axis,\n    isEnabled,\n    client,\n    page,\n    frame,\n    subject,\n  };\n\n  return dimension;\n};\n"
  },
  {
    "path": "src/state/droppable/is-home-of.js",
    "content": "// @flow\nimport type { DraggableDimension, DroppableDimension } from '../../types';\n\nexport default (\n  draggable: DraggableDimension,\n  destination: DroppableDimension,\n): boolean => draggable.descriptor.droppableId === destination.descriptor.id;\n"
  },
  {
    "path": "src/state/droppable/scroll-droppable.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { invariant } from '../../invariant';\nimport type {\n  DroppableDimension,\n  Scrollable,\n  DroppableSubject,\n} from '../../types';\nimport { negate, subtract } from '../position';\nimport getSubject from './util/get-subject';\n\nexport default (\n  droppable: DroppableDimension,\n  newScroll: Position,\n): DroppableDimension => {\n  invariant(droppable.frame);\n  const scrollable: Scrollable = droppable.frame;\n\n  const scrollDiff: Position = subtract(newScroll, scrollable.scroll.initial);\n  // a positive scroll difference leads to a negative displacement\n  // (scrolling down pulls an item upwards)\n  const scrollDisplacement: Position = negate(scrollDiff);\n\n  // Sometimes it is possible to scroll beyond the max point.\n  // This can occur when scrolling a foreign list that now has a placeholder.\n\n  const frame: Scrollable = {\n    ...scrollable,\n    scroll: {\n      initial: scrollable.scroll.initial,\n      current: newScroll,\n      diff: {\n        value: scrollDiff,\n        displacement: scrollDisplacement,\n      },\n      // TODO: rename 'softMax?'\n      max: scrollable.scroll.max,\n    },\n  };\n\n  const subject: DroppableSubject = getSubject({\n    page: droppable.subject.page,\n    withPlaceholder: droppable.subject.withPlaceholder,\n    axis: droppable.axis,\n    frame,\n  });\n  const result: DroppableDimension = {\n    ...droppable,\n    frame,\n    subject,\n  };\n  return result;\n};\n"
  },
  {
    "path": "src/state/droppable/should-use-placeholder.js",
    "content": "// @flow\nimport type { DraggableDescriptor, DragImpact } from '../../types';\nimport whatIsDraggedOver from './what-is-dragged-over';\n\n// use placeholder if dragged over\nexport default (descriptor: DraggableDescriptor, impact: DragImpact): boolean =>\n  whatIsDraggedOver(impact) === descriptor.droppableId;\n"
  },
  {
    "path": "src/state/droppable/util/clip.js",
    "content": "// @flow\nimport { getRect, type Rect, type Spacing } from 'css-box-model';\n\nexport default (frame: Spacing, subject: Spacing): ?Rect => {\n  const result: Rect = getRect({\n    top: Math.max(subject.top, frame.top),\n    right: Math.min(subject.right, frame.right),\n    bottom: Math.min(subject.bottom, frame.bottom),\n    left: Math.max(subject.left, frame.left),\n  });\n\n  if (result.width <= 0 || result.height <= 0) {\n    return null;\n  }\n\n  return result;\n};\n"
  },
  {
    "path": "src/state/droppable/util/get-subject.js",
    "content": "// @flow\nimport { getRect, type Rect, type Spacing, type BoxModel } from 'css-box-model';\nimport type {\n  Axis,\n  Scrollable,\n  DroppableSubject,\n  PlaceholderInSubject,\n} from '../../../types';\nimport executeClip from './clip';\nimport { offsetByPosition } from '../../spacing';\n\nconst scroll = (target: Spacing, frame: ?Scrollable): Spacing => {\n  if (!frame) {\n    return target;\n  }\n\n  return offsetByPosition(target, frame.scroll.diff.displacement);\n};\n\nconst increase = (\n  target: Spacing,\n  axis: Axis,\n  withPlaceholder: ?PlaceholderInSubject,\n): Spacing => {\n  if (withPlaceholder && withPlaceholder.increasedBy) {\n    return {\n      ...target,\n      [axis.end]: target[axis.end] + withPlaceholder.increasedBy[axis.line],\n    };\n  }\n  return target;\n};\n\nconst clip = (target: Spacing, frame: ?Scrollable): ?Rect => {\n  if (frame && frame.shouldClipSubject) {\n    return executeClip(frame.pageMarginBox, target);\n  }\n  return getRect(target);\n};\n\ntype Args = {|\n  page: BoxModel,\n  withPlaceholder: ?PlaceholderInSubject,\n  axis: Axis,\n  frame: ?Scrollable,\n|};\n\nexport default ({\n  page,\n  withPlaceholder,\n  axis,\n  frame,\n}: Args): DroppableSubject => {\n  const scrolled: Spacing = scroll(page.marginBox, frame);\n  const increased: Spacing = increase(scrolled, axis, withPlaceholder);\n  const clipped: ?Rect = clip(increased, frame);\n\n  return {\n    page,\n    withPlaceholder,\n    active: clipped,\n  };\n};\n"
  },
  {
    "path": "src/state/droppable/what-is-dragged-over-from-result.js",
    "content": "// @flow\nimport type { DroppableId, DropResult } from '../../types';\n\nexport default (result: DropResult): ?DroppableId => {\n  const { combine, destination } = result;\n\n  if (destination) {\n    return destination.droppableId;\n  }\n\n  if (combine) {\n    return combine.droppableId;\n  }\n\n  return null;\n};\n"
  },
  {
    "path": "src/state/droppable/what-is-dragged-over.js",
    "content": "// @flow\nimport type { ImpactLocation, DroppableId, DragImpact } from '../../types';\n\nexport default (impact: DragImpact): ?DroppableId => {\n  const at: ?ImpactLocation = impact.at;\n\n  if (!at) {\n    return null;\n  }\n\n  if (at.type === 'REORDER') {\n    return at.destination.droppableId;\n  }\n\n  return at.combine.droppableId;\n};\n"
  },
  {
    "path": "src/state/droppable/with-placeholder.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { invariant } from '../../invariant';\nimport type {\n  Axis,\n  DroppableDimension,\n  DraggableDimension,\n  DraggableDimensionMap,\n  Scrollable,\n  DroppableSubject,\n  PlaceholderInSubject,\n} from '../../types';\nimport getDraggablesInsideDroppable from '../get-draggables-inside-droppable';\nimport { add, patch } from '../position';\nimport getSubject from './util/get-subject';\nimport isHomeOf from './is-home-of';\nimport getDisplacedBy from '../get-displaced-by';\n\nconst getRequiredGrowthForPlaceholder = (\n  droppable: DroppableDimension,\n  placeholderSize: Position,\n  draggables: DraggableDimensionMap,\n): ?Position => {\n  const axis: Axis = droppable.axis;\n\n  // A virtual list will most likely not contain all of the Draggables\n  // so counting them does not help.\n  if (droppable.descriptor.mode === 'virtual') {\n    return patch(axis.line, placeholderSize[axis.line]);\n  }\n\n  // TODO: consider margin collapsing?\n  // Using contentBox as that is where the Draggables will sit\n  const availableSpace: number = droppable.subject.page.contentBox[axis.size];\n  const insideDroppable: DraggableDimension[] = getDraggablesInsideDroppable(\n    droppable.descriptor.id,\n    draggables,\n  );\n  const spaceUsed: number = insideDroppable.reduce(\n    (sum: number, dimension: DraggableDimension): number =>\n      sum + dimension.client.marginBox[axis.size],\n    0,\n  );\n  const requiredSpace: number = spaceUsed + placeholderSize[axis.line];\n  const needsToGrowBy: number = requiredSpace - availableSpace;\n\n  // nothing to do here\n  if (needsToGrowBy <= 0) {\n    return null;\n  }\n\n  return patch(axis.line, needsToGrowBy);\n};\n\nconst withMaxScroll = (frame: Scrollable, max: Position): Scrollable => ({\n  ...frame,\n  scroll: {\n    ...frame.scroll,\n    max,\n  },\n});\n\nexport const addPlaceholder = (\n  droppable: DroppableDimension,\n  draggable: DraggableDimension,\n  draggables: DraggableDimensionMap,\n): DroppableDimension => {\n  const frame: ?Scrollable = droppable.frame;\n\n  invariant(\n    !isHomeOf(draggable, droppable),\n    'Should not add placeholder space to home list',\n  );\n\n  invariant(\n    !droppable.subject.withPlaceholder,\n    'Cannot add placeholder size to a subject when it already has one',\n  );\n\n  const placeholderSize: Position = getDisplacedBy(\n    droppable.axis,\n    draggable.displaceBy,\n  ).point;\n\n  const requiredGrowth: ?Position = getRequiredGrowthForPlaceholder(\n    droppable,\n    placeholderSize,\n    draggables,\n  );\n\n  const added: PlaceholderInSubject = {\n    placeholderSize,\n    increasedBy: requiredGrowth,\n    oldFrameMaxScroll: droppable.frame ? droppable.frame.scroll.max : null,\n  };\n\n  if (!frame) {\n    const subject: DroppableSubject = getSubject({\n      page: droppable.subject.page,\n      withPlaceholder: added,\n      axis: droppable.axis,\n      frame: droppable.frame,\n    });\n    return {\n      ...droppable,\n      subject,\n    };\n  }\n\n  const maxScroll: Position = requiredGrowth\n    ? add(frame.scroll.max, requiredGrowth)\n    : frame.scroll.max;\n\n  const newFrame: Scrollable = withMaxScroll(frame, maxScroll);\n\n  const subject: DroppableSubject = getSubject({\n    page: droppable.subject.page,\n    withPlaceholder: added,\n    axis: droppable.axis,\n    frame: newFrame,\n  });\n  return {\n    ...droppable,\n    subject,\n    frame: newFrame,\n  };\n};\n\nexport const removePlaceholder = (\n  droppable: DroppableDimension,\n): DroppableDimension => {\n  const added: ?PlaceholderInSubject = droppable.subject.withPlaceholder;\n  invariant(\n    added,\n    'Cannot remove placeholder form subject when there was none',\n  );\n\n  const frame: ?Scrollable = droppable.frame;\n\n  if (!frame) {\n    const subject: DroppableSubject = getSubject({\n      page: droppable.subject.page,\n      axis: droppable.axis,\n      frame: null,\n      // cleared\n      withPlaceholder: null,\n    });\n    return {\n      ...droppable,\n      subject,\n    };\n  }\n\n  const oldMaxScroll: ?Position = added.oldFrameMaxScroll;\n  invariant(\n    oldMaxScroll,\n    'Expected droppable with frame to have old max frame scroll when removing placeholder',\n  );\n\n  const newFrame: Scrollable = withMaxScroll(frame, oldMaxScroll);\n\n  const subject: DroppableSubject = getSubject({\n    page: droppable.subject.page,\n    axis: droppable.axis,\n    frame: newFrame,\n    // cleared\n    withPlaceholder: null,\n  });\n  return {\n    ...droppable,\n    subject,\n    frame: newFrame,\n  };\n};\n"
  },
  {
    "path": "src/state/get-center-from-impact/get-client-border-box-center/get-client-from-page-border-box-center.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { Viewport, DraggableDimension } from '../../../types';\nimport { add, subtract } from '../../position';\nimport withViewportDisplacement from '../../with-scroll-change/with-viewport-displacement';\n\ntype Args = {|\n  pageBorderBoxCenter: Position,\n  draggable: DraggableDimension,\n  viewport: Viewport,\n|};\n\nexport default ({\n  pageBorderBoxCenter,\n  draggable,\n  viewport,\n}: Args): Position => {\n  const withoutPageScrollChange: Position = withViewportDisplacement(\n    viewport,\n    pageBorderBoxCenter,\n  );\n\n  const offset: Position = subtract(\n    withoutPageScrollChange,\n    draggable.page.borderBox.center,\n  );\n\n  return add(draggable.client.borderBox.center, offset);\n};\n"
  },
  {
    "path": "src/state/get-center-from-impact/get-client-border-box-center/index.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DroppableDimension,\n  Viewport,\n  DragImpact,\n  DraggableDimension,\n  DraggableDimensionMap,\n  LiftEffect,\n} from '../../../types';\nimport getPageBorderBoxCenterFromImpact from '../get-page-border-box-center';\nimport getClientFromPageBorderBoxCenter from './get-client-from-page-border-box-center';\n\ntype Args = {|\n  impact: DragImpact,\n  draggable: DraggableDimension,\n  droppable: DroppableDimension,\n  draggables: DraggableDimensionMap,\n  viewport: Viewport,\n  afterCritical: LiftEffect,\n|};\n\nexport default ({\n  impact,\n  draggable,\n  droppable,\n  draggables,\n  viewport,\n  afterCritical,\n}: Args): Position => {\n  const pageBorderBoxCenter: Position = getPageBorderBoxCenterFromImpact({\n    impact,\n    draggable,\n    draggables,\n    droppable,\n    afterCritical,\n  });\n\n  return getClientFromPageBorderBoxCenter({\n    pageBorderBoxCenter,\n    draggable,\n    viewport,\n  });\n};\n"
  },
  {
    "path": "src/state/get-center-from-impact/get-page-border-box-center/index.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DragImpact,\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n  ImpactLocation,\n  LiftEffect,\n} from '../../../types';\nimport whenCombining from './when-combining';\nimport whenReordering from './when-reordering';\nimport withDroppableDisplacement from '../../with-scroll-change/with-droppable-displacement';\n\ntype Args = {|\n  impact: DragImpact,\n  afterCritical: LiftEffect,\n  draggable: DraggableDimension,\n  droppable: ?DroppableDimension,\n  draggables: DraggableDimensionMap,\n|};\n\nconst getResultWithoutDroppableDisplacement = ({\n  impact,\n  draggable,\n  droppable,\n  draggables,\n  afterCritical,\n}: Args): Position => {\n  const original: Position = draggable.page.borderBox.center;\n  const at: ?ImpactLocation = impact.at;\n\n  if (!droppable) {\n    return original;\n  }\n\n  if (!at) {\n    return original;\n  }\n\n  if (at.type === 'REORDER') {\n    return whenReordering({\n      impact,\n      draggable,\n      draggables,\n      droppable,\n      afterCritical,\n    });\n  }\n\n  return whenCombining({\n    impact,\n    draggables,\n    afterCritical,\n  });\n};\n\nexport default (args: Args): Position => {\n  const withoutDisplacement: Position = getResultWithoutDroppableDisplacement(\n    args,\n  );\n\n  const droppable: ?DroppableDimension = args.droppable;\n\n  const withDisplacement: Position = droppable\n    ? withDroppableDisplacement(droppable, withoutDisplacement)\n    : withoutDisplacement;\n\n  return withDisplacement;\n};\n"
  },
  {
    "path": "src/state/get-center-from-impact/get-page-border-box-center/when-combining.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { invariant } from '../../../invariant';\nimport type {\n  DraggableDimensionMap,\n  DraggableId,\n  Combine,\n  LiftEffect,\n  DragImpact,\n} from '../../../types';\nimport { add } from '../../position';\nimport getCombinedItemDisplacement from '../../get-combined-item-displacement';\nimport { tryGetCombine } from '../../get-impact-location';\n\ntype Args = {|\n  impact: DragImpact,\n  // all draggables in the system\n  draggables: DraggableDimensionMap,\n  afterCritical: LiftEffect,\n|};\n\n// Returns the client offset required to move an item from its\n// original client position to its final resting position\nexport default ({ afterCritical, impact, draggables }: Args): Position => {\n  const combine: ?Combine = tryGetCombine(impact);\n  invariant(combine);\n\n  const combineWith: DraggableId = combine.draggableId;\n  const center: Position = draggables[combineWith].page.borderBox.center;\n\n  const displaceBy: Position = getCombinedItemDisplacement({\n    displaced: impact.displaced,\n    afterCritical,\n    combineWith,\n    displacedBy: impact.displacedBy,\n  });\n\n  return add(center, displaceBy);\n};\n"
  },
  {
    "path": "src/state/get-center-from-impact/get-page-border-box-center/when-reordering.js",
    "content": "// @flow\nimport { offset, type Position, type BoxModel } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DraggableId,\n  DraggableDimension,\n  DraggableDimensionMap,\n  DroppableDimension,\n  LiftEffect,\n} from '../../../types';\nimport { goBefore, goAfter, goIntoStart } from '../move-relative-to';\nimport getDraggablesInsideDroppable from '../../get-draggables-inside-droppable';\nimport { negate } from '../../position';\nimport didStartAfterCritical from '../../did-start-after-critical';\n\ntype NewHomeArgs = {|\n  impact: DragImpact,\n  draggable: DraggableDimension,\n  draggables: DraggableDimensionMap,\n  droppable: DroppableDimension,\n  afterCritical: LiftEffect,\n|};\n\n// Returns the client offset required to move an item from its\n// original client position to its final resting position\nexport default ({\n  impact,\n  draggable,\n  draggables,\n  droppable,\n  afterCritical,\n}: NewHomeArgs): Position => {\n  const insideDestination: DraggableDimension[] = getDraggablesInsideDroppable(\n    droppable.descriptor.id,\n    draggables,\n  );\n\n  const draggablePage: BoxModel = draggable.page;\n  const axis: Axis = droppable.axis;\n\n  // this will only happen in a foreign list\n  if (!insideDestination.length) {\n    return goIntoStart({\n      axis,\n      moveInto: droppable.page,\n      isMoving: draggablePage,\n    });\n  }\n\n  const { displaced, displacedBy } = impact;\n  const closestAfter: ?DraggableId = displaced.all[0];\n\n  // go before the first displaced item\n  // items can only be displaced forwards\n  if (closestAfter) {\n    const closest: DraggableDimension = draggables[closestAfter];\n    // want to go before where it would be with the displacement\n\n    // target is displaced and is already in it's starting position\n    if (didStartAfterCritical(closestAfter, afterCritical)) {\n      return goBefore({\n        axis,\n        moveRelativeTo: closest.page,\n        isMoving: draggablePage,\n      });\n    }\n\n    // target has been displaced during the drag and it is not in its starting position\n    // we need to account for the displacement\n    const withDisplacement: BoxModel = offset(closest.page, displacedBy.point);\n\n    return goBefore({\n      axis,\n      moveRelativeTo: withDisplacement,\n      isMoving: draggablePage,\n    });\n  }\n\n  // Nothing in list is displaced, we should go after the last item\n\n  const last: DraggableDimension =\n    insideDestination[insideDestination.length - 1];\n\n  // we can just go into our original position if the last item\n  // is the dragging item\n  if (last.descriptor.id === draggable.descriptor.id) {\n    return draggablePage.borderBox.center;\n  }\n\n  if (didStartAfterCritical(last.descriptor.id, afterCritical)) {\n    // if the item started displaced and it is no longer displaced then\n    // we need to go after it it's non-displaced position\n\n    const page: BoxModel = offset(\n      last.page,\n      negate(afterCritical.displacedBy.point),\n    );\n    return goAfter({\n      axis,\n      moveRelativeTo: page,\n      isMoving: draggablePage,\n    });\n  }\n\n  // item is in its resting spot. we can go straight after it\n  return goAfter({\n    axis,\n    moveRelativeTo: last.page,\n    isMoving: draggablePage,\n  });\n};\n"
  },
  {
    "path": "src/state/get-center-from-impact/move-relative-to.js",
    "content": "// @flow\nimport type { Position, BoxModel, Rect } from 'css-box-model';\nimport { patch } from '../position';\nimport type { Axis } from '../../types';\n\ntype Args = {|\n  axis: Axis,\n  moveRelativeTo: BoxModel,\n  isMoving: BoxModel,\n|};\n\nconst distanceFromStartToBorderBoxCenter = (\n  axis: Axis,\n  box: BoxModel,\n): number => box.margin[axis.start] + box.borderBox[axis.size] / 2;\n\nconst distanceFromEndToBorderBoxCenter = (axis: Axis, box: BoxModel): number =>\n  box.margin[axis.end] + box.borderBox[axis.size] / 2;\n\n// We align the moving item against the cross axis start of the target\n// We used to align the moving item cross axis center with the cross axis center of the target.\n// However, this leads to a bad experience when reordering columns\nconst getCrossAxisBorderBoxCenter = (\n  axis: Axis,\n  target: Rect,\n  isMoving: BoxModel,\n): number =>\n  target[axis.crossAxisStart] +\n  isMoving.margin[axis.crossAxisStart] +\n  isMoving.borderBox[axis.crossAxisSize] / 2;\n\nexport const goAfter = ({ axis, moveRelativeTo, isMoving }: Args): Position =>\n  patch(\n    axis.line,\n    // start measuring from the end of the target\n    moveRelativeTo.marginBox[axis.end] +\n      distanceFromStartToBorderBoxCenter(axis, isMoving),\n    getCrossAxisBorderBoxCenter(axis, moveRelativeTo.marginBox, isMoving),\n  );\n\nexport const goBefore = ({ axis, moveRelativeTo, isMoving }: Args): Position =>\n  patch(\n    axis.line,\n    // start measuring from the start of the target\n    moveRelativeTo.marginBox[axis.start] -\n      distanceFromEndToBorderBoxCenter(axis, isMoving),\n    getCrossAxisBorderBoxCenter(axis, moveRelativeTo.marginBox, isMoving),\n  );\ntype GoIntoArgs = {|\n  axis: Axis,\n  moveInto: BoxModel,\n  isMoving: BoxModel,\n|};\n\n// moves into the content box\nexport const goIntoStart = ({\n  axis,\n  moveInto,\n  isMoving,\n}: GoIntoArgs): Position =>\n  patch(\n    axis.line,\n    moveInto.contentBox[axis.start] +\n      distanceFromStartToBorderBoxCenter(axis, isMoving),\n    getCrossAxisBorderBoxCenter(axis, moveInto.contentBox, isMoving),\n  );\n"
  },
  {
    "path": "src/state/get-combined-item-displacement.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DisplacementGroups,\n  LiftEffect,\n  DraggableId,\n  DisplacedBy,\n} from '../types';\nimport { origin, negate } from './position';\nimport didStartAfterCritical from './did-start-after-critical';\n\ntype Args = {|\n  displaced: DisplacementGroups,\n  afterCritical: LiftEffect,\n  combineWith: DraggableId,\n  displacedBy: DisplacedBy,\n|};\n\nexport default ({\n  displaced,\n  afterCritical,\n  combineWith,\n  displacedBy,\n}: Args): Position => {\n  const isDisplaced: boolean = Boolean(\n    displaced.visible[combineWith] || displaced.invisible[combineWith],\n  );\n\n  if (didStartAfterCritical(combineWith, afterCritical)) {\n    return isDisplaced ? origin : negate(displacedBy.point);\n  }\n\n  return isDisplaced ? displacedBy.point : origin;\n};\n"
  },
  {
    "path": "src/state/get-displaced-by.js",
    "content": "// @flow\nimport memoizeOne from 'memoize-one';\nimport { type Position } from 'css-box-model';\nimport type { Axis, DisplacedBy } from '../types';\nimport { patch } from './position';\n\n// TODO: memoization needed?\nexport default memoizeOne(function getDisplacedBy(\n  axis: Axis,\n  displaceBy: Position,\n): DisplacedBy {\n  const displacement: number = displaceBy[axis.line];\n  return {\n    value: displacement,\n    point: patch(axis.line, displacement),\n  };\n});\n"
  },
  {
    "path": "src/state/get-displacement-groups.js",
    "content": "// @flow\nimport { type Rect, type Spacing, expand, getRect } from 'css-box-model';\nimport type {\n  DraggableId,\n  Displacement,\n  DraggableDimension,\n  DroppableDimension,\n  DisplacementGroups,\n  DisplacedBy,\n} from '../types';\nimport { isPartiallyVisible } from './visibility/is-visible';\n\ntype Args = {|\n  afterDragging: DraggableDimension[],\n  destination: DroppableDimension,\n  displacedBy: DisplacedBy,\n  last: ?DisplacementGroups,\n  viewport: Rect,\n  forceShouldAnimate?: boolean,\n|};\n\nconst getShouldAnimate = (\n  id,\n  last: ?DisplacementGroups,\n  forceShouldAnimate: ?boolean,\n) => {\n  // Use a forced value if provided\n  if (typeof forceShouldAnimate === 'boolean') {\n    return forceShouldAnimate;\n  }\n\n  // nothing to gauge animation from\n  if (!last) {\n    return true;\n  }\n\n  const { invisible, visible } = last;\n\n  // it was previously invisible - no animation\n  if (invisible[id]) {\n    return false;\n  }\n\n  const previous: ?Displacement = visible[id];\n\n  return previous ? previous.shouldAnimate : true;\n};\n\n// Note: it is also an optimisation to not render the displacement on\n// items when they are not longer visible.\n// This prevents a lot of .render() calls when leaving / entering a list\n\nfunction getTarget(\n  draggable: DraggableDimension,\n  displacedBy: DisplacedBy,\n): Rect {\n  const marginBox: Rect = draggable.page.marginBox;\n\n  // ## Visibility overscanning\n  // We are expanding rather than offsetting the marginBox.\n  // In some cases we want\n  // - the target based on the starting position (such as when dropping outside of any list)\n  // - the target based on the items position without starting displacement (such as when moving inside a list)\n  // To keep things simple we just expand the whole area for this check\n  // The worst case is some minor redundant offscreen movements\n  const expandBy: Spacing = {\n    // pull backwards into viewport\n    top: displacedBy.point.y,\n    right: 0,\n    bottom: 0,\n    // pull backwards into viewport\n    left: displacedBy.point.x,\n  };\n\n  return getRect(expand(marginBox, expandBy));\n}\n\nexport default function getDisplacementGroups({\n  afterDragging,\n  destination,\n  displacedBy,\n  viewport,\n  forceShouldAnimate,\n  last,\n}: Args): DisplacementGroups {\n  return afterDragging.reduce(\n    function process(\n      groups: DisplacementGroups,\n      draggable: DraggableDimension,\n    ): DisplacementGroups {\n      const target: Rect = getTarget(draggable, displacedBy);\n      const id: DraggableId = draggable.descriptor.id;\n\n      groups.all.push(id);\n\n      const isVisible: boolean = isPartiallyVisible({\n        target,\n        destination,\n        viewport,\n        withDroppableDisplacement: true,\n      });\n\n      if (!isVisible) {\n        groups.invisible[draggable.descriptor.id] = true;\n        return groups;\n      }\n\n      // item is visible\n\n      const shouldAnimate: boolean = getShouldAnimate(\n        id,\n        last,\n        forceShouldAnimate,\n      );\n\n      const displacement: Displacement = {\n        draggableId: id,\n        shouldAnimate,\n      };\n\n      groups.visible[id] = displacement;\n      return groups;\n    },\n    {\n      all: [],\n      visible: {},\n      invisible: {},\n    },\n  );\n}\n"
  },
  {
    "path": "src/state/get-drag-impact/get-combine-impact.js",
    "content": "// @flow\nimport type { Rect } from 'css-box-model';\nimport type {\n  DraggableId,\n  Axis,\n  DraggableDimension,\n  DroppableDimension,\n  DragImpact,\n  LiftEffect,\n  DisplacedBy,\n} from '../../types';\nimport { find } from '../../native-with-fallback';\nimport getDidStartAfterCritical from '../did-start-after-critical';\nimport getDisplacedBy from '../get-displaced-by';\nimport getIsDisplaced from '../get-is-displaced';\nimport removeDraggableFromList from '../remove-draggable-from-list';\n\ntype Args = {|\n  draggable: DraggableDimension,\n  pageBorderBoxWithDroppableScroll: Rect,\n  previousImpact: DragImpact,\n  destination: DroppableDimension,\n  insideDestination: DraggableDimension[],\n  afterCritical: LiftEffect,\n|};\n\n// exported for testing\nexport const combineThresholdDivisor: number = 4;\n\nexport default ({\n  draggable,\n  pageBorderBoxWithDroppableScroll: targetRect,\n  previousImpact,\n  destination,\n  insideDestination,\n  afterCritical,\n}: Args): ?DragImpact => {\n  if (!destination.isCombineEnabled) {\n    return null;\n  }\n  const axis: Axis = destination.axis;\n  const displacedBy: DisplacedBy = getDisplacedBy(\n    destination.axis,\n    draggable.displaceBy,\n  );\n  const displacement: number = displacedBy.value;\n\n  const targetStart: number = targetRect[axis.start];\n  const targetEnd: number = targetRect[axis.end];\n\n  const withoutDragging: DraggableDimension[] = removeDraggableFromList(\n    draggable,\n    insideDestination,\n  );\n\n  const combineWith: ?DraggableDimension = find(\n    withoutDragging,\n    (child: DraggableDimension): boolean => {\n      const id: DraggableId = child.descriptor.id;\n      const childRect: Rect = child.page.borderBox;\n      const childSize: number = childRect[axis.size];\n      const threshold: number = childSize / combineThresholdDivisor;\n\n      const didStartAfterCritical: boolean = getDidStartAfterCritical(\n        id,\n        afterCritical,\n      );\n\n      const isDisplaced: boolean = getIsDisplaced({\n        displaced: previousImpact.displaced,\n        id,\n      });\n\n      /*\n        Only combining when in the combine region\n        As soon as a boundary is hit then no longer combining\n      */\n\n      if (didStartAfterCritical) {\n        // In original position\n        // Will combine with item when inside a band\n        if (isDisplaced) {\n          return (\n            targetEnd > childRect[axis.start] + threshold &&\n            targetEnd < childRect[axis.end] - threshold\n          );\n        }\n\n        // child is now 'displaced' backwards from where it started\n        // want to combine when we move backwards onto it\n        return (\n          targetStart > childRect[axis.start] - displacement + threshold &&\n          targetStart < childRect[axis.end] - displacement - threshold\n        );\n      }\n\n      // item has moved forwards\n      if (isDisplaced) {\n        return (\n          targetEnd > childRect[axis.start] + displacement + threshold &&\n          targetEnd < childRect[axis.end] + displacement - threshold\n        );\n      }\n\n      // is in resting position - being moved backwards on to\n      return (\n        targetStart > childRect[axis.start] + threshold &&\n        targetStart < childRect[axis.end] - threshold\n      );\n    },\n  );\n\n  if (!combineWith) {\n    return null;\n  }\n\n  const impact: DragImpact = {\n    // no change to displacement when combining\n    displacedBy,\n    displaced: previousImpact.displaced,\n    at: {\n      type: 'COMBINE',\n      combine: {\n        draggableId: combineWith.descriptor.id,\n        droppableId: destination.descriptor.id,\n      },\n    },\n  };\n  return impact;\n};\n"
  },
  {
    "path": "src/state/get-drag-impact/get-reorder-impact.js",
    "content": "// @flow\nimport { type Rect } from 'css-box-model';\nimport type {\n  DraggableId,\n  DraggableDimension,\n  DroppableDimension,\n  DragImpact,\n  Axis,\n  DisplacementGroups,\n  Viewport,\n  DisplacedBy,\n  LiftEffect,\n} from '../../types';\nimport getDisplacedBy from '../get-displaced-by';\nimport removeDraggableFromList from '../remove-draggable-from-list';\nimport isHomeOf from '../droppable/is-home-of';\nimport { find } from '../../native-with-fallback';\nimport getDidStartAfterCritical from '../did-start-after-critical';\nimport calculateReorderImpact from '../calculate-drag-impact/calculate-reorder-impact';\nimport getIsDisplaced from '../get-is-displaced';\n\ntype Args = {|\n  pageBorderBoxWithDroppableScroll: Rect,\n  draggable: DraggableDimension,\n  destination: DroppableDimension,\n  insideDestination: DraggableDimension[],\n  last: DisplacementGroups,\n  viewport: Viewport,\n  afterCritical: LiftEffect,\n|};\n\ntype AtIndexArgs = {|\n  draggable: DraggableDimension,\n  closest: ?DraggableDimension,\n  inHomeList: boolean,\n|};\n\nfunction atIndex({ draggable, closest, inHomeList }: AtIndexArgs): ?number {\n  if (!closest) {\n    return null;\n  }\n\n  if (!inHomeList) {\n    return closest.descriptor.index;\n  }\n\n  if (closest.descriptor.index > draggable.descriptor.index) {\n    return closest.descriptor.index - 1;\n  }\n\n  return closest.descriptor.index;\n}\n\nexport default ({\n  pageBorderBoxWithDroppableScroll: targetRect,\n  draggable,\n  destination,\n  insideDestination,\n  last,\n  viewport,\n  afterCritical,\n}: Args): DragImpact => {\n  const axis: Axis = destination.axis;\n  const displacedBy: DisplacedBy = getDisplacedBy(\n    destination.axis,\n    draggable.displaceBy,\n  );\n  const displacement: number = displacedBy.value;\n\n  const targetStart: number = targetRect[axis.start];\n  const targetEnd: number = targetRect[axis.end];\n\n  const withoutDragging: DraggableDimension[] = removeDraggableFromList(\n    draggable,\n    insideDestination,\n  );\n\n  const closest: ?DraggableDimension = find(\n    withoutDragging,\n    (child: DraggableDimension): boolean => {\n      const id: DraggableId = child.descriptor.id;\n      const childCenter: number = child.page.borderBox.center[axis.line];\n\n      const didStartAfterCritical: boolean = getDidStartAfterCritical(\n        id,\n        afterCritical,\n      );\n\n      const isDisplaced: boolean = getIsDisplaced({ displaced: last, id });\n\n      /*\n      Note: we change things when moving *past* the child center - not when it hits the center\n      If we make it when we *hit* the child center then there can be\n      a hit on the next update causing a flicker.\n\n      - Update 1: targetBottom hits center => displace backwards\n      - Update 2: targetStart is now hitting the displaced center => displace forwards\n      - Update 3: goto 1 (boom)\n    */\n\n      if (didStartAfterCritical) {\n        // Continue to displace while targetEnd before the childCenter\n        // Move once we *move forward past* the childCenter\n        if (isDisplaced) {\n          return targetEnd <= childCenter;\n        }\n\n        // Has been moved backwards from where it started\n        // Displace forwards when targetStart *moves backwards past* the displaced childCenter\n        return targetStart < childCenter - displacement;\n      }\n\n      // Item has been shifted forward.\n      // Remove displacement when targetEnd moves forward past the displaced center\n      if (isDisplaced) {\n        return targetEnd <= childCenter + displacement;\n      }\n\n      // Item is behind the dragging item\n      // We want to displace it if the targetStart goes *backwards past* the childCenter\n      return targetStart < childCenter;\n    },\n  );\n\n  const newIndex: ?number = atIndex({\n    draggable,\n    closest,\n    inHomeList: isHomeOf(draggable, destination),\n  });\n\n  // TODO: index cannot be null?\n  // otherwise return null from there and return empty impact\n  // that was calculate reorder impact does not need to account for a null index\n  return calculateReorderImpact({\n    draggable,\n    insideDestination,\n    destination,\n    viewport,\n    last,\n    displacedBy,\n    index: newIndex,\n  });\n};\n"
  },
  {
    "path": "src/state/get-drag-impact/index.js",
    "content": "// @flow\nimport { type Position, type Rect } from 'css-box-model';\nimport type {\n  DroppableId,\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n  DroppableDimensionMap,\n  DragImpact,\n  Viewport,\n  LiftEffect,\n} from '../../types';\nimport getDroppableOver from '../get-droppable-over';\nimport getDraggablesInsideDroppable from '../get-draggables-inside-droppable';\nimport withDroppableScroll from '../with-scroll-change/with-droppable-scroll';\nimport getReorderImpact from './get-reorder-impact';\nimport getCombineImpact from './get-combine-impact';\nimport noImpact from '../no-impact';\nimport { offsetRectByPosition } from '../rect';\n\ntype Args = {|\n  pageOffset: Position,\n  draggable: DraggableDimension,\n  // all dimensions in system\n  draggables: DraggableDimensionMap,\n  droppables: DroppableDimensionMap,\n  previousImpact: DragImpact,\n  viewport: Viewport,\n  afterCritical: LiftEffect,\n|};\n\nexport default ({\n  pageOffset,\n  draggable,\n  draggables,\n  droppables,\n  previousImpact,\n  viewport,\n  afterCritical,\n}: Args): DragImpact => {\n  const pageBorderBox: Rect = offsetRectByPosition(\n    draggable.page.borderBox,\n    pageOffset,\n  );\n\n  const destinationId: ?DroppableId = getDroppableOver({\n    pageBorderBox,\n    draggable,\n    droppables,\n  });\n\n  // not dragging over anything\n\n  if (!destinationId) {\n    // A big design decision was made here to collapse the home list\n    // when not over any list. This yielded the most consistently beautiful experience.\n    return noImpact;\n  }\n\n  const destination: DroppableDimension = droppables[destinationId];\n  const insideDestination: DraggableDimension[] = getDraggablesInsideDroppable(\n    destination.descriptor.id,\n    draggables,\n  );\n\n  // Where the element actually is now.\n  // Need to take into account the change of scroll in the droppable\n  const pageBorderBoxWithDroppableScroll: Rect = withDroppableScroll(\n    destination,\n    pageBorderBox,\n  );\n\n  // checking combine first so we combine before any reordering\n  return (\n    getCombineImpact({\n      pageBorderBoxWithDroppableScroll,\n      draggable,\n      previousImpact,\n      destination,\n      insideDestination,\n      afterCritical,\n    }) ||\n    getReorderImpact({\n      pageBorderBoxWithDroppableScroll,\n      draggable,\n      destination,\n      insideDestination,\n      last: previousImpact.displaced,\n      viewport,\n      afterCritical,\n    })\n  );\n};\n"
  },
  {
    "path": "src/state/get-draggables-inside-droppable.js",
    "content": "// @flow\nimport memoizeOne from 'memoize-one';\nimport { toDraggableList } from './dimension-structures';\nimport type {\n  DraggableDimension,\n  DroppableId,\n  DraggableDimensionMap,\n} from '../types';\n\nexport default memoizeOne(\n  (\n    // using droppableId to avoid cache busted when we\n    // update the droppable (such as when it scrolls)\n    droppableId: DroppableId,\n    draggables: DraggableDimensionMap,\n  ): DraggableDimension[] => {\n    const result = toDraggableList(draggables)\n      .filter(\n        (draggable: DraggableDimension): boolean =>\n          droppableId === draggable.descriptor.droppableId,\n      )\n      // Dimensions are not guarenteed to be ordered in the same order as keys\n      // So we need to sort them so they are in the correct order\n      .sort(\n        (a: DraggableDimension, b: DraggableDimension): number =>\n          a.descriptor.index - b.descriptor.index,\n      );\n\n    return result;\n  },\n);\n"
  },
  {
    "path": "src/state/get-droppable-over.js",
    "content": "// @flow\nimport { type Position, type Rect } from 'css-box-model';\nimport type {\n  DroppableDimension,\n  DroppableDimensionMap,\n  DroppableId,\n  DraggableDimension,\n  Axis,\n} from '../types';\nimport { toDroppableList } from './dimension-structures';\nimport isPositionInFrame from './visibility/is-position-in-frame';\nimport { distance, patch } from './position';\nimport isWithin from './is-within';\n\n// https://stackoverflow.com/questions/306316/determine-if-two-rectangles-overlap-each-other\n// https://silentmatt.com/rectangle-intersection/\nfunction getHasOverlap(first: Rect, second: Rect): boolean {\n  return (\n    first.left < second.right &&\n    first.right > second.left &&\n    first.top < second.bottom &&\n    first.bottom > second.top\n  );\n}\n\ntype Args = {|\n  pageBorderBox: Rect,\n  draggable: DraggableDimension,\n  droppables: DroppableDimensionMap,\n|};\n\ntype WithDistance = {|\n  distance: number,\n  id: DroppableId,\n|};\n\ntype GetFurthestArgs = {|\n  pageBorderBox: Rect,\n  draggable: DraggableDimension,\n  candidates: DroppableDimension[],\n|};\n\nfunction getFurthestAway({\n  pageBorderBox,\n  draggable,\n  candidates,\n}: GetFurthestArgs): ?DroppableId {\n  // We are not comparing the center of the home list with the target list as it would\n  // give preference to giant lists\n\n  // We are measuring the distance from where the draggable started\n  // to where it is *hitting* the candidate\n  // Note: The hit point might technically not be in the bounds of the candidate\n\n  const startCenter: Position = draggable.page.borderBox.center;\n  const sorted: WithDistance[] = candidates\n    .map((candidate: DroppableDimension): WithDistance => {\n      const axis: Axis = candidate.axis;\n      const target: Position = patch(\n        candidate.axis.line,\n        // use the current center of the dragging item on the main axis\n        pageBorderBox.center[axis.line],\n        // use the center of the list on the cross axis\n        candidate.page.borderBox.center[axis.crossAxisLine],\n      );\n\n      return {\n        id: candidate.descriptor.id,\n        distance: distance(startCenter, target),\n      };\n    })\n    // largest value will be first\n    .sort((a: WithDistance, b: WithDistance) => b.distance - a.distance);\n\n  // just being safe\n  return sorted[0] ? sorted[0].id : null;\n}\n\nexport default function getDroppableOver({\n  pageBorderBox,\n  draggable,\n  droppables,\n}: Args): ?DroppableId {\n  // We know at this point that some overlap has to exist\n  const candidates: DroppableDimension[] = toDroppableList(droppables).filter(\n    (item: DroppableDimension): boolean => {\n      // Cannot be a candidate when disabled\n      if (!item.isEnabled) {\n        return false;\n      }\n\n      // Cannot be a candidate when there is no visible area\n      const active: ?Rect = item.subject.active;\n      if (!active) {\n        return false;\n      }\n\n      // Cannot be a candidate when dragging item is not over the droppable at all\n      if (!getHasOverlap(pageBorderBox, active)) {\n        return false;\n      }\n\n      // 1. Candidate if the center position is over a droppable\n      if (isPositionInFrame(active)(pageBorderBox.center)) {\n        return true;\n      }\n\n      // 2. Candidate if an edge is over the cross axis half way point\n      // 3. Candidate if dragging item is totally over droppable on cross axis\n\n      const axis: Axis = item.axis;\n      const childCenter: number = active.center[axis.crossAxisLine];\n      const crossAxisStart: number = pageBorderBox[axis.crossAxisStart];\n      const crossAxisEnd: number = pageBorderBox[axis.crossAxisEnd];\n\n      const isContained = isWithin(\n        active[axis.crossAxisStart],\n        active[axis.crossAxisEnd],\n      );\n\n      const isStartContained: boolean = isContained(crossAxisStart);\n      const isEndContained: boolean = isContained(crossAxisEnd);\n\n      // Dragging item is totally covering the active area\n      if (!isStartContained && !isEndContained) {\n        return true;\n      }\n\n      /**\n       * edges must go beyond the center line in order to avoid\n       * cases were both conditions are satisfied.\n       */\n      if (isStartContained) {\n        return crossAxisStart < childCenter;\n      }\n\n      return crossAxisEnd > childCenter;\n    },\n  );\n\n  if (!candidates.length) {\n    return null;\n  }\n\n  // Only one candidate - use that!\n  if (candidates.length === 1) {\n    return candidates[0].descriptor.id;\n  }\n\n  // Multiple options returned\n  // Should only occur with really large items\n  // Going to use fallback: distance from home\n  return getFurthestAway({\n    pageBorderBox,\n    draggable,\n    candidates,\n  });\n}\n"
  },
  {
    "path": "src/state/get-frame.js",
    "content": "// @flow\nimport { invariant } from '../invariant';\n\nimport type { DroppableDimension, Scrollable } from '../types';\n\nexport default (droppable: DroppableDimension): Scrollable => {\n  const frame: ?Scrollable = droppable.frame;\n  invariant(frame, 'Expected Droppable to have a frame');\n  return frame;\n};\n"
  },
  {
    "path": "src/state/get-home-location.js",
    "content": "// @flow\nimport type { DraggableDescriptor, DraggableLocation } from '../types';\n\nexport default (descriptor: DraggableDescriptor): DraggableLocation => ({\n  index: descriptor.index,\n  droppableId: descriptor.droppableId,\n});\n"
  },
  {
    "path": "src/state/get-impact-location.js",
    "content": "// @flow\nimport type { DragImpact, DraggableLocation, Combine } from '../types';\n\nexport function tryGetDestination(impact: DragImpact): ?DraggableLocation {\n  if (impact.at && impact.at.type === 'REORDER') {\n    return impact.at.destination;\n  }\n  return null;\n}\n\nexport function tryGetCombine(impact: DragImpact): ?Combine {\n  if (impact.at && impact.at.type === 'COMBINE') {\n    return impact.at.combine;\n  }\n  return null;\n}\n"
  },
  {
    "path": "src/state/get-is-displaced.js",
    "content": "// @flow\nimport type { DisplacementGroups, DraggableId } from '../types';\n\ntype Args = {|\n  displaced: DisplacementGroups,\n  id: DraggableId,\n|};\n\nexport default function getIsDisplaced({ displaced, id }: Args): boolean {\n  return Boolean(displaced.visible[id] || displaced.invisible[id]);\n}\n"
  },
  {
    "path": "src/state/get-lift-effect.js",
    "content": "// @flow\nimport { invariant } from '../invariant';\nimport getHomeLocation from './get-home-location';\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n  DragImpact,\n  DisplacedBy,\n  Viewport,\n  DraggableIdMap,\n  DisplacementGroups,\n  LiftEffect,\n} from '../types';\nimport getDraggablesInsideDroppable from './get-draggables-inside-droppable';\nimport getDisplacedBy from './get-displaced-by';\nimport getDisplacementGroups from './get-displacement-groups';\n\ntype Args = {|\n  draggable: DraggableDimension,\n  home: DroppableDimension,\n  draggables: DraggableDimensionMap,\n  viewport: Viewport,\n|};\n\ntype Result = {|\n  afterCritical: LiftEffect,\n  impact: DragImpact,\n|};\n\nexport default ({ draggable, home, draggables, viewport }: Args): Result => {\n  const displacedBy: DisplacedBy = getDisplacedBy(\n    home.axis,\n    draggable.displaceBy,\n  );\n\n  const insideHome: DraggableDimension[] = getDraggablesInsideDroppable(\n    home.descriptor.id,\n    draggables,\n  );\n\n  // in a list that does not start at 0 the descriptor.index might be different from the index in the list\n  // eg a list could be: [2,3,4]. A descriptor.index of '2' would actually be in index '0' of the list\n  const rawIndex: number = insideHome.indexOf(draggable);\n  invariant(rawIndex !== -1, 'Expected draggable to be inside home list');\n\n  const afterDragging: DraggableDimension[] = insideHome.slice(rawIndex + 1);\n  const effected: DraggableIdMap = afterDragging.reduce(\n    (previous: DraggableIdMap, item: DraggableDimension): DraggableIdMap => {\n      previous[item.descriptor.id] = true;\n      return previous;\n    },\n    {},\n  );\n  const afterCritical: LiftEffect = {\n    inVirtualList: home.descriptor.mode === 'virtual',\n    displacedBy,\n    effected,\n  };\n\n  const displaced: DisplacementGroups = getDisplacementGroups({\n    afterDragging,\n    destination: home,\n    displacedBy,\n    last: null,\n    viewport: viewport.frame,\n    // originally we do not want any animation as we want\n    // everything to be fixed in the same position that\n    // it started in\n    forceShouldAnimate: false,\n  });\n\n  const impact: DragImpact = {\n    displaced,\n    displacedBy,\n    at: {\n      type: 'REORDER',\n      destination: getHomeLocation(draggable.descriptor),\n    },\n  };\n  return { impact, afterCritical };\n};\n"
  },
  {
    "path": "src/state/get-max-scroll.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { subtract } from './position';\n\ntype Args = {|\n  scrollHeight: number,\n  scrollWidth: number,\n  height: number,\n  width: number,\n|};\nexport default ({\n  scrollHeight,\n  scrollWidth,\n  height,\n  width,\n}: Args): Position => {\n  const maxScroll: Position = subtract(\n    // full size\n    { x: scrollWidth, y: scrollHeight },\n    // viewport size\n    { x: width, y: height },\n  );\n\n  const adjustedMaxScroll: Position = {\n    x: Math.max(0, maxScroll.x),\n    y: Math.max(0, maxScroll.y),\n  };\n\n  return adjustedMaxScroll;\n};\n"
  },
  {
    "path": "src/state/is-movement-allowed.js",
    "content": "// @flow\nimport type { State } from '../types';\n// Using function declaration as arrow function does not play well with the %checks syntax\nexport default function isMovementAllowed(state: State): boolean %checks {\n  return state.phase === 'DRAGGING' || state.phase === 'COLLECTING';\n}\n"
  },
  {
    "path": "src/state/is-within.js",
    "content": "// @flow\n\n// is a value between two other values\n\nexport default (\n  lowerBound: number,\n  upperBound: number,\n): ((number) => boolean) => (value: number): boolean =>\n  lowerBound <= value && value <= upperBound;\n"
  },
  {
    "path": "src/state/middleware/auto-scroll.js",
    "content": "// @flow\nimport { invariant } from '../../invariant';\nimport type { AutoScroller } from '../auto-scroller/auto-scroller-types';\nimport type { Action, Dispatch, MiddlewareStore } from '../store-types';\nimport type { State } from '../../types';\n\nconst shouldStop = (action: Action): boolean =>\n  action.type === 'DROP_COMPLETE' ||\n  action.type === 'DROP_ANIMATE' ||\n  action.type === 'FLUSH';\n\nexport default (autoScroller: AutoScroller) => (store: MiddlewareStore) => (\n  next: Dispatch,\n) => (action: Action): any => {\n  if (shouldStop(action)) {\n    autoScroller.stop();\n    next(action);\n    return;\n  }\n\n  if (action.type === 'INITIAL_PUBLISH') {\n    // letting the action go first to hydrate the state\n    next(action);\n    const state: State = store.getState();\n    invariant(\n      state.phase === 'DRAGGING',\n      'Expected phase to be DRAGGING after INITIAL_PUBLISH',\n    );\n    autoScroller.start(state);\n    return;\n  }\n\n  // auto scroll happens in response to state changes\n  // releasing all actions to the reducer first\n  next(action);\n\n  autoScroller.scroll(store.getState());\n};\n"
  },
  {
    "path": "src/state/middleware/dimension-marshal-stopper.js",
    "content": "// @flow\nimport type { Action, Dispatch } from '../store-types';\nimport type { DimensionMarshal } from '../dimension-marshal/dimension-marshal-types';\n\nexport default (marshal: DimensionMarshal) => () => (next: Dispatch) => (\n  action: Action,\n): any => {\n  // Not stopping a collection on a 'DROP' as we want a collection to continue\n  if (\n    // drag is finished\n    action.type === 'DROP_COMPLETE' ||\n    action.type === 'FLUSH' ||\n    // no longer accepting changes once the drop has started\n    action.type === 'DROP_ANIMATE'\n  ) {\n    marshal.stopPublishing();\n  }\n\n  next(action);\n};\n"
  },
  {
    "path": "src/state/middleware/drop/drop-animation-finish-middleware.js",
    "content": "// @flow\nimport { invariant } from '../../../invariant';\nimport { completeDrop } from '../../action-creators';\nimport type { State } from '../../../types';\nimport type { MiddlewareStore, Action, Dispatch } from '../../store-types';\n\nexport default (store: MiddlewareStore) => (next: Dispatch) => (\n  action: Action,\n): any => {\n  if (action.type !== 'DROP_ANIMATION_FINISHED') {\n    next(action);\n    return;\n  }\n\n  const state: State = store.getState();\n  invariant(\n    state.phase === 'DROP_ANIMATING',\n    'Cannot finish a drop animating when no drop is occurring',\n  );\n  store.dispatch(completeDrop({ completed: state.completed }));\n};\n"
  },
  {
    "path": "src/state/middleware/drop/drop-animation-flush-on-scroll-middleware.js",
    "content": "// @flow\nimport { dropAnimationFinished } from '../../action-creators';\nimport type { State } from '../../../types';\nimport type { MiddlewareStore, Action, Dispatch } from '../../store-types';\nimport type { EventBinding } from '../../../view/event-bindings/event-types';\nimport bindEvents from '../../../view/event-bindings/bind-events';\n\nexport default (store: MiddlewareStore) => {\n  let unbind: ?() => void = null;\n  let frameId: ?AnimationFrameID = null;\n\n  function clear() {\n    if (frameId) {\n      cancelAnimationFrame(frameId);\n      frameId = null;\n    }\n\n    if (unbind) {\n      unbind();\n      unbind = null;\n    }\n  }\n\n  return (next: Dispatch) => (action: Action): any => {\n    if (\n      action.type === 'FLUSH' ||\n      action.type === 'DROP_COMPLETE' ||\n      action.type === 'DROP_ANIMATION_FINISHED'\n    ) {\n      clear();\n    }\n\n    next(action);\n\n    if (action.type !== 'DROP_ANIMATE') {\n      return;\n    }\n\n    const binding: EventBinding = {\n      eventName: 'scroll',\n      // capture: true will catch all scroll events, event from scroll containers\n      // once: just in case, we only want to ever fire one\n      options: { capture: true, passive: false, once: true },\n      fn: function flushDropAnimation() {\n        const state: State = store.getState();\n        if (state.phase === 'DROP_ANIMATING') {\n          store.dispatch(dropAnimationFinished());\n        }\n      },\n    };\n\n    // The browser can batch a few scroll events in a single frame\n    // including the one that ended the drag.\n    // Binding after a requestAnimationFrame ensures that any scrolls caused\n    // by the auto scroller are finished\n    // TODO: why is a second window scroll being fired?\n    // It leads to funny drop positions :(\n    frameId = requestAnimationFrame(() => {\n      frameId = null;\n      unbind = bindEvents(window, [binding]);\n    });\n  };\n};\n"
  },
  {
    "path": "src/state/middleware/drop/drop-middleware.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { invariant } from '../../../invariant';\nimport type {\n  State,\n  DropReason,\n  Critical,\n  DraggableLocation,\n  DropResult,\n  CompletedDrag,\n  Combine,\n  DimensionMap,\n  DraggableDimension,\n} from '../../../types';\nimport type { MiddlewareStore, Dispatch, Action } from '../../store-types';\nimport {\n  animateDrop,\n  completeDrop,\n  dropPending,\n  type AnimateDropArgs,\n} from '../../action-creators';\nimport { isEqual } from '../../position';\nimport getDropDuration from './get-drop-duration';\nimport getNewHomeClientOffset from './get-new-home-client-offset';\nimport getDropImpact, { type Result } from './get-drop-impact';\nimport { tryGetCombine, tryGetDestination } from '../../get-impact-location';\n\nexport default ({ getState, dispatch }: MiddlewareStore) => (\n  next: Dispatch,\n) => (action: Action): any => {\n  if (action.type !== 'DROP') {\n    next(action);\n    return;\n  }\n\n  const state: State = getState();\n  const reason: DropReason = action.payload.reason;\n\n  // Still waiting for a bulk collection to publish\n  // We are now shifting the application into the 'DROP_PENDING' phase\n  if (state.phase === 'COLLECTING') {\n    dispatch(dropPending({ reason }));\n    return;\n  }\n\n  // Could have occurred in response to an error\n  if (state.phase === 'IDLE') {\n    return;\n  }\n\n  // Still waiting for our drop pending to end\n  // TODO: should this throw?\n  const isWaitingForDrop: boolean =\n    state.phase === 'DROP_PENDING' && state.isWaiting;\n  invariant(\n    !isWaitingForDrop,\n    'A DROP action occurred while DROP_PENDING and still waiting',\n  );\n\n  invariant(\n    state.phase === 'DRAGGING' || state.phase === 'DROP_PENDING',\n    `Cannot drop in phase: ${state.phase}`,\n  );\n  // We are now in the DRAGGING or DROP_PENDING phase\n\n  const critical: Critical = state.critical;\n  const dimensions: DimensionMap = state.dimensions;\n  const draggable: DraggableDimension =\n    dimensions.draggables[state.critical.draggable.id];\n  // Only keeping impact when doing a user drop - otherwise we are cancelling\n\n  const { impact, didDropInsideDroppable }: Result = getDropImpact({\n    reason,\n    lastImpact: state.impact,\n    afterCritical: state.afterCritical,\n    onLiftImpact: state.onLiftImpact,\n    home: state.dimensions.droppables[state.critical.droppable.id],\n    viewport: state.viewport,\n    draggables: state.dimensions.draggables,\n  });\n\n  // only populating destination / combine if 'didDropInsideDroppable' is true\n  const destination: ?DraggableLocation = didDropInsideDroppable\n    ? tryGetDestination(impact)\n    : null;\n  const combine: ?Combine = didDropInsideDroppable\n    ? tryGetCombine(impact)\n    : null;\n\n  const source: DraggableLocation = {\n    index: critical.draggable.index,\n    droppableId: critical.droppable.id,\n  };\n\n  const result: DropResult = {\n    draggableId: draggable.descriptor.id,\n    type: draggable.descriptor.type,\n    source,\n    reason,\n    mode: state.movementMode,\n    // destination / combine will be null if didDropInsideDroppable is true\n    destination,\n    combine,\n  };\n\n  const newHomeClientOffset: Position = getNewHomeClientOffset({\n    impact,\n    draggable,\n    dimensions,\n    viewport: state.viewport,\n    afterCritical: state.afterCritical,\n  });\n\n  const completed: CompletedDrag = {\n    critical: state.critical,\n    afterCritical: state.afterCritical,\n    result,\n    impact,\n  };\n\n  const isAnimationRequired: boolean =\n    // 1. not already in the right spot\n    !isEqual(state.current.client.offset, newHomeClientOffset) ||\n    // 2. doing a combine (we still want to animate the scale and opacity fade)\n    // looking at the result and not the impact as the combine impact is cleared\n    Boolean(result.combine);\n\n  if (!isAnimationRequired) {\n    dispatch(completeDrop({ completed }));\n    return;\n  }\n\n  const dropDuration: number = getDropDuration({\n    current: state.current.client.offset,\n    destination: newHomeClientOffset,\n    reason,\n  });\n\n  const args: AnimateDropArgs = {\n    newHomeClientOffset,\n    dropDuration,\n    completed,\n  };\n\n  dispatch(animateDrop(args));\n};\n"
  },
  {
    "path": "src/state/middleware/drop/get-drop-duration.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { distance as getDistance } from '../../position';\nimport { timings } from '../../../animation';\nimport type { DropReason } from '../../../types';\n\ntype GetDropDurationArgs = {|\n  current: Position,\n  destination: Position,\n  reason: DropReason,\n|};\n\nconst { minDropTime, maxDropTime } = timings;\nconst dropTimeRange: number = maxDropTime - minDropTime;\nconst maxDropTimeAtDistance: number = 1500;\n// will bring a time lower - which makes it faster\nconst cancelDropModifier: number = 0.6;\n\nexport default ({\n  current,\n  destination,\n  reason,\n}: GetDropDurationArgs): number => {\n  const distance: number = getDistance(current, destination);\n  // even if there is no distance to travel, we might still need to animate opacity\n  if (distance <= 0) {\n    return minDropTime;\n  }\n\n  if (distance >= maxDropTimeAtDistance) {\n    return maxDropTime;\n  }\n\n  // * range from:\n  // 0px = 0.33s\n  // 1500px and over = 0.55s\n  // * If reason === 'CANCEL' then speeding up the animation\n  // * round to 2 decimal points\n\n  const percentage: number = distance / maxDropTimeAtDistance;\n  const duration: number = minDropTime + dropTimeRange * percentage;\n\n  const withDuration: number =\n    reason === 'CANCEL' ? duration * cancelDropModifier : duration;\n  // To two decimal points by converting to string and back\n  return Number(withDuration.toFixed(2));\n};\n"
  },
  {
    "path": "src/state/middleware/drop/get-drop-impact.js",
    "content": "// @flow\nimport type {\n  DropReason,\n  DragImpact,\n  Viewport,\n  DroppableDimension,\n  DraggableDimensionMap,\n  LiftEffect,\n} from '../../../types';\nimport recompute from '../../update-displacement-visibility/recompute';\nimport { emptyGroups } from '../../no-impact';\n\ntype Args = {|\n  draggables: DraggableDimensionMap,\n  home: DroppableDimension,\n  reason: DropReason,\n  lastImpact: DragImpact,\n  onLiftImpact: DragImpact,\n  viewport: Viewport,\n  afterCritical: LiftEffect,\n|};\n\nexport type Result = {|\n  impact: DragImpact,\n  didDropInsideDroppable: boolean,\n|};\n\nexport default ({\n  draggables,\n  reason,\n  lastImpact,\n  home,\n  viewport,\n  onLiftImpact,\n}: Args): Result => {\n  if (!lastImpact.at || reason !== 'DROP') {\n    // Dropping outside of a list or the drag was cancelled\n\n    // Going to use the on lift impact\n    // Need to recompute the visibility of the original impact\n    // What is visible can be different to when  the drag started\n\n    const recomputedHomeImpact: DragImpact = recompute({\n      draggables,\n      impact: onLiftImpact,\n      destination: home,\n      viewport,\n      // We need the draggables to animate back to their positions\n      forceShouldAnimate: true,\n    });\n\n    return {\n      impact: recomputedHomeImpact,\n      didDropInsideDroppable: false,\n    };\n  }\n\n  // use the existing impact\n  if (lastImpact.at.type === 'REORDER') {\n    return {\n      impact: lastImpact,\n      didDropInsideDroppable: true,\n    };\n  }\n\n  // When merging we remove the movement so that everything\n  // will animate closed\n  const withoutMovement: DragImpact = {\n    ...lastImpact,\n    displaced: emptyGroups,\n  };\n\n  return {\n    impact: withoutMovement,\n    didDropInsideDroppable: true,\n  };\n};\n"
  },
  {
    "path": "src/state/middleware/drop/get-new-home-client-offset.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DroppableDimension,\n  Viewport,\n  DragImpact,\n  DimensionMap,\n  DraggableDimension,\n  DroppableId,\n  LiftEffect,\n} from '../../../types';\nimport whatIsDraggedOver from '../../droppable/what-is-dragged-over';\nimport { subtract } from '../../position';\nimport getClientBorderBoxCenter from '../../get-center-from-impact/get-client-border-box-center';\n\ntype Args = {|\n  impact: DragImpact,\n  draggable: DraggableDimension,\n  dimensions: DimensionMap,\n  viewport: Viewport,\n  afterCritical: LiftEffect,\n|};\n\nexport default ({\n  impact,\n  draggable,\n  dimensions,\n  viewport,\n  afterCritical,\n}: Args): Position => {\n  const { draggables, droppables } = dimensions;\n  const droppableId: ?DroppableId = whatIsDraggedOver(impact);\n  const destination: ?DroppableDimension = droppableId\n    ? droppables[droppableId]\n    : null;\n  const home: DroppableDimension = droppables[draggable.descriptor.droppableId];\n\n  const newClientCenter: Position = getClientBorderBoxCenter({\n    impact,\n    draggable,\n    draggables,\n    // if there is no destination, then we will be dropping back into the home\n    afterCritical,\n    droppable: destination || home,\n    viewport,\n  });\n\n  const offset: Position = subtract(\n    newClientCenter,\n    draggable.client.borderBox.center,\n  );\n\n  return offset;\n};\n"
  },
  {
    "path": "src/state/middleware/drop/index.js",
    "content": "// @flow\nexport { default } from './drop-middleware';\n"
  },
  {
    "path": "src/state/middleware/focus.js",
    "content": "// @flow\nimport type { DropResult } from '../../types';\nimport type { Action, Dispatch } from '../store-types';\nimport type { FocusMarshal } from '../../view/use-focus-marshal/focus-marshal-types';\n\nexport default (marshal: FocusMarshal) => {\n  let isWatching: boolean = false;\n\n  return () => (next: Dispatch) => (action: Action): any => {\n    if (action.type === 'INITIAL_PUBLISH') {\n      isWatching = true;\n\n      marshal.tryRecordFocus(action.payload.critical.draggable.id);\n      next(action);\n      marshal.tryRestoreFocusRecorded();\n      return;\n    }\n\n    next(action);\n\n    if (!isWatching) {\n      return;\n    }\n\n    if (action.type === 'FLUSH') {\n      isWatching = false;\n      marshal.tryRestoreFocusRecorded();\n      return;\n    }\n\n    if (action.type === 'DROP_COMPLETE') {\n      isWatching = false;\n      const result: DropResult = action.payload.completed.result;\n\n      // give focus to the combine target when combining\n      if (result.combine) {\n        marshal.tryShiftRecord(result.draggableId, result.combine.draggableId);\n      }\n      marshal.tryRestoreFocusRecorded();\n    }\n  };\n};\n"
  },
  {
    "path": "src/state/middleware/lift.js",
    "content": "// @flow\nimport { invariant } from '../../invariant';\nimport type { DimensionMarshal } from '../dimension-marshal/dimension-marshal-types';\nimport type { State, ScrollOptions, LiftRequest } from '../../types';\nimport type { MiddlewareStore, Action, Dispatch } from '../store-types';\nimport {\n  completeDrop,\n  initialPublish,\n  flush,\n  beforeInitialCapture,\n} from '../action-creators';\nimport validateDimensions from './util/validate-dimensions';\n\nexport default (marshal: DimensionMarshal) => ({\n  getState,\n  dispatch,\n}: MiddlewareStore) => (next: Dispatch) => (action: Action): any => {\n  if (action.type !== 'LIFT') {\n    next(action);\n    return;\n  }\n  const { id, clientSelection, movementMode } = action.payload;\n  const initial: State = getState();\n\n  // flush dropping animation if needed\n  // this can change the descriptor of the dragging item\n  // Will call the onDragEnd responders\n\n  if (initial.phase === 'DROP_ANIMATING') {\n    dispatch(completeDrop({ completed: initial.completed }));\n  }\n\n  invariant(getState().phase === 'IDLE', 'Unexpected phase to start a drag');\n\n  // Removing any placeholders before we capture any starting dimensions\n  dispatch(flush());\n\n  // Let consumers know we are just about to publish\n  // We are only publishing a small amount of information as\n  // things might change as a result of the onBeforeCapture callback\n  dispatch(beforeInitialCapture({ draggableId: id, movementMode }));\n\n  // will communicate with the marshal to start requesting dimensions\n  const scrollOptions: ScrollOptions = {\n    shouldPublishImmediately: movementMode === 'SNAP',\n  };\n  const request: LiftRequest = {\n    draggableId: id,\n    scrollOptions,\n  };\n  // Let's get the marshal started!\n  const { critical, dimensions, viewport } = marshal.startPublishing(request);\n\n  validateDimensions(critical, dimensions);\n\n  // Okay, we are good to start dragging now\n  dispatch(\n    initialPublish({\n      critical,\n      dimensions,\n      clientSelection,\n      movementMode,\n      viewport,\n    }),\n  );\n};\n"
  },
  {
    "path": "src/state/middleware/pending-drop.js",
    "content": "// @flow\nimport { drop } from '../action-creators';\nimport type { State } from '../../types';\nimport type { MiddlewareStore, Dispatch, Action } from '../store-types';\n\nexport default (store: MiddlewareStore) => (next: Dispatch) => (\n  action: Action,\n): any => {\n  // Always let the action go through first\n  next(action);\n\n  if (action.type !== 'PUBLISH_WHILE_DRAGGING') {\n    return;\n  }\n\n  // A bulk replace occurred - check if\n  // 1. there is a pending drop\n  // 2. that the pending drop is no longer waiting\n\n  const postActionState: State = store.getState();\n\n  // no pending drop after the publish\n  if (postActionState.phase !== 'DROP_PENDING') {\n    return;\n  }\n\n  // the pending drop is still waiting for completion\n  if (postActionState.isWaiting) {\n    return;\n  }\n\n  store.dispatch(\n    drop({\n      reason: postActionState.reason,\n    }),\n  );\n};\n"
  },
  {
    "path": "src/state/middleware/responders/async-marshal.js",
    "content": "// @flow\nimport { invariant } from '../../../invariant';\nimport { findIndex } from '../../../native-with-fallback';\n\ntype Entry = {|\n  timerId: TimeoutID,\n  callback: Function,\n|};\n\nexport type AsyncMarshal = {|\n  add: (fn: Function) => void,\n  flush: () => void,\n|};\n\nexport default () => {\n  const entries: Entry[] = [];\n\n  const execute = (timerId: TimeoutID) => {\n    const index: number = findIndex(\n      entries,\n      (item: Entry): boolean => item.timerId === timerId,\n    );\n    invariant(index !== -1, 'Could not find timer');\n    // delete in place\n    const [entry] = entries.splice(index, 1);\n    entry.callback();\n  };\n\n  const add = (fn: Function) => {\n    const timerId: TimeoutID = setTimeout(() => execute(timerId));\n    const entry: Entry = {\n      timerId,\n      callback: fn,\n    };\n    entries.push(entry);\n  };\n\n  const flush = () => {\n    // nothing to flush\n    if (!entries.length) {\n      return;\n    }\n\n    const shallow: Entry[] = [...entries];\n    // clearing entries in case a callback adds some more callbacks\n    entries.length = 0;\n\n    shallow.forEach((entry: Entry) => {\n      clearTimeout(entry.timerId);\n      entry.callback();\n    });\n  };\n\n  return { add, flush };\n};\n"
  },
  {
    "path": "src/state/middleware/responders/expiring-announce.js",
    "content": "// @flow\nimport type { Announce } from '../../../types';\nimport { warning } from '../../../dev-warning';\n\nexport type ExpiringAnnounce = Announce & {\n  wasCalled: () => boolean,\n};\n\nexport default (announce: Announce): ExpiringAnnounce => {\n  let wasCalled: boolean = false;\n  let isExpired: boolean = false;\n\n  // not allowing async announcements\n  const timeoutId: TimeoutID = setTimeout(() => {\n    isExpired = true;\n  });\n\n  const result = (message: string): void => {\n    if (wasCalled) {\n      warning('Announcement already made. Not making a second announcement');\n\n      return;\n    }\n\n    if (isExpired) {\n      warning(`\n        Announcements cannot be made asynchronously.\n        Default message has already been announced.\n      `);\n      return;\n    }\n\n    wasCalled = true;\n    announce(message);\n    clearTimeout(timeoutId);\n  };\n\n  // getter for isExpired\n  // using this technique so that a consumer cannot\n  // set the isExpired or wasCalled flags\n  result.wasCalled = (): boolean => wasCalled;\n\n  return result;\n};\n"
  },
  {
    "path": "src/state/middleware/responders/index.js",
    "content": "// @flow\nexport { default } from './responders-middleware';\n"
  },
  {
    "path": "src/state/middleware/responders/is-equal.js",
    "content": "// @flow\nimport type { Critical, DraggableLocation, Combine } from '../../../types';\n\nexport const areLocationsEqual = (\n  first: ?DraggableLocation,\n  second: ?DraggableLocation,\n): boolean => {\n  // if both are null - we are equal\n  if (first == null && second == null) {\n    return true;\n  }\n\n  // if one is null - then they are not equal\n  if (first == null || second == null) {\n    return false;\n  }\n\n  // compare their actual values\n  return (\n    first.droppableId === second.droppableId && first.index === second.index\n  );\n};\n\nexport const isCombineEqual = (first: ?Combine, second: ?Combine): boolean => {\n  // if both are null - we are equal\n  if (first == null && second == null) {\n    return true;\n  }\n\n  // only one is null\n  if (first == null || second == null) {\n    return false;\n  }\n\n  return (\n    first.draggableId === second.draggableId &&\n    first.droppableId === second.droppableId\n  );\n};\n\nexport const isCriticalEqual = (first: Critical, second: Critical): boolean => {\n  if (first === second) {\n    return true;\n  }\n\n  const isDraggableEqual: boolean =\n    first.draggable.id === second.draggable.id &&\n    first.draggable.droppableId === second.draggable.droppableId &&\n    first.draggable.type === second.draggable.type &&\n    first.draggable.index === second.draggable.index;\n\n  const isDroppableEqual: boolean =\n    first.droppable.id === second.droppable.id &&\n    first.droppable.type === second.droppable.type;\n\n  return isDraggableEqual && isDroppableEqual;\n};\n"
  },
  {
    "path": "src/state/middleware/responders/publisher.js",
    "content": "// @flow\nimport { invariant } from '../../../invariant';\nimport messagePreset from '../../../screen-reader-message-preset';\nimport * as timings from '../../../debug/timings';\nimport getExpiringAnnounce, {\n  type ExpiringAnnounce,\n} from './expiring-announce';\nimport getAsyncMarshal, { type AsyncMarshal } from './async-marshal';\nimport type {\n  DropResult,\n  Responders,\n  ResponderProvided,\n  Critical,\n  BeforeCapture,\n  DragImpact,\n  DraggableLocation,\n  Combine,\n  DragStart,\n  Announce,\n  DragUpdate,\n  MovementMode,\n  DraggableId,\n  OnBeforeCaptureResponder,\n  OnBeforeDragStartResponder,\n  OnDragStartResponder,\n  OnDragUpdateResponder,\n  OnDragEndResponder,\n} from '../../../types';\nimport { isCombineEqual, isCriticalEqual, areLocationsEqual } from './is-equal';\nimport { tryGetDestination, tryGetCombine } from '../../get-impact-location';\n\nconst withTimings = (key: string, fn: Function) => {\n  timings.start(key);\n  fn();\n  timings.finish(key);\n};\n\nconst getDragStart = (critical: Critical, mode: MovementMode): DragStart => ({\n  draggableId: critical.draggable.id,\n  type: critical.droppable.type,\n  source: {\n    droppableId: critical.droppable.id,\n    index: critical.draggable.index,\n  },\n  mode,\n});\n\ntype AnyPrimaryResponderFn =\n  | OnDragStartResponder\n  | OnDragUpdateResponder\n  | OnDragEndResponder;\ntype AnyResponderData = DragStart | DragUpdate | DropResult;\n\nconst execute = (\n  responder: ?AnyPrimaryResponderFn,\n  data: AnyResponderData,\n  announce: Announce,\n  getDefaultMessage: (data: any) => string,\n) => {\n  if (!responder) {\n    announce(getDefaultMessage(data));\n    return;\n  }\n\n  const willExpire: ExpiringAnnounce = getExpiringAnnounce(announce);\n  const provided: ResponderProvided = {\n    announce: willExpire,\n  };\n\n  // Casting because we are not validating which data type is going into which responder\n  responder((data: any), provided);\n\n  if (!willExpire.wasCalled()) {\n    announce(getDefaultMessage(data));\n  }\n};\n\ntype WhileDragging = {|\n  mode: MovementMode,\n  lastCritical: Critical,\n  lastCombine: ?Combine,\n  lastLocation: ?DraggableLocation,\n|};\n\nexport default (getResponders: () => Responders, announce: Announce) => {\n  const asyncMarshal: AsyncMarshal = getAsyncMarshal();\n  let dragging: ?WhileDragging = null;\n\n  const beforeCapture = (draggableId: DraggableId, mode: MovementMode) => {\n    invariant(\n      !dragging,\n      'Cannot fire onBeforeCapture as a drag start has already been published',\n    );\n    withTimings('onBeforeCapture', () => {\n      // No use of screen reader for this responder\n      const fn: ?OnBeforeCaptureResponder = getResponders().onBeforeCapture;\n      if (fn) {\n        const before: BeforeCapture = {\n          draggableId,\n          mode,\n        };\n        fn(before);\n      }\n    });\n  };\n\n  const beforeStart = (critical: Critical, mode: MovementMode) => {\n    invariant(\n      !dragging,\n      'Cannot fire onBeforeDragStart as a drag start has already been published',\n    );\n    withTimings('onBeforeDragStart', () => {\n      // No use of screen reader for this responder\n      const fn: ?OnBeforeDragStartResponder = getResponders().onBeforeDragStart;\n      if (fn) {\n        fn(getDragStart(critical, mode));\n      }\n    });\n  };\n\n  const start = (critical: Critical, mode: MovementMode) => {\n    invariant(\n      !dragging,\n      'Cannot fire onBeforeDragStart as a drag start has already been published',\n    );\n    const data: DragStart = getDragStart(critical, mode);\n    dragging = {\n      mode,\n      lastCritical: critical,\n      lastLocation: data.source,\n      lastCombine: null,\n    };\n\n    // we will flush this frame if we receive any responder updates\n    asyncMarshal.add(() => {\n      withTimings('onDragStart', () =>\n        execute(\n          getResponders().onDragStart,\n          data,\n          announce,\n          messagePreset.onDragStart,\n        ),\n      );\n    });\n  };\n\n  // Passing in the critical location again as it can change during a drag\n  const update = (critical: Critical, impact: DragImpact) => {\n    const location: ?DraggableLocation = tryGetDestination(impact);\n    const combine: ?Combine = tryGetCombine(impact);\n\n    invariant(\n      dragging,\n      'Cannot fire onDragMove when onDragStart has not been called',\n    );\n\n    // Has the critical changed? Will result in a source change\n    const hasCriticalChanged: boolean = !isCriticalEqual(\n      critical,\n      dragging.lastCritical,\n    );\n    if (hasCriticalChanged) {\n      dragging.lastCritical = critical;\n    }\n\n    // Has the location changed? Will result in a destination change\n    const hasLocationChanged: boolean = !areLocationsEqual(\n      dragging.lastLocation,\n      location,\n    );\n    if (hasLocationChanged) {\n      dragging.lastLocation = location;\n    }\n    const hasGroupingChanged: boolean = !isCombineEqual(\n      dragging.lastCombine,\n      combine,\n    );\n    if (hasGroupingChanged) {\n      dragging.lastCombine = combine;\n    }\n\n    // Nothing has changed - no update needed\n    if (!hasCriticalChanged && !hasLocationChanged && !hasGroupingChanged) {\n      return;\n    }\n\n    const data: DragUpdate = {\n      ...getDragStart(critical, dragging.mode),\n      combine,\n      destination: location,\n    };\n\n    asyncMarshal.add(() => {\n      withTimings('onDragUpdate', () =>\n        execute(\n          getResponders().onDragUpdate,\n          data,\n          announce,\n          messagePreset.onDragUpdate,\n        ),\n      );\n    });\n  };\n\n  const flush = () => {\n    invariant(dragging, 'Can only flush responders while dragging');\n    asyncMarshal.flush();\n  };\n\n  const drop = (result: DropResult) => {\n    invariant(\n      dragging,\n      'Cannot fire onDragEnd when there is no matching onDragStart',\n    );\n    dragging = null;\n    // not adding to frame marshal - we want this to be done in the same render pass\n    // we also want the consumers reorder logic to be in the same render pass\n    withTimings('onDragEnd', () =>\n      execute(\n        getResponders().onDragEnd,\n        result,\n        announce,\n        messagePreset.onDragEnd,\n      ),\n    );\n  };\n\n  // A non user initiated cancel\n  const abort = () => {\n    // aborting can happen defensively\n    if (!dragging) {\n      return;\n    }\n\n    const result: DropResult = {\n      ...getDragStart(dragging.lastCritical, dragging.mode),\n      combine: null,\n      destination: null,\n      reason: 'CANCEL',\n    };\n    drop(result);\n  };\n\n  return {\n    beforeCapture,\n    beforeStart,\n    start,\n    update,\n    flush,\n    drop,\n    abort,\n  };\n};\n"
  },
  {
    "path": "src/state/middleware/responders/responders-middleware.js",
    "content": "// @flow\nimport getPublisher from './publisher';\nimport type {\n  State,\n  DropResult,\n  Responders,\n  Critical,\n  Announce,\n} from '../../../types';\nimport type {\n  Action,\n  Middleware,\n  MiddlewareStore,\n  Dispatch,\n} from '../../store-types';\n\nexport default (\n  getResponders: () => Responders,\n  announce: Announce,\n): Middleware => {\n  const publisher = getPublisher(\n    (getResponders: () => Responders),\n    (announce: Announce),\n  );\n\n  return (store: MiddlewareStore) => (next: Dispatch) => (\n    action: Action,\n  ): any => {\n    if (action.type === 'BEFORE_INITIAL_CAPTURE') {\n      publisher.beforeCapture(\n        action.payload.draggableId,\n        action.payload.movementMode,\n      );\n      return;\n    }\n\n    if (action.type === 'INITIAL_PUBLISH') {\n      const critical: Critical = action.payload.critical;\n      publisher.beforeStart(critical, action.payload.movementMode);\n      next(action);\n      publisher.start(critical, action.payload.movementMode);\n      return;\n    }\n\n    // Drag end\n    if (action.type === 'DROP_COMPLETE') {\n      // it is important that we use the result and not the last impact\n      // the last impact might be different to the result for visual reasons\n      const result: DropResult = action.payload.completed.result;\n      // flushing all pending responders before snapshots are updated\n      publisher.flush();\n      next(action);\n      publisher.drop(result);\n      return;\n    }\n\n    // All other responders can fire after we have updated our connected components\n    next(action);\n\n    // Drag state resetting - need to check if\n    // we should fire a onDragEnd responder\n    if (action.type === 'FLUSH') {\n      publisher.abort();\n      return;\n    }\n\n    // ## Perform drag updates\n    // impact of action has already been reduced\n\n    const state: State = store.getState();\n    if (state.phase === 'DRAGGING') {\n      publisher.update(state.critical, state.impact);\n    }\n  };\n};\n"
  },
  {
    "path": "src/state/middleware/scroll-listener.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { moveByWindowScroll } from '../action-creators';\nimport type { MiddlewareStore, Action, Dispatch } from '../store-types';\nimport getScrollListener from '../../view/scroll-listener';\n\n// TODO: this is taken from auto-scroll. Let's make it a util\nconst shouldEnd = (action: Action): boolean =>\n  action.type === 'DROP_COMPLETE' ||\n  action.type === 'DROP_ANIMATE' ||\n  action.type === 'FLUSH';\n\nexport default (store: MiddlewareStore) => {\n  const listener = getScrollListener({\n    onWindowScroll: (newScroll: Position) => {\n      store.dispatch(moveByWindowScroll({ newScroll }));\n    },\n  });\n\n  return (next: Dispatch) => (action: Action): any => {\n    if (!listener.isActive() && action.type === 'INITIAL_PUBLISH') {\n      listener.start();\n    }\n\n    if (listener.isActive() && shouldEnd(action)) {\n      listener.stop();\n    }\n\n    next(action);\n  };\n};\n"
  },
  {
    "path": "src/state/middleware/style.js",
    "content": "// @flow\nimport type { Action, Dispatch } from '../store-types';\nimport type { StyleMarshal } from '../../view/use-style-marshal/style-marshal-types';\n\nexport default (marshal: StyleMarshal) => () => (next: Dispatch) => (\n  action: Action,\n): any => {\n  if (action.type === 'INITIAL_PUBLISH') {\n    marshal.dragging();\n  }\n\n  if (action.type === 'DROP_ANIMATE') {\n    marshal.dropping(action.payload.completed.result.reason);\n  }\n\n  // this will clear any styles immediately before a reorder\n  if (action.type === 'FLUSH' || action.type === 'DROP_COMPLETE') {\n    marshal.resting();\n  }\n\n  next(action);\n};\n"
  },
  {
    "path": "src/state/middleware/util/validate-dimensions.js",
    "content": "// @flow\nimport type {\n  Critical,\n  DimensionMap,\n  DraggableDimension,\n} from '../../../types';\nimport getDraggablesInsideDroppable from '../../get-draggables-inside-droppable';\nimport { warning } from '../../../dev-warning';\n\ntype ErrorMap = {\n  [index: number]: true,\n};\n\nfunction checkIndexes(insideDestination: DraggableDimension[]) {\n  // no point running if there are 1 or less items\n  if (insideDestination.length <= 1) {\n    return;\n  }\n\n  const indexes: number[] = insideDestination.map(\n    (d: DraggableDimension): number => d.descriptor.index,\n  );\n\n  const errors: ErrorMap = {};\n\n  for (let i = 1; i < indexes.length; i++) {\n    const current: number = indexes[i];\n    const previous: number = indexes[i - 1];\n\n    // this will be an error if:\n    // 1. index is not consecutive\n    // 2. index is duplicated (which is true if #1 is not passed)\n    if (current !== previous + 1) {\n      errors[current] = true;\n    }\n  }\n\n  if (!Object.keys(errors).length) {\n    return;\n  }\n\n  const formatted: string = indexes\n    .map((index: number): string => {\n      const hasError: boolean = Boolean(errors[index]);\n\n      return hasError ? `[🔥${index}]` : `${index}`;\n    })\n    .join(', ');\n\n  warning(`\n    Detected non-consecutive <Draggable /> indexes.\n\n    (This can cause unexpected bugs)\n\n    ${formatted}\n  `);\n}\n\nexport default function validateDimensions(\n  critical: Critical,\n  dimensions: DimensionMap,\n): void {\n  // wrapping entire block for better minification\n  if (process.env.NODE_ENV !== 'production') {\n    const insideDestination: DraggableDimension[] = getDraggablesInsideDroppable(\n      critical.droppable.id,\n      dimensions.draggables,\n    );\n    checkIndexes(insideDestination);\n  }\n}\n"
  },
  {
    "path": "src/state/move-in-direction/index.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { PublicResult } from './move-in-direction-types';\nimport type {\n  DroppableId,\n  DraggingState,\n  Direction,\n  DroppableDimension,\n  DraggableDimension,\n  DroppableDimensionMap,\n  DragImpact,\n} from '../../types';\nimport moveToNextPlace from './move-to-next-place';\nimport moveCrossAxis from './move-cross-axis';\nimport whatIsDraggedOver from '../droppable/what-is-dragged-over';\n\ntype Args = {|\n  state: DraggingState,\n  type: 'MOVE_UP' | 'MOVE_RIGHT' | 'MOVE_DOWN' | 'MOVE_LEFT',\n|};\n\nconst getDroppableOver = (\n  impact: DragImpact,\n  droppables: DroppableDimensionMap,\n): ?DroppableDimension => {\n  const id: ?DroppableId = whatIsDraggedOver(impact);\n  return id ? droppables[id] : null;\n};\n\nexport default ({ state, type }: Args): ?PublicResult => {\n  const isActuallyOver: ?DroppableDimension = getDroppableOver(\n    state.impact,\n    state.dimensions.droppables,\n  );\n  const isMainAxisMovementAllowed: boolean = Boolean(isActuallyOver);\n  const home: DroppableDimension =\n    state.dimensions.droppables[state.critical.droppable.id];\n  // use home when not actually over a droppable (can happen when move is disabled)\n  const isOver: DroppableDimension = isActuallyOver || home;\n\n  const direction: Direction = isOver.axis.direction;\n  const isMovingOnMainAxis: boolean =\n    (direction === 'vertical' &&\n      (type === 'MOVE_UP' || type === 'MOVE_DOWN')) ||\n    (direction === 'horizontal' &&\n      (type === 'MOVE_LEFT' || type === 'MOVE_RIGHT'));\n\n  // This movement is not permitted right now\n  if (isMovingOnMainAxis && !isMainAxisMovementAllowed) {\n    return null;\n  }\n\n  const isMovingForward: boolean =\n    type === 'MOVE_DOWN' || type === 'MOVE_RIGHT';\n\n  const draggable: DraggableDimension =\n    state.dimensions.draggables[state.critical.draggable.id];\n  const previousPageBorderBoxCenter: Position =\n    state.current.page.borderBoxCenter;\n  const { draggables, droppables } = state.dimensions;\n\n  return isMovingOnMainAxis\n    ? moveToNextPlace({\n        isMovingForward,\n        previousPageBorderBoxCenter,\n        draggable,\n        destination: isOver,\n        draggables,\n        viewport: state.viewport,\n        previousClientSelection: state.current.client.selection,\n        previousImpact: state.impact,\n        afterCritical: state.afterCritical,\n      })\n    : moveCrossAxis({\n        isMovingForward,\n        previousPageBorderBoxCenter,\n        draggable,\n        isOver,\n        draggables,\n        droppables,\n        viewport: state.viewport,\n        afterCritical: state.afterCritical,\n      });\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-cross-axis/get-best-cross-axis-droppable.js",
    "content": "// @flow\nimport { type Position, type Rect } from 'css-box-model';\nimport { invariant } from '../../../invariant';\nimport { closest } from '../../position';\nimport isWithin from '../../is-within';\nimport { getCorners } from '../../spacing';\nimport isPartiallyVisibleThroughFrame from '../../visibility/is-partially-visible-through-frame';\nimport { toDroppableList } from '../../dimension-structures';\nimport type {\n  Axis,\n  DroppableDimension,\n  DroppableDimensionMap,\n  Viewport,\n} from '../../../types';\n\ntype GetBestDroppableArgs = {|\n  isMovingForward: boolean,\n  // the current position of the dragging item\n  pageBorderBoxCenter: Position,\n  // the home of the draggable\n  source: DroppableDimension,\n  // all the droppables in the system\n  droppables: DroppableDimensionMap,\n  viewport: Viewport,\n|};\n\nconst getKnownActive = (droppable: DroppableDimension): Rect => {\n  const rect: ?Rect = droppable.subject.active;\n\n  invariant(rect, 'Cannot get clipped area from droppable');\n\n  return rect;\n};\n\nexport default ({\n  isMovingForward,\n  pageBorderBoxCenter,\n  source,\n  droppables,\n  viewport,\n}: GetBestDroppableArgs): ?DroppableDimension => {\n  const active: ?Rect = source.subject.active;\n\n  if (!active) {\n    return null;\n  }\n\n  const axis: Axis = source.axis;\n  const isBetweenSourceClipped = isWithin(active[axis.start], active[axis.end]);\n  const candidates: DroppableDimension[] = toDroppableList(droppables)\n    // Remove the source droppable from the list\n    .filter((droppable: DroppableDimension): boolean => droppable !== source)\n    // Remove any options that are not enabled\n    .filter((droppable: DroppableDimension): boolean => droppable.isEnabled)\n    // Remove any droppables that do not have a visible subject\n    .filter((droppable: DroppableDimension): boolean =>\n      Boolean(droppable.subject.active),\n    )\n    // Remove any that are not visible in the window\n    .filter((droppable: DroppableDimension): boolean =>\n      isPartiallyVisibleThroughFrame(viewport.frame)(getKnownActive(droppable)),\n    )\n    .filter((droppable: DroppableDimension): boolean => {\n      const activeOfTarget: Rect = getKnownActive(droppable);\n\n      // is the target in front of the source on the cross axis?\n      if (isMovingForward) {\n        return active[axis.crossAxisEnd] < activeOfTarget[axis.crossAxisEnd];\n      }\n      // is the target behind the source on the cross axis?\n      return activeOfTarget[axis.crossAxisStart] < active[axis.crossAxisStart];\n    })\n    // Must have some overlap on the main axis\n    .filter((droppable: DroppableDimension): boolean => {\n      const activeOfTarget: Rect = getKnownActive(droppable);\n\n      const isBetweenDestinationClipped = isWithin(\n        activeOfTarget[axis.start],\n        activeOfTarget[axis.end],\n      );\n\n      return (\n        isBetweenSourceClipped(activeOfTarget[axis.start]) ||\n        isBetweenSourceClipped(activeOfTarget[axis.end]) ||\n        isBetweenDestinationClipped(active[axis.start]) ||\n        isBetweenDestinationClipped(active[axis.end])\n      );\n    })\n    // Sort on the cross axis\n    .sort((a: DroppableDimension, b: DroppableDimension) => {\n      const first: number = getKnownActive(a)[axis.crossAxisStart];\n      const second: number = getKnownActive(b)[axis.crossAxisStart];\n\n      if (isMovingForward) {\n        return first - second;\n      }\n      return second - first;\n    })\n    // Find the droppables that have the same cross axis value as the first item\n    .filter(\n      (\n        droppable: DroppableDimension,\n        index: number,\n        array: DroppableDimension[],\n      ): boolean =>\n        getKnownActive(droppable)[axis.crossAxisStart] ===\n        getKnownActive(array[0])[axis.crossAxisStart],\n    );\n\n  // no possible candidates\n  if (!candidates.length) {\n    return null;\n  }\n\n  // only one result - all done!\n  if (candidates.length === 1) {\n    return candidates[0];\n  }\n\n  // At this point we have a number of candidates that\n  // all have the same axis.crossAxisStart value.\n\n  // Check to see if the center position is within the size of a Droppable on the main axis\n  const contains: DroppableDimension[] = candidates.filter(\n    (droppable: DroppableDimension) => {\n      const isWithinDroppable = isWithin(\n        getKnownActive(droppable)[axis.start],\n        getKnownActive(droppable)[axis.end],\n      );\n      return isWithinDroppable(pageBorderBoxCenter[axis.line]);\n    },\n  );\n\n  if (contains.length === 1) {\n    return contains[0];\n  }\n\n  // The center point of the draggable falls on the boundary between two droppables\n  if (contains.length > 1) {\n    // sort on the main axis and choose the first\n    return contains.sort(\n      (a: DroppableDimension, b: DroppableDimension): number =>\n        getKnownActive(a)[axis.start] - getKnownActive(b)[axis.start],\n    )[0];\n  }\n\n  // The center is not contained within any droppable\n  // 1. Find the candidate that has the closest corner\n  // 2. If there is a tie - choose the one that is first on the main axis\n  return candidates.sort(\n    (a: DroppableDimension, b: DroppableDimension): number => {\n      const first = closest(pageBorderBoxCenter, getCorners(getKnownActive(a)));\n      const second = closest(\n        pageBorderBoxCenter,\n        getCorners(getKnownActive(b)),\n      );\n\n      // if the distances are not equal - choose the shortest\n      if (first !== second) {\n        return first - second;\n      }\n\n      // They both have the same distance -\n      // choose the one that is first on the main axis\n      return getKnownActive(a)[axis.start] - getKnownActive(b)[axis.start];\n    },\n  )[0];\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-cross-axis/get-closest-draggable.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport type {\n  Viewport,\n  DraggableDimension,\n  DroppableDimension,\n  LiftEffect,\n} from '../../../types';\nimport { distance } from '../../position';\nimport { isTotallyVisible } from '../../visibility/is-visible';\nimport withDroppableDisplacement from '../../with-scroll-change/with-droppable-displacement';\nimport {\n  getCurrentPageBorderBox,\n  getCurrentPageBorderBoxCenter,\n} from './without-starting-displacement';\n\ntype Args = {|\n  pageBorderBoxCenter: Position,\n  viewport: Viewport,\n  // the droppable that is being moved to\n  destination: DroppableDimension,\n  // the droppables inside the destination\n  insideDestination: DraggableDimension[],\n  afterCritical: LiftEffect,\n|};\n\nexport default ({\n  pageBorderBoxCenter,\n  viewport,\n  destination,\n  insideDestination,\n  afterCritical,\n}: Args): ?DraggableDimension => {\n  const sorted: DraggableDimension[] = insideDestination\n    .filter((draggable: DraggableDimension): boolean =>\n      // Allowing movement to draggables that are not visible in the viewport\n      // but must be visible in the droppable\n      // We can improve this, but this limitation is easier for now\n      isTotallyVisible({\n        target: getCurrentPageBorderBox(draggable, afterCritical),\n        destination,\n        viewport: viewport.frame,\n        withDroppableDisplacement: true,\n      }),\n    )\n    .sort((a: DraggableDimension, b: DraggableDimension): number => {\n      // Need to consider the change in scroll in the destination\n      const distanceToA = distance(\n        pageBorderBoxCenter,\n        withDroppableDisplacement(\n          destination,\n          getCurrentPageBorderBoxCenter(a, afterCritical),\n        ),\n      );\n      const distanceToB = distance(\n        pageBorderBoxCenter,\n        withDroppableDisplacement(\n          destination,\n          getCurrentPageBorderBoxCenter(b, afterCritical),\n        ),\n      );\n\n      // if a is closer - return a\n      if (distanceToA < distanceToB) {\n        return -1;\n      }\n\n      // if b is closer - return b\n      if (distanceToB < distanceToA) {\n        return 1;\n      }\n\n      // if the distance to a and b are the same:\n      // return the one with the lower index (it will be higher on the main axis)\n      return a.descriptor.index - b.descriptor.index;\n    });\n\n  return sorted[0] || null;\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-cross-axis/index.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport type { PublicResult } from '../move-in-direction-types';\nimport type {\n  DroppableDimension,\n  DraggableDimension,\n  DraggableDimensionMap,\n  DroppableDimensionMap,\n  DragImpact,\n  Viewport,\n  LiftEffect,\n} from '../../../types';\nimport getBestCrossAxisDroppable from './get-best-cross-axis-droppable';\nimport getClosestDraggable from './get-closest-draggable';\n// import moveToNewDroppable from './move-to-new-droppable';\nimport getDraggablesInsideDroppable from '../../get-draggables-inside-droppable';\nimport getClientFromPageBorderBoxCenter from '../../get-center-from-impact/get-client-border-box-center/get-client-from-page-border-box-center';\nimport getPageBorderBoxCenter from '../../get-center-from-impact/get-page-border-box-center';\nimport moveToNewDroppable from './move-to-new-droppable';\n\ntype Args = {|\n  isMovingForward: boolean,\n  // the current page center of the dragging item\n  previousPageBorderBoxCenter: Position,\n  // the dragging item\n  draggable: DraggableDimension,\n  // the droppable the dragging item is in\n  isOver: DroppableDimension,\n  // all the dimensions in the system\n  draggables: DraggableDimensionMap,\n  droppables: DroppableDimensionMap,\n  // the current viewport\n  viewport: Viewport,\n  afterCritical: LiftEffect,\n|};\n\nexport default ({\n  isMovingForward,\n  previousPageBorderBoxCenter,\n  draggable,\n  isOver,\n  draggables,\n  droppables,\n  viewport,\n  afterCritical,\n}: Args): ?PublicResult => {\n  // not considering the container scroll changes as container scrolling cancels a keyboard drag\n\n  const destination: ?DroppableDimension = getBestCrossAxisDroppable({\n    isMovingForward,\n    pageBorderBoxCenter: previousPageBorderBoxCenter,\n    source: isOver,\n    droppables,\n    viewport,\n  });\n\n  // nothing available to move to\n  if (!destination) {\n    return null;\n  }\n\n  const insideDestination: DraggableDimension[] = getDraggablesInsideDroppable(\n    destination.descriptor.id,\n    draggables,\n  );\n\n  const moveRelativeTo: ?DraggableDimension = getClosestDraggable({\n    pageBorderBoxCenter: previousPageBorderBoxCenter,\n    viewport,\n    destination,\n    insideDestination,\n    afterCritical,\n  });\n\n  const impact: ?DragImpact = moveToNewDroppable({\n    previousPageBorderBoxCenter,\n    destination,\n    draggable,\n    draggables,\n    moveRelativeTo,\n    insideDestination,\n    viewport,\n    afterCritical,\n  });\n\n  if (!impact) {\n    return null;\n  }\n\n  const pageBorderBoxCenter: Position = getPageBorderBoxCenter({\n    impact,\n    draggable,\n    droppable: destination,\n    draggables,\n    afterCritical,\n  });\n\n  const clientSelection: Position = getClientFromPageBorderBoxCenter({\n    pageBorderBoxCenter,\n    draggable,\n    viewport,\n  });\n\n  return {\n    clientSelection,\n    impact,\n    scrollJumpRequest: null,\n  };\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-cross-axis/move-to-new-droppable.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DragImpact,\n  DraggableDimension,\n  DraggableDimensionMap,\n  DroppableDimension,\n  Viewport,\n  DisplacedBy,\n  LiftEffect,\n} from '../../../types';\nimport getDisplacedBy from '../../get-displaced-by';\nimport { emptyGroups, noDisplacedBy } from '../../no-impact';\nimport getPageBorderBoxCenter from '../../get-center-from-impact/get-page-border-box-center';\nimport isTotallyVisibleInNewLocation from '../move-to-next-place/is-totally-visible-in-new-location';\nimport { addPlaceholder } from '../../droppable/with-placeholder';\nimport isHomeOf from '../../droppable/is-home-of';\nimport calculateReorderImpact from '../../calculate-drag-impact/calculate-reorder-impact';\n\ntype Args = {|\n  previousPageBorderBoxCenter: Position,\n  moveRelativeTo: ?DraggableDimension,\n  insideDestination: DraggableDimension[],\n  draggable: DraggableDimension,\n  draggables: DraggableDimensionMap,\n  destination: DroppableDimension,\n  viewport: Viewport,\n  afterCritical: LiftEffect,\n|};\n\nexport default ({\n  previousPageBorderBoxCenter,\n  moveRelativeTo,\n  insideDestination,\n  draggable,\n  draggables,\n  destination,\n  viewport,\n  afterCritical,\n}: Args): ?DragImpact => {\n  if (!moveRelativeTo) {\n    // Draggables available, but none are candidates for movement\n    if (insideDestination.length) {\n      return null;\n    }\n\n    // Try move to top of empty list if it is visible\n    const proposed: DragImpact = {\n      displaced: emptyGroups,\n      displacedBy: noDisplacedBy,\n      at: {\n        type: 'REORDER',\n        destination: {\n          droppableId: destination.descriptor.id,\n          index: 0,\n        },\n      },\n    };\n    const proposedPageBorderBoxCenter: Position = getPageBorderBoxCenter({\n      impact: proposed,\n      draggable,\n      droppable: destination,\n      draggables,\n      afterCritical,\n    });\n\n    // need to add room for a placeholder in a foreign list\n    const withPlaceholder: DroppableDimension = isHomeOf(draggable, destination)\n      ? destination\n      : addPlaceholder(destination, draggable, draggables);\n\n    const isVisibleInNewLocation: boolean = isTotallyVisibleInNewLocation({\n      draggable,\n      destination: withPlaceholder,\n      newPageBorderBoxCenter: proposedPageBorderBoxCenter,\n      viewport: viewport.frame,\n      // already taken into account by getPageBorderBoxCenter\n      withDroppableDisplacement: false,\n      onlyOnMainAxis: true,\n    });\n\n    return isVisibleInNewLocation ? proposed : null;\n  }\n\n  const isGoingBeforeTarget: boolean = Boolean(\n    // Using <= as we optimise slightly for moving before items in a new list\n    // This is nicer in lists with fixed height items\n    previousPageBorderBoxCenter[destination.axis.line] <=\n      moveRelativeTo.page.borderBox.center[destination.axis.line],\n  );\n\n  const proposedIndex: number = (() => {\n    const relativeTo: number = moveRelativeTo.descriptor.index;\n\n    if (moveRelativeTo.descriptor.id === draggable.descriptor.id) {\n      return relativeTo;\n    }\n\n    if (isGoingBeforeTarget) {\n      return relativeTo;\n    }\n\n    return relativeTo + 1;\n  })();\n\n  const displacedBy: DisplacedBy = getDisplacedBy(\n    destination.axis,\n    draggable.displaceBy,\n  );\n\n  return calculateReorderImpact({\n    draggable,\n    insideDestination,\n    destination,\n    viewport,\n    displacedBy,\n    // last groups won't be relevant\n    last: emptyGroups,\n    index: proposedIndex,\n  });\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-cross-axis/without-starting-displacement.js",
    "content": "// @flow\nimport type { Position, Rect, Spacing } from 'css-box-model';\nimport type { DraggableDimension, LiftEffect } from '../../../types';\nimport { negate, subtract } from '../../position';\nimport { offsetByPosition } from '../../spacing';\nimport didStartAfterCritical from '../../did-start-after-critical';\n\nexport const getCurrentPageBorderBoxCenter = (\n  draggable: DraggableDimension,\n  afterCritical: LiftEffect,\n): Position => {\n  // If an item started displaced it is now resting\n  // in a non-displaced location\n  const original: Position = draggable.page.borderBox.center;\n  return didStartAfterCritical(draggable.descriptor.id, afterCritical)\n    ? subtract(original, afterCritical.displacedBy.point)\n    : original;\n};\n\nexport const getCurrentPageBorderBox = (\n  draggable: DraggableDimension,\n  afterCritical: LiftEffect,\n): Spacing => {\n  // If an item started displaced it is now resting\n  // in a non-displaced location\n  const original: Rect = draggable.page.borderBox;\n\n  return didStartAfterCritical(draggable.descriptor.id, afterCritical)\n    ? offsetByPosition(original, negate(afterCritical.displacedBy.point))\n    : original;\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-in-direction-types.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { DragImpact } from '../../types';\n\nexport type PublicResult = {|\n  clientSelection: Position,\n  impact: DragImpact,\n  scrollJumpRequest: ?Position,\n|};\n"
  },
  {
    "path": "src/state/move-in-direction/move-to-next-place/index.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DroppableDimension,\n  DraggableDimension,\n  DraggableDimensionMap,\n  DragImpact,\n  Viewport,\n  LiftEffect,\n} from '../../../types';\nimport type { PublicResult } from '../move-in-direction-types';\nimport getDraggablesInsideDroppable from '../../get-draggables-inside-droppable';\nimport moveToNextCombine from './move-to-next-combine';\nimport moveToNextIndex from './move-to-next-index';\nimport isHomeOf from '../../droppable/is-home-of';\nimport getPageBorderBoxCenter from '../../get-center-from-impact/get-page-border-box-center';\nimport speculativelyIncrease from '../../update-displacement-visibility/speculatively-increase';\nimport getClientFromPageBorderBoxCenter from '../../get-center-from-impact/get-client-border-box-center/get-client-from-page-border-box-center';\nimport { subtract } from '../../position';\nimport isTotallyVisibleInNewLocation from './is-totally-visible-in-new-location';\n\ntype Args = {|\n  isMovingForward: boolean,\n  draggable: DraggableDimension,\n  destination: DroppableDimension,\n  draggables: DraggableDimensionMap,\n  previousImpact: DragImpact,\n  viewport: Viewport,\n  previousClientSelection: Position,\n  previousPageBorderBoxCenter: Position,\n  afterCritical: LiftEffect,\n|};\n\nexport default ({\n  isMovingForward,\n  draggable,\n  destination,\n  draggables,\n  previousImpact,\n  viewport,\n  previousPageBorderBoxCenter,\n  previousClientSelection,\n  afterCritical,\n}: Args): ?PublicResult => {\n  if (!destination.isEnabled) {\n    return null;\n  }\n\n  const insideDestination: DraggableDimension[] = getDraggablesInsideDroppable(\n    destination.descriptor.id,\n    draggables,\n  );\n  const isInHomeList: boolean = isHomeOf(draggable, destination);\n\n  const impact: ?DragImpact =\n    moveToNextCombine({\n      isMovingForward,\n      draggable,\n      destination,\n      insideDestination,\n      previousImpact,\n    }) ||\n    moveToNextIndex({\n      isMovingForward,\n      isInHomeList,\n      draggable,\n      draggables,\n      destination,\n      insideDestination,\n      previousImpact,\n      viewport,\n      afterCritical,\n    });\n\n  if (!impact) {\n    return null;\n  }\n\n  const pageBorderBoxCenter: Position = getPageBorderBoxCenter({\n    impact,\n    draggable,\n    droppable: destination,\n    draggables,\n    afterCritical,\n  });\n\n  const isVisibleInNewLocation: boolean = isTotallyVisibleInNewLocation({\n    draggable,\n    destination,\n    newPageBorderBoxCenter: pageBorderBoxCenter,\n    viewport: viewport.frame,\n    // already taken into account by getPageBorderBoxCenter\n    withDroppableDisplacement: false,\n    // we only care about it being visible relative to the main axis\n    // this is important with dynamic changes as scroll bar and toggle\n    // on the cross axis during a drag\n    onlyOnMainAxis: true,\n  });\n\n  if (isVisibleInNewLocation) {\n    // using the client center as the selection point\n    const clientSelection: Position = getClientFromPageBorderBoxCenter({\n      pageBorderBoxCenter,\n      draggable,\n      viewport,\n    });\n    return {\n      clientSelection,\n      impact,\n      scrollJumpRequest: null,\n    };\n  }\n\n  const distance: Position = subtract(\n    pageBorderBoxCenter,\n    previousPageBorderBoxCenter,\n  );\n\n  const cautious: DragImpact = speculativelyIncrease({\n    impact,\n    viewport,\n    destination,\n    draggables,\n    maxScrollChange: distance,\n  });\n\n  return {\n    clientSelection: previousClientSelection,\n    impact: cautious,\n    scrollJumpRequest: distance,\n  };\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-to-next-place/is-totally-visible-in-new-location.js",
    "content": "// @flow\nimport { type Position, type Rect, type Spacing } from 'css-box-model';\nimport { subtract } from '../../position';\nimport { offsetByPosition } from '../../spacing';\nimport {\n  isTotallyVisible,\n  isTotallyVisibleOnAxis,\n  type Args as IsVisibleArgs,\n} from '../../visibility/is-visible';\nimport type { DraggableDimension, DroppableDimension } from '../../../types';\n\ntype Args = {|\n  draggable: DraggableDimension,\n  destination: DroppableDimension,\n  newPageBorderBoxCenter: Position,\n  viewport: Rect,\n  // only allowing a 'false' value. Being super clear\n  withDroppableDisplacement: false,\n  onlyOnMainAxis?: boolean,\n|};\n\nexport default ({\n  draggable,\n  destination,\n  newPageBorderBoxCenter,\n  viewport,\n  withDroppableDisplacement,\n  onlyOnMainAxis = false,\n}: Args): boolean => {\n  // What would the location of the Draggable be once the move is completed?\n  // We are not considering margins for this calculation.\n  // This is because a move might move a Draggable slightly outside of the bounds\n  // of a Droppable (which is okay)\n  const changeNeeded: Position = subtract(\n    newPageBorderBoxCenter,\n    draggable.page.borderBox.center,\n  );\n  const shifted: Spacing = offsetByPosition(\n    draggable.page.borderBox,\n    changeNeeded,\n  );\n\n  // Must be totally visible, not just partially visible.\n  const args: IsVisibleArgs = {\n    target: shifted,\n    destination,\n    withDroppableDisplacement,\n    viewport,\n  };\n\n  return onlyOnMainAxis ? isTotallyVisibleOnAxis(args) : isTotallyVisible(args);\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-to-next-place/move-to-next-combine/index.js",
    "content": "// @flow\nimport { invariant } from '../../../../invariant';\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n  DragImpact,\n  CombineImpact,\n  DraggableLocation,\n  DraggableId,\n} from '../../../../types';\nimport { tryGetDestination } from '../../../get-impact-location';\nimport { findIndex } from '../../../../native-with-fallback';\nimport removeDraggableFromList from '../../../remove-draggable-from-list';\n\nexport type Args = {|\n  isMovingForward: boolean,\n  draggable: DraggableDimension,\n  destination: DroppableDimension,\n  insideDestination: DraggableDimension[],\n  previousImpact: DragImpact,\n|};\n\nexport default ({\n  isMovingForward,\n  draggable,\n  destination,\n  insideDestination,\n  previousImpact,\n}: Args): ?DragImpact => {\n  if (!destination.isCombineEnabled) {\n    return null;\n  }\n\n  const location: ?DraggableLocation = tryGetDestination(previousImpact);\n\n  if (!location) {\n    return null;\n  }\n\n  function getImpact(target: DraggableId) {\n    const at: CombineImpact = {\n      type: 'COMBINE',\n      combine: {\n        draggableId: target,\n        droppableId: destination.descriptor.id,\n      },\n    };\n    return {\n      ...previousImpact,\n      at,\n    };\n  }\n\n  const all: DraggableId[] = previousImpact.displaced.all;\n  const closestId: ?DraggableId = all.length ? all[0] : null;\n\n  if (isMovingForward) {\n    return closestId ? getImpact(closestId) : null;\n  }\n\n  const withoutDraggable = removeDraggableFromList(\n    draggable,\n    insideDestination,\n  );\n\n  // Moving backwards\n\n  // if nothing is displaced - move backwards onto the last item\n  if (!closestId) {\n    if (!withoutDraggable.length) {\n      return null;\n    }\n    const last: DraggableDimension =\n      withoutDraggable[withoutDraggable.length - 1];\n    return getImpact(last.descriptor.id);\n  }\n\n  // We are moving from being between two displaced items\n  // backwards onto the first one\n\n  // need to find the first item before the closest\n  const indexOfClosest: number = findIndex(\n    withoutDraggable,\n    (d) => d.descriptor.id === closestId,\n  );\n  invariant(indexOfClosest !== -1, 'Could not find displaced item in set');\n\n  const proposedIndex: number = indexOfClosest - 1;\n\n  // There is no displaced item before\n  if (proposedIndex < 0) {\n    return null;\n  }\n\n  const before: DraggableDimension = withoutDraggable[proposedIndex];\n  return getImpact(before.descriptor.id);\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-to-next-place/move-to-next-index/from-combine.js",
    "content": "// @flow\nimport type {\n  DroppableDimension,\n  Combine,\n  DraggableDimension,\n  DraggableDimensionMap,\n  DisplacementGroups,\n  DraggableId,\n  LiftEffect,\n} from '../../../../types';\nimport didStartAfterCritical from '../../../did-start-after-critical';\n\ntype Args = {|\n  isMovingForward: boolean,\n  destination: DroppableDimension,\n  displaced: DisplacementGroups,\n  draggables: DraggableDimensionMap,\n  combine: Combine,\n  afterCritical: LiftEffect,\n|};\n\nexport default ({\n  isMovingForward,\n  destination,\n  draggables,\n  combine,\n  afterCritical,\n}: Args): ?number => {\n  if (!destination.isCombineEnabled) {\n    return null;\n  }\n  const combineId: DraggableId = combine.draggableId;\n  const combineWith: DraggableDimension = draggables[combineId];\n  const combineWithIndex: number = combineWith.descriptor.index;\n  const didCombineWithStartAfterCritical: boolean = didStartAfterCritical(\n    combineId,\n    afterCritical,\n  );\n\n  if (didCombineWithStartAfterCritical) {\n    if (isMovingForward) {\n      return combineWithIndex;\n    }\n    return combineWithIndex - 1;\n  }\n\n  if (isMovingForward) {\n    return combineWithIndex + 1;\n  }\n\n  return combineWithIndex;\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-to-next-place/move-to-next-index/from-reorder.js",
    "content": "// @flow\nimport type { DraggableDimension, DraggableLocation } from '../../../../types';\n\ntype Args = {|\n  isMovingForward: boolean,\n  isInHomeList: boolean,\n  location: DraggableLocation,\n  insideDestination: DraggableDimension[],\n|};\n\nexport default ({\n  isMovingForward,\n  isInHomeList,\n  insideDestination,\n  location,\n}: Args): ?number => {\n  // cannot move in the list\n  if (!insideDestination.length) {\n    return null;\n  }\n\n  const currentIndex: number = location.index;\n  const proposedIndex: number = isMovingForward\n    ? currentIndex + 1\n    : currentIndex - 1;\n\n  // Accounting for lists that might not start with an index of 0\n  const firstIndex: number = insideDestination[0].descriptor.index;\n  const lastIndex: number =\n    insideDestination[insideDestination.length - 1].descriptor.index;\n\n  // When in foreign list we allow movement after the last item\n  const upperBound: number = isInHomeList ? lastIndex : lastIndex + 1;\n\n  if (proposedIndex < firstIndex) {\n    return null;\n  }\n  if (proposedIndex > upperBound) {\n    return null;\n  }\n\n  return proposedIndex;\n};\n"
  },
  {
    "path": "src/state/move-in-direction/move-to-next-place/move-to-next-index/index.js",
    "content": "// @flow\nimport { invariant } from '../../../../invariant';\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n  DragImpact,\n  LiftEffect,\n  Viewport,\n  ImpactLocation,\n} from '../../../../types';\nimport calculateReorderImpact from '../../../calculate-drag-impact/calculate-reorder-impact';\nimport fromCombine from './from-combine';\nimport fromReorder from './from-reorder';\n\nexport type Args = {|\n  isMovingForward: boolean,\n  isInHomeList: boolean,\n  draggable: DraggableDimension,\n  draggables: DraggableDimensionMap,\n  destination: DroppableDimension,\n  insideDestination: DraggableDimension[],\n  previousImpact: DragImpact,\n  viewport: Viewport,\n  afterCritical: LiftEffect,\n|};\n\nexport default ({\n  isMovingForward,\n  isInHomeList,\n  draggable,\n  draggables,\n  destination,\n  insideDestination,\n  previousImpact,\n  viewport,\n  afterCritical,\n}: Args): ?DragImpact => {\n  const wasAt: ?ImpactLocation = previousImpact.at;\n  invariant(wasAt, 'Cannot move in direction without previous impact location');\n\n  if (wasAt.type === 'REORDER') {\n    const newIndex: ?number = fromReorder({\n      isMovingForward,\n      isInHomeList,\n      location: wasAt.destination,\n      insideDestination,\n    });\n    // TODO: can we just pass new index on?\n    if (newIndex == null) {\n      return null;\n    }\n    return calculateReorderImpact({\n      draggable,\n      insideDestination,\n      destination,\n      viewport,\n      last: previousImpact.displaced,\n      displacedBy: previousImpact.displacedBy,\n      index: newIndex,\n    });\n  }\n\n  // COMBINE\n  const newIndex: ?number = fromCombine({\n    isMovingForward,\n    destination,\n    displaced: previousImpact.displaced,\n    draggables,\n    combine: wasAt.combine,\n    afterCritical,\n  });\n  if (newIndex == null) {\n    return null;\n  }\n\n  return calculateReorderImpact({\n    draggable,\n    insideDestination,\n    destination,\n    viewport,\n    last: previousImpact.displaced,\n    displacedBy: previousImpact.displacedBy,\n    index: newIndex,\n  });\n};\n"
  },
  {
    "path": "src/state/no-impact.js",
    "content": "// @flow\nimport type {\n  DisplacementGroups,\n  DragImpact,\n  DisplacedBy,\n  LiftEffect,\n} from '../types';\nimport { origin } from './position';\n\nexport const noDisplacedBy: DisplacedBy = {\n  point: origin,\n  value: 0,\n};\n\nexport const emptyGroups: DisplacementGroups = {\n  invisible: {},\n  visible: {},\n  all: [],\n};\n\nconst noImpact: DragImpact = {\n  displaced: emptyGroups,\n  displacedBy: noDisplacedBy,\n  at: null,\n};\n\nexport default noImpact;\n\nexport const noAfterCritical: LiftEffect = {\n  inVirtualList: false,\n  effected: {},\n  displacedBy: noDisplacedBy,\n};\n"
  },
  {
    "path": "src/state/patch-dimension-map.js",
    "content": "// @flow\nimport type { DimensionMap, DroppableDimension } from '../types';\nimport patchDroppableMap from './patch-droppable-map';\n\nexport default (\n  dimensions: DimensionMap,\n  updated: DroppableDimension,\n): DimensionMap => ({\n  draggables: dimensions.draggables,\n  droppables: patchDroppableMap(dimensions.droppables, updated),\n});\n"
  },
  {
    "path": "src/state/patch-droppable-map.js",
    "content": "// @flow\nimport type { DroppableDimension, DroppableDimensionMap } from '../types';\n\nexport default (\n  droppables: DroppableDimensionMap,\n  updated: DroppableDimension,\n): DroppableDimensionMap => ({\n  ...droppables,\n  [updated.descriptor.id]: updated,\n});\n"
  },
  {
    "path": "src/state/position.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\n\nexport const origin: Position = { x: 0, y: 0 };\n\nexport const add = (point1: Position, point2: Position): Position => ({\n  x: point1.x + point2.x,\n  y: point1.y + point2.y,\n});\n\nexport const subtract = (point1: Position, point2: Position): Position => ({\n  x: point1.x - point2.x,\n  y: point1.y - point2.y,\n});\n\nexport const isEqual = (point1: Position, point2: Position): boolean =>\n  point1.x === point2.x && point1.y === point2.y;\n\nexport const negate = (point: Position): Position => ({\n  // if the value is already 0, do not return -0\n  x: point.x !== 0 ? -point.x : 0,\n  y: point.y !== 0 ? -point.y : 0,\n});\n\n// Allows you to build a position from values.\n// Really useful when working with the Axis type\n// patch('x', 5)    = { x: 5, y: 0 }\n// patch('y', 5, 1) = { x: 1, y: 5 }\nexport const patch = (\n  line: 'x' | 'y',\n  value: number,\n  otherValue?: number = 0,\n): Position => ({\n  // set the value of 'x', or 'y'\n  [line]: value,\n  // set the value of the other line\n  [line === 'x' ? 'y' : 'x']: otherValue,\n});\n\n// Returns the distance between two points\n// https://www.mathsisfun.com/algebra/distance-2-points.html\nexport const distance = (point1: Position, point2: Position): number =>\n  Math.sqrt(\n    Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2),\n  );\n\n// When given a list of points, it finds the smallest distance to any point\nexport const closest = (target: Position, points: Position[]): number =>\n  Math.min(...points.map((point: Position) => distance(target, point)));\n\n// used to apply any function to both values of a point\n// eg: const floor = apply(Math.floor)(point);\nexport const apply = (fn: (value: number) => number) => (\n  point: Position,\n): Position => ({\n  x: fn(point.x),\n  y: fn(point.y),\n});\n"
  },
  {
    "path": "src/state/post-reducer/when-moving/refresh-snap.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { invariant } from '../../../invariant';\nimport type {\n  DroppableDimension,\n  DraggableDimension,\n  StateWhenUpdatesAllowed,\n  DroppableId,\n  DimensionMap,\n  DragImpact,\n  Viewport,\n} from '../../../types';\nimport whatIsDraggedOver from '../../droppable/what-is-dragged-over';\nimport recomputeDisplacementVisibility from '../../update-displacement-visibility/recompute';\nimport getClientBorderBoxCenter from '../../get-center-from-impact/get-client-border-box-center';\nimport update from './update';\n\ntype Args = {|\n  state: StateWhenUpdatesAllowed,\n  dimensions?: DimensionMap,\n  viewport?: Viewport,\n|};\n\nexport default ({\n  state,\n  dimensions: forcedDimensions,\n  viewport: forcedViewport,\n}: // when a draggable is changing enabled state, sometimes it needs to force refresh an impact\nArgs): StateWhenUpdatesAllowed => {\n  invariant(state.movementMode === 'SNAP');\n\n  const needsVisibilityCheck: DragImpact = state.impact;\n  const viewport: Viewport = forcedViewport || state.viewport;\n  const dimensions: DimensionMap = forcedDimensions || state.dimensions;\n  const { draggables, droppables } = dimensions;\n\n  const draggable: DraggableDimension = draggables[state.critical.draggable.id];\n  const isOver: ?DroppableId = whatIsDraggedOver(needsVisibilityCheck);\n  invariant(isOver, 'Must be over a destination in SNAP movement mode');\n  const destination: DroppableDimension = droppables[isOver];\n\n  const impact: DragImpact = recomputeDisplacementVisibility({\n    impact: needsVisibilityCheck,\n    viewport,\n    destination,\n    draggables,\n  });\n\n  const clientSelection: Position = getClientBorderBoxCenter({\n    impact,\n    draggable,\n    droppable: destination,\n    draggables,\n    viewport,\n    afterCritical: state.afterCritical,\n  });\n\n  return update({\n    // new\n    impact,\n    clientSelection,\n    // pass through\n    state,\n    dimensions,\n    viewport,\n  });\n};\n"
  },
  {
    "path": "src/state/post-reducer/when-moving/update.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DraggableDimension,\n  DraggingState,\n  ClientPositions,\n  PagePositions,\n  DragPositions,\n  DragImpact,\n  Viewport,\n  DimensionMap,\n  StateWhenUpdatesAllowed,\n  DroppableDimensionMap,\n} from '../../../types';\nimport getDragImpact from '../../get-drag-impact';\nimport { add, subtract } from '../../position';\nimport recomputePlaceholders from '../../recompute-placeholders';\n\ntype Args = {|\n  state: StateWhenUpdatesAllowed,\n  clientSelection?: Position,\n  dimensions?: DimensionMap,\n  viewport?: Viewport,\n  // force a custom drag impact\n  impact?: ?DragImpact,\n  // provide a scroll jump request (optionally provided - and can be null)\n  scrollJumpRequest?: ?Position,\n|};\n\nexport default ({\n  state,\n  clientSelection: forcedClientSelection,\n  dimensions: forcedDimensions,\n  viewport: forcedViewport,\n  impact: forcedImpact,\n  scrollJumpRequest,\n}: Args): StateWhenUpdatesAllowed => {\n  // DRAGGING: can update position and impact\n  // COLLECTING: can update position but cannot update impact\n\n  const viewport: Viewport = forcedViewport || state.viewport;\n  const dimensions: DimensionMap = forcedDimensions || state.dimensions;\n  const clientSelection: Position =\n    forcedClientSelection || state.current.client.selection;\n\n  const offset: Position = subtract(\n    clientSelection,\n    state.initial.client.selection,\n  );\n\n  const client: ClientPositions = {\n    offset,\n    selection: clientSelection,\n    borderBoxCenter: add(state.initial.client.borderBoxCenter, offset),\n  };\n\n  const page: PagePositions = {\n    selection: add(client.selection, viewport.scroll.current),\n    borderBoxCenter: add(client.borderBoxCenter, viewport.scroll.current),\n    offset: add(client.offset, viewport.scroll.diff.value),\n  };\n\n  const current: DragPositions = {\n    client,\n    page,\n  };\n\n  // Not updating impact while bulk collecting\n  if (state.phase === 'COLLECTING') {\n    return {\n      // adding phase to appease flow (even though it will be overwritten by spread)\n      phase: 'COLLECTING',\n      ...state,\n      dimensions,\n      viewport,\n      current,\n    };\n  }\n\n  const draggable: DraggableDimension =\n    dimensions.draggables[state.critical.draggable.id];\n\n  const newImpact: DragImpact =\n    forcedImpact ||\n    getDragImpact({\n      pageOffset: page.offset,\n      draggable,\n      draggables: dimensions.draggables,\n      droppables: dimensions.droppables,\n      previousImpact: state.impact,\n      viewport,\n      afterCritical: state.afterCritical,\n    });\n\n  const withUpdatedPlaceholders: DroppableDimensionMap = recomputePlaceholders({\n    draggable,\n    impact: newImpact,\n    previousImpact: state.impact,\n    draggables: dimensions.draggables,\n    droppables: dimensions.droppables,\n  });\n  // dragging!\n  const result: DraggingState = {\n    ...state,\n    current,\n    dimensions: {\n      draggables: dimensions.draggables,\n      droppables: withUpdatedPlaceholders,\n    },\n    impact: newImpact,\n    viewport,\n    scrollJumpRequest: scrollJumpRequest || null,\n    // client updates can be applied as a part of a jump scroll\n    // this can be to immediately reverse movement to allow for a nice animation\n    // into the final position\n    forceShouldAnimate: scrollJumpRequest ? false : null,\n  };\n\n  return result;\n};\n"
  },
  {
    "path": "src/state/publish-while-dragging-in-virtual/adjust-additions-for-scroll-changes.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport type {\n  Viewport,\n  DraggableDimension,\n  DroppableDimension,\n  Scrollable,\n  DroppableDimensionMap,\n  DroppableId,\n} from '../../types';\nimport { add } from '../position';\nimport offsetDraggable from './offset-draggable';\nimport getFrame from '../get-frame';\n\ntype Args = {|\n  additions: DraggableDimension[],\n  updatedDroppables: DroppableDimensionMap,\n  viewport: Viewport,\n|};\n\nexport default ({\n  additions,\n  updatedDroppables,\n  viewport,\n}: Args): DraggableDimension[] => {\n  // We need to adjust collected draggables so that they\n  // match the model we had when the drag started.\n  // When a draggable is dynamically collected it does not have\n  // the same relative client position. We need to unwind\n  // any changes in window scroll and droppable scroll so that\n  // the newly collected draggables fit in with our other draggables\n  // and give the same dimensions that would have had if they were\n  // collected at the start of the drag.\n\n  // Need to undo the displacement caused by window scroll changes\n  const windowScrollChange: Position = viewport.scroll.diff.value;\n  // These modified droppables have already had their scroll changes correctly updated\n\n  return additions.map((draggable: DraggableDimension): DraggableDimension => {\n    const droppableId: DroppableId = draggable.descriptor.droppableId;\n    const modified: DroppableDimension = updatedDroppables[droppableId];\n    const frame: Scrollable = getFrame(modified);\n    const droppableScrollChange: Position = frame.scroll.diff.value;\n\n    const totalChange: Position = add(\n      windowScrollChange,\n      droppableScrollChange,\n    );\n\n    const moved: DraggableDimension = offsetDraggable({\n      draggable,\n      offset: totalChange,\n      initialWindowScroll: viewport.scroll.initial,\n    });\n\n    return moved;\n  });\n};\n"
  },
  {
    "path": "src/state/publish-while-dragging-in-virtual/index.js",
    "content": "// @flow\nimport type {\n  DimensionMap,\n  DraggingState,\n  CollectingState,\n  DropPendingState,\n  Published,\n  DraggableId,\n  DraggableDimension,\n  DroppableDimensionMap,\n  DraggableDimensionMap,\n  DroppableDimension,\n  DragImpact,\n  DroppablePublish,\n  DroppableId,\n} from '../../types';\nimport * as timings from '../../debug/timings';\nimport getDragImpact from '../get-drag-impact';\nimport adjustAdditionsForScrollChanges from './adjust-additions-for-scroll-changes';\nimport { toDraggableMap, toDroppableMap } from '../dimension-structures';\nimport getLiftEffect from '../get-lift-effect';\nimport scrollDroppable from '../droppable/scroll-droppable';\nimport whatIsDraggedOver from '../droppable/what-is-dragged-over';\n\ntype Args = {|\n  state: CollectingState | DropPendingState,\n  published: Published,\n|};\n\nconst timingsKey: string = 'Processing dynamic changes';\n\nexport default ({\n  state,\n  published,\n}: Args): DraggingState | DropPendingState => {\n  timings.start(timingsKey);\n\n  // TODO: update window scroll (needs to be a part of the published object)\n  // TODO: validate.\n  // - Check that all additions / removals have a droppable\n  // - Check that all droppables are virtual\n\n  // The scroll might be different to what is currently in the state\n  // We want to ensure the new draggables are in step with the state\n  const withScrollChange: DroppableDimension[] = published.modified.map(\n    (update: DroppablePublish): DroppableDimension => {\n      const existing: DroppableDimension =\n        state.dimensions.droppables[update.droppableId];\n\n      const scrolled: DroppableDimension = scrollDroppable(\n        existing,\n        update.scroll,\n      );\n      return scrolled;\n    },\n  );\n\n  const droppables: DroppableDimensionMap = {\n    ...state.dimensions.droppables,\n    ...toDroppableMap(withScrollChange),\n  };\n\n  const updatedAdditions: DraggableDimensionMap = toDraggableMap(\n    adjustAdditionsForScrollChanges({\n      additions: published.additions,\n      updatedDroppables: droppables,\n      viewport: state.viewport,\n    }),\n  );\n\n  const draggables: DraggableDimensionMap = {\n    ...state.dimensions.draggables,\n    ...updatedAdditions,\n  };\n\n  // remove all the old ones (except for the critical)\n  // we do this so that list operations remain fast\n  // TODO: need to test the impact of this like crazy\n  published.removals.forEach((id: DraggableId) => {\n    delete draggables[id];\n  });\n\n  const dimensions: DimensionMap = {\n    droppables,\n    draggables,\n  };\n\n  const wasOverId: ?DroppableId = whatIsDraggedOver(state.impact);\n  const wasOver: ?DroppableDimension = wasOverId\n    ? dimensions.droppables[wasOverId]\n    : null;\n\n  const draggable: DraggableDimension =\n    dimensions.draggables[state.critical.draggable.id];\n  const home: DroppableDimension =\n    dimensions.droppables[state.critical.droppable.id];\n\n  const { impact: onLiftImpact, afterCritical } = getLiftEffect({\n    draggable,\n    home,\n    draggables,\n    viewport: state.viewport,\n  });\n\n  const previousImpact: DragImpact =\n    wasOver && wasOver.isCombineEnabled\n      ? // Cheating here\n        // TODO: pursue a more robust approach\n        state.impact\n      : onLiftImpact;\n\n  const impact: DragImpact = getDragImpact({\n    pageOffset: state.current.page.offset,\n    draggable: dimensions.draggables[state.critical.draggable.id],\n    draggables: dimensions.draggables,\n    droppables: dimensions.droppables,\n    previousImpact,\n    viewport: state.viewport,\n    afterCritical,\n  });\n\n  timings.finish(timingsKey);\n\n  const draggingState: DraggingState = {\n    // appeasing flow\n    phase: 'DRAGGING',\n    ...state,\n    // eslint-disable-next-line\n    phase: 'DRAGGING',\n    impact,\n    onLiftImpact,\n    dimensions,\n    afterCritical,\n    // not animating this movement\n    forceShouldAnimate: false,\n  };\n\n  if (state.phase === 'COLLECTING') {\n    return draggingState;\n  }\n\n  // There was a DROP_PENDING\n  // Staying in the DROP_PENDING phase\n  // setting isWaiting for false\n\n  const dropPending: DropPendingState = {\n    // appeasing flow\n    phase: 'DROP_PENDING',\n    ...draggingState,\n    // eslint-disable-next-line\n    phase: 'DROP_PENDING',\n    // No longer waiting\n    reason: state.reason,\n    isWaiting: false,\n  };\n\n  return dropPending;\n};\n"
  },
  {
    "path": "src/state/publish-while-dragging-in-virtual/offset-draggable.js",
    "content": "// @flow\nimport {\n  withScroll,\n  offset as offsetBox,\n  type Position,\n  type BoxModel,\n} from 'css-box-model';\nimport type { DraggableDimension } from '../../types';\n\ntype Args = {|\n  draggable: DraggableDimension,\n  offset: Position,\n  initialWindowScroll: Position,\n|};\n\nexport default ({\n  draggable,\n  offset,\n  initialWindowScroll,\n}: Args): DraggableDimension => {\n  const client: BoxModel = offsetBox(draggable.client, offset);\n  const page: BoxModel = withScroll(client, initialWindowScroll);\n\n  const moved: DraggableDimension = {\n    ...draggable,\n    placeholder: {\n      ...draggable.placeholder,\n      client,\n    },\n    client,\n    page,\n  };\n\n  return moved;\n};\n"
  },
  {
    "path": "src/state/recompute-placeholders.js",
    "content": "// @flow\nimport {\n  addPlaceholder,\n  removePlaceholder,\n} from './droppable/with-placeholder';\nimport whatIsDraggedOver from './droppable/what-is-dragged-over';\nimport type {\n  DroppableDimension,\n  DraggableDimensionMap,\n  DroppableDimensionMap,\n  DraggableDimension,\n  DragImpact,\n  DroppableId,\n} from '../types';\nimport patchDroppableMap from './patch-droppable-map';\nimport isHomeOf from './droppable/is-home-of';\n\ntype ClearArgs = {|\n  previousImpact: DragImpact,\n  impact: DragImpact,\n  droppables: DroppableDimensionMap,\n|};\n\nconst clearUnusedPlaceholder = ({\n  previousImpact,\n  impact,\n  droppables,\n}: ClearArgs): DroppableDimensionMap => {\n  const last: ?DroppableId = whatIsDraggedOver(previousImpact);\n  const now: ?DroppableId = whatIsDraggedOver(impact);\n\n  if (!last) {\n    return droppables;\n  }\n\n  // no change - can keep the last state\n  if (last === now) {\n    return droppables;\n  }\n\n  const lastDroppable: DroppableDimension = droppables[last];\n\n  // nothing to clear\n  if (!lastDroppable.subject.withPlaceholder) {\n    return droppables;\n  }\n\n  const updated: DroppableDimension = removePlaceholder(lastDroppable);\n  return patchDroppableMap(droppables, updated);\n};\n\ntype Args = {|\n  draggable: DraggableDimension,\n  draggables: DraggableDimensionMap,\n  droppables: DroppableDimensionMap,\n  impact: DragImpact,\n  previousImpact: DragImpact,\n|};\n\nexport default ({\n  draggable,\n  draggables,\n  droppables,\n  previousImpact,\n  impact,\n}: Args): DroppableDimensionMap => {\n  const cleaned: DroppableDimensionMap = clearUnusedPlaceholder({\n    previousImpact,\n    impact,\n    droppables,\n  });\n\n  const isOver: ?DroppableId = whatIsDraggedOver(impact);\n\n  if (!isOver) {\n    return cleaned;\n  }\n\n  const droppable: DroppableDimension = droppables[isOver];\n\n  // no need to add additional space to home droppable\n  if (isHomeOf(draggable, droppable)) {\n    return cleaned;\n  }\n\n  // already have a placeholder - nothing to do here!\n  if (droppable.subject.withPlaceholder) {\n    return cleaned;\n  }\n\n  // Need to patch the existing droppable\n  const patched: DroppableDimension = addPlaceholder(\n    droppable,\n    draggable,\n    draggables,\n  );\n\n  return patchDroppableMap(cleaned, patched);\n};\n"
  },
  {
    "path": "src/state/rect.js",
    "content": "// @flow\nimport { getRect } from 'css-box-model';\nimport type { Rect, Position } from 'css-box-model';\nimport { offsetByPosition } from './spacing';\n\nexport const offsetRectByPosition = (rect: Rect, point: Position): Rect =>\n  getRect(offsetByPosition(rect, point));\n"
  },
  {
    "path": "src/state/reducer.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { invariant } from '../invariant';\nimport type {\n  DimensionMap,\n  State,\n  StateWhenUpdatesAllowed,\n  DraggableDimension,\n  DroppableDimension,\n  IdleState,\n  DraggingState,\n  DragPositions,\n  ClientPositions,\n  CollectingState,\n  DropAnimatingState,\n  DropPendingState,\n  Viewport,\n  DropReason,\n} from '../types';\nimport type { Action } from './store-types';\nimport type { PublicResult as MoveInDirectionResult } from './move-in-direction/move-in-direction-types';\nimport scrollDroppable from './droppable/scroll-droppable';\nimport moveInDirection from './move-in-direction';\nimport { add, isEqual, origin } from './position';\nimport scrollViewport from './scroll-viewport';\nimport isMovementAllowed from './is-movement-allowed';\nimport { toDroppableList } from './dimension-structures';\nimport update from './post-reducer/when-moving/update';\nimport refreshSnap from './post-reducer/when-moving/refresh-snap';\nimport getLiftEffect from './get-lift-effect';\nimport patchDimensionMap from './patch-dimension-map';\nimport publishWhileDraggingInVirtual from './publish-while-dragging-in-virtual';\n\nconst isSnapping = (state: StateWhenUpdatesAllowed): boolean =>\n  state.movementMode === 'SNAP';\n\nconst postDroppableChange = (\n  state: StateWhenUpdatesAllowed,\n  updated: DroppableDimension,\n  isEnabledChanging: boolean,\n): StateWhenUpdatesAllowed => {\n  const dimensions: DimensionMap = patchDimensionMap(state.dimensions, updated);\n\n  // if the enabled state is changing, we need to force a update\n  if (!isSnapping(state) || isEnabledChanging) {\n    return update({\n      state,\n      dimensions,\n    });\n  }\n\n  return refreshSnap({\n    state,\n    dimensions,\n  });\n};\n\nfunction removeScrollJumpRequest(state: State): State {\n  if (state.isDragging && state.movementMode === 'SNAP') {\n    return {\n      // will be overwritten by spread\n      // needed for flow\n      phase: 'DRAGGING',\n      ...state,\n      scrollJumpRequest: null,\n    };\n  }\n  return state;\n}\n\nconst idle: IdleState = { phase: 'IDLE', completed: null, shouldFlush: false };\n\nexport default (state: State = idle, action: Action): State => {\n  if (action.type === 'FLUSH') {\n    return {\n      ...idle,\n      shouldFlush: true,\n    };\n  }\n\n  if (action.type === 'INITIAL_PUBLISH') {\n    invariant(\n      state.phase === 'IDLE',\n      'INITIAL_PUBLISH must come after a IDLE phase',\n    );\n    const {\n      critical,\n      clientSelection,\n      viewport,\n      dimensions,\n      movementMode,\n    } = action.payload;\n\n    const draggable: DraggableDimension =\n      dimensions.draggables[critical.draggable.id];\n    const home: DroppableDimension =\n      dimensions.droppables[critical.droppable.id];\n\n    const client: ClientPositions = {\n      selection: clientSelection,\n      borderBoxCenter: draggable.client.borderBox.center,\n      offset: origin,\n    };\n\n    const initial: DragPositions = {\n      client,\n      page: {\n        selection: add(client.selection, viewport.scroll.initial),\n        borderBoxCenter: add(client.selection, viewport.scroll.initial),\n        offset: add(client.selection, viewport.scroll.diff.value),\n      },\n    };\n\n    // Can only auto scroll the window if every list is not fixed on the page\n    const isWindowScrollAllowed: boolean = toDroppableList(\n      dimensions.droppables,\n    ).every((item: DroppableDimension) => !item.isFixedOnPage);\n\n    const { impact, afterCritical } = getLiftEffect({\n      draggable,\n      home,\n      draggables: dimensions.draggables,\n      viewport,\n    });\n\n    const result: DraggingState = {\n      phase: 'DRAGGING',\n      isDragging: true,\n      critical,\n      movementMode,\n      dimensions,\n      initial,\n      current: initial,\n      isWindowScrollAllowed,\n      impact,\n      afterCritical,\n      onLiftImpact: impact,\n      viewport,\n      scrollJumpRequest: null,\n      forceShouldAnimate: null,\n    };\n\n    return result;\n  }\n\n  if (action.type === 'COLLECTION_STARTING') {\n    // A collection might have restarted. We do not care as we are already in the right phase\n    // TODO: remove?\n    if (state.phase === 'COLLECTING' || state.phase === 'DROP_PENDING') {\n      return state;\n    }\n\n    invariant(\n      state.phase === 'DRAGGING',\n      `Collection cannot start from phase ${state.phase}`,\n    );\n\n    const result: CollectingState = {\n      // putting phase first to appease flow\n      phase: 'COLLECTING',\n      ...state,\n      // eslint-disable-next-line\n      phase: 'COLLECTING',\n    };\n\n    return result;\n  }\n\n  if (action.type === 'PUBLISH_WHILE_DRAGGING') {\n    // Unexpected bulk publish\n    invariant(\n      state.phase === 'COLLECTING' || state.phase === 'DROP_PENDING',\n      `Unexpected ${action.type} received in phase ${state.phase}`,\n    );\n\n    return publishWhileDraggingInVirtual({\n      state,\n      published: action.payload,\n    });\n  }\n\n  if (action.type === 'MOVE') {\n    // Not allowing any more movements\n    if (state.phase === 'DROP_PENDING') {\n      return state;\n    }\n\n    invariant(\n      isMovementAllowed(state),\n      `${action.type} not permitted in phase ${state.phase}`,\n    );\n\n    const { client: clientSelection } = action.payload;\n\n    // nothing needs to be done\n    if (isEqual(clientSelection, state.current.client.selection)) {\n      return state;\n    }\n\n    return update({\n      state,\n      clientSelection,\n      // If we are snap moving - manual movements should not update the impact\n      impact: isSnapping(state) ? state.impact : null,\n    });\n  }\n\n  if (action.type === 'UPDATE_DROPPABLE_SCROLL') {\n    // Not allowing changes while a drop is pending\n    // Cannot get this during a DROP_ANIMATING as the dimension\n    // marshal will cancel any pending scroll updates\n    if (state.phase === 'DROP_PENDING') {\n      return removeScrollJumpRequest(state);\n    }\n\n    // We will be updating the scroll in response to dynamic changes\n    // manually on the droppable so we can ignore this change\n    if (state.phase === 'COLLECTING') {\n      return removeScrollJumpRequest(state);\n    }\n\n    invariant(\n      isMovementAllowed(state),\n      `${action.type} not permitted in phase ${state.phase}`,\n    );\n\n    const { id, newScroll } = action.payload;\n    const target: ?DroppableDimension = state.dimensions.droppables[id];\n\n    // This is possible if a droppable has been asked to watch scroll but\n    // the dimension has not been published yet\n    if (!target) {\n      return state;\n    }\n\n    const scrolled: DroppableDimension = scrollDroppable(target, newScroll);\n    return postDroppableChange(state, scrolled, false);\n  }\n\n  if (action.type === 'UPDATE_DROPPABLE_IS_ENABLED') {\n    // Things are locked at this point\n    if (state.phase === 'DROP_PENDING') {\n      return state;\n    }\n\n    invariant(\n      isMovementAllowed(state),\n      `Attempting to move in an unsupported phase ${state.phase}`,\n    );\n\n    const { id, isEnabled } = action.payload;\n    const target: ?DroppableDimension = state.dimensions.droppables[id];\n\n    invariant(\n      target,\n      `Cannot find Droppable[id: ${id}] to toggle its enabled state`,\n    );\n\n    invariant(\n      target.isEnabled !== isEnabled,\n      `Trying to set droppable isEnabled to ${String(isEnabled)}\n      but it is already ${String(target.isEnabled)}`,\n    );\n\n    const updated: DroppableDimension = {\n      ...target,\n      isEnabled,\n    };\n\n    return postDroppableChange(state, updated, true);\n  }\n\n  if (action.type === 'UPDATE_DROPPABLE_IS_COMBINE_ENABLED') {\n    // Things are locked at this point\n    if (state.phase === 'DROP_PENDING') {\n      return state;\n    }\n\n    invariant(\n      isMovementAllowed(state),\n      `Attempting to move in an unsupported phase ${state.phase}`,\n    );\n\n    const { id, isCombineEnabled } = action.payload;\n    const target: ?DroppableDimension = state.dimensions.droppables[id];\n\n    invariant(\n      target,\n      `Cannot find Droppable[id: ${id}] to toggle its isCombineEnabled state`,\n    );\n\n    invariant(\n      target.isCombineEnabled !== isCombineEnabled,\n      `Trying to set droppable isCombineEnabled to ${String(isCombineEnabled)}\n      but it is already ${String(target.isCombineEnabled)}`,\n    );\n\n    const updated: DroppableDimension = {\n      ...target,\n      isCombineEnabled,\n    };\n\n    return postDroppableChange(state, updated, true);\n  }\n\n  if (action.type === 'MOVE_BY_WINDOW_SCROLL') {\n    // No longer accepting changes\n    if (state.phase === 'DROP_PENDING' || state.phase === 'DROP_ANIMATING') {\n      return state;\n    }\n\n    invariant(\n      isMovementAllowed(state),\n      `Cannot move by window in phase ${state.phase}`,\n    );\n\n    invariant(\n      state.isWindowScrollAllowed,\n      'Window scrolling is currently not supported for fixed lists',\n    );\n\n    const newScroll: Position = action.payload.newScroll;\n\n    // nothing needs to be done\n    if (isEqual(state.viewport.scroll.current, newScroll)) {\n      return removeScrollJumpRequest(state);\n    }\n\n    const viewport: Viewport = scrollViewport(state.viewport, newScroll);\n\n    if (isSnapping(state)) {\n      return refreshSnap({\n        state,\n        viewport,\n      });\n    }\n\n    return update({\n      state,\n      viewport,\n    });\n  }\n\n  if (action.type === 'UPDATE_VIEWPORT_MAX_SCROLL') {\n    // Could occur if a transitionEnd occurs after a drag ends\n    if (!isMovementAllowed(state)) {\n      return state;\n    }\n\n    const maxScroll: Position = action.payload.maxScroll;\n\n    if (isEqual(maxScroll, state.viewport.scroll.max)) {\n      return state;\n    }\n\n    const withMaxScroll: Viewport = {\n      ...state.viewport,\n      scroll: {\n        ...state.viewport.scroll,\n        max: maxScroll,\n      },\n    };\n\n    // don't need to recalc any updates\n    return {\n      // phase will be overridden - appeasing flow\n      phase: 'DRAGGING',\n      ...state,\n      viewport: withMaxScroll,\n    };\n  }\n  if (\n    action.type === 'MOVE_UP' ||\n    action.type === 'MOVE_DOWN' ||\n    action.type === 'MOVE_LEFT' ||\n    action.type === 'MOVE_RIGHT'\n  ) {\n    // Not doing keyboard movements during these phases\n    if (state.phase === 'COLLECTING' || state.phase === 'DROP_PENDING') {\n      return state;\n    }\n\n    invariant(\n      state.phase === 'DRAGGING',\n      `${action.type} received while not in DRAGGING phase`,\n    );\n\n    const result: ?MoveInDirectionResult = moveInDirection({\n      state,\n      type: action.type,\n    });\n\n    // cannot move in that direction\n    if (!result) {\n      return state;\n    }\n\n    return update({\n      state,\n      impact: result.impact,\n      clientSelection: result.clientSelection,\n      scrollJumpRequest: result.scrollJumpRequest,\n    });\n  }\n\n  if (action.type === 'DROP_PENDING') {\n    const reason: DropReason = action.payload.reason;\n    invariant(\n      state.phase === 'COLLECTING',\n      'Can only move into the DROP_PENDING phase from the COLLECTING phase',\n    );\n\n    const newState: DropPendingState = {\n      // appeasing flow\n      phase: 'DROP_PENDING',\n      ...state,\n      // eslint-disable-next-line\n      phase: 'DROP_PENDING',\n      isWaiting: true,\n      reason,\n    };\n    return newState;\n  }\n\n  if (action.type === 'DROP_ANIMATE') {\n    const { completed, dropDuration, newHomeClientOffset } = action.payload;\n    invariant(\n      state.phase === 'DRAGGING' || state.phase === 'DROP_PENDING',\n      `Cannot animate drop from phase ${state.phase}`,\n    );\n\n    // Moving into a new phase\n    const result: DropAnimatingState = {\n      phase: 'DROP_ANIMATING',\n      completed,\n      dropDuration,\n      newHomeClientOffset,\n      dimensions: state.dimensions,\n    };\n\n    return result;\n  }\n\n  // Action will be used by responders to call consumers\n  // We can simply return to the idle state\n  if (action.type === 'DROP_COMPLETE') {\n    const { completed } = action.payload;\n\n    return {\n      phase: 'IDLE',\n      completed,\n      shouldFlush: false,\n    };\n  }\n\n  return state;\n};\n"
  },
  {
    "path": "src/state/registry/create-registry.js",
    "content": "// @flow\nimport { invariant } from '../../invariant';\nimport type { TypeId, DraggableId, DroppableId } from '../../types';\nimport type {\n  Registry,\n  DraggableAPI,\n  DroppableAPI,\n  DraggableEntry,\n  DroppableEntry,\n  RegistryEvent,\n  Subscriber,\n  Unsubscribe,\n  DraggableEntryMap,\n  DroppableEntryMap,\n} from './registry-types';\nimport { values } from '../../native-with-fallback';\n\ntype EntryMap = {\n  draggables: DraggableEntryMap,\n  droppables: DroppableEntryMap,\n};\n\nexport default function createRegistry(): Registry {\n  const entries: EntryMap = {\n    draggables: {},\n    droppables: {},\n  };\n\n  const subscribers: Subscriber[] = [];\n\n  function subscribe(cb: Subscriber): Unsubscribe {\n    subscribers.push(cb);\n\n    return function unsubscribe(): void {\n      const index: number = subscribers.indexOf(cb);\n\n      // might have been removed by a clean\n      if (index === -1) {\n        return;\n      }\n\n      subscribers.splice(index, 1);\n    };\n  }\n\n  function notify(event: RegistryEvent) {\n    if (subscribers.length) {\n      subscribers.forEach((cb) => cb(event));\n    }\n  }\n\n  function findDraggableById(id: DraggableId): ?DraggableEntry {\n    return entries.draggables[id] || null;\n  }\n\n  function getDraggableById(id: DraggableId): DraggableEntry {\n    const entry: ?DraggableEntry = findDraggableById(id);\n    invariant(entry, `Cannot find draggable entry with id [${id}]`);\n    return entry;\n  }\n\n  const draggableAPI: DraggableAPI = {\n    register: (entry: DraggableEntry) => {\n      entries.draggables[entry.descriptor.id] = entry;\n      notify({ type: 'ADDITION', value: entry });\n    },\n    update: (entry: DraggableEntry, last: DraggableEntry) => {\n      const current: ?DraggableEntry = entries.draggables[last.descriptor.id];\n\n      // item already removed\n      if (!current) {\n        return;\n      }\n\n      // id already used for another mount\n      if (current.uniqueId !== entry.uniqueId) {\n        return;\n      }\n\n      // We are safe to delete the old entry and add a new one\n      delete entries.draggables[last.descriptor.id];\n      entries.draggables[entry.descriptor.id] = entry;\n    },\n    unregister: (entry: DraggableEntry) => {\n      const draggableId: DraggableId = entry.descriptor.id;\n      const current: ?DraggableEntry = findDraggableById(draggableId);\n\n      // can occur if cleaned before unregistration\n      if (!current) {\n        return;\n      }\n\n      // outdated uniqueId\n      if (entry.uniqueId !== current.uniqueId) {\n        return;\n      }\n\n      delete entries.draggables[draggableId];\n      notify({ type: 'REMOVAL', value: entry });\n    },\n    getById: getDraggableById,\n    findById: findDraggableById,\n    exists: (id: DraggableId): boolean => Boolean(findDraggableById(id)),\n    getAllByType: (type: TypeId): DraggableEntry[] =>\n      values(entries.draggables).filter(\n        (entry: DraggableEntry): boolean => entry.descriptor.type === type,\n      ),\n  };\n\n  function findDroppableById(id: DroppableId): ?DroppableEntry {\n    return entries.droppables[id] || null;\n  }\n\n  function getDroppableById(id: DroppableId): DroppableEntry {\n    const entry: ?DroppableEntry = findDroppableById(id);\n    invariant(entry, `Cannot find droppable entry with id [${id}]`);\n    return entry;\n  }\n\n  const droppableAPI: DroppableAPI = {\n    register: (entry: DroppableEntry) => {\n      entries.droppables[entry.descriptor.id] = entry;\n    },\n    unregister: (entry: DroppableEntry) => {\n      const current: ?DroppableEntry = findDroppableById(entry.descriptor.id);\n\n      // can occur if cleaned before an unregistry\n      if (!current) {\n        return;\n      }\n\n      // already changed\n      if (entry.uniqueId !== current.uniqueId) {\n        return;\n      }\n\n      delete entries.droppables[entry.descriptor.id];\n    },\n    getById: getDroppableById,\n    findById: findDroppableById,\n    exists: (id: DroppableId): boolean => Boolean(findDroppableById(id)),\n    getAllByType: (type: TypeId): DroppableEntry[] =>\n      values(entries.droppables).filter(\n        (entry: DroppableEntry): boolean => entry.descriptor.type === type,\n      ),\n  };\n\n  function clean(): void {\n    // kill entries\n    entries.draggables = {};\n    entries.droppables = {};\n    // remove all subscribers\n    subscribers.length = 0;\n  }\n\n  return {\n    draggable: draggableAPI,\n    droppable: droppableAPI,\n    subscribe,\n    clean,\n  };\n}\n"
  },
  {
    "path": "src/state/registry/registry-types.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Id,\n  DraggableId,\n  DraggableDescriptor,\n  DraggableOptions,\n  DraggableDimension,\n  DroppableId,\n  ScrollOptions,\n  DroppableDescriptor,\n  DroppableDimension,\n  TypeId,\n} from '../../types';\n\nexport type GetDraggableDimensionFn = (\n  windowScroll: Position,\n) => DraggableDimension;\n\nexport type DraggableEntry = {|\n  uniqueId: Id,\n  descriptor: DraggableDescriptor,\n  options: DraggableOptions,\n  getDimension: GetDraggableDimensionFn,\n|};\n\nexport type DraggableAPI = {|\n  register: (entry: DraggableEntry) => void,\n  update: (entry: DraggableEntry, last: DraggableEntry) => void,\n  unregister: (entry: DraggableEntry) => void,\n  exists: (id: DraggableId) => boolean,\n  getById: (id: DraggableId) => DraggableEntry,\n  findById: (id: DraggableId) => ?DraggableEntry,\n  getAllByType: (type: TypeId) => DraggableEntry[],\n|};\n\nexport type GetDroppableDimensionFn = (\n  windowScroll: Position,\n  options: ScrollOptions,\n) => DroppableDimension;\n\nexport type RecollectDroppableOptions = {|\n  withoutPlaceholder: boolean,\n|};\n\nexport type DroppableCallbacks = {|\n  // a drag is starting\n  getDimensionAndWatchScroll: GetDroppableDimensionFn,\n  getScrollWhileDragging: () => Position,\n  // scroll a droppable\n  scroll: (change: Position) => void,\n  // If the Droppable is listening for scroll events - it needs to stop!\n  // Can be called on droppables that have not been asked to watch scroll\n  dragStopped: () => void,\n|};\n\nexport type DroppableEntry = {|\n  uniqueId: Id,\n  descriptor: DroppableDescriptor,\n  callbacks: DroppableCallbacks,\n|};\n\nexport type DraggableEntryMap = {\n  [id: DraggableId]: DraggableEntry,\n};\n\nexport type DroppableEntryMap = {\n  [id: DroppableId]: DroppableEntry,\n};\n\nexport type DroppableAPI = {|\n  register: (entry: DroppableEntry) => void,\n  unregister: (entry: DroppableEntry) => void,\n  exists: (id: DraggableId) => boolean,\n  getById: (id: DroppableId) => DroppableEntry,\n  findById: (id: DroppableId) => ?DroppableEntry,\n  getAllByType: (type: TypeId) => DroppableEntry[],\n|};\n\nexport type RegistryEvent =\n  | {|\n      type: 'ADDITION',\n      value: DraggableEntry,\n    |}\n  | {|\n      type: 'REMOVAL',\n      value: DraggableEntry,\n    |};\n\nexport type Subscriber = (event: RegistryEvent) => void;\nexport type Unsubscribe = () => void;\n\nexport type Registry = {|\n  draggable: DraggableAPI,\n  droppable: DroppableAPI,\n  subscribe: (cb: Subscriber) => Unsubscribe,\n  clean: () => void,\n|};\n"
  },
  {
    "path": "src/state/registry/use-registry.js",
    "content": "// @flow\nimport { useEffect } from 'react';\nimport { useMemo } from 'use-memo-one';\nimport type { Registry } from './registry-types';\nimport createRegistry from './create-registry';\n\nexport default function useRegistry(): Registry {\n  const registry: Registry = useMemo(createRegistry, []);\n\n  useEffect(() => {\n    return function unmount() {\n      // clean up the registry to avoid any leaks\n      // doing it after an animation frame so that other things unmounting\n      // can continue to interact with the registry\n      requestAnimationFrame(registry.clean);\n    };\n  }, [registry]);\n\n  return registry;\n}\n"
  },
  {
    "path": "src/state/remove-draggable-from-list.js",
    "content": "// @flow\nimport memoizeOne from 'memoize-one';\nimport type { DraggableDimension } from '../types';\n\nexport default memoizeOne(\n  (\n    remove: DraggableDimension,\n    list: DraggableDimension[],\n  ): DraggableDimension[] =>\n    list.filter(\n      (item: DraggableDimension) => item.descriptor.id !== remove.descriptor.id,\n    ),\n);\n"
  },
  {
    "path": "src/state/scroll-viewport.js",
    "content": "// @flow\nimport { getRect, type Rect } from 'css-box-model';\nimport type { Position } from 'css-box-model';\nimport { subtract, negate } from './position';\nimport type { Viewport } from '../types';\n\nexport default (viewport: Viewport, newScroll: Position): Viewport => {\n  const diff: Position = subtract(newScroll, viewport.scroll.initial);\n  const displacement: Position = negate(diff);\n\n  // We need to update the frame so that it is always a live value\n  // The top / left of the frame should always match the newScroll position\n  const frame: Rect = getRect({\n    top: newScroll.y,\n    bottom: newScroll.y + viewport.frame.height,\n    left: newScroll.x,\n    right: newScroll.x + viewport.frame.width,\n  });\n\n  const updated: Viewport = {\n    frame,\n    scroll: {\n      initial: viewport.scroll.initial,\n      max: viewport.scroll.max,\n      current: newScroll,\n      diff: {\n        value: diff,\n        displacement,\n      },\n    },\n  };\n\n  return updated;\n};\n"
  },
  {
    "path": "src/state/spacing.js",
    "content": "// @flow\nimport type { Spacing, Position } from 'css-box-model';\n\n// TODO add test\nexport const isEqual = (first: Spacing, second: Spacing): boolean =>\n  first.top === second.top &&\n  first.right === second.right &&\n  first.bottom === second.bottom &&\n  first.left === second.left;\n\nexport const offsetByPosition = (\n  spacing: Spacing,\n  point: Position,\n): Spacing => ({\n  top: spacing.top + point.y,\n  left: spacing.left + point.x,\n  bottom: spacing.bottom + point.y,\n  right: spacing.right + point.x,\n});\n\nexport const expandByPosition = (\n  spacing: Spacing,\n  position: Position,\n): Spacing => ({\n  // pulling back to increase size\n  top: spacing.top - position.y,\n  left: spacing.left - position.x,\n  // pushing forward to increase size\n  right: spacing.right + position.x,\n  bottom: spacing.bottom + position.y,\n});\n\nexport const getCorners = (spacing: Spacing): Position[] => [\n  { x: spacing.left, y: spacing.top },\n  { x: spacing.right, y: spacing.top },\n  { x: spacing.left, y: spacing.bottom },\n  { x: spacing.right, y: spacing.bottom },\n];\n\nexport const noSpacing: Spacing = {\n  top: 0,\n  right: 0,\n  bottom: 0,\n  left: 0,\n};\n"
  },
  {
    "path": "src/state/store-types.js",
    "content": "// @flow\n// This file exists to avoid a circular dependency between types.js and action-creators.js\nimport type {\n  Store as ReduxStore,\n  Dispatch as ReduxDispatch,\n  Middleware as ReduxMiddleware,\n  MiddlewareAPI as ReduxMiddlewareAPI,\n} from 'redux';\nimport type { Action as ActionCreators } from './action-creators';\nimport type { State } from '../types';\n\nexport type Action = ActionCreators;\nexport type Dispatch = ReduxDispatch<Action>;\nexport type Store = ReduxStore<State, Action, Dispatch>;\nexport type Middleware = ReduxMiddleware<State, Action, Dispatch>;\nexport type MiddlewareStore = ReduxMiddlewareAPI<State, Action, Dispatch>;\n"
  },
  {
    "path": "src/state/update-displacement-visibility/recompute.js",
    "content": "// @flow\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n  DragImpact,\n  Viewport,\n  DraggableId,\n  DisplacementGroups,\n} from '../../types';\nimport getDisplacementGroups from '../get-displacement-groups';\n\ntype RecomputeArgs = {|\n  impact: DragImpact,\n  draggables: DraggableDimensionMap,\n  destination: DroppableDimension,\n  viewport: Viewport,\n  forceShouldAnimate?: boolean,\n|};\n\nfunction getDraggables(\n  ids: DraggableId[],\n  draggables: DraggableDimensionMap,\n): DraggableDimension[] {\n  return ids.map((id: DraggableId): DraggableDimension => draggables[id]);\n}\n\nexport default ({\n  impact,\n  viewport,\n  draggables,\n  destination,\n  forceShouldAnimate,\n}: RecomputeArgs): DragImpact => {\n  const last: DisplacementGroups = impact.displaced;\n  const afterDragging: DraggableDimension[] = getDraggables(\n    last.all,\n    draggables,\n  );\n\n  const displaced: DisplacementGroups = getDisplacementGroups({\n    afterDragging,\n    destination,\n    displacedBy: impact.displacedBy,\n    viewport: viewport.frame,\n    forceShouldAnimate,\n    last,\n  });\n\n  return {\n    ...impact,\n    displaced,\n  };\n};\n"
  },
  {
    "path": "src/state/update-displacement-visibility/speculatively-increase.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DraggableId,\n  DroppableDimension,\n  DraggableDimension,\n  DraggableDimensionMap,\n  DragImpact,\n  Displacement,\n  DisplacementGroups,\n  DraggableIdMap,\n  DisplacementMap,\n  Viewport,\n} from '../../types';\nimport scrollViewport from '../scroll-viewport';\nimport scrollDroppable from '../droppable/scroll-droppable';\nimport { add } from '../position';\nimport getDisplacementGroups from '../get-displacement-groups';\n\ntype SpeculativeArgs = {|\n  impact: DragImpact,\n  destination: DroppableDimension,\n  viewport: Viewport,\n  draggables: DraggableDimensionMap,\n  maxScrollChange: Position,\n|};\n\nfunction getDraggables(\n  ids: DraggableId[],\n  draggables: DraggableDimensionMap,\n): DraggableDimension[] {\n  return ids.map((id: DraggableId): DraggableDimension => draggables[id]);\n}\n\nfunction tryGetVisible(\n  id: DraggableId,\n  groups: DisplacementGroups[],\n): ?Displacement {\n  for (let i = 0; i < groups.length; i++) {\n    const displacement: ?Displacement = groups[i].visible[id];\n    if (displacement) {\n      return displacement;\n    }\n  }\n  return null;\n}\n\nexport default ({\n  impact,\n  viewport,\n  destination,\n  draggables,\n  maxScrollChange,\n}: SpeculativeArgs): DragImpact => {\n  const scrolledViewport: Viewport = scrollViewport(\n    viewport,\n    add(viewport.scroll.current, maxScrollChange),\n  );\n  const scrolledDroppable: DroppableDimension = destination.frame\n    ? scrollDroppable(\n        destination,\n        add(destination.frame.scroll.current, maxScrollChange),\n      )\n    : destination;\n\n  const last: DisplacementGroups = impact.displaced;\n  const withViewportScroll: DisplacementGroups = getDisplacementGroups({\n    afterDragging: getDraggables(last.all, draggables),\n    destination,\n    displacedBy: impact.displacedBy,\n    viewport: scrolledViewport.frame,\n    last,\n    // we want the addition to be animated\n    forceShouldAnimate: false,\n  });\n  const withDroppableScroll: DisplacementGroups = getDisplacementGroups({\n    afterDragging: getDraggables(last.all, draggables),\n    destination: scrolledDroppable,\n    displacedBy: impact.displacedBy,\n    viewport: viewport.frame,\n    last,\n    // we want the addition to be animated\n    forceShouldAnimate: false,\n  });\n\n  const invisible: DraggableIdMap = {};\n  const visible: DisplacementMap = {};\n  const groups: DisplacementGroups[] = [\n    // this will populate the previous entries with the correct animation values\n    last,\n    withViewportScroll,\n    withDroppableScroll,\n  ];\n\n  last.all.forEach((id: DraggableId) => {\n    const displacement: ?Displacement = tryGetVisible(id, groups);\n\n    if (displacement) {\n      visible[id] = displacement;\n      return;\n    }\n    invisible[id] = true;\n  });\n\n  const newImpact: DragImpact = {\n    ...impact,\n    displaced: { all: last.all, invisible, visible },\n  };\n\n  return newImpact;\n};\n"
  },
  {
    "path": "src/state/visibility/is-partially-visible-through-frame.js",
    "content": "// @flow\nimport { type Spacing } from 'css-box-model';\nimport isWithin from '../is-within';\n\nexport default (frame: Spacing) => {\n  const isWithinVertical = isWithin(frame.top, frame.bottom);\n  const isWithinHorizontal = isWithin(frame.left, frame.right);\n\n  return (subject: Spacing) => {\n    // situations where target is visible:\n    // 1. is completely contained within frame\n    // 2. is partially visible on both axis within frame\n    // 3. is bigger than frame on both axis\n    // 4. is bigger than frame on one axis and is partially visible on the other\n\n    // completely contained\n    const isContained: boolean =\n      isWithinVertical(subject.top) &&\n      isWithinVertical(subject.bottom) &&\n      isWithinHorizontal(subject.left) &&\n      isWithinHorizontal(subject.right);\n\n    if (isContained) {\n      return true;\n    }\n\n    const isPartiallyVisibleVertically: boolean =\n      isWithinVertical(subject.top) || isWithinVertical(subject.bottom);\n    const isPartiallyVisibleHorizontally: boolean =\n      isWithinHorizontal(subject.left) || isWithinHorizontal(subject.right);\n\n    // partially visible on both axis\n    const isPartiallyContained: boolean =\n      isPartiallyVisibleVertically && isPartiallyVisibleHorizontally;\n\n    if (isPartiallyContained) {\n      return true;\n    }\n\n    const isBiggerVertically: boolean =\n      subject.top < frame.top && subject.bottom > frame.bottom;\n    const isBiggerHorizontally: boolean =\n      subject.left < frame.left && subject.right > frame.right;\n\n    // is bigger than frame on both axis\n    const isTargetBiggerThanFrame: boolean =\n      isBiggerVertically && isBiggerHorizontally;\n\n    if (isTargetBiggerThanFrame) {\n      return true;\n    }\n\n    // is bigger on one axis, and partially visible on another\n    const isTargetBiggerOnOneAxis: boolean =\n      (isBiggerVertically && isPartiallyVisibleHorizontally) ||\n      (isBiggerHorizontally && isPartiallyVisibleVertically);\n\n    return isTargetBiggerOnOneAxis;\n  };\n};\n"
  },
  {
    "path": "src/state/visibility/is-position-in-frame.js",
    "content": "// @flow\nimport { type Position, type Spacing } from 'css-box-model';\nimport isWithin from '../is-within';\n\nexport default function isPositionInFrame(frame: Spacing) {\n  const isWithinVertical = isWithin(frame.top, frame.bottom);\n  const isWithinHorizontal = isWithin(frame.left, frame.right);\n\n  return function run(point: Position) {\n    return isWithinVertical(point.y) && isWithinHorizontal(point.x);\n  };\n}\n"
  },
  {
    "path": "src/state/visibility/is-totally-visible-through-frame-on-axis.js",
    "content": "// @flow\nimport { type Spacing } from 'css-box-model';\nimport type { Axis } from '../../types';\nimport isWithin from '../is-within';\nimport { vertical } from '../axis';\n\nexport default (axis: Axis) => (frame: Spacing) => {\n  const isWithinVertical = isWithin(frame.top, frame.bottom);\n  const isWithinHorizontal = isWithin(frame.left, frame.right);\n\n  return (subject: Spacing) => {\n    if (axis === vertical) {\n      return isWithinVertical(subject.top) && isWithinVertical(subject.bottom);\n    }\n    return (\n      isWithinHorizontal(subject.left) && isWithinHorizontal(subject.right)\n    );\n  };\n};\n"
  },
  {
    "path": "src/state/visibility/is-totally-visible-through-frame.js",
    "content": "// @flow\nimport { type Spacing } from 'css-box-model';\nimport isWithin from '../is-within';\n\nexport default (frame: Spacing) => {\n  const isWithinVertical = isWithin(frame.top, frame.bottom);\n  const isWithinHorizontal = isWithin(frame.left, frame.right);\n\n  return (subject: Spacing) => {\n    const isContained: boolean =\n      isWithinVertical(subject.top) &&\n      isWithinVertical(subject.bottom) &&\n      isWithinHorizontal(subject.left) &&\n      isWithinHorizontal(subject.right);\n\n    return isContained;\n  };\n};\n"
  },
  {
    "path": "src/state/visibility/is-visible.js",
    "content": "// @flow\nimport { type Position, type Spacing, type Rect } from 'css-box-model';\nimport type { DroppableDimension } from '../../types';\nimport isPartiallyVisibleThroughFrame from './is-partially-visible-through-frame';\nimport isTotallyVisibleThroughFrame from './is-totally-visible-through-frame';\nimport isTotallyVisibleThroughFrameOnAxis from './is-totally-visible-through-frame-on-axis';\nimport { offsetByPosition } from '../spacing';\nimport { origin } from '../position';\n\nexport type Args = {|\n  target: Spacing,\n  destination: DroppableDimension,\n  viewport: Rect,\n  withDroppableDisplacement: boolean,\n  shouldCheckDroppable?: boolean,\n  shouldCheckViewport?: boolean,\n|};\n\ntype IsVisibleThroughFrameFn = (\n  frame: Spacing,\n) => (subject: Spacing) => boolean;\n\ntype InternalArgs = {|\n  ...Args,\n  isVisibleThroughFrameFn: IsVisibleThroughFrameFn,\n|};\n\nconst getDroppableDisplaced = (\n  target: Spacing,\n  destination: DroppableDimension,\n): Spacing => {\n  const displacement: Position = destination.frame\n    ? destination.frame.scroll.diff.displacement\n    : origin;\n\n  return offsetByPosition(target, displacement);\n};\n\nconst isVisibleInDroppable = (\n  target: Spacing,\n  destination: DroppableDimension,\n  isVisibleThroughFrameFn: IsVisibleThroughFrameFn,\n): boolean => {\n  // destination subject is totally hidden by frame\n  // this should never happen - but just guarding against it\n  if (!destination.subject.active) {\n    return false;\n  }\n\n  // When considering if the target is visible in the droppable we need\n  // to consider the change in scroll of the droppable. We need to\n  // adjust for the scroll as the clipped viewport takes into account\n  // the scroll of the droppable.\n\n  return isVisibleThroughFrameFn(destination.subject.active)(target);\n};\n\nconst isVisibleInViewport = (\n  target: Spacing,\n  viewport: Rect,\n  isVisibleThroughFrameFn: IsVisibleThroughFrameFn,\n): boolean => isVisibleThroughFrameFn(viewport)(target);\n\nconst isVisible = ({\n  target: toBeDisplaced,\n  destination,\n  viewport,\n  withDroppableDisplacement,\n  isVisibleThroughFrameFn,\n}: InternalArgs): boolean => {\n  const displacedTarget: Spacing = withDroppableDisplacement\n    ? getDroppableDisplaced(toBeDisplaced, destination)\n    : toBeDisplaced;\n\n  return (\n    isVisibleInDroppable(\n      displacedTarget,\n      destination,\n      isVisibleThroughFrameFn,\n    ) && isVisibleInViewport(displacedTarget, viewport, isVisibleThroughFrameFn)\n  );\n};\n\nexport const isPartiallyVisible = (args: Args): boolean =>\n  isVisible({\n    ...args,\n    isVisibleThroughFrameFn: isPartiallyVisibleThroughFrame,\n  });\n\nexport const isTotallyVisible = (args: Args): boolean =>\n  isVisible({\n    ...args,\n    isVisibleThroughFrameFn: isTotallyVisibleThroughFrame,\n  });\n\nexport const isTotallyVisibleOnAxis = (args: Args): boolean =>\n  isVisible({\n    ...args,\n    isVisibleThroughFrameFn: isTotallyVisibleThroughFrameOnAxis(\n      args.destination.axis,\n    ),\n  });\n"
  },
  {
    "path": "src/state/with-scroll-change/with-all-displacement.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { DroppableDimension, Viewport } from '../../types';\nimport withDroppableDisplacement from './with-droppable-displacement';\nimport withViewportDisplacement from './with-viewport-displacement';\n\nexport default (\n  page: Position,\n  droppable: DroppableDimension,\n  viewport: Viewport,\n): Position =>\n  withDroppableDisplacement(\n    droppable,\n    withViewportDisplacement(viewport, page),\n  );\n"
  },
  {
    "path": "src/state/with-scroll-change/with-droppable-displacement.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { add } from '../position';\nimport type { Scrollable, DroppableDimension } from '../../types';\n\nexport default (droppable: DroppableDimension, point: Position): Position => {\n  const frame: ?Scrollable = droppable.frame;\n  if (!frame) {\n    return point;\n  }\n\n  return add(point, frame.scroll.diff.displacement);\n};\n"
  },
  {
    "path": "src/state/with-scroll-change/with-droppable-scroll.js",
    "content": "// @flow\nimport { type Rect } from 'css-box-model';\nimport type { Scrollable, DroppableDimension } from '../../types';\nimport { offsetRectByPosition } from '../rect';\n\nexport default (droppable: DroppableDimension, area: Rect): Rect => {\n  const frame: ?Scrollable = droppable.frame;\n  if (!frame) {\n    return area;\n  }\n\n  return offsetRectByPosition(area, frame.scroll.diff.value);\n};\n"
  },
  {
    "path": "src/state/with-scroll-change/with-viewport-displacement.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport type { Viewport } from '../../types';\nimport { add } from '../position';\n\nexport default (viewport: Viewport, point: Position): Position =>\n  add(viewport.scroll.diff.displacement, point);\n"
  },
  {
    "path": "src/types.js",
    "content": "// @flow\nimport type { BoxModel, Rect, Position } from 'css-box-model';\n\nexport type Id = string;\nexport type DraggableId = Id;\nexport type DroppableId = Id;\nexport type TypeId = Id;\nexport type ContextId = Id;\nexport type ElementId = Id;\n\nexport type DroppableMode = 'standard' | 'virtual';\nexport type DroppableDescriptor = {|\n  id: DroppableId,\n  type: TypeId,\n  mode: DroppableMode,\n|};\n\nexport type DraggableDescriptor = {|\n  id: DraggableId,\n  index: number,\n  // Inherited from Droppable\n  droppableId: DroppableId,\n  // This is technically redundant but it avoids\n  // needing to look up a parent droppable just to get its type\n  type: TypeId,\n|};\n\nexport type DraggableOptions = {|\n  canDragInteractiveElements: boolean,\n  shouldRespectForcePress: boolean,\n  isEnabled: boolean,\n|};\n\nexport type Direction = 'horizontal' | 'vertical';\n\nexport type VerticalAxis = {|\n  direction: 'vertical',\n  line: 'y',\n  start: 'top',\n  end: 'bottom',\n  size: 'height',\n  crossAxisLine: 'x',\n  crossAxisStart: 'left',\n  crossAxisEnd: 'right',\n  crossAxisSize: 'width',\n|};\n\nexport type HorizontalAxis = {|\n  direction: 'horizontal',\n  line: 'x',\n  start: 'left',\n  end: 'right',\n  size: 'width',\n  crossAxisLine: 'y',\n  crossAxisStart: 'top',\n  crossAxisEnd: 'bottom',\n  crossAxisSize: 'height',\n|};\n\nexport type Axis = VerticalAxis | HorizontalAxis;\n\nexport type ScrollSize = {|\n  scrollHeight: number,\n  scrollWidth: number,\n|};\n\nexport type ScrollDetails = {|\n  initial: Position,\n  current: Position,\n  // the maximum allowable scroll for the frame\n  max: Position,\n  diff: {|\n    value: Position,\n    // The actual displacement as a result of a scroll is in the opposite\n    // direction to the scroll itself. When scrolling down items are displaced\n    // upwards. This value is the negated version of the 'value'\n    displacement: Position,\n  |},\n|};\n\nexport type Placeholder = {|\n  client: BoxModel,\n  tagName: string,\n  display: string,\n|};\n\nexport type DraggableDimension = {|\n  descriptor: DraggableDescriptor,\n  // the placeholder for the draggable\n  placeholder: Placeholder,\n  // relative to the viewport when the drag started\n  client: BoxModel,\n  // relative to the whole page\n  page: BoxModel,\n  // how much displacement the draggable causes\n  // this is the size of the marginBox\n  displaceBy: Position,\n|};\n\nexport type Scrollable = {|\n  // This is the window through which the droppable is observed\n  // It does not change during a drag\n  pageMarginBox: Rect,\n  // Used for comparision with dynamic recollecting\n  frameClient: BoxModel,\n  scrollSize: ScrollSize,\n  // Whether or not we should clip the subject by the frame\n  // Is controlled by the ignoreContainerClipping prop\n  shouldClipSubject: boolean,\n  scroll: ScrollDetails,\n|};\n\nexport type PlaceholderInSubject = {|\n  // might not actually be increased by\n  // placeholder if there is no required space\n  increasedBy: ?Position,\n  placeholderSize: Position,\n  // max scroll before placeholder added\n  // will be null if there was no frame\n  oldFrameMaxScroll: ?Position,\n|};\n\nexport type DroppableSubject = {|\n  // raw, unchanging\n  page: BoxModel,\n  withPlaceholder: ?PlaceholderInSubject,\n  // The hitbox for a droppable\n  // - page margin box\n  // - with scroll changes\n  // - with any additional droppable placeholder\n  // - clipped by frame\n  // The subject will be null if the hit area is completely empty\n  active: ?Rect,\n|};\n\nexport type DroppableDimension = {|\n  descriptor: DroppableDescriptor,\n  axis: Axis,\n  isEnabled: boolean,\n  isCombineEnabled: boolean,\n  // relative to the current viewport\n  client: BoxModel,\n  // relative to the whole page\n  isFixedOnPage: boolean,\n  // relative to the page\n  page: BoxModel,\n  // The container of the droppable\n  frame: ?Scrollable,\n  // what is visible through the frame\n  subject: DroppableSubject,\n|};\nexport type DraggableLocation = {|\n  droppableId: DroppableId,\n  index: number,\n|};\n\nexport type DraggableIdMap = {\n  [id: DraggableId]: true,\n};\n\nexport type DroppableIdMap = {\n  [id: DroppableId]: true,\n};\n\nexport type DraggableDimensionMap = { [key: DraggableId]: DraggableDimension };\nexport type DroppableDimensionMap = { [key: DroppableId]: DroppableDimension };\n\nexport type Displacement = {|\n  draggableId: DraggableId,\n  shouldAnimate: boolean,\n|};\n\nexport type DisplacementMap = { [key: DraggableId]: Displacement };\n\nexport type DisplacedBy = {|\n  value: number,\n  point: Position,\n|};\n\nexport type Combine = {|\n  draggableId: DraggableId,\n  droppableId: DroppableId,\n|};\nexport type DisplacementGroups = {|\n  all: DraggableId[],\n  visible: DisplacementMap,\n  invisible: DraggableIdMap,\n|};\n\nexport type ReorderImpact = {|\n  type: 'REORDER',\n  destination: DraggableLocation,\n|};\n\nexport type CombineImpact = {|\n  type: 'COMBINE',\n  combine: Combine,\n|};\n\nexport type ImpactLocation = ReorderImpact | CombineImpact;\n\nexport type Displaced = {|\n  forwards: DisplacementGroups,\n  backwards: DisplacementGroups,\n|};\n\nexport type DragImpact = {|\n  displaced: DisplacementGroups,\n  displacedBy: DisplacedBy,\n  at: ?ImpactLocation,\n|};\n\nexport type ClientPositions = {|\n  // where the user initially selected\n  // This point is not used to calculate the impact of a dragging item\n  // It is used to calculate the offset from the initial selection point\n  selection: Position,\n  // the current center of the item\n  borderBoxCenter: Position,\n  // how far the item has moved from its original position\n  offset: Position,\n|};\n\nexport type PagePositions = {|\n  selection: Position,\n  borderBoxCenter: Position,\n  // how much the page position has changed from the initial\n  offset: Position,\n|};\n\n// There are two seperate modes that a drag can be in\n// FLUID: everything is done in response to highly granular input (eg mouse)\n// SNAP: items move in response to commands (eg keyboard);\nexport type MovementMode = 'FLUID' | 'SNAP';\n\nexport type DragPositions = {|\n  client: ClientPositions,\n  page: PagePositions,\n|};\n\nexport type DraggableRubric = {|\n  draggableId: DraggableId,\n  type: TypeId,\n  source: DraggableLocation,\n|};\n\n// Published in onBeforeCapture\n// We cannot give more information as things might change in the\n// onBeforeCapture responder!\nexport type BeforeCapture = {|\n  draggableId: DraggableId,\n  mode: MovementMode,\n|};\n\n// published when a drag starts\nexport type DragStart = {|\n  ...DraggableRubric,\n  mode: MovementMode,\n|};\n\nexport type DragUpdate = {|\n  ...DragStart,\n  // may not have any destination (drag to nowhere)\n  destination: ?DraggableLocation,\n  // populated when a draggable is dragging over another in combine mode\n  combine: ?Combine,\n|};\n\nexport type DropReason = 'DROP' | 'CANCEL';\n\n// published when a drag finishes\nexport type DropResult = {|\n  ...DragUpdate,\n  reason: DropReason,\n|};\n\nexport type ScrollOptions = {|\n  shouldPublishImmediately: boolean,\n|};\n\n// using the draggable id rather than the descriptor as the descriptor\n// may change as a result of the initial flush. This means that the lift\n// descriptor may not be the same as the actual descriptor. To avoid\n// confusion the request is just an id which is looked up\n// in the dimension-marshal post-flush\n// Not including droppableId as it might change in a drop flush\nexport type LiftRequest = {|\n  draggableId: DraggableId,\n  scrollOptions: ScrollOptions,\n|};\n\nexport type Critical = {|\n  draggable: DraggableDescriptor,\n  droppable: DroppableDescriptor,\n|};\n\nexport type Viewport = {|\n  // live updates with the latest values\n  frame: Rect,\n  scroll: ScrollDetails,\n|};\n\nexport type LiftEffect = {|\n  inVirtualList: boolean,\n  effected: DraggableIdMap,\n  displacedBy: DisplacedBy,\n|};\n\nexport type DimensionMap = {|\n  draggables: DraggableDimensionMap,\n  droppables: DroppableDimensionMap,\n|};\n\nexport type DroppablePublish = {|\n  droppableId: DroppableId,\n  scroll: Position,\n|};\nexport type Published = {|\n  additions: DraggableDimension[],\n  removals: DraggableId[],\n  modified: DroppablePublish[],\n|};\n\nexport type CompletedDrag = {|\n  critical: Critical,\n  result: DropResult,\n  impact: DragImpact,\n  afterCritical: LiftEffect,\n|};\n\nexport type IdleState = {|\n  phase: 'IDLE',\n  completed: ?CompletedDrag,\n  shouldFlush: boolean,\n|};\n\nexport type DraggingState = {|\n  phase: 'DRAGGING',\n  isDragging: true,\n  critical: Critical,\n  movementMode: MovementMode,\n  dimensions: DimensionMap,\n  initial: DragPositions,\n  current: DragPositions,\n  impact: DragImpact,\n  viewport: Viewport,\n  afterCritical: LiftEffect,\n  onLiftImpact: DragImpact,\n  // when there is a fixed list we want to opt out of this behaviour\n  isWindowScrollAllowed: boolean,\n  // if we need to jump the scroll (keyboard dragging)\n  scrollJumpRequest: ?Position,\n  // whether or not draggable movements should be animated\n  forceShouldAnimate: ?boolean,\n|};\n\n// While dragging we can enter into a bulk collection phase\n// During this phase no drag updates are permitted.\n// If a drop occurs during this phase, it must wait until it is\n// completed before continuing with the drop\n// TODO: rename to BulkCollectingState\nexport type CollectingState = {|\n  ...DraggingState,\n  phase: 'COLLECTING',\n|};\n\n// If a drop action occurs during a bulk collection we need to\n// wait for the collection to finish before performing the drop.\n// This is to ensure that everything has the correct index after\n// a drop\nexport type DropPendingState = {|\n  ...DraggingState,\n  phase: 'DROP_PENDING',\n  isWaiting: boolean,\n  reason: DropReason,\n|};\n\n// An optional phase for animating the drop / cancel if it is needed\nexport type DropAnimatingState = {|\n  phase: 'DROP_ANIMATING',\n  completed: CompletedDrag,\n  newHomeClientOffset: Position,\n  dropDuration: number,\n  // We still need to render placeholders and fix the dimensions of the dragging item\n  dimensions: DimensionMap,\n|};\n\nexport type State =\n  | IdleState\n  | DraggingState\n  | CollectingState\n  | DropPendingState\n  | DropAnimatingState;\n\nexport type StateWhenUpdatesAllowed = DraggingState | CollectingState;\n\nexport type Announce = (message: string) => void;\n\nexport type InOutAnimationMode = 'none' | 'open' | 'close';\n\nexport type ResponderProvided = {|\n  announce: Announce,\n|};\n\nexport type OnBeforeCaptureResponder = (before: BeforeCapture) => mixed;\nexport type OnBeforeDragStartResponder = (start: DragStart) => mixed;\nexport type OnDragStartResponder = (\n  start: DragStart,\n  provided: ResponderProvided,\n) => mixed;\nexport type OnDragUpdateResponder = (\n  update: DragUpdate,\n  provided: ResponderProvided,\n) => mixed;\nexport type OnDragEndResponder = (\n  result: DropResult,\n  provided: ResponderProvided,\n) => mixed;\n\nexport type Responders = {|\n  onBeforeCapture?: OnBeforeCaptureResponder,\n  onBeforeDragStart?: OnBeforeDragStartResponder,\n  onDragStart?: OnDragStartResponder,\n  onDragUpdate?: OnDragUpdateResponder,\n  // always required\n  onDragEnd: OnDragEndResponder,\n|};\n\n// ## Sensors\nexport type StopDragOptions = {|\n  shouldBlockNextClick: boolean,\n|};\n\ntype DragActions = {|\n  drop: (args?: StopDragOptions) => void,\n  cancel: (args?: StopDragOptions) => void,\n  isActive: () => boolean,\n  shouldRespectForcePress: () => boolean,\n|};\n\nexport type FluidDragActions = {|\n  ...DragActions,\n  move: (clientSelection: Position) => void,\n|};\n\nexport type SnapDragActions = {|\n  ...DragActions,\n  moveUp: () => void,\n  moveDown: () => void,\n  moveRight: () => void,\n  moveLeft: () => void,\n|};\n\nexport type PreDragActions = {|\n  // discover if the lock is still active\n  isActive: () => boolean,\n  // whether it has been indicated if force press should be respected\n  shouldRespectForcePress: () => boolean,\n  // lift the current item\n  fluidLift: (clientSelection: Position) => FluidDragActions,\n  snapLift: () => SnapDragActions,\n  // cancel the pre drag without starting a drag. Releases the lock\n  abort: () => void,\n|};\n\nexport type TryGetLockOptions = {\n  sourceEvent?: Event,\n};\n\nexport type TryGetLock = (\n  draggableId: DraggableId,\n  forceStop?: () => void,\n  options?: TryGetLockOptions,\n) => ?PreDragActions;\n\nexport type SensorAPI = {|\n  tryGetLock: TryGetLock,\n  canGetLock: (id: DraggableId) => boolean,\n  isLockClaimed: () => boolean,\n  tryReleaseLock: () => void,\n  findClosestDraggableId: (event: Event) => ?DraggableId,\n  findOptionsForDraggable: (id: DraggableId) => ?DraggableOptions,\n|};\n\nexport type Sensor = (api: SensorAPI) => void;\n"
  },
  {
    "path": "src/view/animate-in-out/animate-in-out.jsx",
    "content": "// @flow\nimport React, { type Node } from 'react';\nimport type { InOutAnimationMode } from '../../types';\n\nexport type AnimateProvided = {|\n  onClose: () => void,\n  animate: InOutAnimationMode,\n  data: mixed,\n|};\n\ntype Props = {|\n  on: mixed,\n  shouldAnimate: boolean,\n  children: (provided: AnimateProvided) => Node,\n|};\n\ntype State = {|\n  data: mixed,\n  isVisible: boolean,\n  animate: InOutAnimationMode,\n|};\n\n// Using a class here rather than hooks because\n// getDerivedStateFromProps results in far less renders.\n// Using hooks to implement this was quite messy and resulted in lots of additional renders\n\nexport default class AnimateInOut extends React.PureComponent<Props, State> {\n  state: State = {\n    isVisible: Boolean(this.props.on),\n    data: this.props.on,\n    // not allowing to animate close on mount\n    animate: this.props.shouldAnimate && this.props.on ? 'open' : 'none',\n  };\n\n  static getDerivedStateFromProps(props: Props, state: State): State {\n    if (!props.shouldAnimate) {\n      return {\n        isVisible: Boolean(props.on),\n        data: props.on,\n        animate: 'none',\n      };\n    }\n\n    // need to animate in\n    if (props.on) {\n      return {\n        isVisible: true,\n        // have new data to animate in with\n        data: props.on,\n        animate: 'open',\n      };\n    }\n\n    // need to animate out if there was data\n\n    if (state.isVisible) {\n      return {\n        isVisible: true,\n        // use old data for animating out\n        data: state.data,\n        animate: 'close',\n      };\n    }\n\n    // close animation no longer visible\n    return {\n      isVisible: false,\n      animate: 'close',\n      data: null,\n    };\n  }\n\n  onClose = () => {\n    if (this.state.animate !== 'close') {\n      return;\n    }\n\n    this.setState({\n      isVisible: false,\n    });\n  };\n\n  render() {\n    if (!this.state.isVisible) {\n      return null;\n    }\n\n    const provided: AnimateProvided = {\n      onClose: this.onClose,\n      data: this.state.data,\n      animate: this.state.animate,\n    };\n    return this.props.children(provided);\n  }\n}\n"
  },
  {
    "path": "src/view/animate-in-out/index.js",
    "content": "// @flow\nexport { default } from './animate-in-out';\n"
  },
  {
    "path": "src/view/check-is-valid-inner-ref.js",
    "content": "// @flow\nimport { invariant } from '../invariant';\nimport isHtmlElement from './is-type-of-element/is-html-element';\n\nexport default function checkIsValidInnerRef(el: ?HTMLElement) {\n  invariant(\n    el && isHtmlElement(el),\n    `\n    provided.innerRef has not been provided with a HTMLElement.\n\n    You can find a guide on using the innerRef callback functions at:\n    https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/using-inner-ref.md\n  `,\n  );\n}\n"
  },
  {
    "path": "src/view/context/app-context.js",
    "content": "// @flow\nimport React from 'react';\nimport type { DraggableId, ContextId, ElementId } from '../../types';\nimport type { DimensionMarshal } from '../../state/dimension-marshal/dimension-marshal-types';\nimport type { FocusMarshal } from '../use-focus-marshal/focus-marshal-types';\nimport type { Registry } from '../../state/registry/registry-types';\n\nexport type AppContextValue = {|\n  focus: FocusMarshal,\n  contextId: ContextId,\n  canLift: (id: DraggableId) => boolean,\n  isMovementAllowed: () => boolean,\n  dragHandleUsageInstructionsId: ElementId,\n  marshal: DimensionMarshal,\n  registry: Registry,\n|};\n\nexport default React.createContext<?AppContextValue>(null);\n"
  },
  {
    "path": "src/view/context/droppable-context.js",
    "content": "// @flow\nimport React from 'react';\nimport type { DraggableId, DroppableId, TypeId } from '../../types';\n\nexport type DroppableContextValue = {|\n  isUsingCloneFor: ?DraggableId,\n  droppableId: DroppableId,\n  type: TypeId,\n|};\n\nexport default React.createContext<?DroppableContextValue>(null);\n"
  },
  {
    "path": "src/view/context/store-context.js",
    "content": "// @flow\nimport React from 'react';\nimport type { Store } from '../../state/store-types';\n\nexport default React.createContext<?Store>(null);\n"
  },
  {
    "path": "src/view/data-attributes.js",
    "content": "// @flow\nexport const prefix: string = 'data-rbd';\nexport const dragHandle = (() => {\n  const base = `${prefix}-drag-handle`;\n\n  return {\n    base,\n    draggableId: `${base}-draggable-id`,\n    contextId: `${base}-context-id`,\n  };\n})();\n\nexport const draggable = (() => {\n  const base: string = `${prefix}-draggable`;\n  return {\n    base,\n    contextId: `${base}-context-id`,\n    id: `${base}-id`,\n  };\n})();\n\nexport const droppable = (() => {\n  const base: string = `${prefix}-droppable`;\n  return {\n    base,\n    contextId: `${base}-context-id`,\n    id: `${base}-id`,\n  };\n})();\n\nexport const placeholder = {\n  contextId: `${prefix}-placeholder-context-id`,\n};\n\nexport const scrollContainer = {\n  contextId: `${prefix}-scroll-container-context-id`,\n};\n"
  },
  {
    "path": "src/view/drag-drop-context/app.jsx",
    "content": "// @flow\nimport React, { useEffect, useRef, type Node } from 'react';\nimport { bindActionCreators } from 'redux';\nimport { Provider } from 'react-redux';\nimport { useMemo, useCallback } from 'use-memo-one';\nimport { invariant } from '../../invariant';\nimport createStore from '../../state/create-store';\nimport createDimensionMarshal from '../../state/dimension-marshal/dimension-marshal';\nimport canStartDrag from '../../state/can-start-drag';\nimport scrollWindow from '../window/scroll-window';\nimport createAutoScroller from '../../state/auto-scroller';\nimport useStyleMarshal from '../use-style-marshal/use-style-marshal';\nimport useFocusMarshal from '../use-focus-marshal';\nimport useRegistry from '../../state/registry/use-registry';\nimport type { Registry } from '../../state/registry/registry-types';\nimport type { FocusMarshal } from '../use-focus-marshal/focus-marshal-types';\nimport type { AutoScroller } from '../../state/auto-scroller/auto-scroller-types';\nimport type { StyleMarshal } from '../use-style-marshal/style-marshal-types';\nimport type {\n  DimensionMarshal,\n  Callbacks as DimensionMarshalCallbacks,\n} from '../../state/dimension-marshal/dimension-marshal-types';\nimport type {\n  DraggableId,\n  State,\n  Responders,\n  Announce,\n  Sensor,\n  ElementId,\n} from '../../types';\nimport type { Store, Action } from '../../state/store-types';\nimport type { SetAppCallbacks, AppCallbacks } from './drag-drop-context-types';\nimport StoreContext from '../context/store-context';\nimport {\n  move,\n  publishWhileDragging,\n  updateDroppableScroll,\n  updateDroppableIsEnabled,\n  updateDroppableIsCombineEnabled,\n  collectionStarting,\n  flush,\n} from '../../state/action-creators';\nimport isMovementAllowed from '../../state/is-movement-allowed';\nimport useAnnouncer from '../use-announcer';\nimport useHiddenTextElement from '../use-hidden-text-element';\nimport AppContext, { type AppContextValue } from '../context/app-context';\nimport useStartupValidation from './use-startup-validation';\nimport usePrevious from '../use-previous-ref';\nimport { warning } from '../../dev-warning';\nimport useSensorMarshal from '../use-sensor-marshal/use-sensor-marshal';\n\nexport type Props = {|\n  ...Responders,\n  contextId: string,\n  setCallbacks: SetAppCallbacks,\n  nonce?: string,\n  // we do not technically need any children for this component\n  children: Node | null,\n\n  // sensors\n  sensors?: Sensor[],\n  enableDefaultSensors?: ?boolean,\n\n  // screen reader\n  dragHandleUsageInstructions: string,\n|};\n\nconst createResponders = (props: Props): Responders => ({\n  onBeforeCapture: props.onBeforeCapture,\n  onBeforeDragStart: props.onBeforeDragStart,\n  onDragStart: props.onDragStart,\n  onDragEnd: props.onDragEnd,\n  onDragUpdate: props.onDragUpdate,\n});\n\n// flow does not support MutableRefObject\n// type LazyStoreRef = MutableRefObject<?Store>;\ntype LazyStoreRef = {| current: ?Store |};\n\nfunction getStore(lazyRef: LazyStoreRef): Store {\n  invariant(lazyRef.current, 'Could not find store from lazy ref');\n  return lazyRef.current;\n}\n\nexport default function App(props: Props) {\n  const {\n    contextId,\n    setCallbacks,\n    sensors,\n    nonce,\n    dragHandleUsageInstructions,\n  } = props;\n  const lazyStoreRef: LazyStoreRef = useRef<?Store>(null);\n\n  useStartupValidation();\n\n  // lazy collection of responders using a ref - update on ever render\n  const lastPropsRef = usePrevious<Props>(props);\n\n  const getResponders: () => Responders = useCallback(() => {\n    return createResponders(lastPropsRef.current);\n  }, [lastPropsRef]);\n\n  const announce: Announce = useAnnouncer(contextId);\n\n  const dragHandleUsageInstructionsId: ElementId = useHiddenTextElement({\n    contextId,\n    text: dragHandleUsageInstructions,\n  });\n  const styleMarshal: StyleMarshal = useStyleMarshal(contextId, nonce);\n\n  const lazyDispatch: (Action) => void = useCallback((action: Action): void => {\n    getStore(lazyStoreRef).dispatch(action);\n  }, []);\n\n  const marshalCallbacks: DimensionMarshalCallbacks = useMemo(\n    () =>\n      bindActionCreators(\n        {\n          publishWhileDragging,\n          updateDroppableScroll,\n          updateDroppableIsEnabled,\n          updateDroppableIsCombineEnabled,\n          collectionStarting,\n        },\n        // $FlowFixMe - not sure why this is wrong\n        lazyDispatch,\n      ),\n    [lazyDispatch],\n  );\n\n  const registry: Registry = useRegistry();\n\n  const dimensionMarshal: DimensionMarshal = useMemo<DimensionMarshal>(() => {\n    return createDimensionMarshal(registry, marshalCallbacks);\n  }, [registry, marshalCallbacks]);\n\n  const autoScroller: AutoScroller = useMemo<AutoScroller>(\n    () =>\n      createAutoScroller({\n        scrollWindow,\n        scrollDroppable: dimensionMarshal.scrollDroppable,\n        ...bindActionCreators(\n          {\n            move,\n          },\n          // $FlowFixMe - not sure why this is wrong\n          lazyDispatch,\n        ),\n      }),\n    [dimensionMarshal.scrollDroppable, lazyDispatch],\n  );\n\n  const focusMarshal: FocusMarshal = useFocusMarshal(contextId);\n\n  const store: Store = useMemo<Store>(\n    () =>\n      createStore({\n        announce,\n        autoScroller,\n        dimensionMarshal,\n        focusMarshal,\n        getResponders,\n        styleMarshal,\n      }),\n    [\n      announce,\n      autoScroller,\n      dimensionMarshal,\n      focusMarshal,\n      getResponders,\n      styleMarshal,\n    ],\n  );\n\n  // Checking for unexpected store changes\n  if (process.env.NODE_ENV !== 'production') {\n    if (lazyStoreRef.current && lazyStoreRef.current !== store) {\n      warning('unexpected store change');\n    }\n  }\n\n  // assigning lazy store ref\n  lazyStoreRef.current = store;\n\n  const tryResetStore = useCallback(() => {\n    const current: Store = getStore(lazyStoreRef);\n    const state: State = current.getState();\n    if (state.phase !== 'IDLE') {\n      current.dispatch(flush());\n    }\n  }, []);\n\n  const isDragging = useCallback((): boolean => {\n    const state: State = getStore(lazyStoreRef).getState();\n    return state.isDragging || state.phase === 'DROP_ANIMATING';\n  }, []);\n\n  const appCallbacks: AppCallbacks = useMemo(\n    () => ({\n      isDragging,\n      tryAbort: tryResetStore,\n    }),\n    [isDragging, tryResetStore],\n  );\n\n  // doing this in render rather than a side effect so any errors on the\n  // initial mount are caught\n  setCallbacks(appCallbacks);\n\n  const getCanLift = useCallback(\n    (id: DraggableId) => canStartDrag(getStore(lazyStoreRef).getState(), id),\n    [],\n  );\n\n  const getIsMovementAllowed = useCallback(\n    () => isMovementAllowed(getStore(lazyStoreRef).getState()),\n    [],\n  );\n\n  const appContext: AppContextValue = useMemo(\n    () => ({\n      marshal: dimensionMarshal,\n      focus: focusMarshal,\n      contextId,\n      canLift: getCanLift,\n      isMovementAllowed: getIsMovementAllowed,\n      dragHandleUsageInstructionsId,\n      registry,\n    }),\n    [\n      contextId,\n      dimensionMarshal,\n      dragHandleUsageInstructionsId,\n      focusMarshal,\n      getCanLift,\n      getIsMovementAllowed,\n      registry,\n    ],\n  );\n\n  useSensorMarshal({\n    contextId,\n    store,\n    registry,\n    customSensors: sensors,\n    // default to 'true' unless 'false' is explicitly passed\n    enableDefaultSensors: props.enableDefaultSensors !== false,\n  });\n\n  // Clean store when unmounting\n  useEffect(() => {\n    return tryResetStore;\n  }, [tryResetStore]);\n\n  return (\n    <AppContext.Provider value={appContext}>\n      <Provider context={StoreContext} store={store}>\n        {props.children}\n      </Provider>\n    </AppContext.Provider>\n  );\n}\n"
  },
  {
    "path": "src/view/drag-drop-context/check-doctype.js",
    "content": "// @flow\nimport { warning } from '../../dev-warning';\n\nconst suffix: string = `\n  We expect a html5 doctype: <!doctype html>\n  This is to ensure consistent browser layout and measurement\n\n  More information: https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/doctype.md\n`;\n\nexport default (doc: Document) => {\n  const doctype: ?DocumentType = doc.doctype;\n\n  if (!doctype) {\n    warning(`\n      No <!doctype html> found.\n\n      ${suffix}\n    `);\n    return;\n  }\n\n  if (doctype.name.toLowerCase() !== 'html') {\n    warning(`\n      Unexpected <!doctype> found: (${doctype.name})\n\n      ${suffix}\n    `);\n  }\n\n  if (doctype.publicId !== '') {\n    warning(`\n      Unexpected <!doctype> publicId found: (${doctype.publicId})\n      A html5 doctype does not have a publicId\n\n      ${suffix}\n    `);\n  }\n};\n"
  },
  {
    "path": "src/view/drag-drop-context/check-react-version.js",
    "content": "// @flow\nimport { invariant } from '../../invariant';\nimport { warning } from '../../dev-warning';\n\ntype Version = {|\n  major: number,\n  minor: number,\n  patch: number,\n  raw: string,\n|};\n\n// We can use a simple regex here given that:\n// - the version that react supplies is always full: eg 16.5.2\n// - our peer dependency version is to a full version (eg ^16.3.1)\nconst semver: RegExp = /(\\d+)\\.(\\d+)\\.(\\d+)/;\nconst getVersion = (value: string): Version => {\n  const result: ?(string[]) = semver.exec(value);\n\n  invariant(result != null, `Unable to parse React version ${value}`);\n\n  const major: number = Number(result[1]);\n  const minor: number = Number(result[2]);\n  const patch: number = Number(result[3]);\n\n  return {\n    major,\n    minor,\n    patch,\n    raw: value,\n  };\n};\n\nconst isSatisfied = (expected: Version, actual: Version): boolean => {\n  if (actual.major > expected.major) {\n    return true;\n  }\n\n  if (actual.major < expected.major) {\n    return false;\n  }\n\n  // major is equal, continue on\n\n  if (actual.minor > expected.minor) {\n    return true;\n  }\n\n  if (actual.minor < expected.minor) {\n    return false;\n  }\n\n  // minor is equal, continue on\n\n  return actual.patch >= expected.patch;\n};\n\nexport default (peerDepValue: string, actualValue: string) => {\n  const peerDep: Version = getVersion(peerDepValue);\n  const actual: Version = getVersion(actualValue);\n\n  if (isSatisfied(peerDep, actual)) {\n    return;\n  }\n\n  warning(`\n    React version: [${actual.raw}]\n    does not satisfy expected peer dependency version: [${peerDep.raw}]\n\n    This can result in run time bugs, and even fatal crashes\n  `);\n};\n"
  },
  {
    "path": "src/view/drag-drop-context/drag-drop-context-types.js",
    "content": "// @flow\nexport type AppCallbacks = {|\n  isDragging: () => boolean,\n  tryAbort: () => void,\n|};\n\nexport type SetAppCallbacks = (callbacks: AppCallbacks) => void;\n"
  },
  {
    "path": "src/view/drag-drop-context/drag-drop-context.jsx",
    "content": "// @flow\nimport React, { type Node } from 'react';\nimport type { Responders, ContextId, Sensor } from '../../types';\nimport ErrorBoundary from './error-boundary';\nimport preset from '../../screen-reader-message-preset';\nimport App from './app';\nimport useUniqueContextId, {\n  reset as resetContextId,\n} from './use-unique-context-id';\nimport { reset as resetUniqueIds } from '../use-unique-id';\n\ntype Props = {|\n  ...Responders,\n  // We do not technically need any children for this component\n  children: Node | null,\n  // Read out by screen readers when focusing on a drag handle\n  dragHandleUsageInstructions?: string,\n  // Used for strict content security policies\n  // See our [content security policy guide](/docs/guides/content-security-policy.md)\n  nonce?: string,\n  // See our [sensor api](/docs/sensors/sensor-api.md)\n  sensors?: Sensor[],\n  enableDefaultSensors?: ?boolean,\n|};\n\n// Reset any context that gets persisted across server side renders\nexport function resetServerContext() {\n  resetContextId();\n  resetUniqueIds();\n}\n\nexport default function DragDropContext(props: Props) {\n  const contextId: ContextId = useUniqueContextId();\n  const dragHandleUsageInstructions: string =\n    props.dragHandleUsageInstructions || preset.dragHandleUsageInstructions;\n\n  // We need the error boundary to be on the outside of App\n  // so that it can catch any errors caused by App\n  return (\n    <ErrorBoundary>\n      {(setCallbacks) => (\n        <App\n          nonce={props.nonce}\n          contextId={contextId}\n          setCallbacks={setCallbacks}\n          dragHandleUsageInstructions={dragHandleUsageInstructions}\n          enableDefaultSensors={props.enableDefaultSensors}\n          sensors={props.sensors}\n          onBeforeCapture={props.onBeforeCapture}\n          onBeforeDragStart={props.onBeforeDragStart}\n          onDragStart={props.onDragStart}\n          onDragUpdate={props.onDragUpdate}\n          onDragEnd={props.onDragEnd}\n        >\n          {props.children}\n        </App>\n      )}\n    </ErrorBoundary>\n  );\n}\n"
  },
  {
    "path": "src/view/drag-drop-context/error-boundary.jsx",
    "content": "// @flow\nimport React, { type Node } from 'react';\nimport { warning, error } from '../../dev-warning';\nimport { noop } from '../../empty';\nimport bindEvents from '../event-bindings/bind-events';\nimport { RbdInvariant } from '../../invariant';\nimport type { AppCallbacks } from './drag-drop-context-types';\n\ntype Props = {|\n  children: (setCallbacks: (callbacks: AppCallbacks) => void) => Node,\n|};\n\n// Lame that this is not in flow\ntype ErrorEvent = Event & {\n  error: ?Error,\n};\n\nexport default class ErrorBoundary extends React.Component<Props> {\n  callbacks: ?AppCallbacks = null;\n  unbind: () => void = noop;\n\n  componentDidMount() {\n    this.unbind = bindEvents(window, [\n      {\n        eventName: 'error',\n        fn: this.onWindowError,\n      },\n    ]);\n  }\n\n  componentDidCatch(err: Error) {\n    if (err instanceof RbdInvariant) {\n      if (process.env.NODE_ENV !== 'production') {\n        error(err.message);\n      }\n\n      this.setState({});\n      return;\n    }\n\n    // throwing error for other error boundaries\n    // eslint-disable-next-line no-restricted-syntax\n    throw err;\n  }\n\n  componentWillUnmount() {\n    this.unbind();\n  }\n\n  onWindowError = (event: ErrorEvent) => {\n    const callbacks: AppCallbacks = this.getCallbacks();\n\n    if (callbacks.isDragging()) {\n      callbacks.tryAbort();\n      warning(`\n        An error was caught by our window 'error' event listener while a drag was occurring.\n        The active drag has been aborted.\n      `);\n    }\n\n    const err: ?Error = event.error;\n\n    if (err instanceof RbdInvariant) {\n      // Marking the event as dealt with.\n      // This will prevent any 'uncaught' error warnings in the console\n      event.preventDefault();\n      if (process.env.NODE_ENV !== 'production') {\n        error(err.message);\n      }\n    }\n  };\n\n  getCallbacks = (): AppCallbacks => {\n    if (!this.callbacks) {\n      // eslint-disable-next-line no-restricted-syntax\n      throw new Error('Unable to find AppCallbacks in <ErrorBoundary/>');\n    }\n    return this.callbacks;\n  };\n\n  setCallbacks = (callbacks: AppCallbacks) => {\n    this.callbacks = callbacks;\n  };\n\n  render() {\n    return this.props.children(this.setCallbacks);\n  }\n}\n"
  },
  {
    "path": "src/view/drag-drop-context/index.js",
    "content": "// @flow\nexport { default, resetServerContext } from './drag-drop-context';\n"
  },
  {
    "path": "src/view/drag-drop-context/use-startup-validation.js",
    "content": "// @flow\nimport React from 'react';\nimport { peerDependencies } from '../../../package.json';\nimport checkReactVersion from './check-react-version';\nimport checkDoctype from './check-doctype';\nimport useDevSetupWarning from '../use-dev-setup-warning';\n\nexport default function useStartupValidation() {\n  useDevSetupWarning(() => {\n    checkReactVersion(peerDependencies.react, React.version);\n    checkDoctype(document);\n  }, []);\n}\n"
  },
  {
    "path": "src/view/drag-drop-context/use-unique-context-id.js",
    "content": "// @flow\nimport { useMemo } from 'use-memo-one';\nimport type { ContextId } from '../../types';\n\nlet count = 0;\n\nexport function reset() {\n  count = 0;\n}\n\nexport default function useInstanceCount(): ContextId {\n  return useMemo(() => `${count++}`, []);\n}\n"
  },
  {
    "path": "src/view/draggable/connected-draggable.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\n// eslint-disable-next-line\nimport { Component } from 'react';\nimport memoizeOne from 'memoize-one';\nimport { connect } from 'react-redux';\nimport Draggable from './draggable';\nimport { origin, negate } from '../../state/position';\nimport isStrictEqual from '../is-strict-equal';\nimport * as animation from '../../animation';\nimport { dropAnimationFinished as dropAnimationFinishedAction } from '../../state/action-creators';\nimport type {\n  State,\n  DraggableId,\n  DroppableId,\n  DraggableDimension,\n  Displacement,\n  CompletedDrag,\n  DragImpact,\n  MovementMode,\n  DropResult,\n  LiftEffect,\n  Combine,\n} from '../../types';\nimport type {\n  MapProps,\n  OwnProps,\n  DispatchProps,\n  Selector,\n  StateSnapshot,\n  DropAnimation,\n} from './draggable-types';\nimport whatIsDraggedOver from '../../state/droppable/what-is-dragged-over';\nimport StoreContext from '../context/store-context';\nimport whatIsDraggedOverFromResult from '../../state/droppable/what-is-dragged-over-from-result';\nimport { tryGetCombine } from '../../state/get-impact-location';\n\nconst getCombineWithFromResult = (result: DropResult): ?DraggableId => {\n  return result.combine ? result.combine.draggableId : null;\n};\n\nconst getCombineWithFromImpact = (impact: DragImpact): ?DraggableId => {\n  return impact.at && impact.at.type === 'COMBINE'\n    ? impact.at.combine.draggableId\n    : null;\n};\n\ntype TrySelect = (state: State, ownProps: OwnProps) => ?MapProps;\n\nfunction getDraggableSelector(): TrySelect {\n  const memoizedOffset = memoizeOne((x: number, y: number): Position => ({\n    x,\n    y,\n  }));\n\n  const getMemoizedSnapshot = memoizeOne(\n    (\n      mode: MovementMode,\n      isClone: boolean,\n      draggingOver: ?DroppableId,\n      combineWith: ?DraggableId,\n      dropping: ?DropAnimation,\n    ): StateSnapshot => ({\n      isDragging: true,\n      isClone,\n      isDropAnimating: Boolean(dropping),\n      dropAnimation: dropping,\n      mode,\n      draggingOver,\n      combineWith,\n      combineTargetFor: null,\n    }),\n  );\n\n  const getMemoizedProps = memoizeOne((\n    offset: Position,\n    mode: MovementMode,\n    dimension: DraggableDimension,\n    isClone: boolean,\n    // the id of the droppable you are over\n    draggingOver: ?DroppableId,\n    // the id of a draggable you are grouping with\n    combineWith: ?DraggableId,\n    forceShouldAnimate: ?boolean,\n  ): MapProps => ({\n    mapped: {\n      type: 'DRAGGING',\n      dropping: null,\n      draggingOver,\n      combineWith,\n      mode,\n      offset,\n      dimension,\n      forceShouldAnimate,\n      snapshot: getMemoizedSnapshot(\n        mode,\n        isClone,\n        draggingOver,\n        combineWith,\n        null,\n      ),\n    },\n  }));\n\n  const selector: TrySelect = (state: State, ownProps: OwnProps): ?MapProps => {\n    // Dragging\n    if (state.isDragging) {\n      // not the dragging item\n      if (state.critical.draggable.id !== ownProps.draggableId) {\n        return null;\n      }\n\n      const offset: Position = state.current.client.offset;\n      const dimension: DraggableDimension =\n        state.dimensions.draggables[ownProps.draggableId];\n      // const shouldAnimateDragMovement: boolean = state.shouldAnimate;\n      const draggingOver: ?DroppableId = whatIsDraggedOver(state.impact);\n      const combineWith: ?DraggableId = getCombineWithFromImpact(state.impact);\n      const forceShouldAnimate: ?boolean = state.forceShouldAnimate;\n\n      return getMemoizedProps(\n        memoizedOffset(offset.x, offset.y),\n        state.movementMode,\n        dimension,\n        ownProps.isClone,\n        draggingOver,\n        combineWith,\n        forceShouldAnimate,\n      );\n    }\n\n    // Dropping\n    if (state.phase === 'DROP_ANIMATING') {\n      const completed: CompletedDrag = state.completed;\n      if (completed.result.draggableId !== ownProps.draggableId) {\n        return null;\n      }\n\n      const isClone: boolean = ownProps.isClone;\n      const dimension: DraggableDimension =\n        state.dimensions.draggables[ownProps.draggableId];\n      const result: DropResult = completed.result;\n      const mode: MovementMode = result.mode;\n      // these need to be pulled from the result as they can be different to the final impact\n      const draggingOver: ?DroppableId = whatIsDraggedOverFromResult(result);\n      const combineWith: ?DraggableId = getCombineWithFromResult(result);\n      const duration: number = state.dropDuration;\n\n      // not memoized as it is the only execution\n      const dropping: DropAnimation = {\n        duration,\n        curve: animation.curves.drop,\n        moveTo: state.newHomeClientOffset,\n        opacity: combineWith ? animation.combine.opacity.drop : null,\n        scale: combineWith ? animation.combine.scale.drop : null,\n      };\n\n      return {\n        mapped: {\n          type: 'DRAGGING',\n          offset: state.newHomeClientOffset,\n          dimension,\n          dropping,\n          draggingOver,\n          combineWith,\n          mode,\n          forceShouldAnimate: null,\n          snapshot: getMemoizedSnapshot(\n            mode,\n            isClone,\n            draggingOver,\n            combineWith,\n            dropping,\n          ),\n        },\n      };\n    }\n\n    return null;\n  };\n\n  return selector;\n}\n\nfunction getSecondarySnapshot(combineTargetFor: ?DraggableId): StateSnapshot {\n  return {\n    isDragging: false,\n    isDropAnimating: false,\n    isClone: false,\n    dropAnimation: null,\n    mode: null,\n    draggingOver: null,\n    combineTargetFor,\n    combineWith: null,\n  };\n}\n\nconst atRest: MapProps = {\n  mapped: {\n    type: 'SECONDARY',\n    offset: origin,\n    combineTargetFor: null,\n    shouldAnimateDisplacement: true,\n    snapshot: getSecondarySnapshot(null),\n  },\n};\n\nfunction getSecondarySelector(): TrySelect {\n  const memoizedOffset = memoizeOne((x: number, y: number): Position => ({\n    x,\n    y,\n  }));\n\n  const getMemoizedSnapshot = memoizeOne(getSecondarySnapshot);\n\n  const getMemoizedProps = memoizeOne(\n    (\n      offset: Position,\n      combineTargetFor: ?DraggableId = null,\n      shouldAnimateDisplacement: boolean,\n    ): MapProps => ({\n      mapped: {\n        type: 'SECONDARY',\n        offset,\n        combineTargetFor,\n        shouldAnimateDisplacement,\n        snapshot: getMemoizedSnapshot(combineTargetFor),\n      },\n    }),\n  );\n\n  // Is we are the combine target for something then we need to publish that\n  // otherwise we will return null to get the default props\n  const getFallback = (combineTargetFor: ?DraggableId): ?MapProps => {\n    return combineTargetFor\n      ? getMemoizedProps(origin, combineTargetFor, true)\n      : null;\n  };\n\n  const getProps = (\n    ownId: DraggableId,\n    draggingId: DraggableId,\n    impact: DragImpact,\n    afterCritical: LiftEffect,\n  ): ?MapProps => {\n    const visualDisplacement: ?Displacement = impact.displaced.visible[ownId];\n    const isAfterCriticalInVirtualList: boolean = Boolean(\n      afterCritical.inVirtualList && afterCritical.effected[ownId],\n    );\n\n    const combine: ?Combine = tryGetCombine(impact);\n    const combineTargetFor: ?DraggableId =\n      combine && combine.draggableId === ownId ? draggingId : null;\n\n    if (!visualDisplacement) {\n      if (!isAfterCriticalInVirtualList) {\n        return getFallback(combineTargetFor);\n      }\n\n      // After critical but not visibly displaced in a virtual list\n      // This can occur if:\n      // 1. the item is not visible (displaced.invisible)\n      // 2. We have moved out of the home list.\n\n      // Don't need to do anything - item is invisible\n      if (impact.displaced.invisible[ownId]) {\n        return null;\n      }\n\n      // We are no longer over the home list.\n      // We need to move backwards to close the gap that the dragging item has left\n      const change: Position = negate(afterCritical.displacedBy.point);\n      const offset: Position = memoizedOffset(change.x, change.y);\n      return getMemoizedProps(offset, combineTargetFor, true);\n    }\n\n    if (isAfterCriticalInVirtualList) {\n      // In a virtual list the removal of a dragging item does\n      // not cause the list to collapse. So when something is 'displaced'\n      // we can just leave it in the original spot.\n      return getFallback(combineTargetFor);\n    }\n    const displaceBy: Position = impact.displacedBy.point;\n    const offset: Position = memoizedOffset(displaceBy.x, displaceBy.y);\n\n    return getMemoizedProps(\n      offset,\n      combineTargetFor,\n      visualDisplacement.shouldAnimate,\n    );\n  };\n\n  const selector: TrySelect = (state: State, ownProps: OwnProps): ?MapProps => {\n    // Dragging\n    if (state.isDragging) {\n      // we do not care about the dragging item\n      if (state.critical.draggable.id === ownProps.draggableId) {\n        return null;\n      }\n\n      return getProps(\n        ownProps.draggableId,\n        state.critical.draggable.id,\n        state.impact,\n        state.afterCritical,\n      );\n    }\n\n    // Dropping\n    if (state.phase === 'DROP_ANIMATING') {\n      const completed: CompletedDrag = state.completed;\n      // do nothing if this was the dragging item\n      if (completed.result.draggableId === ownProps.draggableId) {\n        return null;\n      }\n      return getProps(\n        ownProps.draggableId,\n        completed.result.draggableId,\n        completed.impact,\n        completed.afterCritical,\n      );\n    }\n\n    // Otherwise\n    return null;\n  };\n\n  return selector;\n}\n\n// Returning a function to ensure each\n// Draggable gets its own selector\nexport const makeMapStateToProps = (): Selector => {\n  const draggingSelector: TrySelect = getDraggableSelector();\n  const secondarySelector: TrySelect = getSecondarySelector();\n\n  const selector = (state: State, ownProps: OwnProps): MapProps =>\n    draggingSelector(state, ownProps) ||\n    secondarySelector(state, ownProps) ||\n    atRest;\n\n  return selector;\n};\n\nconst mapDispatchToProps: DispatchProps = {\n  dropAnimationFinished: dropAnimationFinishedAction,\n};\n\n// Leaning heavily on the default shallow equality checking\n// that `connect` provides.\n// It avoids needing to do it own within `<Draggable />`\nconst ConnectedDraggable = connect(\n  // returning a function so each component can do its own memoization\n  makeMapStateToProps,\n  mapDispatchToProps,\n  // mergeProps: use default\n  null,\n  // options\n  // $FlowFixMe: current react-redux type does not know about context property\n  {\n    // Using our own context for the store to avoid clashing with consumers\n    context: StoreContext,\n    // Default value, but being really clear\n    pure: true,\n    // When pure, compares the result of mapStateToProps to its previous value.\n    // Default value: shallowEqual\n    // Switching to a strictEqual as we return a memoized object on changes\n    areStatePropsEqual: isStrictEqual,\n  },\n)(Draggable);\n\nexport default ConnectedDraggable;\n"
  },
  {
    "path": "src/view/draggable/draggable-api.jsx",
    "content": "// @flow\nimport React from 'react';\nimport type { DraggableId } from '../../types';\nimport type { PublicOwnProps, PrivateOwnProps } from './draggable-types';\nimport ConnectedDraggable from './connected-draggable';\nimport useRequiredContext from '../use-required-context';\nimport DroppableContext, {\n  type DroppableContextValue,\n} from '../context/droppable-context';\n\n// We can use this to render a draggable with more control\n// It is used by a Droppable to render a clone\nexport function PrivateDraggable(props: PrivateOwnProps) {\n  const droppableContext: DroppableContextValue = useRequiredContext(\n    DroppableContext,\n  );\n  // The droppable can render a clone of the draggable item.\n  // In that case we unmount the existing dragging item\n  const isUsingCloneFor: ?DraggableId = droppableContext.isUsingCloneFor;\n  if (isUsingCloneFor === props.draggableId && !props.isClone) {\n    return null;\n  }\n\n  return <ConnectedDraggable {...props} />;\n}\n\n// What we give to consumers\nexport function PublicDraggable(props: PublicOwnProps) {\n  // default values for props\n  const isEnabled: boolean =\n    typeof props.isDragDisabled === 'boolean' ? !props.isDragDisabled : true;\n  const canDragInteractiveElements: boolean = Boolean(\n    props.disableInteractiveElementBlocking,\n  );\n  const shouldRespectForcePress: boolean = Boolean(\n    props.shouldRespectForcePress,\n  );\n\n  return (\n    <PrivateDraggable\n      {...props}\n      isClone={false}\n      isEnabled={isEnabled}\n      canDragInteractiveElements={canDragInteractiveElements}\n      shouldRespectForcePress={shouldRespectForcePress}\n    />\n  );\n}\n"
  },
  {
    "path": "src/view/draggable/draggable-types.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { type Node } from 'react';\nimport type {\n  DraggableId,\n  DroppableId,\n  DraggableDimension,\n  State,\n  MovementMode,\n  ContextId,\n  ElementId,\n  DraggableRubric,\n} from '../../types';\nimport { dropAnimationFinished } from '../../state/action-creators';\n\nexport type DraggingStyle = {|\n  position: 'fixed',\n  top: number,\n  left: number,\n  boxSizing: 'border-box',\n  width: number,\n  height: number,\n  transition: string,\n  transform: ?string,\n  zIndex: number,\n\n  // for combining\n  opacity: ?number,\n\n  // Avoiding any processing of mouse events.\n  // This is already applied by the shared styles during a drag.\n  // During a drop it prevents a draggable from being dragged.\n  // canStartDrag() will prevent drags in some cases for non primary draggable.\n  // It is also a minor performance optimisation\n  pointerEvents: 'none',\n|};\n\nexport type NotDraggingStyle = {|\n  transform: ?string,\n  // null: use the global animation style\n  // none: skip animation (used in certain displacement situations)\n  transition: null | 'none',\n|};\n\nexport type DraggableStyle = DraggingStyle | NotDraggingStyle;\n\nexport type ZIndexOptions = {|\n  dragging: number,\n  dropAnimating: number,\n|};\n\n// Props that can be spread onto the element directly\nexport type DraggableProps = {|\n  // inline style\n  style: ?DraggableStyle,\n  // used for shared global styles\n  'data-rbd-draggable-context-id': ContextId,\n  // used for lookups\n  'data-rbd-draggable-id': DraggableId,\n  // used to know when a transition ends\n  onTransitionEnd: ?(event: TransitionEvent) => void,\n|};\n\nexport type DragHandleProps = {|\n  // what draggable the handle belongs to\n  'data-rbd-drag-handle-draggable-id': DraggableId,\n\n  // What DragDropContext the drag handle is in\n  'data-rbd-drag-handle-context-id': ContextId,\n\n  // We need a drag handle to be a widget in order to correctly set accessibility properties\n  // Note: JAWS and VoiceOver don't need the element to be a 'widget' to read the accessibility properties, but NVDA does\n  // Using `role=\"button\"` but leaving the public API as a string to allow for changing without a major\n  role: string,\n\n  // Overriding default role to have a more descriptive text (\"Draggable item\")\n  // Sadly we cannot use this right now due an issue with lighthouse\n  // https://github.com/atlassian/react-beautiful-dnd/issues/1742\n  // 'aria-roledescription': string,\n\n  // Using the description property of the drag handle to provide usage instructions\n  'aria-describedby': ElementId,\n\n  // Allow tabbing to this element\n  // Adding a tab index marks the element as interactive content: https://www.w3.org/TR/html51/dom.html#kinds-of-content-interactive-content\n  tabIndex: number,\n\n  // Opting out of html5 drag and drop\n  draggable: boolean,\n  onDragStart: (event: DragEvent) => void,\n|};\n\nexport type Provided = {|\n  draggableProps: DraggableProps,\n  // will be null if the draggable is disabled\n  dragHandleProps: ?DragHandleProps,\n  // The following props will be removed once we move to react 16\n  innerRef: (?HTMLElement) => void,\n|};\n\n// to easily enable patching of styles\nexport type DropAnimation = {|\n  duration: number,\n  curve: string,\n  moveTo: Position,\n  opacity: ?number,\n  scale: ?number,\n|};\n\nexport type StateSnapshot = {|\n  isDragging: boolean,\n  isDropAnimating: boolean,\n  isClone: boolean,\n  dropAnimation: ?DropAnimation,\n  draggingOver: ?DroppableId,\n  combineWith: ?DraggableId,\n  combineTargetFor: ?DraggableId,\n  mode: ?MovementMode,\n|};\n\nexport type DispatchProps = {|\n  dropAnimationFinished: typeof dropAnimationFinished,\n|};\n\nexport type DraggingMapProps = {|\n  type: 'DRAGGING',\n  offset: Position,\n  mode: MovementMode,\n  dropping: ?DropAnimation,\n  draggingOver: ?DraggableId,\n  combineWith: ?DraggableId,\n  dimension: DraggableDimension,\n  forceShouldAnimate: ?boolean,\n  snapshot: StateSnapshot,\n|};\n\nexport type SecondaryMapProps = {|\n  type: 'SECONDARY',\n  offset: Position,\n  combineTargetFor: ?DraggableId,\n  shouldAnimateDisplacement: boolean,\n  snapshot: StateSnapshot,\n|};\n\nexport type MappedProps = DraggingMapProps | SecondaryMapProps;\n\nexport type MapProps = {|\n  // when an item is being displaced by a dragging item,\n  // we need to know if that movement should be animated\n  mapped: MappedProps,\n  // dragging: ?DraggingMapProps,\n  // secondary: ?SecondaryMapProps,\n|};\n\nexport type ChildrenFn = (\n  Provided,\n  StateSnapshot,\n  DraggableRubric,\n) => Node | null;\n\nexport type PublicOwnProps = {|\n  draggableId: DraggableId,\n  index: number,\n  children: ChildrenFn,\n\n  // optional own props\n  isDragDisabled?: boolean,\n  disableInteractiveElementBlocking?: boolean,\n  shouldRespectForcePress?: boolean,\n|};\n\nexport type PrivateOwnProps = {|\n  ...PublicOwnProps,\n  isClone: boolean,\n  // no longer optional\n  isEnabled: boolean,\n  canDragInteractiveElements: boolean,\n  shouldRespectForcePress: boolean,\n|};\n\nexport type OwnProps = {|\n  ...PrivateOwnProps,\n|};\n\nexport type Props = {|\n  ...MapProps,\n  ...DispatchProps,\n  ...OwnProps,\n|};\n\nexport type Selector = (state: State, ownProps: OwnProps) => MapProps;\n"
  },
  {
    "path": "src/view/draggable/draggable.jsx",
    "content": "// @flow\nimport { useRef } from 'react';\nimport { useMemo, useCallback } from 'use-memo-one';\nimport type { DraggableRubric, DraggableDescriptor } from '../../types';\nimport getStyle from './get-style';\nimport useDraggablePublisher, {\n  type Args as PublisherArgs,\n} from '../use-draggable-publisher/use-draggable-publisher';\nimport AppContext from '../context/app-context';\nimport DroppableContext from '../context/droppable-context';\nimport type {\n  Props,\n  Provided,\n  DraggableStyle,\n  DragHandleProps,\n} from './draggable-types';\nimport { useValidation, useClonePropValidation } from './use-validation';\nimport useRequiredContext from '../use-required-context';\n\nfunction preventHtml5Dnd(event: DragEvent) {\n  event.preventDefault();\n}\n\nexport default function Draggable(props: Props) {\n  // reference to DOM node\n  const ref = useRef<?HTMLElement>(null);\n  const setRef = useCallback((el: ?HTMLElement) => {\n    ref.current = el;\n  }, []);\n  const getRef = useCallback((): ?HTMLElement => ref.current, []);\n\n  // context\n  const {\n    contextId,\n    dragHandleUsageInstructionsId,\n    registry,\n  } = useRequiredContext(AppContext);\n  const { type, droppableId } = useRequiredContext(DroppableContext);\n\n  const descriptor: DraggableDescriptor = useMemo(\n    () => ({\n      id: props.draggableId,\n      index: props.index,\n      type,\n      droppableId,\n    }),\n    [props.draggableId, props.index, type, droppableId],\n  );\n\n  // props\n  const {\n    // ownProps\n    children,\n    draggableId,\n    isEnabled,\n    shouldRespectForcePress,\n    canDragInteractiveElements,\n    isClone,\n\n    // mapProps\n    mapped,\n\n    // dispatchProps\n    dropAnimationFinished: dropAnimationFinishedAction,\n  } = props;\n\n  // Validating props and innerRef\n  useValidation(props, contextId, getRef);\n\n  // Clones do not speak to the dimension marshal\n  // We are violating the rules of hooks here: conditional hooks.\n  // In this specific use case it is okay as an item will always either be a\n  // clone or not for it's whole lifecycle\n  /* eslint-disable react-hooks/rules-of-hooks */\n\n  // Being super sure that isClone is not changing during a draggable lifecycle\n  useClonePropValidation(isClone);\n  if (!isClone) {\n    const forPublisher: PublisherArgs = useMemo(\n      () => ({\n        descriptor,\n        registry,\n        getDraggableRef: getRef,\n        canDragInteractiveElements,\n        shouldRespectForcePress,\n        isEnabled,\n      }),\n      [\n        descriptor,\n        registry,\n        getRef,\n        canDragInteractiveElements,\n        shouldRespectForcePress,\n        isEnabled,\n      ],\n    );\n    useDraggablePublisher(forPublisher);\n  }\n  /* eslint-enable react-hooks/rules-of-hooks */\n\n  const dragHandleProps: ?DragHandleProps = useMemo(\n    () =>\n      isEnabled\n        ? {\n            // See `draggable-types` for an explanation of why these are used\n            tabIndex: 0,\n            role: 'button',\n            'aria-describedby': dragHandleUsageInstructionsId,\n            'data-rbd-drag-handle-draggable-id': draggableId,\n            'data-rbd-drag-handle-context-id': contextId,\n            draggable: false,\n            onDragStart: preventHtml5Dnd,\n          }\n        : null,\n    [contextId, dragHandleUsageInstructionsId, draggableId, isEnabled],\n  );\n\n  const onMoveEnd = useCallback(\n    (event: TransitionEvent) => {\n      if (mapped.type !== 'DRAGGING') {\n        return;\n      }\n\n      if (!mapped.dropping) {\n        return;\n      }\n\n      // There might be other properties on the element that are\n      // being transitioned. We do not want those to end a drop animation!\n      if (event.propertyName !== 'transform') {\n        return;\n      }\n\n      dropAnimationFinishedAction();\n    },\n    [dropAnimationFinishedAction, mapped],\n  );\n\n  const provided: Provided = useMemo(() => {\n    const style: DraggableStyle = getStyle(mapped);\n    const onTransitionEnd =\n      mapped.type === 'DRAGGING' && mapped.dropping ? onMoveEnd : null;\n\n    const result: Provided = {\n      innerRef: setRef,\n      draggableProps: {\n        'data-rbd-draggable-context-id': contextId,\n        'data-rbd-draggable-id': draggableId,\n        style,\n        onTransitionEnd,\n      },\n      dragHandleProps,\n    };\n\n    return result;\n  }, [contextId, dragHandleProps, draggableId, mapped, onMoveEnd, setRef]);\n\n  const rubric: DraggableRubric = useMemo(\n    () => ({\n      draggableId: descriptor.id,\n      type: descriptor.type,\n      source: {\n        index: descriptor.index,\n        droppableId: descriptor.droppableId,\n      },\n    }),\n    [descriptor.droppableId, descriptor.id, descriptor.index, descriptor.type],\n  );\n\n  return children(provided, mapped.snapshot, rubric);\n}\n"
  },
  {
    "path": "src/view/draggable/get-style.js",
    "content": "// @flow\nimport type { BoxModel } from 'css-box-model';\nimport { combine, transforms, transitions } from '../../animation';\nimport type { DraggableDimension } from '../../types';\nimport type {\n  DraggingStyle,\n  NotDraggingStyle,\n  ZIndexOptions,\n  DropAnimation,\n  SecondaryMapProps,\n  DraggingMapProps,\n  DraggableStyle,\n  MappedProps,\n} from './draggable-types';\n\nexport const zIndexOptions: ZIndexOptions = {\n  dragging: 5000,\n  dropAnimating: 4500,\n};\n\nconst getDraggingTransition = (\n  shouldAnimateDragMovement: boolean,\n  dropping: ?DropAnimation,\n): string => {\n  if (dropping) {\n    return transitions.drop(dropping.duration);\n  }\n  if (shouldAnimateDragMovement) {\n    return transitions.snap;\n  }\n  return transitions.fluid;\n};\n\nconst getDraggingOpacity = (\n  isCombining: boolean,\n  isDropAnimating: boolean,\n): ?number => {\n  // if not combining: no not impact opacity\n  if (!isCombining) {\n    return null;\n  }\n\n  return isDropAnimating ? combine.opacity.drop : combine.opacity.combining;\n};\n\nconst getShouldDraggingAnimate = (dragging: DraggingMapProps): boolean => {\n  if (dragging.forceShouldAnimate != null) {\n    return dragging.forceShouldAnimate;\n  }\n  return dragging.mode === 'SNAP';\n};\n\nfunction getDraggingStyle(dragging: DraggingMapProps): DraggingStyle {\n  const dimension: DraggableDimension = dragging.dimension;\n  const box: BoxModel = dimension.client;\n  const { offset, combineWith, dropping } = dragging;\n\n  const isCombining: boolean = Boolean(combineWith);\n\n  const shouldAnimate: boolean = getShouldDraggingAnimate(dragging);\n  const isDropAnimating: boolean = Boolean(dropping);\n\n  const transform: ?string = isDropAnimating\n    ? transforms.drop(offset, isCombining)\n    : transforms.moveTo(offset);\n\n  const style: DraggingStyle = {\n    // ## Placement\n    position: 'fixed',\n    // As we are applying the margins we need to align to the start of the marginBox\n    top: box.marginBox.top,\n    left: box.marginBox.left,\n\n    // ## Sizing\n    // Locking these down as pulling the node out of the DOM could cause it to change size\n    boxSizing: 'border-box',\n    width: box.borderBox.width,\n    height: box.borderBox.height,\n\n    // ## Movement\n    // Opting out of the standard css transition for the dragging item\n    transition: getDraggingTransition(shouldAnimate, dropping),\n    transform,\n    opacity: getDraggingOpacity(isCombining, isDropAnimating),\n    // ## Layering\n    zIndex: isDropAnimating\n      ? zIndexOptions.dropAnimating\n      : zIndexOptions.dragging,\n\n    // ## Blocking any pointer events on the dragging or dropping item\n    // global styles on cover while dragging\n    pointerEvents: 'none',\n  };\n  return style;\n}\n\nfunction getSecondaryStyle(secondary: SecondaryMapProps): NotDraggingStyle {\n  return {\n    transform: transforms.moveTo(secondary.offset),\n    // transition style is applied in the head\n    transition: secondary.shouldAnimateDisplacement ? null : 'none',\n  };\n}\n\nexport default function getStyle(mapped: MappedProps): DraggableStyle {\n  return mapped.type === 'DRAGGING'\n    ? getDraggingStyle(mapped)\n    : getSecondaryStyle(mapped);\n}\n"
  },
  {
    "path": "src/view/draggable/index.js",
    "content": "// @flow\nexport { PublicDraggable as default } from './draggable-api';\n"
  },
  {
    "path": "src/view/draggable/use-validation.js",
    "content": "// @flow\nimport { useRef } from 'react';\nimport { invariant } from '../../invariant';\nimport { isInteger } from '../../native-with-fallback';\nimport type { DraggableId, ContextId } from '../../types';\nimport type { Props } from './draggable-types';\nimport checkIsValidInnerRef from '../check-is-valid-inner-ref';\nimport findDragHandle from '../get-elements/find-drag-handle';\nimport useDevSetupWarning from '../use-dev-setup-warning';\nimport useDev from '../use-dev';\n\nexport function useValidation(\n  props: Props,\n  contextId: ContextId,\n  getRef: () => ?HTMLElement,\n) {\n  // running after every update in development\n  useDevSetupWarning(() => {\n    function prefix(id: DraggableId): string {\n      return `Draggable[id: ${id}]: `;\n    }\n\n    // wrapping entire block for better minification\n    const id: ?DraggableId = props.draggableId;\n    invariant(id, 'Draggable requires a draggableId');\n    invariant(\n      typeof id === 'string',\n      `Draggable requires a [string] draggableId.\n      Provided: [type: ${typeof id}] (value: ${id})`,\n    );\n\n    invariant(\n      isInteger(props.index),\n      `${prefix(id)} requires an integer index prop`,\n    );\n\n    if (props.mapped.type === 'DRAGGING') {\n      return;\n    }\n\n    // Checking provided ref (only when not dragging as it might be removed)\n    checkIsValidInnerRef(getRef());\n\n    // Checking that drag handle is provided\n    // Only running check when enabled.\n    // When not enabled there is no drag handle props\n    if (props.isEnabled) {\n      invariant(\n        findDragHandle(contextId, id),\n        `${prefix(id)} Unable to find drag handle`,\n      );\n    }\n  });\n}\n\n// we expect isClone not to change for entire component's life\nexport function useClonePropValidation(isClone: boolean) {\n  useDev(() => {\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    const initialRef = useRef<boolean>(isClone);\n\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    useDevSetupWarning(() => {\n      invariant(\n        isClone === initialRef.current,\n        'Draggable isClone prop value changed during component life',\n      );\n    }, [isClone]);\n  });\n}\n"
  },
  {
    "path": "src/view/droppable/connected-droppable.js",
    "content": "// @flow\n// eslint-disable-next-line no-unused-vars\nimport { Component } from 'react';\nimport { connect } from 'react-redux';\nimport memoizeOne from 'memoize-one';\nimport { invariant } from '../../invariant';\nimport type {\n  State,\n  DroppableId,\n  DraggableId,\n  CompletedDrag,\n  DraggableDimension,\n  DimensionMap,\n  TypeId,\n  Critical,\n  DraggableRubric,\n  DraggableDescriptor,\n} from '../../types';\nimport type {\n  MapProps,\n  OwnProps,\n  DefaultProps,\n  Selector,\n  DispatchProps,\n  StateSnapshot,\n  UseClone,\n  DraggableChildrenFn,\n} from './droppable-types';\nimport Droppable from './droppable';\nimport isStrictEqual from '../is-strict-equal';\nimport whatIsDraggedOver from '../../state/droppable/what-is-dragged-over';\nimport { updateViewportMaxScroll as updateViewportMaxScrollAction } from '../../state/action-creators';\nimport StoreContext from '../context/store-context';\nimport whatIsDraggedOverFromResult from '../../state/droppable/what-is-dragged-over-from-result';\n\nconst isMatchingType = (type: TypeId, critical: Critical): boolean =>\n  type === critical.droppable.type;\n\nconst getDraggable = (\n  critical: Critical,\n  dimensions: DimensionMap,\n): DraggableDimension => dimensions.draggables[critical.draggable.id];\n\n// Returning a function to ensure each\n// Droppable gets its own selector\nexport const makeMapStateToProps = (): Selector => {\n  const idleWithAnimation: MapProps = {\n    placeholder: null,\n    shouldAnimatePlaceholder: true,\n    snapshot: {\n      isDraggingOver: false,\n      draggingOverWith: null,\n      draggingFromThisWith: null,\n      isUsingPlaceholder: false,\n    },\n    useClone: null,\n  };\n\n  const idleWithoutAnimation = {\n    ...idleWithAnimation,\n    shouldAnimatePlaceholder: false,\n  };\n\n  const getDraggableRubric = memoizeOne(\n    (descriptor: DraggableDescriptor): DraggableRubric => ({\n      draggableId: descriptor.id,\n      type: descriptor.type,\n      source: {\n        index: descriptor.index,\n        droppableId: descriptor.droppableId,\n      },\n    }),\n  );\n\n  const getMapProps = memoizeOne(\n    (\n      id: DroppableId,\n      isEnabled: boolean,\n      isDraggingOverForConsumer: boolean,\n      isDraggingOverForImpact: boolean,\n      dragging: DraggableDimension,\n      // snapshot: StateSnapshot,\n      renderClone: ?DraggableChildrenFn,\n    ): MapProps => {\n      const draggableId: DraggableId = dragging.descriptor.id;\n      const isHome: boolean = dragging.descriptor.droppableId === id;\n\n      if (isHome) {\n        const useClone: ?UseClone = renderClone\n          ? {\n              render: renderClone,\n              dragging: getDraggableRubric(dragging.descriptor),\n            }\n          : null;\n\n        const snapshot: StateSnapshot = {\n          isDraggingOver: isDraggingOverForConsumer,\n          draggingOverWith: isDraggingOverForConsumer ? draggableId : null,\n          draggingFromThisWith: draggableId,\n          isUsingPlaceholder: true,\n        };\n\n        return {\n          placeholder: dragging.placeholder,\n          shouldAnimatePlaceholder: false,\n          snapshot,\n          useClone,\n        };\n      }\n\n      if (!isEnabled) {\n        return idleWithoutAnimation;\n      }\n\n      // not over foreign list - return idle\n      if (!isDraggingOverForImpact) {\n        return idleWithAnimation;\n      }\n\n      const snapshot: StateSnapshot = {\n        isDraggingOver: isDraggingOverForConsumer,\n        draggingOverWith: draggableId,\n        draggingFromThisWith: null,\n        isUsingPlaceholder: true,\n      };\n\n      return {\n        placeholder: dragging.placeholder,\n        // Animating placeholder in foreign list\n        shouldAnimatePlaceholder: true,\n        snapshot,\n        useClone: null,\n      };\n    },\n  );\n\n  const selector = (state: State, ownProps: OwnProps): MapProps => {\n    // not checking if item is disabled as we need the home list to display a placeholder\n\n    const id: DroppableId = ownProps.droppableId;\n    const type: TypeId = ownProps.type;\n    const isEnabled: boolean = !ownProps.isDropDisabled;\n    const renderClone: ?DraggableChildrenFn = ownProps.renderClone;\n\n    if (state.isDragging) {\n      const critical: Critical = state.critical;\n      if (!isMatchingType(type, critical)) {\n        return idleWithoutAnimation;\n      }\n\n      const dragging: DraggableDimension = getDraggable(\n        critical,\n        state.dimensions,\n      );\n      const isDraggingOver: boolean = whatIsDraggedOver(state.impact) === id;\n\n      return getMapProps(\n        id,\n        isEnabled,\n        isDraggingOver,\n        isDraggingOver,\n        dragging,\n        renderClone,\n      );\n    }\n\n    if (state.phase === 'DROP_ANIMATING') {\n      const completed: CompletedDrag = state.completed;\n      if (!isMatchingType(type, completed.critical)) {\n        return idleWithoutAnimation;\n      }\n\n      const dragging: DraggableDimension = getDraggable(\n        completed.critical,\n        state.dimensions,\n      );\n\n      // Snapshot based on result and not impact\n      // The result might be null (cancel) but the impact is populated\n      // to move everything back\n      return getMapProps(\n        id,\n        isEnabled,\n        whatIsDraggedOverFromResult(completed.result) === id,\n        whatIsDraggedOver(completed.impact) === id,\n        dragging,\n        renderClone,\n      );\n    }\n\n    if (state.phase === 'IDLE' && state.completed && !state.shouldFlush) {\n      const completed: CompletedDrag = state.completed;\n      if (!isMatchingType(type, completed.critical)) {\n        return idleWithoutAnimation;\n      }\n\n      // Looking at impact as this controls the placeholder\n      const wasOver: boolean = whatIsDraggedOver(completed.impact) === id;\n      const wasCombining: boolean = Boolean(\n        completed.impact.at && completed.impact.at.type === 'COMBINE',\n      );\n      const isHome: boolean = completed.critical.droppable.id === id;\n\n      if (wasOver) {\n        // if reordering we need to cut an animation immediately\n        // if merging: animate placeholder closed after drop\n        return wasCombining ? idleWithAnimation : idleWithoutAnimation;\n      }\n\n      // we need to animate the home placeholder closed if it is not\n      // being dropped into\n      if (isHome) {\n        return idleWithAnimation;\n      }\n\n      return idleWithoutAnimation;\n    }\n\n    // default: including when flushed\n    return idleWithoutAnimation;\n  };\n\n  return selector;\n};\n\nconst mapDispatchToProps: DispatchProps = {\n  updateViewportMaxScroll: updateViewportMaxScrollAction,\n};\n\nfunction getBody(): HTMLElement {\n  invariant(document.body, 'document.body is not ready');\n  return document.body;\n}\n\nconst defaultProps = ({\n  mode: 'standard',\n  type: 'DEFAULT',\n  direction: 'vertical',\n  isDropDisabled: false,\n  isCombineEnabled: false,\n  ignoreContainerClipping: false,\n  renderClone: null,\n  getContainerForClone: getBody,\n}: DefaultProps);\n\n// Abstract class allows to specify props and defaults to component.\n// All other ways give any or do not let add default props.\n// eslint-disable-next-line\n/*::\nclass DroppableType extends Component<OwnProps> {\n  static defaultProps = defaultProps;\n}\n*/\n\n// Leaning heavily on the default shallow equality checking\n// that `connect` provides.\n// It avoids needing to do it own within `Droppable`\nconst ConnectedDroppable: typeof DroppableType = connect(\n  // returning a function so each component can do its own memoization\n  makeMapStateToProps,\n  // no dispatch props for droppable\n  mapDispatchToProps,\n  // mergeProps - using default\n  null,\n  // $FlowFixMe: current react-redux type does not know about context property\n  {\n    // Ensuring our context does not clash with consumers\n    context: StoreContext,\n    // pure: true is default value, but being really clear\n    pure: true,\n    // When pure, compares the result of mapStateToProps to its previous value.\n    // Default value: shallowEqual\n    // Switching to a strictEqual as we return a memoized object on changes\n    areStatePropsEqual: isStrictEqual,\n  },\n)(Droppable);\n\nConnectedDroppable.defaultProps = defaultProps;\n\nexport default ConnectedDroppable;\n"
  },
  {
    "path": "src/view/droppable/droppable-types.js",
    "content": "// @flow\nimport { type Node } from 'react';\nimport type {\n  DraggableId,\n  DroppableId,\n  TypeId,\n  Direction,\n  Placeholder,\n  State,\n  ContextId,\n  DraggableRubric,\n  DroppableMode,\n} from '../../types';\nimport type { ChildrenFn } from '../draggable/draggable-types';\nimport { updateViewportMaxScroll } from '../../state/action-creators';\n\nexport type DraggableChildrenFn = ChildrenFn;\n\nexport type DroppableProps = {|\n  // used for shared global styles\n  'data-rbd-droppable-context-id': ContextId,\n  // Used to lookup. Currently not used for drag and drop lifecycle\n  'data-rbd-droppable-id': DroppableId,\n|};\n\nexport type Provided = {|\n  innerRef: (?HTMLElement) => void,\n  placeholder: ?Node,\n  droppableProps: DroppableProps,\n|};\n\nexport type UseClone = {|\n  dragging: DraggableRubric,\n  render: DraggableChildrenFn,\n|};\n\nexport type StateSnapshot = {|\n  // Is the Droppable being dragged over?\n  isDraggingOver: boolean,\n  // What is the id of the draggable that is dragging over the Droppable?\n  draggingOverWith: ?DraggableId,\n  // What is the id of the draggable that is dragging from this list?\n  // Useful for styling the home list when not being dragged over\n  draggingFromThisWith: ?DraggableId,\n  // Whether or not the placeholder is actively being used.\n  // This is useful information when working with virtual lists\n  isUsingPlaceholder: boolean,\n|};\n\nexport type MapProps = {|\n  // placeholder:\n  // - used to keep space in the home list during the whole drag and drop\n  // - used to make space in foreign lists during a drag\n  placeholder: ?Placeholder,\n  shouldAnimatePlaceholder: boolean,\n  // snapshot based on redux state to be provided to consumers\n  snapshot: StateSnapshot,\n  useClone: ?UseClone,\n|};\n\nexport type DefaultProps = {|\n  mode: DroppableMode,\n  type: TypeId,\n  isDropDisabled: boolean,\n  isCombineEnabled: boolean,\n  direction: Direction,\n  renderClone: ?DraggableChildrenFn,\n  ignoreContainerClipping: boolean,\n  getContainerForClone: () => HTMLElement,\n|};\n\nexport type DispatchProps = {|\n  updateViewportMaxScroll: typeof updateViewportMaxScroll,\n|};\n\nexport type OwnProps = {|\n  ...DefaultProps,\n  children: (Provided, StateSnapshot) => Node,\n  droppableId: DroppableId,\n  renderClone: ?DraggableChildrenFn,\n|};\n\nexport type Props = {|\n  ...MapProps,\n  ...DispatchProps,\n  ...OwnProps,\n|};\n\n// Having issues getting the correct type\n// export type Selector = OutputSelector<State, OwnProps, MapProps>;\nexport type Selector = (state: State, ownProps: OwnProps) => MapProps;\n"
  },
  {
    "path": "src/view/droppable/droppable.jsx",
    "content": "// @flow\nimport ReactDOM from 'react-dom';\nimport { useMemo, useCallback } from 'use-memo-one';\nimport React, { useRef, useContext, type Node } from 'react';\nimport { invariant } from '../../invariant';\nimport type { DraggableId } from '../../types';\nimport type { Props, Provided } from './droppable-types';\nimport useDroppablePublisher from '../use-droppable-publisher';\nimport Placeholder from '../placeholder';\nimport AppContext, { type AppContextValue } from '../context/app-context';\nimport DroppableContext, {\n  type DroppableContextValue,\n} from '../context/droppable-context';\n// import useAnimateInOut from '../use-animate-in-out/use-animate-in-out';\nimport getMaxWindowScroll from '../window/get-max-window-scroll';\nimport useValidation from './use-validation';\nimport type {\n  StateSnapshot as DraggableStateSnapshot,\n  Provided as DraggableProvided,\n} from '../draggable/draggable-types';\nimport AnimateInOut, {\n  type AnimateProvided,\n} from '../animate-in-out/animate-in-out';\nimport { PrivateDraggable } from '../draggable/draggable-api';\n\nexport default function Droppable(props: Props) {\n  const appContext: ?AppContextValue = useContext<?AppContextValue>(AppContext);\n  invariant(appContext, 'Could not find app context');\n  const { contextId, isMovementAllowed } = appContext;\n  const droppableRef = useRef<?HTMLElement>(null);\n  const placeholderRef = useRef<?HTMLElement>(null);\n\n  const {\n    // own props\n    children,\n    droppableId,\n    type,\n    mode,\n    direction,\n    ignoreContainerClipping,\n    isDropDisabled,\n    isCombineEnabled,\n    // map props\n    snapshot,\n    useClone,\n    // dispatch props\n    updateViewportMaxScroll,\n\n    // clone (ownProps)\n    getContainerForClone,\n  } = props;\n\n  const getDroppableRef = useCallback(\n    (): ?HTMLElement => droppableRef.current,\n    [],\n  );\n  const setDroppableRef = useCallback((value: ?HTMLElement) => {\n    droppableRef.current = value;\n  }, []);\n  const getPlaceholderRef = useCallback(\n    (): ?HTMLElement => placeholderRef.current,\n    [],\n  );\n  const setPlaceholderRef = useCallback((value: ?HTMLElement) => {\n    placeholderRef.current = value;\n  }, []);\n\n  useValidation({\n    props,\n    getDroppableRef,\n    getPlaceholderRef,\n  });\n\n  const onPlaceholderTransitionEnd = useCallback(() => {\n    // A placeholder change can impact the window's max scroll\n    if (isMovementAllowed()) {\n      updateViewportMaxScroll({ maxScroll: getMaxWindowScroll() });\n    }\n  }, [isMovementAllowed, updateViewportMaxScroll]);\n\n  useDroppablePublisher({\n    droppableId,\n    type,\n    mode,\n    direction,\n    isDropDisabled,\n    isCombineEnabled,\n    ignoreContainerClipping,\n    getDroppableRef,\n  });\n\n  const placeholder: Node = (\n    <AnimateInOut\n      on={props.placeholder}\n      shouldAnimate={props.shouldAnimatePlaceholder}\n    >\n      {({ onClose, data, animate }: AnimateProvided) => (\n        <Placeholder\n          placeholder={(data: any)}\n          onClose={onClose}\n          innerRef={setPlaceholderRef}\n          animate={animate}\n          contextId={contextId}\n          onTransitionEnd={onPlaceholderTransitionEnd}\n        />\n      )}\n    </AnimateInOut>\n  );\n\n  const provided: Provided = useMemo(\n    (): Provided => ({\n      innerRef: setDroppableRef,\n      placeholder,\n      droppableProps: {\n        'data-rbd-droppable-id': droppableId,\n        'data-rbd-droppable-context-id': contextId,\n      },\n    }),\n    [contextId, droppableId, placeholder, setDroppableRef],\n  );\n\n  const isUsingCloneFor: ?DraggableId = useClone\n    ? useClone.dragging.draggableId\n    : null;\n\n  const droppableContext: ?DroppableContextValue = useMemo(\n    () => ({\n      droppableId,\n      type,\n      isUsingCloneFor,\n    }),\n    [droppableId, isUsingCloneFor, type],\n  );\n\n  function getClone(): ?Node {\n    if (!useClone) {\n      return null;\n    }\n    const { dragging, render } = useClone;\n\n    const node: Node = (\n      <PrivateDraggable\n        draggableId={dragging.draggableId}\n        index={dragging.source.index}\n        isClone\n        isEnabled\n        // not important as drag has already started\n        shouldRespectForcePress={false}\n        canDragInteractiveElements\n      >\n        {(\n          draggableProvided: DraggableProvided,\n          draggableSnapshot: DraggableStateSnapshot,\n        ) => render(draggableProvided, draggableSnapshot, dragging)}\n      </PrivateDraggable>\n    );\n\n    return ReactDOM.createPortal(node, getContainerForClone());\n  }\n\n  return (\n    <DroppableContext.Provider value={droppableContext}>\n      {children(provided, snapshot)}\n      {getClone()}\n    </DroppableContext.Provider>\n  );\n}\n"
  },
  {
    "path": "src/view/droppable/index.js",
    "content": "// @flow\nexport { default } from './connected-droppable';\n"
  },
  {
    "path": "src/view/droppable/use-validation.js",
    "content": "// @flow\nimport { invariant } from '../../invariant';\nimport type { Props } from './droppable-types';\nimport { warning } from '../../dev-warning';\nimport checkIsValidInnerRef from '../check-is-valid-inner-ref';\nimport useDevSetupWarning from '../use-dev-setup-warning';\n\ntype Args = {|\n  props: Props,\n  getDroppableRef: () => ?HTMLElement,\n  getPlaceholderRef: () => ?HTMLElement,\n|};\n\ntype CheckFn = (args: Args) => void;\n\nfunction isBoolean(value: mixed): boolean {\n  return typeof value === 'boolean';\n}\n\nfunction runChecks(args: Args, checks: CheckFn[]) {\n  checks.forEach((check: CheckFn) => check(args));\n}\n\nconst shared: CheckFn[] = [\n  function required({ props }: Args) {\n    invariant(props.droppableId, 'A Droppable requires a droppableId prop');\n    invariant(\n      typeof props.droppableId === 'string',\n      `A Droppable requires a [string] droppableId. Provided: [${typeof props.droppableId}]`,\n    );\n  },\n  function boolean({ props }: Args) {\n    invariant(\n      isBoolean(props.isDropDisabled),\n      'isDropDisabled must be a boolean',\n    );\n    invariant(\n      isBoolean(props.isCombineEnabled),\n      'isCombineEnabled must be a boolean',\n    );\n    invariant(\n      isBoolean(props.ignoreContainerClipping),\n      'ignoreContainerClipping must be a boolean',\n    );\n  },\n  function ref({ getDroppableRef }: Args) {\n    checkIsValidInnerRef(getDroppableRef());\n  },\n];\n\nconst standard: CheckFn[] = [\n  function placeholder({ props, getPlaceholderRef }: Args) {\n    if (!props.placeholder) {\n      return;\n    }\n\n    const ref: ?HTMLElement = getPlaceholderRef();\n\n    if (ref) {\n      return;\n    }\n\n    warning(`\n      Droppable setup issue [droppableId: \"${props.droppableId}\"]:\n      DroppableProvided > placeholder could not be found.\n\n      Please be sure to add the {provided.placeholder} React Node as a child of your Droppable.\n      More information: https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/api/droppable.md\n    `);\n  },\n];\n\nconst virtual: CheckFn[] = [\n  function hasClone({ props }: Args) {\n    invariant(\n      props.renderClone,\n      'Must provide a clone render function (renderClone) for virtual lists',\n    );\n  },\n  function hasNoPlaceholder({ getPlaceholderRef }: Args) {\n    invariant(\n      !getPlaceholderRef(),\n      'Expected virtual list to not have a placeholder',\n    );\n  },\n];\n\nexport default function useValidation(args: Args) {\n  useDevSetupWarning(() => {\n    // wrapping entire block for better minification\n    runChecks(args, shared);\n\n    if (args.props.mode === 'standard') {\n      runChecks(args, standard);\n    }\n\n    if (args.props.mode === 'virtual') {\n      runChecks(args, virtual);\n    }\n  });\n}\n"
  },
  {
    "path": "src/view/event-bindings/bind-events.js",
    "content": "// @flow\nimport type { EventBinding, EventOptions } from './event-types';\n\ntype UnbindFn = () => void;\n\nfunction getOptions(\n  shared?: EventOptions,\n  fromBinding: ?EventOptions,\n): EventOptions {\n  return {\n    ...shared,\n    ...fromBinding,\n  };\n}\n\nexport default function bindEvents(\n  el: HTMLElement,\n  bindings: EventBinding[],\n  sharedOptions?: EventOptions,\n): Function {\n  const unbindings: UnbindFn[] = bindings.map(\n    (binding: EventBinding): UnbindFn => {\n      const options: Object = getOptions(sharedOptions, binding.options);\n\n      el.addEventListener(binding.eventName, binding.fn, options);\n\n      return function unbind() {\n        el.removeEventListener(binding.eventName, binding.fn, options);\n      };\n    },\n  );\n\n  // Return a function to unbind events\n  return function unbindAll() {\n    unbindings.forEach((unbind: UnbindFn) => {\n      unbind();\n    });\n  };\n}\n"
  },
  {
    "path": "src/view/event-bindings/event-types.js",
    "content": "// @flow\n\nexport type EventOptions = {|\n  passive?: boolean,\n  capture?: boolean,\n  // sometimes an event might only event want to be bound once\n  once?: boolean,\n|};\n\nexport type EventBinding = {|\n  eventName: string,\n  fn: Function,\n  options?: EventOptions,\n|};\n"
  },
  {
    "path": "src/view/get-body-element.js",
    "content": "// @flow\nimport { invariant } from '../invariant';\n\nexport default (): HTMLBodyElement => {\n  const body: ?HTMLBodyElement = document.body;\n  invariant(body, 'Cannot find document.body');\n  return body;\n};\n"
  },
  {
    "path": "src/view/get-border-box-center-position.js",
    "content": "// @flow\nimport { getRect, type Position } from 'css-box-model';\n\nexport default (el: HTMLElement): Position =>\n  getRect(el.getBoundingClientRect()).center;\n"
  },
  {
    "path": "src/view/get-document-element.js",
    "content": "// @flow\nimport { invariant } from '../invariant';\n\nexport default (): HTMLElement => {\n  const doc: ?HTMLElement = document.documentElement;\n  invariant(doc, 'Cannot find document.documentElement');\n  return doc;\n};\n"
  },
  {
    "path": "src/view/get-elements/find-drag-handle.js",
    "content": "// @flow\nimport type { DraggableId, ContextId } from '../../types';\nimport { dragHandle as dragHandleAttr } from '../data-attributes';\nimport { warning } from '../../dev-warning';\nimport { find, toArray } from '../../native-with-fallback';\nimport isHtmlElement from '../is-type-of-element/is-html-element';\n\nexport default function findDragHandle(\n  contextId: ContextId,\n  draggableId: DraggableId,\n): ?HTMLElement {\n  // cannot create a selector with the draggable id as it might not be a valid attribute selector\n  const selector: string = `[${dragHandleAttr.contextId}=\"${contextId}\"]`;\n  const possible: Element[] = toArray(document.querySelectorAll(selector));\n\n  if (!possible.length) {\n    warning(`Unable to find any drag handles in the context \"${contextId}\"`);\n    return null;\n  }\n\n  const handle: ?Element = find(possible, (el: Element): boolean => {\n    return el.getAttribute(dragHandleAttr.draggableId) === draggableId;\n  });\n\n  if (!handle) {\n    warning(\n      `Unable to find drag handle with id \"${draggableId}\" as no handle with a matching id was found`,\n    );\n    return null;\n  }\n\n  if (!isHtmlElement(handle)) {\n    warning('drag handle needs to be a HTMLElement');\n    return null;\n  }\n\n  return handle;\n}\n"
  },
  {
    "path": "src/view/get-elements/find-draggable.js",
    "content": "// @flow\nimport type { DraggableId, ContextId } from '../../types';\nimport * as attributes from '../data-attributes';\nimport { find, toArray } from '../../native-with-fallback';\nimport { warning } from '../../dev-warning';\nimport isHtmlElement from '../is-type-of-element/is-html-element';\n\nexport default function findDraggable(\n  contextId: ContextId,\n  draggableId: DraggableId,\n): ?HTMLElement {\n  // cannot create a selector with the draggable id as it might not be a valid attribute selector\n  const selector: string = `[${attributes.draggable.contextId}=\"${contextId}\"]`;\n  const possible: Element[] = toArray(document.querySelectorAll(selector));\n\n  const draggable: ?Element = find(possible, (el: Element): boolean => {\n    return el.getAttribute(attributes.draggable.id) === draggableId;\n  });\n\n  if (!draggable) {\n    return null;\n  }\n\n  if (!isHtmlElement(draggable)) {\n    warning('Draggable element is not a HTMLElement');\n    return null;\n  }\n\n  return draggable;\n}\n"
  },
  {
    "path": "src/view/is-strict-equal.js",
    "content": "// @flow\nexport default (a: mixed, b: mixed): boolean => a === b;\n"
  },
  {
    "path": "src/view/is-type-of-element/is-element.js",
    "content": "// @flow\nimport getWindowFromEl from '../window/get-window-from-el';\n\nexport default function isElement(el: Object): boolean %checks {\n  return el instanceof getWindowFromEl(el).Element;\n}\n"
  },
  {
    "path": "src/view/is-type-of-element/is-html-element.js",
    "content": "// @flow\nimport getWindowFromEl from '../window/get-window-from-el';\n\nexport default function isHtmlElement(el: Object): boolean %checks {\n  return el instanceof getWindowFromEl(el).HTMLElement;\n}\n"
  },
  {
    "path": "src/view/is-type-of-element/is-svg-element.js",
    "content": "// @flow\nimport getWindowFromEl from '../window/get-window-from-el';\n\nexport default function isSvgElement(el: Object): boolean %checks {\n  // Some environments do not support SVGElement\n  // Doing a double lookup rather than storing the window\n  // as a %checks function can only be a 'simple predicate'\n  return (\n    Boolean(getWindowFromEl(el).SVGElement) &&\n    el instanceof getWindowFromEl(el).SVGElement\n  );\n}\n"
  },
  {
    "path": "src/view/key-codes.js",
    "content": "// @flow\nexport const tab: number = 9;\nexport const enter: number = 13;\nexport const escape: number = 27;\nexport const space: number = 32;\nexport const pageUp: number = 33;\nexport const pageDown: number = 34;\nexport const end: number = 35;\nexport const home: number = 36;\nexport const arrowLeft: number = 37;\nexport const arrowUp: number = 38;\nexport const arrowRight: number = 39;\nexport const arrowDown: number = 40;\n"
  },
  {
    "path": "src/view/placeholder/index.js",
    "content": "// @flow\nexport { default } from './placeholder';\n"
  },
  {
    "path": "src/view/placeholder/placeholder-types.js",
    "content": "// @flow\n\nexport type PlaceholderStyle = {|\n  display: string,\n  boxSizing: 'border-box',\n  width: number,\n  height: number,\n  marginTop: number,\n  marginRight: number,\n  marginBottom: number,\n  marginLeft: number,\n  flexShrink: '0',\n  flexGrow: '0',\n  pointerEvents: 'none',\n  transition: string,\n|};\n"
  },
  {
    "path": "src/view/placeholder/placeholder.jsx",
    "content": "// @flow\nimport React, { useState, useRef, useEffect, type Node } from 'react';\nimport { useCallback } from 'use-memo-one';\nimport type { Spacing } from 'css-box-model';\nimport type {\n  Placeholder as PlaceholderType,\n  InOutAnimationMode,\n  ContextId,\n} from '../../types';\nimport { transitions } from '../../animation';\nimport { noSpacing } from '../../state/spacing';\n\nfunction noop() {}\n\nexport type PlaceholderStyle = {|\n  display: string,\n  boxSizing: 'border-box',\n  width: number,\n  height: number,\n  marginTop: number,\n  marginRight: number,\n  marginBottom: number,\n  marginLeft: number,\n  flexShrink: '0',\n  flexGrow: '0',\n  pointerEvents: 'none',\n  transition: ?string,\n|};\nexport type Props = {|\n  placeholder: PlaceholderType,\n  animate: InOutAnimationMode,\n  onClose: () => void,\n  innerRef?: () => ?HTMLElement,\n  onTransitionEnd: () => void,\n  contextId: ContextId,\n|};\n\ntype Size = {|\n  width: number,\n  height: number,\n  // Need to animate in/out animation as well as size\n  margin: Spacing,\n|};\n\ntype HelperArgs = {|\n  isAnimatingOpenOnMount: boolean,\n  placeholder: PlaceholderType,\n  animate: InOutAnimationMode,\n|};\n\nconst empty: Size = {\n  width: 0,\n  height: 0,\n  margin: noSpacing,\n};\n\nconst getSize = ({\n  isAnimatingOpenOnMount,\n  placeholder,\n  animate,\n}: HelperArgs): Size => {\n  if (isAnimatingOpenOnMount) {\n    return empty;\n  }\n\n  if (animate === 'close') {\n    return empty;\n  }\n\n  return {\n    height: placeholder.client.borderBox.height,\n    width: placeholder.client.borderBox.width,\n    margin: placeholder.client.margin,\n  };\n};\n\nconst getStyle = ({\n  isAnimatingOpenOnMount,\n  placeholder,\n  animate,\n}: HelperArgs): PlaceholderStyle => {\n  const size: Size = getSize({ isAnimatingOpenOnMount, placeholder, animate });\n\n  return {\n    display: placeholder.display,\n    // ## Recreating the box model\n    // We created the borderBox and then apply the margins directly\n    // this is to maintain any margin collapsing behaviour\n\n    // creating borderBox\n    // background: 'green',\n    boxSizing: 'border-box',\n    width: size.width,\n    height: size.height,\n    // creating marginBox\n    marginTop: size.margin.top,\n    marginRight: size.margin.right,\n    marginBottom: size.margin.bottom,\n    marginLeft: size.margin.left,\n\n    // ## Avoiding collapsing\n    // Avoiding the collapsing or growing of this element when pushed by flex child siblings.\n    // We have already taken a snapshot the current dimensions we do not want this element\n    // to recalculate its dimensions\n    // It is okay for these properties to be applied on elements that are not flex children\n    flexShrink: '0',\n    flexGrow: '0',\n    // Just a little performance optimisation: avoiding the browser needing\n    // to worry about pointer events for this element\n    pointerEvents: 'none',\n\n    // Animate the placeholder size and margin\n    transition: animate !== 'none' ? transitions.placeholder : null,\n  };\n};\n\nfunction Placeholder(props: Props): Node {\n  const animateOpenTimerRef = useRef<?TimeoutID>(null);\n\n  const tryClearAnimateOpenTimer = useCallback(() => {\n    if (!animateOpenTimerRef.current) {\n      return;\n    }\n    clearTimeout(animateOpenTimerRef.current);\n    animateOpenTimerRef.current = null;\n  }, []);\n\n  const { animate, onTransitionEnd, onClose, contextId } = props;\n  const [isAnimatingOpenOnMount, setIsAnimatingOpenOnMount] = useState<boolean>(\n    props.animate === 'open',\n  );\n\n  // Will run after a render is flushed\n  // Still need to wait a timeout to ensure that the\n  // update is completely applied to the DOM\n  useEffect(() => {\n    // No need to do anything\n    if (!isAnimatingOpenOnMount) {\n      return noop;\n    }\n\n    // might need to clear the timer\n    if (animate !== 'open') {\n      tryClearAnimateOpenTimer();\n      setIsAnimatingOpenOnMount(false);\n      return noop;\n    }\n\n    // timer already pending\n    if (animateOpenTimerRef.current) {\n      return noop;\n    }\n\n    animateOpenTimerRef.current = setTimeout(() => {\n      animateOpenTimerRef.current = null;\n      setIsAnimatingOpenOnMount(false);\n    });\n\n    // clear the timer if needed\n    return tryClearAnimateOpenTimer;\n  }, [animate, isAnimatingOpenOnMount, tryClearAnimateOpenTimer]);\n\n  const onSizeChangeEnd = useCallback(\n    (event: TransitionEvent) => {\n      // We transition height, width and margin\n      // each of those transitions will independently call this callback\n      // Because they all have the same duration we can just respond to one of them\n      // 'height' was chosen for no particular reason :D\n      if (event.propertyName !== 'height') {\n        return;\n      }\n\n      onTransitionEnd();\n\n      if (animate === 'close') {\n        onClose();\n      }\n    },\n    [animate, onClose, onTransitionEnd],\n  );\n\n  const style: PlaceholderStyle = getStyle({\n    isAnimatingOpenOnMount,\n    animate: props.animate,\n    placeholder: props.placeholder,\n  });\n\n  return React.createElement(props.placeholder.tagName, {\n    style,\n    'data-rbd-placeholder-context-id': contextId,\n    onTransitionEnd: onSizeChangeEnd,\n    ref: props.innerRef,\n  });\n}\n\nexport default React.memo<Props>(Placeholder);\n// enzyme does not work well with memo, so exporting the non-memo version\nexport const WithoutMemo = Placeholder;\n"
  },
  {
    "path": "src/view/scroll-listener.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport rafSchd from 'raf-schd';\nimport { invariant } from '../invariant';\nimport bindEvents from './event-bindings/bind-events';\nimport type { EventBinding } from './event-bindings/event-types';\nimport getWindowScroll from './window/get-window-scroll';\nimport { noop } from '../empty';\n\ntype OnWindowScroll = (newScroll: Position) => void;\n\ntype Args = {|\n  onWindowScroll: OnWindowScroll,\n|};\n\ntype Result = {|\n  start: () => void,\n  stop: () => void,\n  isActive: () => boolean,\n|};\n\nfunction getWindowScrollBinding(update: () => void): EventBinding {\n  return {\n    eventName: 'scroll',\n    // ## Passive: true\n    // Eventual consistency is fine because we use position: fixed on the item\n    // ## Capture: false\n    // Scroll events on elements do not bubble, but they go through the capture phase\n    // https://twitter.com/alexandereardon/status/985994224867819520\n    // Using capture: false here as we want to avoid intercepting droppable scroll requests\n    options: { passive: true, capture: false },\n    fn: (event: UIEvent) => {\n      // IE11 fix\n      // All scrollable events still bubble up and are caught by this handler in ie11.\n      // On a window scroll the event.target should be the window or the document.\n      // If this is not the case then it is not a 'window' scroll event and can be ignored\n      if (event.target !== window && event.target !== window.document) {\n        return;\n      }\n\n      update();\n    },\n  };\n}\n\nexport default function getScrollListener({ onWindowScroll }: Args): Result {\n  function updateScroll() {\n    // letting the update function read the latest scroll when called\n    onWindowScroll(getWindowScroll());\n  }\n\n  const scheduled = rafSchd(updateScroll);\n  const binding: EventBinding = getWindowScrollBinding(scheduled);\n  let unbind: () => void = noop;\n\n  function isActive(): boolean {\n    return unbind !== noop;\n  }\n\n  function start() {\n    invariant(!isActive(), 'Cannot start scroll listener when already active');\n    unbind = bindEvents(window, [binding]);\n  }\n  function stop() {\n    invariant(isActive(), 'Cannot stop scroll listener when not active');\n    scheduled.cancel();\n    unbind();\n    unbind = noop;\n  }\n\n  return { start, stop, isActive };\n}\n"
  },
  {
    "path": "src/view/throw-if-invalid-inner-ref.js",
    "content": "// @flow\nimport { invariant } from '../invariant';\nimport isHtmlElement from './is-type-of-element/is-html-element';\n\nexport default (ref: ?mixed) => {\n  invariant(\n    ref && isHtmlElement(ref),\n    `\n    provided.innerRef has not been provided with a HTMLElement.\n\n    You can find a guide on using the innerRef callback functions at:\n    https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/using-inner-ref.md\n  `,\n  );\n};\n"
  },
  {
    "path": "src/view/use-announcer/index.js",
    "content": "// @flow\nexport { default } from './use-announcer';\n"
  },
  {
    "path": "src/view/use-announcer/use-announcer.js",
    "content": "// @flow\nimport { useRef, useEffect } from 'react';\nimport { useMemo, useCallback } from 'use-memo-one';\nimport type { Announce, ContextId } from '../../types';\nimport { warning } from '../../dev-warning';\nimport getBodyElement from '../get-body-element';\nimport visuallyHidden from '../visually-hidden-style';\n\nexport const getId = (contextId: ContextId): string =>\n  `rbd-announcement-${contextId}`;\n\nexport default function useAnnouncer(contextId: ContextId): Announce {\n  const id: string = useMemo(() => getId(contextId), [contextId]);\n  const ref = useRef<?HTMLElement>(null);\n\n  useEffect(\n    function setup() {\n      const el: HTMLElement = document.createElement('div');\n      // storing reference for usage in announce\n      ref.current = el;\n\n      // identifier\n      el.id = id;\n\n      // Aria live region\n\n      // will force itself to be read\n      el.setAttribute('aria-live', 'assertive');\n      // must read the whole thing every time\n      el.setAttribute('aria-atomic', 'true');\n\n      // hide the element visually\n      Object.assign(el.style, visuallyHidden);\n\n      // Add to body\n      getBodyElement().appendChild(el);\n\n      return function cleanup() {\n        // Not clearing the ref as it might be used by announce before the timeout expires\n\n        // unmounting after a timeout to let any announcements\n        // during a mount be published\n        setTimeout(function remove() {\n          // checking if element exists as the body might have been changed by things like 'turbolinks'\n          const body: HTMLBodyElement = getBodyElement();\n          if (body.contains(el)) {\n            body.removeChild(el);\n          }\n          // if el was the current ref - clear it so that\n          // we can get a warning if announce is called\n          if (el === ref.current) {\n            ref.current = null;\n          }\n        });\n      };\n    },\n    [id],\n  );\n\n  const announce: Announce = useCallback((message: string): void => {\n    const el: ?HTMLElement = ref.current;\n    if (el) {\n      el.textContent = message;\n      return;\n    }\n\n    warning(`\n      A screen reader message was trying to be announced but it was unable to do so.\n      This can occur if you unmount your <DragDropContext /> in your onDragEnd.\n      Consider calling provided.announce() before the unmount so that the instruction will\n      not be lost for users relying on a screen reader.\n\n      Message not passed to screen reader:\n\n      \"${message}\"\n    `);\n  }, []);\n\n  return announce;\n}\n"
  },
  {
    "path": "src/view/use-dev-setup-warning.js",
    "content": "// @flow\nimport { useEffect } from 'react';\nimport { error } from '../dev-warning';\nimport useDev from './use-dev';\n\nexport default function useDevSetupWarning(fn: () => void, inputs?: mixed[]) {\n  useDev(() => {\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    useEffect(() => {\n      try {\n        fn();\n      } catch (e) {\n        error(`\n          A setup problem was encountered.\n\n          > ${e.message}\n        `);\n      }\n      // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, inputs);\n  });\n}\n"
  },
  {
    "path": "src/view/use-dev.js",
    "content": "// @flow\n\nexport default function useDev(useHook: () => void) {\n  // Don't run any validation in production\n  if (process.env.NODE_ENV !== 'production') {\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    useHook();\n  }\n}\n"
  },
  {
    "path": "src/view/use-draggable-publisher/get-dimension.js",
    "content": "// @flow\nimport {\n  type BoxModel,\n  type Position,\n  calculateBox,\n  withScroll,\n} from 'css-box-model';\nimport type {\n  DraggableDescriptor,\n  DraggableDimension,\n  Placeholder,\n} from '../../types';\nimport { origin } from '../../state/position';\n\nexport default function getDimension(\n  descriptor: DraggableDescriptor,\n  el: HTMLElement,\n  windowScroll?: Position = origin,\n): DraggableDimension {\n  const computedStyles: CSSStyleDeclaration = window.getComputedStyle(el);\n  const borderBox: ClientRect = el.getBoundingClientRect();\n  const client: BoxModel = calculateBox(borderBox, computedStyles);\n  const page: BoxModel = withScroll(client, windowScroll);\n\n  const placeholder: Placeholder = {\n    client,\n    tagName: el.tagName.toLowerCase(),\n    display: computedStyles.display,\n  };\n  const displaceBy: Position = {\n    x: client.marginBox.width,\n    y: client.marginBox.height,\n  };\n\n  const dimension: DraggableDimension = {\n    descriptor,\n    placeholder,\n    displaceBy,\n    client,\n    page,\n  };\n\n  return dimension;\n}\n"
  },
  {
    "path": "src/view/use-draggable-publisher/index.js",
    "content": "// @flow\nexport { default } from './use-draggable-publisher';\n"
  },
  {
    "path": "src/view/use-draggable-publisher/use-draggable-publisher.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { useMemo, useCallback } from 'use-memo-one';\nimport { useRef } from 'react';\nimport { invariant } from '../../invariant';\nimport type {\n  DraggableDescriptor,\n  DraggableDimension,\n  Id,\n  DraggableOptions,\n} from '../../types';\nimport type {\n  Registry,\n  DraggableEntry,\n} from '../../state/registry/registry-types';\nimport makeDimension from './get-dimension';\nimport useLayoutEffect from '../use-isomorphic-layout-effect';\nimport useUniqueId from '../use-unique-id';\n\nexport type Args = {|\n  descriptor: DraggableDescriptor,\n  getDraggableRef: () => ?HTMLElement,\n  registry: Registry,\n  ...DraggableOptions,\n|};\n\nexport default function useDraggablePublisher(args: Args) {\n  const uniqueId: Id = useUniqueId('draggable');\n\n  const {\n    descriptor,\n    registry,\n    getDraggableRef,\n    canDragInteractiveElements,\n    shouldRespectForcePress,\n    isEnabled,\n  } = args;\n\n  const options: DraggableOptions = useMemo(\n    () => ({\n      canDragInteractiveElements,\n      shouldRespectForcePress,\n      isEnabled,\n    }),\n    [canDragInteractiveElements, isEnabled, shouldRespectForcePress],\n  );\n\n  const getDimension = useCallback(\n    (windowScroll?: Position): DraggableDimension => {\n      const el: ?HTMLElement = getDraggableRef();\n      invariant(el, 'Cannot get dimension when no ref is set');\n      return makeDimension(descriptor, el, windowScroll);\n    },\n    [descriptor, getDraggableRef],\n  );\n\n  const entry: DraggableEntry = useMemo(\n    () => ({\n      uniqueId,\n      descriptor,\n      options,\n      getDimension,\n    }),\n    [descriptor, getDimension, options, uniqueId],\n  );\n\n  const publishedRef = useRef<DraggableEntry>(entry);\n  const isFirstPublishRef = useRef<boolean>(true);\n\n  // mounting and unmounting\n  useLayoutEffect(() => {\n    registry.draggable.register(publishedRef.current);\n    return () => registry.draggable.unregister(publishedRef.current);\n  }, [registry.draggable]);\n\n  // updates while mounted\n  useLayoutEffect(() => {\n    if (isFirstPublishRef.current) {\n      isFirstPublishRef.current = false;\n      return;\n    }\n\n    const last: DraggableEntry = publishedRef.current;\n    publishedRef.current = entry;\n    registry.draggable.update(entry, last);\n  }, [entry, registry.draggable]);\n}\n"
  },
  {
    "path": "src/view/use-droppable-publisher/check-for-nested-scroll-container.js",
    "content": "// @flow\nimport getClosestScrollable from './get-closest-scrollable';\nimport { warning } from '../../dev-warning';\n\n// We currently do not support nested scroll containers\n// But will hopefully support this soon!\nexport default (scrollable: ?Element) => {\n  if (!scrollable) {\n    return;\n  }\n\n  const anotherScrollParent: ?Element = getClosestScrollable(\n    scrollable.parentElement,\n  );\n\n  if (!anotherScrollParent) {\n    return;\n  }\n\n  warning(`\n    Droppable: unsupported nested scroll container detected.\n    A Droppable can only have one scroll parent (which can be itself)\n    Nested scroll containers are currently not supported.\n\n    We hope to support nested scroll containers soon: https://github.com/atlassian/react-beautiful-dnd/issues/131\n  `);\n};\n"
  },
  {
    "path": "src/view/use-droppable-publisher/get-closest-scrollable.js",
    "content": "// @flow\nimport { invariant } from '../../invariant';\nimport { warning } from '../../dev-warning';\nimport getBodyElement from '../get-body-element';\n\ntype Overflow = {|\n  overflowX: string,\n  overflowY: string,\n|};\n\nconst isEqual = (base: string) => (value: string): boolean => base === value;\nconst isScroll = isEqual('scroll');\nconst isAuto = isEqual('auto');\nconst isVisible = isEqual('visible');\nconst isEither = (overflow: Overflow, fn: (value: string) => boolean) =>\n  fn(overflow.overflowX) || fn(overflow.overflowY);\nconst isBoth = (overflow: Overflow, fn: (value: string) => boolean) =>\n  fn(overflow.overflowX) && fn(overflow.overflowY);\n\nconst isElementScrollable = (el: Element): boolean => {\n  const style: CSSStyleDeclaration = window.getComputedStyle(el);\n  const overflow: Overflow = {\n    overflowX: style.overflowX,\n    overflowY: style.overflowY,\n  };\n\n  return isEither(overflow, isScroll) || isEither(overflow, isAuto);\n};\n\n// Special case for a body element\n// Playground: https://codepen.io/alexreardon/pen/ZmyLgX?editors=1111\nconst isBodyScrollable = (): boolean => {\n  // Because we always return false for now, we can skip any actual processing in production\n  if (process.env.NODE_ENV === 'production') {\n    return false;\n  }\n\n  const body: HTMLBodyElement = getBodyElement();\n  const html: ?HTMLElement = document.documentElement;\n  invariant(html);\n\n  // 1. The `body` has `overflow-[x|y]: auto | scroll`\n  if (!isElementScrollable(body)) {\n    return false;\n  }\n\n  const htmlStyle: CSSStyleDeclaration = window.getComputedStyle(html);\n  const htmlOverflow: Overflow = {\n    overflowX: htmlStyle.overflowX,\n    overflowY: htmlStyle.overflowY,\n  };\n\n  if (isBoth(htmlOverflow, isVisible)) {\n    return false;\n  }\n\n  warning(`\n    We have detected that your <body> element might be a scroll container.\n    We have found no reliable way of detecting whether the <body> element is a scroll container.\n    Under most circumstances a <body> scroll bar will be on the <html> element (document.documentElement)\n\n    Because we cannot determine if the <body> is a scroll container, and generally it is not one,\n    we will be treating the <body> as *not* a scroll container\n\n    More information: https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/how-we-detect-scroll-containers.md\n  `);\n  return false;\n};\n\nconst getClosestScrollable = (el: ?Element): ?Element => {\n  // cannot do anything else!\n  if (el == null) {\n    return null;\n  }\n\n  // not allowing us to go higher then body\n  if (el === document.body) {\n    return isBodyScrollable() ? el : null;\n  }\n\n  // Should never get here, but just being safe\n  if (el === document.documentElement) {\n    return null;\n  }\n\n  if (!isElementScrollable(el)) {\n    // keep recursing\n    return getClosestScrollable(el.parentElement);\n  }\n\n  // success!\n  return el;\n};\n\nexport default getClosestScrollable;\n"
  },
  {
    "path": "src/view/use-droppable-publisher/get-dimension.js",
    "content": "// @flow\nimport {\n  getBox,\n  withScroll,\n  createBox,\n  expand,\n  type BoxModel,\n  type Position,\n  type Spacing,\n} from 'css-box-model';\nimport getDroppableDimension, {\n  type Closest,\n} from '../../state/droppable/get-droppable';\nimport type { Env } from './get-env';\nimport type {\n  DroppableDimension,\n  DroppableDescriptor,\n  Direction,\n  ScrollSize,\n} from '../../types';\nimport getScroll from './get-scroll';\n\nconst getClient = (\n  targetRef: HTMLElement,\n  closestScrollable: ?Element,\n): BoxModel => {\n  const base: BoxModel = getBox(targetRef);\n\n  // Droppable has no scroll parent\n  if (!closestScrollable) {\n    return base;\n  }\n\n  // Droppable is not the same as the closest scrollable\n  if (targetRef !== closestScrollable) {\n    return base;\n  }\n\n  // Droppable is scrollable\n\n  // Element.getBoundingClient() returns a clipped padding box:\n  // When not scrollable: the full size of the element\n  // When scrollable: the visible size of the element\n  // (which is not the full width of its scrollable content)\n  // So we recalculate the borderBox of a scrollable droppable to give\n  // it its full dimensions. This will be cut to the correct size by the frame\n\n  // Creating the paddingBox based on scrollWidth / scrollTop\n  // scrollWidth / scrollHeight are based on the paddingBox of an element\n  // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight\n  const top: number = base.paddingBox.top - closestScrollable.scrollTop;\n  const left: number = base.paddingBox.left - closestScrollable.scrollLeft;\n  const bottom: number = top + closestScrollable.scrollHeight;\n  const right: number = left + closestScrollable.scrollWidth;\n\n  // unclipped padding box\n  const paddingBox: Spacing = {\n    top,\n    right,\n    bottom,\n    left,\n  };\n\n  // Creating the borderBox by adding the borders to the paddingBox\n  const borderBox: Spacing = expand(paddingBox, base.border);\n\n  // We are not accounting for scrollbars\n  // Adjusting for scrollbars is hard because:\n  // - they are different between browsers\n  // - scrollbars can be activated and removed during a drag\n  // We instead account for this slightly in our auto scroller\n\n  const client: BoxModel = createBox({\n    borderBox,\n    margin: base.margin,\n    border: base.border,\n    padding: base.padding,\n  });\n  return client;\n};\n\ntype Args = {|\n  ref: HTMLElement,\n  descriptor: DroppableDescriptor,\n  env: Env,\n  windowScroll: Position,\n  direction: Direction,\n  isDropDisabled: boolean,\n  isCombineEnabled: boolean,\n  shouldClipSubject: boolean,\n|};\n\nexport default ({\n  ref,\n  descriptor,\n  env,\n  windowScroll,\n  direction,\n  isDropDisabled,\n  isCombineEnabled,\n  shouldClipSubject,\n}: Args): DroppableDimension => {\n  const closestScrollable: ?Element = env.closestScrollable;\n  const client: BoxModel = getClient(ref, closestScrollable);\n  const page: BoxModel = withScroll(client, windowScroll);\n\n  const closest: ?Closest = (() => {\n    if (!closestScrollable) {\n      return null;\n    }\n\n    const frameClient: BoxModel = getBox(closestScrollable);\n    const scrollSize: ScrollSize = {\n      scrollHeight: closestScrollable.scrollHeight,\n      scrollWidth: closestScrollable.scrollWidth,\n    };\n\n    return {\n      client: frameClient,\n      page: withScroll(frameClient, windowScroll),\n      scroll: getScroll(closestScrollable),\n      scrollSize,\n      shouldClipSubject,\n    };\n  })();\n\n  const dimension: DroppableDimension = getDroppableDimension({\n    descriptor,\n    isEnabled: !isDropDisabled,\n    isCombineEnabled,\n    isFixedOnPage: env.isFixedOnPage,\n    direction,\n    client,\n    page,\n    closest,\n  });\n\n  return dimension;\n};\n"
  },
  {
    "path": "src/view/use-droppable-publisher/get-env.js",
    "content": "// @flow\nimport getClosestScrollable from './get-closest-scrollable';\n\nexport type Env = {|\n  closestScrollable: ?Element,\n  isFixedOnPage: boolean,\n|};\n\n// TODO: do this check at the same time as the closest scrollable\n// in order to avoid double calling getComputedStyle\n// Do this when we move to multiple scroll containers\nconst getIsFixed = (el: ?Element): boolean => {\n  if (!el) {\n    return false;\n  }\n  const style: CSSStyleDeclaration = window.getComputedStyle(el);\n  if (style.position === 'fixed') {\n    return true;\n  }\n  return getIsFixed(el.parentElement);\n};\n\nexport default (start: Element): Env => {\n  const closestScrollable: ?Element = getClosestScrollable(start);\n  const isFixedOnPage: boolean = getIsFixed(start);\n\n  return {\n    closestScrollable,\n    isFixedOnPage,\n  };\n};\n"
  },
  {
    "path": "src/view/use-droppable-publisher/get-listener-options.js",
    "content": "// @flow\nimport type { ScrollOptions } from '../../types';\n\nconst immediate = {\n  passive: false,\n};\nconst delayed = {\n  passive: true,\n};\n\nexport default (options: ScrollOptions) =>\n  options.shouldPublishImmediately ? immediate : delayed;\n"
  },
  {
    "path": "src/view/use-droppable-publisher/get-scroll.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\n\nexport default (el: Element): Position => ({\n  x: el.scrollLeft,\n  y: el.scrollTop,\n});\n"
  },
  {
    "path": "src/view/use-droppable-publisher/index.js",
    "content": "// @flow\nexport { default } from './use-droppable-publisher';\n"
  },
  {
    "path": "src/view/use-droppable-publisher/is-in-fixed-container.js",
    "content": "// @flow\n\nconst isElementFixed = (el: Element): boolean =>\n  window.getComputedStyle(el).position === 'fixed';\n\nconst find = (el: ?Element): boolean => {\n  // cannot do anything else!\n  if (el == null) {\n    return false;\n  }\n\n  // keep looking\n  if (!isElementFixed(el)) {\n    return find(el.parentElement);\n  }\n\n  // success!\n  return true;\n};\n\nexport default find;\n"
  },
  {
    "path": "src/view/use-droppable-publisher/use-droppable-publisher.js",
    "content": "// @flow\nimport { useRef } from 'react';\nimport { type Position } from 'css-box-model';\nimport rafSchedule from 'raf-schd';\nimport { useMemo, useCallback } from 'use-memo-one';\nimport memoizeOne from 'memoize-one';\nimport { invariant } from '../../invariant';\nimport checkForNestedScrollContainers from './check-for-nested-scroll-container';\nimport * as dataAttr from '../data-attributes';\nimport { origin } from '../../state/position';\nimport getScroll from './get-scroll';\nimport type {\n  DroppableEntry,\n  DroppableCallbacks,\n} from '../../state/registry/registry-types';\nimport getEnv, { type Env } from './get-env';\nimport type {\n  Id,\n  DroppableId,\n  TypeId,\n  DroppableDimension,\n  DroppableDescriptor,\n  Direction,\n  ScrollOptions,\n  DroppableMode,\n} from '../../types';\nimport getDimension from './get-dimension';\nimport AppContext, { type AppContextValue } from '../context/app-context';\nimport { warning } from '../../dev-warning';\nimport getListenerOptions from './get-listener-options';\nimport useRequiredContext from '../use-required-context';\nimport usePreviousRef from '../use-previous-ref';\nimport useLayoutEffect from '../use-isomorphic-layout-effect';\nimport useUniqueId from '../use-unique-id';\n\ntype Props = {|\n  droppableId: DroppableId,\n  type: TypeId,\n  mode: DroppableMode,\n  direction: Direction,\n  isDropDisabled: boolean,\n  isCombineEnabled: boolean,\n  ignoreContainerClipping: boolean,\n  getDroppableRef: () => ?HTMLElement,\n|};\n\ntype WhileDragging = {|\n  ref: HTMLElement,\n  descriptor: DroppableDescriptor,\n  env: Env,\n  scrollOptions: ScrollOptions,\n|};\n\nconst getClosestScrollableFromDrag = (dragging: ?WhileDragging): ?Element =>\n  (dragging && dragging.env.closestScrollable) || null;\n\nexport default function useDroppablePublisher(args: Props) {\n  const whileDraggingRef = useRef<?WhileDragging>(null);\n  const appContext: AppContextValue = useRequiredContext(AppContext);\n  const uniqueId: Id = useUniqueId('droppable');\n  const { registry, marshal } = appContext;\n  const previousRef = usePreviousRef(args);\n\n  const descriptor = useMemo<DroppableDescriptor>(\n    () => ({\n      id: args.droppableId,\n      type: args.type,\n      mode: args.mode,\n    }),\n    [args.droppableId, args.mode, args.type],\n  );\n  const publishedDescriptorRef = useRef<DroppableDescriptor>(descriptor);\n\n  const memoizedUpdateScroll = useMemo(\n    () =>\n      memoizeOne((x: number, y: number) => {\n        invariant(\n          whileDraggingRef.current,\n          'Can only update scroll when dragging',\n        );\n        const scroll: Position = { x, y };\n        marshal.updateDroppableScroll(descriptor.id, scroll);\n      }),\n    [descriptor.id, marshal],\n  );\n\n  const getClosestScroll = useCallback((): Position => {\n    const dragging: ?WhileDragging = whileDraggingRef.current;\n    if (!dragging || !dragging.env.closestScrollable) {\n      return origin;\n    }\n\n    return getScroll(dragging.env.closestScrollable);\n  }, []);\n\n  const updateScroll = useCallback(() => {\n    // reading scroll value when called so value will be the latest\n    const scroll: Position = getClosestScroll();\n    memoizedUpdateScroll(scroll.x, scroll.y);\n  }, [getClosestScroll, memoizedUpdateScroll]);\n\n  const scheduleScrollUpdate = useMemo(() => rafSchedule(updateScroll), [\n    updateScroll,\n  ]);\n\n  const onClosestScroll = useCallback(() => {\n    const dragging: ?WhileDragging = whileDraggingRef.current;\n    const closest: ?Element = getClosestScrollableFromDrag(dragging);\n\n    invariant(\n      dragging && closest,\n      'Could not find scroll options while scrolling',\n    );\n    const options: ScrollOptions = dragging.scrollOptions;\n    if (options.shouldPublishImmediately) {\n      updateScroll();\n      return;\n    }\n    scheduleScrollUpdate();\n  }, [scheduleScrollUpdate, updateScroll]);\n\n  const getDimensionAndWatchScroll = useCallback(\n    (windowScroll: Position, options: ScrollOptions) => {\n      invariant(\n        !whileDraggingRef.current,\n        'Cannot collect a droppable while a drag is occurring',\n      );\n      const previous: Props = previousRef.current;\n      const ref: ?HTMLElement = previous.getDroppableRef();\n      invariant(ref, 'Cannot collect without a droppable ref');\n      const env: Env = getEnv(ref);\n\n      const dragging: WhileDragging = {\n        ref,\n        descriptor,\n        env,\n        scrollOptions: options,\n      };\n      // side effect\n      whileDraggingRef.current = dragging;\n\n      const dimension: DroppableDimension = getDimension({\n        ref,\n        descriptor,\n        env,\n        windowScroll,\n        direction: previous.direction,\n        isDropDisabled: previous.isDropDisabled,\n        isCombineEnabled: previous.isCombineEnabled,\n        shouldClipSubject: !previous.ignoreContainerClipping,\n      });\n\n      const scrollable: ?Element = env.closestScrollable;\n\n      if (scrollable) {\n        scrollable.setAttribute(\n          dataAttr.scrollContainer.contextId,\n          appContext.contextId,\n        );\n\n        // bind scroll listener\n        scrollable.addEventListener(\n          'scroll',\n          onClosestScroll,\n          getListenerOptions(dragging.scrollOptions),\n        );\n        // print a debug warning if using an unsupported nested scroll container setup\n        if (process.env.NODE_ENV !== 'production') {\n          checkForNestedScrollContainers(scrollable);\n        }\n      }\n\n      return dimension;\n    },\n    [appContext.contextId, descriptor, onClosestScroll, previousRef],\n  );\n\n  const getScrollWhileDragging = useCallback((): Position => {\n    const dragging: ?WhileDragging = whileDraggingRef.current;\n    const closest: ?Element = getClosestScrollableFromDrag(dragging);\n    invariant(\n      dragging && closest,\n      'Can only recollect Droppable client for Droppables that have a scroll container',\n    );\n\n    return getScroll(closest);\n  }, []);\n\n  const dragStopped = useCallback(() => {\n    const dragging: ?WhileDragging = whileDraggingRef.current;\n    invariant(dragging, 'Cannot stop drag when no active drag');\n    const closest: ?Element = getClosestScrollableFromDrag(dragging);\n\n    // goodbye old friend\n    whileDraggingRef.current = null;\n\n    if (!closest) {\n      return;\n    }\n\n    // unwatch scroll\n    scheduleScrollUpdate.cancel();\n    closest.removeAttribute(dataAttr.scrollContainer.contextId);\n    closest.removeEventListener(\n      'scroll',\n      onClosestScroll,\n      getListenerOptions(dragging.scrollOptions),\n    );\n  }, [onClosestScroll, scheduleScrollUpdate]);\n\n  const scroll = useCallback((change: Position) => {\n    // arrange\n    const dragging: ?WhileDragging = whileDraggingRef.current;\n    invariant(dragging, 'Cannot scroll when there is no drag');\n    const closest: ?Element = getClosestScrollableFromDrag(dragging);\n    invariant(closest, 'Cannot scroll a droppable with no closest scrollable');\n\n    // act\n    closest.scrollTop += change.y;\n    closest.scrollLeft += change.x;\n  }, []);\n\n  const callbacks: DroppableCallbacks = useMemo(() => {\n    return {\n      getDimensionAndWatchScroll,\n      getScrollWhileDragging,\n      dragStopped,\n      scroll,\n    };\n  }, [dragStopped, getDimensionAndWatchScroll, getScrollWhileDragging, scroll]);\n\n  const entry: DroppableEntry = useMemo(\n    () => ({\n      uniqueId,\n      descriptor,\n      callbacks,\n    }),\n    [callbacks, descriptor, uniqueId],\n  );\n\n  // Register with the marshal and let it know of:\n  // - any descriptor changes\n  // - when it unmounts\n  useLayoutEffect(() => {\n    publishedDescriptorRef.current = entry.descriptor;\n    registry.droppable.register(entry);\n\n    return () => {\n      if (whileDraggingRef.current) {\n        warning(\n          'Unsupported: changing the droppableId or type of a Droppable during a drag',\n        );\n        dragStopped();\n      }\n\n      registry.droppable.unregister(entry);\n    };\n  }, [callbacks, descriptor, dragStopped, entry, marshal, registry.droppable]);\n\n  // update is enabled with the marshal\n  // only need to update when there is a drag\n  useLayoutEffect(() => {\n    if (!whileDraggingRef.current) {\n      return;\n    }\n    marshal.updateDroppableIsEnabled(\n      publishedDescriptorRef.current.id,\n      !args.isDropDisabled,\n    );\n  }, [args.isDropDisabled, marshal]);\n\n  // update is combine enabled with the marshal\n  // only need to update when there is a drag\n  useLayoutEffect(() => {\n    if (!whileDraggingRef.current) {\n      return;\n    }\n    marshal.updateDroppableIsCombineEnabled(\n      publishedDescriptorRef.current.id,\n      args.isCombineEnabled,\n    );\n  }, [args.isCombineEnabled, marshal]);\n}\n"
  },
  {
    "path": "src/view/use-focus-marshal/focus-marshal-types.js",
    "content": "// @flow\nimport type { DraggableId } from '../../types';\n\nexport type Unregister = () => void;\n\nexport type Register = (id: DraggableId, focus: () => void) => Unregister;\n\nexport type FocusMarshal = {|\n  register: Register,\n  tryRecordFocus: (tryRecordFor: DraggableId) => void,\n  tryRestoreFocusRecorded: () => void,\n  tryShiftRecord: (previous: DraggableId, redirectTo: DraggableId) => void,\n|};\n"
  },
  {
    "path": "src/view/use-focus-marshal/index.js",
    "content": "// @flow\nexport { default } from './use-focus-marshal';\n"
  },
  {
    "path": "src/view/use-focus-marshal/use-focus-marshal.js",
    "content": "// @flow\nimport { useRef } from 'react';\nimport { useMemo, useCallback } from 'use-memo-one';\nimport type { DraggableId, ContextId } from '../../types';\nimport type { FocusMarshal, Unregister } from './focus-marshal-types';\nimport { dragHandle as dragHandleAttr } from '../data-attributes';\nimport useLayoutEffect from '../use-isomorphic-layout-effect';\nimport findDragHandle from '../get-elements/find-drag-handle';\n\ntype Entry = {|\n  id: DraggableId,\n  focus: () => void,\n|};\n\ntype EntryMap = {\n  [id: DraggableId]: Entry,\n};\n\nexport default function useFocusMarshal(contextId: ContextId): FocusMarshal {\n  const entriesRef = useRef<EntryMap>({});\n  const recordRef = useRef<?DraggableId>(null);\n  const restoreFocusFrameRef = useRef<?AnimationFrameID>(null);\n  const isMountedRef = useRef<boolean>(false);\n\n  const register = useCallback(function register(\n    id: DraggableId,\n    focus: () => void,\n  ): Unregister {\n    const entry: Entry = { id, focus };\n    entriesRef.current[id] = entry;\n\n    return function unregister() {\n      const entries: EntryMap = entriesRef.current;\n      const current: Entry = entries[id];\n      // entry might have been overrided by another registration\n      if (current !== entry) {\n        delete entries[id];\n      }\n    };\n  },\n  []);\n\n  const tryGiveFocus = useCallback(\n    function tryGiveFocus(tryGiveFocusTo: DraggableId) {\n      const handle: ?HTMLElement = findDragHandle(contextId, tryGiveFocusTo);\n\n      if (handle && handle !== document.activeElement) {\n        handle.focus();\n      }\n    },\n    [contextId],\n  );\n\n  const tryShiftRecord = useCallback(function tryShiftRecord(\n    previous: DraggableId,\n    redirectTo: DraggableId,\n  ) {\n    if (recordRef.current === previous) {\n      recordRef.current = redirectTo;\n    }\n  },\n  []);\n\n  const tryRestoreFocusRecorded = useCallback(\n    function tryRestoreFocusRecorded() {\n      // frame already queued\n      if (restoreFocusFrameRef.current) {\n        return;\n      }\n\n      // cannot give focus if unmounted\n      // this code path is generally not hit expect for some hot-reloading flows\n      if (!isMountedRef.current) {\n        return;\n      }\n\n      restoreFocusFrameRef.current = requestAnimationFrame(() => {\n        restoreFocusFrameRef.current = null;\n        const record: ?DraggableId = recordRef.current;\n        if (record) {\n          tryGiveFocus(record);\n        }\n      });\n    },\n    [tryGiveFocus],\n  );\n\n  const tryRecordFocus = useCallback(function tryRecordFocus(id: DraggableId) {\n    // clear any existing record\n    recordRef.current = null;\n\n    const focused: ?Element = document.activeElement;\n\n    // no item focused so it cannot be our item\n    if (!focused) {\n      return;\n    }\n\n    // focused element is not a drag handle or does not have the right id\n    if (focused.getAttribute(dragHandleAttr.draggableId) !== id) {\n      return;\n    }\n\n    recordRef.current = id;\n  }, []);\n\n  useLayoutEffect(() => {\n    isMountedRef.current = true;\n    return function clearFrameOnUnmount() {\n      isMountedRef.current = false;\n      const frameId: ?AnimationFrameID = restoreFocusFrameRef.current;\n      if (frameId) {\n        cancelAnimationFrame(frameId);\n      }\n    };\n  }, []);\n\n  const marshal: FocusMarshal = useMemo(\n    () => ({\n      register,\n      tryRecordFocus,\n      tryRestoreFocusRecorded,\n      tryShiftRecord,\n    }),\n    [register, tryRecordFocus, tryRestoreFocusRecorded, tryShiftRecord],\n  );\n\n  return marshal;\n}\n"
  },
  {
    "path": "src/view/use-hidden-text-element/index.js",
    "content": "// @flow\nexport { default } from './use-hidden-text-element';\n"
  },
  {
    "path": "src/view/use-hidden-text-element/use-hidden-text-element.js",
    "content": "// @flow\nimport { useEffect } from 'react';\nimport { useMemo } from 'use-memo-one';\nimport type { ContextId, ElementId } from '../../types';\nimport getBodyElement from '../get-body-element';\nimport useUniqueId from '../use-unique-id';\n\ntype GetIdArgs = {|\n  contextId: ContextId,\n  uniqueId: string,\n|};\n\nexport function getElementId({ contextId, uniqueId }: GetIdArgs): ElementId {\n  return `rbd-hidden-text-${contextId}-${uniqueId}`;\n}\n\ntype Args = {|\n  contextId: ContextId,\n  text: string,\n|};\n\nexport default function useHiddenTextElement({\n  contextId,\n  text,\n}: Args): ElementId {\n  const uniqueId: string = useUniqueId('hidden-text', { separator: '-' });\n  const id: ElementId = useMemo(() => getElementId({ contextId, uniqueId }), [\n    uniqueId,\n    contextId,\n  ]);\n\n  useEffect(\n    function mount() {\n      const el: HTMLElement = document.createElement('div');\n\n      // identifier\n      el.id = id;\n\n      // add the description text\n      el.textContent = text;\n\n      // Using `display: none` prevent screen readers from reading this element in the document flow\n      el.style.display = 'none';\n\n      // Add to body\n      getBodyElement().appendChild(el);\n\n      return function unmount() {\n        // checking if element exists as the body might have been changed by things like 'turbolinks'\n        const body: HTMLBodyElement = getBodyElement();\n        if (body.contains(el)) {\n          body.removeChild(el);\n        }\n      };\n    },\n    [id, text],\n  );\n\n  return id;\n}\n"
  },
  {
    "path": "src/view/use-isomorphic-layout-effect.js",
    "content": "// @flow\n// eslint-disable-next-line no-restricted-imports\nimport { useLayoutEffect, useEffect } from 'react';\n\n// https://github.com/reduxjs/react-redux/blob/v7-beta/src/components/connectAdvanced.js#L35\n// React currently throws a warning when using useLayoutEffect on the server.\n// To get around it, we can conditionally useEffect on the server (no-op) and\n// useLayoutEffect in the browser. We need useLayoutEffect because we want\n// `connect` to perform sync updates to a ref to save the latest props after\n// a render is actually committed to the DOM.\nconst useIsomorphicLayoutEffect =\n  typeof window !== 'undefined' &&\n  typeof window.document !== 'undefined' &&\n  typeof window.document.createElement !== 'undefined'\n    ? useLayoutEffect\n    : useEffect;\n\nexport default useIsomorphicLayoutEffect;\n"
  },
  {
    "path": "src/view/use-previous-ref.js",
    "content": "// @flow\nimport { useRef, useEffect } from 'react';\n\nexport default function usePrevious<T>(current: T): {| current: T |} {\n  const ref = useRef<T>(current);\n\n  // will be updated on the next render\n  useEffect(() => {\n    ref.current = current;\n  });\n\n  // return the existing current (pre render)\n  return ref;\n}\n"
  },
  {
    "path": "src/view/use-required-context.js",
    "content": "// @flow\nimport { useContext, type Context as ContextType } from 'react';\nimport { invariant } from '../invariant';\n\nexport default function useRequiredContext<T>(Context: ContextType<?T>): T {\n  const result: ?T = useContext(Context);\n  invariant(result, 'Could not find required context');\n  return result;\n}\n"
  },
  {
    "path": "src/view/use-sensor-marshal/closest.js",
    "content": "// @flow\nimport { find } from '../../native-with-fallback';\n\nconst supportedMatchesName: string = ((): string => {\n  const base: string = 'matches';\n\n  // Server side rendering\n  if (typeof document === 'undefined') {\n    return base;\n  }\n\n  // See https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API\n  const candidates: string[] = [\n    base,\n    'msMatchesSelector',\n    'webkitMatchesSelector',\n  ];\n\n  const value: ?string = find(\n    candidates,\n    (name: string): boolean => name in Element.prototype,\n  );\n\n  return value || base;\n})();\n\nfunction closestPonyfill(el: ?Element, selector: string) {\n  if (el == null) {\n    return null;\n  }\n\n  // Element.prototype.matches is supported in ie11 with a different name\n  // https://caniuse.com/#feat=matchesselector\n  // $FlowFixMe - dynamic property\n  if (el[supportedMatchesName](selector)) {\n    return el;\n  }\n\n  // recursively look up the tree\n  return closestPonyfill(el.parentElement, selector);\n}\n\nexport default function closest(el: Element, selector: string): ?Element {\n  // Using native closest for maximum speed where we can\n  if (el.closest) {\n    return el.closest(selector);\n  }\n  // ie11: damn you!\n  return closestPonyfill(el, selector);\n}\n"
  },
  {
    "path": "src/view/use-sensor-marshal/find-closest-draggable-id-from-event.js",
    "content": "// @flow\nimport type { ContextId, DraggableId } from '../../types';\nimport * as attributes from '../data-attributes';\nimport isElement from '../is-type-of-element/is-element';\nimport isHtmlElement from '../is-type-of-element/is-html-element';\nimport closest from './closest';\nimport { warning } from '../../dev-warning';\n\nfunction getSelector(contextId: ContextId): string {\n  return `[${attributes.dragHandle.contextId}=\"${contextId}\"]`;\n}\n\nfunction findClosestDragHandleFromEvent(\n  contextId: ContextId,\n  event: Event,\n): ?HTMLElement {\n  const target: ?EventTarget = event.target;\n\n  if (!isElement(target)) {\n    warning('event.target must be a Element');\n    return null;\n  }\n\n  const selector: string = getSelector(contextId);\n  const handle: ?Element = closest(target, selector);\n\n  if (!handle) {\n    return null;\n  }\n\n  if (!isHtmlElement(handle)) {\n    warning('drag handle must be a HTMLElement');\n    return null;\n  }\n\n  return handle;\n}\n\nexport default function tryGetClosestDraggableIdFromEvent(\n  contextId: ContextId,\n  event: Event,\n): ?DraggableId {\n  const handle: ?HTMLElement = findClosestDragHandleFromEvent(contextId, event);\n\n  if (!handle) {\n    return null;\n  }\n\n  return handle.getAttribute(attributes.dragHandle.draggableId);\n}\n"
  },
  {
    "path": "src/view/use-sensor-marshal/index.js",
    "content": "// @flow\nexport { default } from './use-sensor-marshal';\nexport { default as useMouseSensor } from './sensors/use-mouse-sensor';\nexport { default as useTouchSensor } from './sensors/use-touch-sensor';\nexport { default as useKeyboardSensor } from './sensors/use-keyboard-sensor';\n"
  },
  {
    "path": "src/view/use-sensor-marshal/is-event-in-interactive-element.js",
    "content": "// @flow\nimport isHtmlElement from '../is-type-of-element/is-html-element';\n\nexport type TagNameMap = {\n  [tagName: string]: true,\n};\n\nexport const interactiveTagNames: TagNameMap = {\n  input: true,\n  button: true,\n  textarea: true,\n  select: true,\n  option: true,\n  optgroup: true,\n  video: true,\n  audio: true,\n};\n\nfunction isAnInteractiveElement(parent: Element, current: ?Element) {\n  if (current == null) {\n    return false;\n  }\n\n  // Most interactive elements cannot have children. However, some can such as 'button'.\n  // See 'Permitted content' on https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button\n  // Rather than having two different functions we can consolidate our checks into this single\n  // function to keep things simple.\n  // There is no harm checking if the parent has an interactive tag name even if it cannot have\n  // any children. We need to perform this loop anyway to check for the contenteditable attribute\n  const hasAnInteractiveTag: boolean = Boolean(\n    interactiveTagNames[current.tagName.toLowerCase()],\n  );\n\n  if (hasAnInteractiveTag) {\n    return true;\n  }\n\n  // contenteditable=\"true\" or contenteditable=\"\" are valid ways\n  // of creating a contenteditable container\n  // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable\n  const attribute: ?string = current.getAttribute('contenteditable');\n  if (attribute === 'true' || attribute === '') {\n    return true;\n  }\n\n  // nothing more can be done and no results found\n  if (current === parent) {\n    return false;\n  }\n\n  // recursion to check parent\n  return isAnInteractiveElement(parent, current.parentElement);\n}\n\nexport default function isEventInInteractiveElement(\n  draggable: Element,\n  event: Event,\n): boolean {\n  const target: EventTarget = event.target;\n\n  if (!isHtmlElement(target)) {\n    return false;\n  }\n\n  return isAnInteractiveElement(draggable, target);\n}\n"
  },
  {
    "path": "src/view/use-sensor-marshal/lock.js",
    "content": "// @flow\nimport { invariant } from '../../invariant';\n\nexport type Lock = {|\n  abandon: () => void,\n|};\n\nexport type LockAPI = {|\n  isClaimed: () => boolean,\n  isActive: (lock: Lock) => boolean,\n  claim: (abandon: () => void) => Lock,\n  release: () => void,\n  tryAbandon: () => void,\n|};\n\nexport default function create(): LockAPI {\n  let lock: ?Lock = null;\n\n  function isClaimed(): boolean {\n    return Boolean(lock);\n  }\n\n  function isActive(value: Lock): boolean {\n    return value === lock;\n  }\n\n  function claim(abandon: () => void): Lock {\n    invariant(!lock, 'Cannot claim lock as it is already claimed');\n    const newLock: Lock = { abandon };\n    // update singleton\n    lock = newLock;\n    // return lock\n    return newLock;\n  }\n  function release() {\n    invariant(lock, 'Cannot release lock when there is no lock');\n    lock = null;\n  }\n\n  function tryAbandon() {\n    if (lock) {\n      lock.abandon();\n      release();\n    }\n  }\n\n  return { isClaimed, isActive, claim, release, tryAbandon };\n}\n"
  },
  {
    "path": "src/view/use-sensor-marshal/sensors/use-keyboard-sensor.js",
    "content": "// @flow\nimport { useRef } from 'react';\nimport { useMemo, useCallback } from 'use-memo-one';\nimport { invariant } from '../../../invariant';\nimport type {\n  SensorAPI,\n  PreDragActions,\n  SnapDragActions,\n  DraggableId,\n} from '../../../types';\nimport type {\n  EventBinding,\n  EventOptions,\n} from '../../event-bindings/event-types';\nimport * as keyCodes from '../../key-codes';\nimport bindEvents from '../../event-bindings/bind-events';\nimport preventStandardKeyEvents from './util/prevent-standard-key-events';\nimport supportedPageVisibilityEventName from './util/supported-page-visibility-event-name';\nimport useLayoutEffect from '../../use-isomorphic-layout-effect';\n\nfunction noop() {}\n\ntype KeyMap = {\n  [key: number]: true,\n};\n\nconst scrollJumpKeys: KeyMap = {\n  [keyCodes.pageDown]: true,\n  [keyCodes.pageUp]: true,\n  [keyCodes.home]: true,\n  [keyCodes.end]: true,\n};\n\nfunction getDraggingBindings(\n  actions: SnapDragActions,\n  stop: () => void,\n): EventBinding[] {\n  function cancel() {\n    stop();\n    actions.cancel();\n  }\n\n  function drop() {\n    stop();\n    actions.drop();\n  }\n\n  return [\n    {\n      eventName: 'keydown',\n      fn: (event: KeyboardEvent) => {\n        if (event.keyCode === keyCodes.escape) {\n          event.preventDefault();\n          cancel();\n          return;\n        }\n\n        // Dropping\n        if (event.keyCode === keyCodes.space) {\n          // need to stop parent Draggable's thinking this is a lift\n          event.preventDefault();\n          drop();\n          return;\n        }\n\n        // Movement\n\n        if (event.keyCode === keyCodes.arrowDown) {\n          event.preventDefault();\n          actions.moveDown();\n          return;\n        }\n\n        if (event.keyCode === keyCodes.arrowUp) {\n          event.preventDefault();\n          actions.moveUp();\n          return;\n        }\n\n        if (event.keyCode === keyCodes.arrowRight) {\n          event.preventDefault();\n          actions.moveRight();\n          return;\n        }\n\n        if (event.keyCode === keyCodes.arrowLeft) {\n          event.preventDefault();\n          actions.moveLeft();\n          return;\n        }\n\n        // preventing scroll jumping at this time\n        if (scrollJumpKeys[event.keyCode]) {\n          event.preventDefault();\n          return;\n        }\n\n        preventStandardKeyEvents(event);\n      },\n    },\n    // any mouse actions kills a drag\n    {\n      eventName: 'mousedown',\n      fn: cancel,\n    },\n    {\n      eventName: 'mouseup',\n      fn: cancel,\n    },\n    {\n      eventName: 'click',\n      fn: cancel,\n    },\n    {\n      eventName: 'touchstart',\n      fn: cancel,\n    },\n    // resizing the browser kills a drag\n    {\n      eventName: 'resize',\n      fn: cancel,\n    },\n    // kill if the user is using the mouse wheel\n    // We are not supporting wheel / trackpad scrolling with keyboard dragging\n    {\n      eventName: 'wheel',\n      fn: cancel,\n      // chrome says it is a violation for this to not be passive\n      // it is fine for it to be passive as we just cancel as soon as we get\n      // any event\n      options: { passive: true },\n    },\n    // Cancel on page visibility change\n    {\n      eventName: supportedPageVisibilityEventName,\n      fn: cancel,\n    },\n  ];\n}\n\nexport default function useKeyboardSensor(api: SensorAPI) {\n  const unbindEventsRef = useRef<() => void>(noop);\n\n  const startCaptureBinding: EventBinding = useMemo(\n    () => ({\n      eventName: 'keydown',\n      fn: function onKeyDown(event: KeyboardEvent) {\n        // Event already used\n        if (event.defaultPrevented) {\n          return;\n        }\n\n        // Need to start drag with a spacebar press\n        if (event.keyCode !== keyCodes.space) {\n          return;\n        }\n\n        const draggableId: ?DraggableId = api.findClosestDraggableId(event);\n\n        if (!draggableId) {\n          return;\n        }\n\n        const preDrag: ?PreDragActions = api.tryGetLock(\n          draggableId,\n          // abort function not defined yet\n          // eslint-disable-next-line no-use-before-define\n          stop,\n          { sourceEvent: event },\n        );\n\n        // Cannot start capturing at this time\n        if (!preDrag) {\n          return;\n        }\n\n        // we are consuming the event\n        event.preventDefault();\n        let isCapturing: boolean = true;\n\n        // There is no pending period for a keyboard drag\n        // We can lift immediately\n        const actions: SnapDragActions = preDrag.snapLift();\n\n        // unbind this listener\n        unbindEventsRef.current();\n\n        // setup our function to end everything\n        function stop() {\n          invariant(\n            isCapturing,\n            'Cannot stop capturing a keyboard drag when not capturing',\n          );\n          isCapturing = false;\n\n          // unbind dragging bindings\n          unbindEventsRef.current();\n          // start listening for capture again\n          // eslint-disable-next-line no-use-before-define\n          listenForCapture();\n        }\n\n        // bind dragging listeners\n        unbindEventsRef.current = bindEvents(\n          window,\n          getDraggingBindings(actions, stop),\n          { capture: true, passive: false },\n        );\n      },\n    }),\n    // not including startPendingDrag as it is not defined initially\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [api],\n  );\n\n  const listenForCapture = useCallback(\n    function tryStartCapture() {\n      const options: EventOptions = {\n        passive: false,\n        capture: true,\n      };\n\n      unbindEventsRef.current = bindEvents(\n        window,\n        [startCaptureBinding],\n        options,\n      );\n    },\n    [startCaptureBinding],\n  );\n\n  useLayoutEffect(\n    function mount() {\n      listenForCapture();\n\n      // kill any pending window events when unmounting\n      return function unmount() {\n        unbindEventsRef.current();\n      };\n    },\n    [listenForCapture],\n  );\n}\n"
  },
  {
    "path": "src/view/use-sensor-marshal/sensors/use-mouse-sensor.js",
    "content": "// @flow\nimport { useRef } from 'react';\nimport { useCallback, useMemo } from 'use-memo-one';\nimport type { Position } from 'css-box-model';\nimport { invariant } from '../../../invariant';\nimport type {\n  PreDragActions,\n  FluidDragActions,\n  DraggableId,\n  SensorAPI,\n  DraggableOptions,\n} from '../../../types';\nimport type {\n  EventBinding,\n  EventOptions,\n} from '../../event-bindings/event-types';\nimport bindEvents from '../../event-bindings/bind-events';\nimport * as keyCodes from '../../key-codes';\nimport preventStandardKeyEvents from './util/prevent-standard-key-events';\nimport supportedPageVisibilityEventName from './util/supported-page-visibility-event-name';\nimport useLayoutEffect from '../../use-isomorphic-layout-effect';\nimport { noop } from '../../../empty';\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button\nexport const primaryButton: number = 0;\nexport const sloppyClickThreshold: number = 5;\n\nfunction isSloppyClickThresholdExceeded(\n  original: Position,\n  current: Position,\n): boolean {\n  return (\n    Math.abs(current.x - original.x) >= sloppyClickThreshold ||\n    Math.abs(current.y - original.y) >= sloppyClickThreshold\n  );\n}\ntype Idle = {|\n  type: 'IDLE',\n|};\n\ntype Pending = {|\n  type: 'PENDING',\n  point: Position,\n  actions: PreDragActions,\n|};\n\ntype Dragging = {|\n  type: 'DRAGGING',\n  actions: FluidDragActions,\n|};\n\ntype Phase = Idle | Pending | Dragging;\n\nconst idle: Idle = { type: 'IDLE' };\n\ntype GetCaptureArgs = {|\n  cancel: () => void,\n  completed: () => void,\n  getPhase: () => Phase,\n  setPhase: (phase: Phase) => void,\n|};\n\nfunction getCaptureBindings({\n  cancel,\n  completed,\n  getPhase,\n  setPhase,\n}: GetCaptureArgs): EventBinding[] {\n  return [\n    {\n      eventName: 'mousemove',\n      fn: (event: MouseEvent) => {\n        const { button, clientX, clientY } = event;\n        if (button !== primaryButton) {\n          return;\n        }\n\n        const point: Position = {\n          x: clientX,\n          y: clientY,\n        };\n\n        const phase: Phase = getPhase();\n\n        // Already dragging\n        if (phase.type === 'DRAGGING') {\n          // preventing default as we are using this event\n          event.preventDefault();\n          phase.actions.move(point);\n          return;\n        }\n\n        // There should be a pending drag at this point\n        invariant(phase.type === 'PENDING', 'Cannot be IDLE');\n        const pending: Position = phase.point;\n\n        // threshold not yet exceeded\n        if (!isSloppyClickThresholdExceeded(pending, point)) {\n          return;\n        }\n\n        // preventing default as we are using this event\n        event.preventDefault();\n\n        // Lifting at the current point to prevent the draggable item from\n        // jumping by the sloppyClickThreshold\n        const actions: FluidDragActions = phase.actions.fluidLift(point);\n\n        setPhase({\n          type: 'DRAGGING',\n          actions,\n        });\n      },\n    },\n    {\n      eventName: 'mouseup',\n      fn: (event: MouseEvent) => {\n        const phase: Phase = getPhase();\n\n        if (phase.type !== 'DRAGGING') {\n          cancel();\n          return;\n        }\n\n        // preventing default as we are using this event\n        event.preventDefault();\n        phase.actions.drop({ shouldBlockNextClick: true });\n        completed();\n      },\n    },\n    {\n      eventName: 'mousedown',\n      fn: (event: MouseEvent) => {\n        // this can happen during a drag when the user clicks a button\n        // other than the primary mouse button\n        if (getPhase().type === 'DRAGGING') {\n          event.preventDefault();\n        }\n\n        cancel();\n      },\n    },\n    {\n      eventName: 'keydown',\n      fn: (event: KeyboardEvent) => {\n        const phase: Phase = getPhase();\n        // Abort if any keystrokes while a drag is pending\n        if (phase.type === 'PENDING') {\n          cancel();\n          return;\n        }\n\n        // cancelling a drag\n        if (event.keyCode === keyCodes.escape) {\n          event.preventDefault();\n          cancel();\n          return;\n        }\n\n        preventStandardKeyEvents(event);\n      },\n    },\n    {\n      eventName: 'resize',\n      fn: cancel,\n    },\n    {\n      eventName: 'scroll',\n      // kill a pending drag if there is a window scroll\n      options: { passive: true, capture: false },\n      fn: () => {\n        if (getPhase().type === 'PENDING') {\n          cancel();\n        }\n      },\n    },\n\n    // Need to opt out of dragging if the user is a force press\n    // Only for safari which has decided to introduce its own custom way of doing things\n    // https://developer.apple.com/library/content/documentation/AppleApplications/Conceptual/SafariJSProgTopics/RespondingtoForceTouchEventsfromJavaScript.html\n    {\n      eventName: 'webkitmouseforcedown',\n      // it is considered a indirect cancel so we do not\n      // prevent default in any situation.\n      fn: (event: Event) => {\n        const phase: Phase = getPhase();\n        invariant(phase.type !== 'IDLE', 'Unexpected phase');\n\n        if (phase.actions.shouldRespectForcePress()) {\n          cancel();\n          return;\n        }\n\n        // This technically doesn't do anything.\n        // It won't do anything if `webkitmouseforcewillbegin` is prevented.\n        // But it is a good signal that we want to opt out of this\n\n        event.preventDefault();\n      },\n    },\n    // Cancel on page visibility change\n    {\n      eventName: supportedPageVisibilityEventName,\n      fn: cancel,\n    },\n  ];\n}\n\nexport default function useMouseSensor(api: SensorAPI) {\n  const phaseRef = useRef<Phase>(idle);\n  const unbindEventsRef = useRef<() => void>(noop);\n\n  const startCaptureBinding: EventBinding = useMemo(\n    () => ({\n      eventName: 'mousedown',\n      fn: function onMouseDown(event: MouseEvent) {\n        // Event already used\n        if (event.defaultPrevented) {\n          return;\n        }\n        // only starting a drag if dragging with the primary mouse button\n        if (event.button !== primaryButton) {\n          return;\n        }\n\n        // Do not start a drag if any modifier key is pressed\n        if (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) {\n          return;\n        }\n\n        const draggableId: ?DraggableId = api.findClosestDraggableId(event);\n\n        if (!draggableId) {\n          return;\n        }\n\n        const actions: ?PreDragActions = api.tryGetLock(\n          draggableId,\n          // stop is defined later\n          // eslint-disable-next-line no-use-before-define\n          stop,\n          { sourceEvent: event },\n        );\n\n        if (!actions) {\n          return;\n        }\n\n        // consuming the event\n        event.preventDefault();\n\n        const point: Position = {\n          x: event.clientX,\n          y: event.clientY,\n        };\n\n        // unbind this listener\n        unbindEventsRef.current();\n        // using this function before it is defined as their is a circular usage pattern\n        // eslint-disable-next-line no-use-before-define\n        startPendingDrag(actions, point);\n      },\n    }),\n    // not including startPendingDrag as it is not defined initially\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [api],\n  );\n\n  const preventForcePressBinding: EventBinding = useMemo(\n    () => ({\n      eventName: 'webkitmouseforcewillbegin',\n      fn: (event: Event) => {\n        if (event.defaultPrevented) {\n          return;\n        }\n\n        const id: ?DraggableId = api.findClosestDraggableId(event);\n\n        if (!id) {\n          return;\n        }\n\n        const options: ?DraggableOptions = api.findOptionsForDraggable(id);\n\n        if (!options) {\n          return;\n        }\n\n        if (options.shouldRespectForcePress) {\n          return;\n        }\n\n        if (!api.canGetLock(id)) {\n          return;\n        }\n\n        event.preventDefault();\n      },\n    }),\n    [api],\n  );\n\n  const listenForCapture = useCallback(\n    function listenForCapture() {\n      const options: EventOptions = {\n        passive: false,\n        capture: true,\n      };\n\n      unbindEventsRef.current = bindEvents(\n        window,\n        [preventForcePressBinding, startCaptureBinding],\n        options,\n      );\n    },\n    [preventForcePressBinding, startCaptureBinding],\n  );\n\n  const stop = useCallback(() => {\n    const current: Phase = phaseRef.current;\n    if (current.type === 'IDLE') {\n      return;\n    }\n\n    phaseRef.current = idle;\n    unbindEventsRef.current();\n\n    listenForCapture();\n  }, [listenForCapture]);\n\n  const cancel = useCallback(() => {\n    const phase: Phase = phaseRef.current;\n    stop();\n    if (phase.type === 'DRAGGING') {\n      phase.actions.cancel({ shouldBlockNextClick: true });\n    }\n    if (phase.type === 'PENDING') {\n      phase.actions.abort();\n    }\n  }, [stop]);\n\n  const bindCapturingEvents = useCallback(\n    function bindCapturingEvents() {\n      const options = { capture: true, passive: false };\n      const bindings: EventBinding[] = getCaptureBindings({\n        cancel,\n        completed: stop,\n        getPhase: () => phaseRef.current,\n        setPhase: (phase: Phase) => {\n          phaseRef.current = phase;\n        },\n      });\n\n      unbindEventsRef.current = bindEvents(window, bindings, options);\n    },\n    [cancel, stop],\n  );\n\n  const startPendingDrag = useCallback(\n    function startPendingDrag(actions: PreDragActions, point: Position) {\n      invariant(\n        phaseRef.current.type === 'IDLE',\n        'Expected to move from IDLE to PENDING drag',\n      );\n      phaseRef.current = {\n        type: 'PENDING',\n        point,\n        actions,\n      };\n      bindCapturingEvents();\n    },\n    [bindCapturingEvents],\n  );\n\n  useLayoutEffect(\n    function mount() {\n      listenForCapture();\n\n      // kill any pending window events when unmounting\n      return function unmount() {\n        unbindEventsRef.current();\n      };\n    },\n    [listenForCapture],\n  );\n}\n"
  },
  {
    "path": "src/view/use-sensor-marshal/sensors/use-touch-sensor.js",
    "content": "// @flow\nimport { useRef } from 'react';\nimport { useCallback, useMemo } from 'use-memo-one';\nimport type { Position } from 'css-box-model';\nimport { invariant } from '../../../invariant';\nimport type {\n  DraggableId,\n  SensorAPI,\n  PreDragActions,\n  FluidDragActions,\n} from '../../../types';\nimport type {\n  EventBinding,\n  EventOptions,\n} from '../../event-bindings/event-types';\nimport bindEvents from '../../event-bindings/bind-events';\nimport * as keyCodes from '../../key-codes';\nimport supportedPageVisibilityEventName from './util/supported-page-visibility-event-name';\nimport { noop } from '../../../empty';\nimport useLayoutEffect from '../../use-isomorphic-layout-effect';\n\ntype TouchWithForce = Touch & {\n  force: number,\n};\n\ntype Idle = {|\n  type: 'IDLE',\n|};\n\ntype Pending = {|\n  type: 'PENDING',\n  point: Position,\n  actions: PreDragActions,\n  longPressTimerId: TimeoutID,\n|};\n\ntype Dragging = {|\n  type: 'DRAGGING',\n  actions: FluidDragActions,\n  hasMoved: boolean,\n|};\n\ntype Phase = Idle | Pending | Dragging;\n\nconst idle: Idle = { type: 'IDLE' };\n// Decreased from 150 as a work around for an issue for forcepress on iOS\n// https://github.com/atlassian/react-beautiful-dnd/issues/1401\nexport const timeForLongPress: number = 120;\nexport const forcePressThreshold: number = 0.15;\n\ntype GetBindingArgs = {|\n  cancel: () => void,\n  completed: () => void,\n  getPhase: () => Phase,\n|};\n\nfunction getWindowBindings({\n  cancel,\n  getPhase,\n}: GetBindingArgs): EventBinding[] {\n  return [\n    // If the orientation of the device changes - kill the drag\n    // https://davidwalsh.name/orientation-change\n    {\n      eventName: 'orientationchange',\n      fn: cancel,\n    },\n    // some devices fire resize if the orientation changes\n    {\n      eventName: 'resize',\n      fn: cancel,\n    },\n    // Long press can bring up a context menu\n    // need to opt out of this behavior\n    {\n      eventName: 'contextmenu',\n      fn: (event: Event) => {\n        // always opting out of context menu events\n        event.preventDefault();\n      },\n    },\n    // On some devices it is possible to have a touch interface with a keyboard.\n    // On any keyboard event we cancel a touch drag\n    {\n      eventName: 'keydown',\n      fn: (event: KeyboardEvent) => {\n        if (getPhase().type !== 'DRAGGING') {\n          cancel();\n          return;\n        }\n\n        // direct cancel: we are preventing the default action\n        // indirect cancel: we are not preventing the default action\n\n        // escape is a direct cancel\n        if (event.keyCode === keyCodes.escape) {\n          event.preventDefault();\n        }\n        cancel();\n      },\n    },\n    // Cancel on page visibility change\n    {\n      eventName: supportedPageVisibilityEventName,\n      fn: cancel,\n    },\n  ];\n}\n\n// All of the touch events get applied to the drag handle of the touch interaction\n// This plays well with the event.target being unmounted during a drag\nfunction getHandleBindings({\n  cancel,\n  completed,\n  getPhase,\n}: GetBindingArgs): EventBinding[] {\n  return [\n    {\n      eventName: 'touchmove',\n      // Opting out of passive touchmove (default) so as to prevent scrolling while moving\n      // Not worried about performance as effect of move is throttled in requestAnimationFrame\n      // Using `capture: false` due to a recent horrible firefox bug: https://twitter.com/alexandereardon/status/1125904207184187393\n      options: { capture: false },\n      fn: (event: TouchEvent) => {\n        const phase: Phase = getPhase();\n        // Drag has not yet started and we are waiting for a long press.\n        if (phase.type !== 'DRAGGING') {\n          cancel();\n          return;\n        }\n\n        // At this point we are dragging\n        phase.hasMoved = true;\n\n        const { clientX, clientY } = event.touches[0];\n\n        const point: Position = {\n          x: clientX,\n          y: clientY,\n        };\n\n        // We need to prevent the default event in order to block native scrolling\n        // Also because we are using it as part of a drag we prevent the default action\n        // as a sign that we are using the event\n        event.preventDefault();\n        phase.actions.move(point);\n      },\n    },\n    {\n      eventName: 'touchend',\n      fn: (event: TouchEvent) => {\n        const phase: Phase = getPhase();\n        // drag had not started yet - do not prevent the default action\n        if (phase.type !== 'DRAGGING') {\n          cancel();\n          return;\n        }\n\n        // ending the drag\n        event.preventDefault();\n        phase.actions.drop({ shouldBlockNextClick: true });\n        completed();\n      },\n    },\n    {\n      eventName: 'touchcancel',\n      fn: (event: TouchEvent) => {\n        // drag had not started yet - do not prevent the default action\n        if (getPhase().type !== 'DRAGGING') {\n          cancel();\n          return;\n        }\n\n        // already dragging - this event is directly ending a drag\n        event.preventDefault();\n        cancel();\n      },\n    },\n    // Need to opt out of dragging if the user is a force press\n    // Only for webkit which has decided to introduce its own custom way of doing things\n    // https://developer.apple.com/library/content/documentation/AppleApplications/Conceptual/SafariJSProgTopics/RespondingtoForceTouchEventsfromJavaScript.html\n    {\n      eventName: 'touchforcechange',\n      fn: (event: TouchEvent) => {\n        const phase: Phase = getPhase();\n\n        // needed to use phase.actions\n        invariant(phase.type !== 'IDLE');\n\n        // This is not fantastic logic, but it is done to account for\n        // and issue with forcepress on iOS\n        // Calling event.preventDefault() will currently opt out of scrolling and clicking\n        // https://github.com/atlassian/react-beautiful-dnd/issues/1401\n\n        const touch: ?TouchWithForce = (event.touches[0]: any);\n\n        if (!touch) {\n          return;\n        }\n\n        const isForcePress: boolean = touch.force >= forcePressThreshold;\n\n        if (!isForcePress) {\n          return;\n        }\n\n        const shouldRespect: boolean = phase.actions.shouldRespectForcePress();\n\n        if (phase.type === 'PENDING') {\n          if (shouldRespect) {\n            cancel();\n          }\n          // If not respecting we just let the event go through\n          // It will not have an impact on the browser until\n          // there has been a sufficient time ellapsed\n          return;\n        }\n\n        // 'DRAGGING'\n\n        if (shouldRespect) {\n          if (phase.hasMoved) {\n            // After the user has moved we do not allow the dragging item to be force pressed\n            // This prevents strange behaviour such as a link preview opening mid drag\n            event.preventDefault();\n            return;\n          }\n          // indirect cancel\n          cancel();\n          return;\n        }\n\n        // not respecting during a drag\n        event.preventDefault();\n      },\n    },\n    // Cancel on page visibility change\n    {\n      eventName: supportedPageVisibilityEventName,\n      fn: cancel,\n    },\n    // Not adding a cancel on touchstart as this handler will pick up the initial touchstart event\n  ];\n}\n\nexport default function useTouchSensor(api: SensorAPI) {\n  const phaseRef = useRef<Phase>(idle);\n  const unbindEventsRef = useRef<() => void>(noop);\n\n  const getPhase = useCallback(function getPhase(): Phase {\n    return phaseRef.current;\n  }, []);\n\n  const setPhase = useCallback(function setPhase(phase: Phase) {\n    phaseRef.current = phase;\n  }, []);\n\n  const startCaptureBinding: EventBinding = useMemo(\n    () => ({\n      eventName: 'touchstart',\n      fn: function onTouchStart(event: TouchEvent) {\n        // Event already used by something else\n        if (event.defaultPrevented) {\n          return;\n        }\n\n        // We need to NOT call event.preventDefault() so as to maintain as much standard\n        // browser interactions as possible.\n        // This includes navigation on anchors which we want to preserve\n\n        const draggableId: ?DraggableId = api.findClosestDraggableId(event);\n\n        if (!draggableId) {\n          return;\n        }\n\n        const actions: ?PreDragActions = api.tryGetLock(\n          draggableId,\n          // eslint-disable-next-line no-use-before-define\n          stop,\n          { sourceEvent: event },\n        );\n\n        // could not start a drag\n        if (!actions) {\n          return;\n        }\n\n        const touch: Touch = event.touches[0];\n        const { clientX, clientY } = touch;\n        const point: Position = {\n          x: clientX,\n          y: clientY,\n        };\n\n        // unbind this event handler\n        unbindEventsRef.current();\n\n        // eslint-disable-next-line no-use-before-define\n        startPendingDrag(actions, point);\n      },\n    }),\n    // not including stop or startPendingDrag as it is not defined initially\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [api],\n  );\n\n  const listenForCapture = useCallback(\n    function listenForCapture() {\n      const options: EventOptions = {\n        capture: true,\n        passive: false,\n      };\n\n      unbindEventsRef.current = bindEvents(\n        window,\n        [startCaptureBinding],\n        options,\n      );\n    },\n    [startCaptureBinding],\n  );\n\n  const stop = useCallback(() => {\n    const current: Phase = phaseRef.current;\n    if (current.type === 'IDLE') {\n      return;\n    }\n\n    // aborting any pending drag\n    if (current.type === 'PENDING') {\n      clearTimeout(current.longPressTimerId);\n    }\n\n    setPhase(idle);\n    unbindEventsRef.current();\n\n    listenForCapture();\n  }, [listenForCapture, setPhase]);\n\n  const cancel = useCallback(() => {\n    const phase: Phase = phaseRef.current;\n    stop();\n    if (phase.type === 'DRAGGING') {\n      phase.actions.cancel({ shouldBlockNextClick: true });\n    }\n    if (phase.type === 'PENDING') {\n      phase.actions.abort();\n    }\n  }, [stop]);\n\n  const bindCapturingEvents = useCallback(\n    function bindCapturingEvents() {\n      const options: EventOptions = { capture: true, passive: false };\n      const args: GetBindingArgs = {\n        cancel,\n        completed: stop,\n        getPhase,\n      };\n\n      // In prior versions of iOS it was required that touch listeners be added\n      // to the handle to work correctly (even if the handle got removed in a portal / clone)\n      // In the latest version it appears to be the opposite: for reparenting to work\n      // the events need to be attached to the window.\n      // For now i'll keep these two functions seperate in case we need to swap it back again\n      // Old behaviour:\n      // https://gist.github.com/parris/dda613e3ae78f14eb2dc9fa0f4bfce3d\n      // https://stackoverflow.com/questions/33298828/touch-move-event-dont-fire-after-touch-start-target-is-removed\n      const unbindTarget = bindEvents(window, getHandleBindings(args), options);\n      const unbindWindow = bindEvents(window, getWindowBindings(args), options);\n\n      unbindEventsRef.current = function unbindAll() {\n        unbindTarget();\n        unbindWindow();\n      };\n    },\n    [cancel, getPhase, stop],\n  );\n\n  const startDragging = useCallback(\n    function startDragging() {\n      const phase: Phase = getPhase();\n      invariant(\n        phase.type === 'PENDING',\n        `Cannot start dragging from phase ${phase.type}`,\n      );\n\n      const actions: FluidDragActions = phase.actions.fluidLift(phase.point);\n\n      setPhase({\n        type: 'DRAGGING',\n        actions,\n        hasMoved: false,\n      });\n    },\n    [getPhase, setPhase],\n  );\n\n  const startPendingDrag = useCallback(\n    function startPendingDrag(actions: PreDragActions, point: Position) {\n      invariant(\n        getPhase().type === 'IDLE',\n        'Expected to move from IDLE to PENDING drag',\n      );\n\n      const longPressTimerId: TimeoutID = setTimeout(\n        startDragging,\n        timeForLongPress,\n      );\n\n      setPhase({\n        type: 'PENDING',\n        point,\n        actions,\n        longPressTimerId,\n      });\n\n      bindCapturingEvents();\n    },\n    [bindCapturingEvents, getPhase, setPhase, startDragging],\n  );\n\n  useLayoutEffect(\n    function mount() {\n      listenForCapture();\n\n      return function unmount() {\n        // remove any existing listeners\n        unbindEventsRef.current();\n\n        // need to kill any pending drag start timer\n        const phase: Phase = getPhase();\n        if (phase.type === 'PENDING') {\n          clearTimeout(phase.longPressTimerId);\n          setPhase(idle);\n        }\n      };\n    },\n    [getPhase, listenForCapture, setPhase],\n  );\n\n  // This is needed for safari\n  // Simply adding a non capture, non passive 'touchmove' listener.\n  // This forces event.preventDefault() in dynamically added\n  // touchmove event handlers to actually work\n  // https://github.com/atlassian/react-beautiful-dnd/issues/1374\n  useLayoutEffect(function webkitHack() {\n    const unbind = bindEvents(window, [\n      {\n        eventName: 'touchmove',\n        // using a new noop function for each usage as a single `removeEventListener()`\n        // call will remove all handlers with the same reference\n        // https://codesandbox.io/s/removing-multiple-handlers-with-same-reference-fxe15\n        fn: () => {},\n        options: { capture: false, passive: false },\n      },\n    ]);\n\n    return unbind;\n  }, []);\n}\n"
  },
  {
    "path": "src/view/use-sensor-marshal/sensors/util/prevent-standard-key-events.js",
    "content": "// @flow\nimport * as keyCodes from '../../../key-codes';\n\ntype KeyMap = {\n  [key: number]: true,\n};\n\nconst preventedKeys: KeyMap = {\n  // submission\n  [keyCodes.enter]: true,\n  // tabbing\n  [keyCodes.tab]: true,\n};\n\nexport default (event: KeyboardEvent) => {\n  if (preventedKeys[event.keyCode]) {\n    event.preventDefault();\n  }\n};\n"
  },
  {
    "path": "src/view/use-sensor-marshal/sensors/util/supported-page-visibility-event-name.js",
    "content": "// @flow\nimport { find } from '../../../../native-with-fallback';\n\nconst supportedEventName: string = ((): string => {\n  const base: string = 'visibilitychange';\n\n  // Server side rendering\n  if (typeof document === 'undefined') {\n    return base;\n  }\n\n  // See https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API\n  const candidates: string[] = [\n    base,\n    `ms${base}`,\n    `webkit${base}`,\n    `moz${base}`,\n    `o${base}`,\n  ];\n\n  const supported: ?string = find(\n    candidates,\n    (eventName: string): boolean => `on${eventName}` in document,\n  );\n\n  return supported || base;\n})();\n\nexport default supportedEventName;\n"
  },
  {
    "path": "src/view/use-sensor-marshal/use-sensor-marshal.js",
    "content": "// @flow\nimport rafSchd from 'raf-schd';\nimport { useState } from 'react';\nimport { useCallback, useMemo } from 'use-memo-one';\nimport type { Position } from 'css-box-model';\nimport { invariant } from '../../invariant';\nimport type {\n  ContextId,\n  State,\n  Sensor,\n  StopDragOptions,\n  PreDragActions,\n  FluidDragActions,\n  SnapDragActions,\n  DraggableId,\n  SensorAPI,\n  TryGetLock,\n  TryGetLockOptions,\n  DraggableOptions,\n} from '../../types';\nimport create, { type Lock, type LockAPI } from './lock';\nimport type { Store, Action } from '../../state/store-types';\nimport canStartDrag from '../../state/can-start-drag';\nimport {\n  move as moveAction,\n  moveUp as moveUpAction,\n  moveRight as moveRightAction,\n  moveDown as moveDownAction,\n  moveLeft as moveLeftAction,\n  drop as dropAction,\n  lift as liftAction,\n  type LiftArgs as LiftActionArgs,\n  flush,\n} from '../../state/action-creators';\nimport type {\n  Registry,\n  DraggableEntry,\n} from '../../state/registry/registry-types';\nimport useMouseSensor from './sensors/use-mouse-sensor';\nimport useKeyboardSensor from './sensors/use-keyboard-sensor';\nimport useTouchSensor from './sensors/use-touch-sensor';\nimport useValidateSensorHooks from './use-validate-sensor-hooks';\nimport isEventInInteractiveElement from './is-event-in-interactive-element';\nimport getBorderBoxCenterPosition from '../get-border-box-center-position';\nimport { warning } from '../../dev-warning';\nimport useLayoutEffect from '../use-isomorphic-layout-effect';\nimport { noop } from '../../empty';\nimport findClosestDraggableIdFromEvent from './find-closest-draggable-id-from-event';\nimport findDraggable from '../get-elements/find-draggable';\nimport bindEvents from '../event-bindings/bind-events';\n\nfunction preventDefault(event: Event) {\n  event.preventDefault();\n}\n\ntype LockPhase = 'PRE_DRAG' | 'DRAGGING' | 'COMPLETED';\n\ntype IsActiveArgs = {|\n  expected: LockPhase,\n  phase: LockPhase,\n  isLockActive: () => boolean,\n  shouldWarn: boolean,\n|};\n\nfunction isActive({\n  expected,\n  phase,\n  isLockActive,\n  shouldWarn,\n}: IsActiveArgs): boolean {\n  // lock is no longer active\n  if (!isLockActive()) {\n    if (shouldWarn) {\n      warning(`\n        Cannot perform action.\n        The sensor no longer has an action lock.\n\n        Tips:\n\n        - Throw away your action handlers when forceStop() is called\n        - Check actions.isActive() if you really need to\n      `);\n    }\n    return false;\n  }\n  // wrong phase\n  if (expected !== phase) {\n    if (shouldWarn) {\n      warning(`\n        Cannot perform action.\n        The actions you used belong to an outdated phase\n\n        Current phase: ${expected}\n        You called an action from outdated phase: ${phase}\n\n        Tips:\n\n        - Do not use preDragActions actions after calling preDragActions.lift()\n      `);\n    }\n    return false;\n  }\n  return true;\n}\n\ntype CanStartArgs = {|\n  lockAPI: LockAPI,\n  registry: Registry,\n  store: Store,\n  draggableId: DraggableId,\n|};\n\nfunction canStart({\n  lockAPI,\n  store,\n  registry,\n  draggableId,\n}: CanStartArgs): boolean {\n  // lock is already claimed - cannot start\n  if (lockAPI.isClaimed()) {\n    return false;\n  }\n\n  const entry: ?DraggableEntry = registry.draggable.findById(draggableId);\n\n  if (!entry) {\n    warning(`Unable to find draggable with id: ${draggableId}`);\n    return false;\n  }\n\n  // draggable is not enabled - cannot start\n  if (!entry.options.isEnabled) {\n    return false;\n  }\n\n  // Application might now allow dragging right now\n  if (!canStartDrag(store.getState(), draggableId)) {\n    return false;\n  }\n\n  return true;\n}\n\ntype TryStartArgs = {|\n  lockAPI: LockAPI,\n  contextId: ContextId,\n  registry: Registry,\n  store: Store,\n  draggableId: DraggableId,\n  forceSensorStop: ?() => void,\n  sourceEvent: ?Event,\n|};\n\nfunction tryStart({\n  lockAPI,\n  contextId,\n  store,\n  registry,\n  draggableId,\n  forceSensorStop,\n  sourceEvent,\n}: TryStartArgs): ?PreDragActions {\n  const shouldStart: boolean = canStart({\n    lockAPI,\n    store,\n    registry,\n    draggableId,\n  });\n\n  if (!shouldStart) {\n    return null;\n  }\n\n  const entry: DraggableEntry = registry.draggable.getById(draggableId);\n  const el: ?HTMLElement = findDraggable(contextId, entry.descriptor.id);\n\n  if (!el) {\n    warning(`Unable to find draggable element with id: ${draggableId}`);\n    return null;\n  }\n\n  // Do not allow dragging from interactive elements\n  if (\n    sourceEvent &&\n    !entry.options.canDragInteractiveElements &&\n    isEventInInteractiveElement(el, sourceEvent)\n  ) {\n    return null;\n  }\n\n  // claiming lock\n  const lock: Lock = lockAPI.claim(forceSensorStop || noop);\n  let phase: LockPhase = 'PRE_DRAG';\n\n  function getShouldRespectForcePress(): boolean {\n    // not looking up the entry as it might have been removed in a virtual list\n    return entry.options.shouldRespectForcePress;\n  }\n\n  function isLockActive(): boolean {\n    return lockAPI.isActive(lock);\n  }\n\n  function tryDispatch(expected: LockPhase, getAction: () => Action): void {\n    if (isActive({ expected, phase, isLockActive, shouldWarn: true })) {\n      store.dispatch(getAction());\n    }\n  }\n\n  const tryDispatchWhenDragging = tryDispatch.bind(null, 'DRAGGING');\n\n  type LiftArgs = {|\n    liftActionArgs: LiftActionArgs,\n    cleanup: () => void,\n    actions: Object,\n  |};\n\n  function lift(args: LiftArgs) {\n    function completed() {\n      lockAPI.release();\n      phase = 'COMPLETED';\n    }\n    // Double lift = bad\n    if (phase !== 'PRE_DRAG') {\n      completed();\n      invariant(phase === 'PRE_DRAG', `Cannot lift in phase ${phase}`);\n    }\n\n    store.dispatch(liftAction(args.liftActionArgs));\n\n    // We are now in the DRAGGING phase\n    phase = 'DRAGGING';\n\n    function finish(\n      reason: 'CANCEL' | 'DROP',\n      options?: StopDragOptions = { shouldBlockNextClick: false },\n    ) {\n      args.cleanup();\n\n      // block next click if requested\n      if (options.shouldBlockNextClick) {\n        const unbind = bindEvents(window, [\n          {\n            eventName: 'click',\n            fn: preventDefault,\n            options: {\n              // only blocking a single click\n              once: true,\n              passive: false,\n              capture: true,\n            },\n          },\n        ]);\n        // Sometimes the click is swallowed, such as when there is reparenting\n        // The click event (in the message queue) will occur before the next setTimeout expiry\n        // https://codesandbox.io/s/click-behaviour-pkfk2\n        setTimeout(unbind);\n      }\n\n      // releasing\n      completed();\n      store.dispatch(dropAction({ reason }));\n    }\n\n    return {\n      isActive: () =>\n        isActive({\n          expected: 'DRAGGING',\n          phase,\n          isLockActive,\n          // Do not want to want warnings for boolean checks\n          shouldWarn: false,\n        }),\n      shouldRespectForcePress: getShouldRespectForcePress,\n      drop: (options?: StopDragOptions) => finish('DROP', options),\n      cancel: (options?: StopDragOptions) => finish('CANCEL', options),\n      ...args.actions,\n    };\n  }\n\n  function fluidLift(clientSelection: Position): FluidDragActions {\n    const move = rafSchd((client: Position) => {\n      tryDispatchWhenDragging(() => moveAction({ client }));\n    });\n\n    const api = lift({\n      liftActionArgs: {\n        id: draggableId,\n        clientSelection,\n        movementMode: 'FLUID',\n      },\n      cleanup: () => move.cancel(),\n      actions: { move },\n    });\n\n    return {\n      ...api,\n      move,\n    };\n  }\n\n  function snapLift(): SnapDragActions {\n    const actions = {\n      moveUp: () => tryDispatchWhenDragging(moveUpAction),\n      moveRight: () => tryDispatchWhenDragging(moveRightAction),\n      moveDown: () => tryDispatchWhenDragging(moveDownAction),\n      moveLeft: () => tryDispatchWhenDragging(moveLeftAction),\n    };\n\n    return lift({\n      liftActionArgs: {\n        id: draggableId,\n        clientSelection: getBorderBoxCenterPosition(el),\n        movementMode: 'SNAP',\n      },\n      cleanup: noop,\n      actions,\n    });\n  }\n\n  function abortPreDrag() {\n    const shouldRelease: boolean = isActive({\n      expected: 'PRE_DRAG',\n      phase,\n      isLockActive,\n      shouldWarn: true,\n    });\n\n    if (shouldRelease) {\n      lockAPI.release();\n    }\n  }\n\n  const preDrag: PreDragActions = {\n    isActive: () =>\n      isActive({\n        expected: 'PRE_DRAG',\n        phase,\n        isLockActive,\n        // Do not want to want warnings for boolean checks\n        shouldWarn: false,\n      }),\n    shouldRespectForcePress: getShouldRespectForcePress,\n    fluidLift,\n    snapLift,\n    abort: abortPreDrag,\n  };\n\n  return preDrag;\n}\n\ntype SensorMarshalArgs = {|\n  contextId: ContextId,\n  registry: Registry,\n  store: Store,\n  customSensors: ?(Sensor[]),\n  enableDefaultSensors: boolean,\n|};\n\n// default sensors are now exported to library consumers\nconst defaultSensors: Sensor[] = [\n  useMouseSensor,\n  useKeyboardSensor,\n  useTouchSensor,\n];\n\nexport default function useSensorMarshal({\n  contextId,\n  store,\n  registry,\n  customSensors,\n  enableDefaultSensors,\n}: SensorMarshalArgs) {\n  const useSensors: Sensor[] = [\n    ...(enableDefaultSensors ? defaultSensors : []),\n    ...(customSensors || []),\n  ];\n  const lockAPI: LockAPI = useState(() => create())[0];\n\n  const tryAbandonLock = useCallback(\n    function tryAbandonLock(previous: State, current: State) {\n      if (previous.isDragging && !current.isDragging) {\n        lockAPI.tryAbandon();\n      }\n    },\n    [lockAPI],\n  );\n\n  // We need to abort any capturing if there is no longer a drag\n  useLayoutEffect(\n    function listenToStore() {\n      let previous: State = store.getState();\n      const unsubscribe = store.subscribe(() => {\n        const current: State = store.getState();\n        tryAbandonLock(previous, current);\n        previous = current;\n      });\n\n      // unsubscribe from store when unmounting\n      return unsubscribe;\n    },\n    [lockAPI, store, tryAbandonLock],\n  );\n\n  // abort any lock on unmount\n  useLayoutEffect(() => {\n    return lockAPI.tryAbandon;\n  }, [lockAPI.tryAbandon]);\n\n  const canGetLock = useCallback(\n    (draggableId: DraggableId): boolean => {\n      return canStart({\n        lockAPI,\n        registry,\n        store,\n        draggableId,\n      });\n    },\n    [lockAPI, registry, store],\n  );\n\n  const tryGetLock: TryGetLock = useCallback(\n    (\n      draggableId: DraggableId,\n      forceStop?: () => void,\n      options?: TryGetLockOptions,\n    ): ?PreDragActions =>\n      tryStart({\n        lockAPI,\n        registry,\n        contextId,\n        store,\n        draggableId,\n        forceSensorStop: forceStop,\n        sourceEvent:\n          options && options.sourceEvent ? options.sourceEvent : null,\n      }),\n    [contextId, lockAPI, registry, store],\n  );\n\n  const findClosestDraggableId = useCallback(\n    (event: Event): ?DraggableId =>\n      findClosestDraggableIdFromEvent(contextId, event),\n    [contextId],\n  );\n\n  const findOptionsForDraggable = useCallback(\n    (id: DraggableId): ?DraggableOptions => {\n      const entry: ?DraggableEntry = registry.draggable.findById(id);\n      return entry ? entry.options : null;\n    },\n    [registry.draggable],\n  );\n\n  const tryReleaseLock = useCallback(\n    function tryReleaseLock() {\n      if (!lockAPI.isClaimed()) {\n        return;\n      }\n\n      lockAPI.tryAbandon();\n\n      if (store.getState().phase !== 'IDLE') {\n        store.dispatch(flush());\n      }\n    },\n    [lockAPI, store],\n  );\n  const isLockClaimed = useCallback(lockAPI.isClaimed, [lockAPI]);\n\n  const api: SensorAPI = useMemo(\n    () => ({\n      canGetLock,\n      tryGetLock,\n      findClosestDraggableId,\n      findOptionsForDraggable,\n      tryReleaseLock,\n      isLockClaimed,\n    }),\n    [\n      canGetLock,\n      tryGetLock,\n      findClosestDraggableId,\n      findOptionsForDraggable,\n      tryReleaseLock,\n      isLockClaimed,\n    ],\n  );\n\n  // Bad ass\n  useValidateSensorHooks(useSensors);\n  for (let i = 0; i < useSensors.length; i++) {\n    useSensors[i](api);\n  }\n}\n"
  },
  {
    "path": "src/view/use-sensor-marshal/use-validate-sensor-hooks.js",
    "content": "// @flow\n/* eslint-disable react-hooks/rules-of-hooks */\nimport { invariant } from '../../invariant';\nimport type { Sensor } from '../../types';\nimport usePreviousRef from '../use-previous-ref';\nimport useDevSetupWarning from '../use-dev-setup-warning';\nimport useDev from '../use-dev';\n\nexport default function useValidateSensorHooks(sensorHooks: Sensor[]) {\n  useDev(() => {\n    const previousRef = usePreviousRef<Sensor[]>(sensorHooks);\n\n    useDevSetupWarning(() => {\n      invariant(\n        previousRef.current.length === sensorHooks.length,\n        'Cannot change the amount of sensor hooks after mounting',\n      );\n    });\n  });\n}\n"
  },
  {
    "path": "src/view/use-style-marshal/get-styles.js",
    "content": "// @flow\nimport type { ContextId } from '../../types';\nimport { transitions } from '../../animation';\nimport * as attributes from '../data-attributes';\n\nexport type Styles = {|\n  always: string,\n  dragging: string,\n  resting: string,\n  dropAnimating: string,\n  userCancel: string,\n|};\n\ntype Rule = {|\n  selector: string,\n  styles: {|\n    always?: string,\n    resting?: string,\n    dragging?: string,\n    dropAnimating?: string,\n    userCancel?: string,\n  |},\n|};\n\nconst makeGetSelector = (context: string) => (attribute: string) =>\n  `[${attribute}=\"${context}\"]`;\n\nconst getStyles = (rules: Rule[], property: string): string =>\n  rules\n    .map((rule: Rule): string => {\n      const value: ?string = rule.styles[property];\n      if (!value) {\n        return '';\n      }\n\n      return `${rule.selector} { ${value} }`;\n    })\n    .join(' ');\n\nconst noPointerEvents: string = 'pointer-events: none;';\n\nexport default (contextId: ContextId): Styles => {\n  const getSelector = makeGetSelector(contextId);\n\n  // ## Drag handle styles\n\n  // -webkit-touch-callout\n  // A long press on anchors usually pops a content menu that has options for\n  // the link such as 'Open in new tab'. Because long press is used to start\n  // a drag we need to opt out of this behavior\n\n  // -webkit-tap-highlight-color\n  // Webkit based browsers add a grey overlay to anchors when they are active.\n  // We remove this tap overlay as it is confusing for users\n  // https://css-tricks.com/snippets/css/remove-gray-highlight-when-tapping-links-in-mobile-safari/\n\n  // touch-action: manipulation\n  // Avoid the *pull to refresh action* and *delayed anchor focus* on Android Chrome\n\n  // cursor: grab\n  // We apply this by default for an improved user experience. It is such a common default that we\n  // bake it right in. Consumers can opt out of this by adding a selector with higher specificity\n  // The cursor will not apply when pointer-events is set to none\n\n  // pointer-events: none\n  // this is used to prevent pointer events firing on draggables during a drag\n  // Reasons:\n  // 1. performance: it stops the other draggables from processing mouse events\n  // 2. scrolling: it allows the user to scroll through the current draggable\n  // to scroll the list behind\n  // 3.* function: it blocks other draggables from starting. This is not relied on though as there\n  // is a function on the context (canLift) which is a more robust way of controlling this\n\n  const dragHandle: Rule = (() => {\n    const grabCursor = `\n      cursor: -webkit-grab;\n      cursor: grab;\n    `;\n    return {\n      selector: getSelector(attributes.dragHandle.contextId),\n      styles: {\n        always: `\n          -webkit-touch-callout: none;\n          -webkit-tap-highlight-color: rgba(0,0,0,0);\n          touch-action: manipulation;\n        `,\n        resting: grabCursor,\n        dragging: noPointerEvents,\n        // it is fine for users to start dragging another item when a drop animation is occurring\n        dropAnimating: grabCursor,\n        // Not applying grab cursor during a user cancel as it is not possible for users to reorder\n        // items during a cancel\n      },\n    };\n  })();\n\n  // ## Draggable styles\n\n  // transition: transform\n  // This controls the animation of draggables that are moving out of the way\n  // The main draggable is controlled by react-motion.\n\n  const draggable: Rule = (() => {\n    const transition: string = `\n      transition: ${transitions.outOfTheWay};\n    `;\n    return {\n      selector: getSelector(attributes.draggable.contextId),\n      styles: {\n        dragging: transition,\n        dropAnimating: transition,\n        userCancel: transition,\n      },\n    };\n  })();\n\n  // ## Droppable styles\n\n  // overflow-anchor: none;\n  // Opting out of the browser feature which tries to maintain\n  // the scroll position when the DOM changes above the fold.\n  // This does not work well with reordering DOM nodes.\n  // When we drop a Draggable it already has the correct scroll applied.\n\n  const droppable: Rule = {\n    selector: getSelector(attributes.droppable.contextId),\n    styles: {\n      always: `overflow-anchor: none;`,\n      // need pointer events on the droppable to allow manual scrolling\n    },\n  };\n\n  // ## Body styles\n\n  // cursor: grab\n  // We apply this by default for an improved user experience. It is such a common default that we\n  // bake it right in. Consumers can opt out of this by adding a selector with higher specificity\n\n  // user-select: none\n  // This prevents the user from selecting text on the page while dragging\n\n  // overflow-anchor: none\n  // We are in control and aware of all of the window scrolls that occur\n  // we do not want the browser to have behaviors we do not expect\n\n  const body: Rule = {\n    selector: 'body',\n    styles: {\n      dragging: `\n        cursor: grabbing;\n        cursor: -webkit-grabbing;\n        user-select: none;\n        -webkit-user-select: none;\n        -moz-user-select: none;\n        -ms-user-select: none;\n        overflow-anchor: none;\n      `,\n    },\n  };\n\n  const rules: Rule[] = [draggable, dragHandle, droppable, body];\n\n  return {\n    always: getStyles(rules, 'always'),\n    resting: getStyles(rules, 'resting'),\n    dragging: getStyles(rules, 'dragging'),\n    dropAnimating: getStyles(rules, 'dropAnimating'),\n    userCancel: getStyles(rules, 'userCancel'),\n  };\n};\n"
  },
  {
    "path": "src/view/use-style-marshal/index.js",
    "content": "// @flow\nexport { default } from './use-style-marshal';\n"
  },
  {
    "path": "src/view/use-style-marshal/style-marshal-types.js",
    "content": "// @flow\nimport type { DropReason } from '../../types';\n\nexport type StyleMarshal = {|\n  dragging: () => void,\n  dropping: (reason: DropReason) => void,\n  resting: () => void,\n|};\n"
  },
  {
    "path": "src/view/use-style-marshal/use-style-marshal.js",
    "content": "// @flow\nimport { useRef } from 'react';\nimport memoizeOne from 'memoize-one';\nimport { useMemo, useCallback } from 'use-memo-one';\nimport { invariant } from '../../invariant';\nimport type { StyleMarshal } from './style-marshal-types';\nimport type { ContextId, DropReason } from '../../types';\nimport getStyles, { type Styles } from './get-styles';\nimport { prefix } from '../data-attributes';\nimport useLayoutEffect from '../use-isomorphic-layout-effect';\n\nconst getHead = (): HTMLHeadElement => {\n  const head: ?HTMLHeadElement = document.querySelector('head');\n  invariant(head, 'Cannot find the head to append a style to');\n  return head;\n};\n\nconst createStyleEl = (nonce?: string): HTMLStyleElement => {\n  const el: HTMLStyleElement = document.createElement('style');\n  if (nonce) {\n    el.setAttribute('nonce', nonce);\n  }\n  el.type = 'text/css';\n  return el;\n};\n\nexport default function useStyleMarshal(contextId: ContextId, nonce?: string) {\n  const styles: Styles = useMemo(() => getStyles(contextId), [contextId]);\n  const alwaysRef = useRef<?HTMLStyleElement>(null);\n  const dynamicRef = useRef<?HTMLStyleElement>(null);\n\n  const setDynamicStyle = useCallback(\n    // Using memoizeOne to prevent frequent updates to textContext\n    memoizeOne((proposed: string) => {\n      const el: ?HTMLStyleElement = dynamicRef.current;\n      invariant(el, 'Cannot set dynamic style element if it is not set');\n      el.textContent = proposed;\n    }),\n    [],\n  );\n\n  const setAlwaysStyle = useCallback((proposed: string) => {\n    const el: ?HTMLStyleElement = alwaysRef.current;\n    invariant(el, 'Cannot set dynamic style element if it is not set');\n    el.textContent = proposed;\n  }, []);\n\n  // using layout effect as programatic dragging might start straight away (such as for cypress)\n  useLayoutEffect(() => {\n    invariant(\n      !alwaysRef.current && !dynamicRef.current,\n      'style elements already mounted',\n    );\n\n    const always: HTMLStyleElement = createStyleEl(nonce);\n    const dynamic: HTMLStyleElement = createStyleEl(nonce);\n\n    // store their refs\n    alwaysRef.current = always;\n    dynamicRef.current = dynamic;\n\n    // for easy identification\n    always.setAttribute(`${prefix}-always`, contextId);\n    dynamic.setAttribute(`${prefix}-dynamic`, contextId);\n\n    // add style tags to head\n    getHead().appendChild(always);\n    getHead().appendChild(dynamic);\n\n    // set initial style\n    setAlwaysStyle(styles.always);\n    setDynamicStyle(styles.resting);\n\n    return () => {\n      const remove = (ref) => {\n        const current: ?HTMLStyleElement = ref.current;\n        invariant(current, 'Cannot unmount ref as it is not set');\n        getHead().removeChild(current);\n        ref.current = null;\n      };\n\n      remove(alwaysRef);\n      remove(dynamicRef);\n    };\n  }, [\n    nonce,\n    setAlwaysStyle,\n    setDynamicStyle,\n    styles.always,\n    styles.resting,\n    contextId,\n  ]);\n\n  const dragging = useCallback(() => setDynamicStyle(styles.dragging), [\n    setDynamicStyle,\n    styles.dragging,\n  ]);\n  const dropping = useCallback(\n    (reason: DropReason) => {\n      if (reason === 'DROP') {\n        setDynamicStyle(styles.dropAnimating);\n        return;\n      }\n      setDynamicStyle(styles.userCancel);\n    },\n    [setDynamicStyle, styles.dropAnimating, styles.userCancel],\n  );\n  const resting = useCallback(() => {\n    // Can be called defensively\n    if (!dynamicRef.current) {\n      return;\n    }\n    setDynamicStyle(styles.resting);\n  }, [setDynamicStyle, styles.resting]);\n\n  const marshal: StyleMarshal = useMemo(\n    () => ({\n      dragging,\n      dropping,\n      resting,\n    }),\n    [dragging, dropping, resting],\n  );\n\n  return marshal;\n}\n"
  },
  {
    "path": "src/view/use-unique-id.js",
    "content": "// @flow\nimport { useMemo } from 'use-memo-one';\nimport type { Id } from '../types';\n\nlet count: number = 0;\n\ntype Options = {\n  separator: string,\n};\n\nconst defaults: Options = { separator: '::' };\n\nexport function reset() {\n  count = 0;\n}\n\nexport default function useUniqueId(\n  prefix: string,\n  options?: Options = defaults,\n): Id {\n  return useMemo(() => `${prefix}${options.separator}${count++}`, [\n    options.separator,\n    prefix,\n  ]);\n}\n"
  },
  {
    "path": "src/view/visually-hidden-style.js",
    "content": "// @flow\n// https://allyjs.io/tutorials/hiding-elements.html\n// Element is visually hidden but is readable by screen readers\nconst visuallyHidden: Object = {\n  position: 'absolute',\n  width: '1px',\n  height: '1px',\n  margin: '-1px',\n  border: '0',\n  padding: '0',\n  overflow: 'hidden',\n  clip: 'rect(0 0 0 0)',\n  'clip-path': 'inset(100%)',\n};\n\nexport default visuallyHidden;\n"
  },
  {
    "path": "src/view/window/get-max-window-scroll.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport getMaxScroll from '../../state/get-max-scroll';\nimport getDocumentElement from '../get-document-element';\n\nexport default (): Position => {\n  const doc: HTMLElement = getDocumentElement();\n\n  const maxScroll: Position = getMaxScroll({\n    // unclipped padding box, with scrollbar\n    scrollHeight: doc.scrollHeight,\n    scrollWidth: doc.scrollWidth,\n    // clipped padding box, without scrollbar\n    width: doc.clientWidth,\n    height: doc.clientHeight,\n  });\n\n  return maxScroll;\n};\n"
  },
  {
    "path": "src/view/window/get-viewport.js",
    "content": "// @flow\nimport { getRect, type Rect, type Position } from 'css-box-model';\nimport type { Viewport } from '../../types';\nimport { origin } from '../../state/position';\nimport getWindowScroll from './get-window-scroll';\nimport getMaxWindowScroll from './get-max-window-scroll';\nimport getDocumentElement from '../get-document-element';\n\nexport default (): Viewport => {\n  const scroll: Position = getWindowScroll();\n  const maxScroll: Position = getMaxWindowScroll();\n\n  const top: number = scroll.y;\n  const left: number = scroll.x;\n\n  // window.innerHeight: includes scrollbars (not what we want)\n  // document.clientHeight gives us the correct value when using the html5 doctype\n  const doc: HTMLElement = getDocumentElement();\n  // Using these values as they do not consider scrollbars\n  // padding box, without scrollbar\n  const width: number = doc.clientWidth;\n  const height: number = doc.clientHeight;\n\n  // Computed\n  const right: number = left + width;\n  const bottom: number = top + height;\n\n  const frame: Rect = getRect({\n    top,\n    left,\n    right,\n    bottom,\n  });\n\n  const viewport: Viewport = {\n    frame,\n    scroll: {\n      initial: scroll,\n      current: scroll,\n      max: maxScroll,\n      diff: {\n        value: origin,\n        displacement: origin,\n      },\n    },\n  };\n\n  return viewport;\n};\n"
  },
  {
    "path": "src/view/window/get-window-from-el.js",
    "content": "// @flow\nexport default (el: ?Element): typeof window =>\n  el && el.ownerDocument ? el.ownerDocument.defaultView : window;\n"
  },
  {
    "path": "src/view/window/get-window-scroll.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\n\n// The browsers update document.documentElement.scrollTop and window.pageYOffset\n// differently as the window scrolls.\n\n// Webkit\n// documentElement.scrollTop: no update. Stays at 0\n// window.pageYOffset: updates to whole number\n\n// Chrome\n// documentElement.scrollTop: update with fractional value\n// window.pageYOffset: update with fractional value\n\n// FireFox\n// documentElement.scrollTop: updates to whole number\n// window.pageYOffset: updates to whole number\n\n// IE11 (same as firefox)\n// documentElement.scrollTop: updates to whole number\n// window.pageYOffset: updates to whole number\n\n// Edge (same as webkit)\n// documentElement.scrollTop: no update. Stays at 0\n// window.pageYOffset: updates to whole number\n\nexport default (): Position => ({\n  x: window.pageXOffset,\n  y: window.pageYOffset,\n});\n"
  },
  {
    "path": "src/view/window/scroll-window.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\n\n// Not guarenteed to scroll by the entire amount\nexport default (change: Position): void => {\n  window.scrollBy(change.x, change.y);\n};\n"
  },
  {
    "path": "stories/.eslintrc.js",
    "content": "module.exports = {\n  rules: {\n    // allowing console.warn / console.error\n    // this is because we often mock console.warn and console.error and adding this rul\n    // avoids needing to constantly be opting out of the rule\n    'no-console': ['error', { allow: ['warn', 'error'] }],\n\n    // allowing useMemo and useCallback\n    'no-restricted-imports': 'off',\n\n    // Allowing Array.from\n    'no-restricted-syntax': 'off',\n\n    // Sometimes used for simple examples\n    'react/state-in-constructor': 'off',\n  },\n};\n"
  },
  {
    "path": "stories/1-single-vertical-list.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport styled from '@emotion/styled';\nimport QuoteApp from './src/vertical/quote-app';\nimport { quotes, getQuotes } from './src/data';\nimport { grid } from './src/constants';\n\nconst data = {\n  small: quotes,\n  medium: getQuotes(40),\n  large: getQuotes(500),\n};\n\nconst ScrollContainer = styled.div`\n  box-sizing: border-box;\n  background: lightgrey;\n  padding: ${grid * 2}px;\n  overflow-y: scroll;\n  width: 500px;\n  height: 100vh;\n  position: relative;\n`;\n\nconst Title = styled.h4`\n  text-align: center;\n  margin-bottom: ${grid}px;\n`;\n\nstoriesOf('single vertical list', module)\n  .add('basic', () => <QuoteApp initial={data.small} />)\n  .add('large data set', () => <QuoteApp initial={data.large} />)\n  .add('Droppable is a scroll container', () => (\n    <QuoteApp\n      initial={data.medium}\n      listStyle={{\n        overflowY: 'scroll',\n        maxHeight: '80vh',\n        position: 'relative',\n      }}\n    />\n  ))\n  .add('window scrolling and a Droppable scroll container', () => (\n    <QuoteApp\n      initial={data.medium}\n      listStyle={{\n        overflowY: 'scroll',\n        maxHeight: '120vh',\n        position: 'relative',\n      }}\n    />\n  ))\n  .add('within a larger scroll container', () => (\n    <ScrollContainer>\n      <Title>List is within a larger scroll container</Title>\n      <QuoteApp initial={data.medium} />\n    </ScrollContainer>\n  ))\n  .add('with combine enabled', () => (\n    <QuoteApp initial={data.small} isCombineEnabled />\n  ));\n"
  },
  {
    "path": "stories/10-table.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport WithDimensionLocking from './src/table/with-dimension-locking';\nimport WithFixedColumns from './src/table/with-fixed-columns';\nimport WithPortal from './src/table/with-portal';\nimport WithClone from './src/table/with-clone';\nimport { quotes } from './src/data';\n\nstoriesOf('Tables', module)\n  .add('with fixed width columns', () => <WithFixedColumns initial={quotes} />)\n  .add('with dimension locking', () => (\n    <WithDimensionLocking initial={quotes} />\n  ))\n  .add('with clone', () => <WithClone initial={quotes} />)\n  .add('with custom portal', () => <WithPortal initial={quotes} />);\n"
  },
  {
    "path": "stories/11-portal.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport PortalApp from './src/portal/portal-app';\nimport { quotes } from './src/data';\n\nstoriesOf('Portals', module).add('Using your own portal', () => (\n  <PortalApp initial={quotes.slice(0, 2)} />\n));\n"
  },
  {
    "path": "stories/12-dynamic.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport WithControls from './src/dynamic/with-controls';\nimport LazyLoading from './src/dynamic/lazy-loading';\n\nstoriesOf('Dynamic changes during a drag (v11 only)', module)\n  .add('With controls', () => <WithControls />)\n  .add('Lazy loading', () => <LazyLoading />);\n"
  },
  {
    "path": "stories/15-on-before-capture.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport AddingThings from './src/on-before-capture/adding-things';\n\nstoriesOf('onBeforeCapture', module).add('adding things', () => (\n  <AddingThings />\n));\n"
  },
  {
    "path": "stories/2-single-horizontal.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport styled from '@emotion/styled';\nimport AuthorApp from './src/horizontal/author-app';\nimport { quotes, getQuotes } from './src/data';\nimport type { Quote } from './src/types';\n\nconst bigData: Quote[] = getQuotes(30);\n\nconst WideWindow = styled.div`\n  width: 120vw;\n`;\n\nstoriesOf('single horizontal list', module)\n  .add('simple', () => <AuthorApp initial={quotes} />)\n  .add('with combine enabled', () => (\n    <AuthorApp initial={quotes} isCombineEnabled />\n  ))\n  .add('with overflow scroll', () => (\n    <AuthorApp initial={bigData} internalScroll />\n  ))\n  .add('with window scroll and overflow scroll', () => (\n    <WideWindow>\n      <AuthorApp initial={bigData} internalScroll />\n    </WideWindow>\n  ));\n"
  },
  {
    "path": "stories/20-super-simple.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport Simple from './src/simple/simple';\nimport SimpleWithScroll from './src/simple/simple-scrollable';\nimport WithMixedSpacing from './src/simple/simple-mixed-spacing';\n\nstoriesOf('Super simple', module)\n  .add('vertical list', () => <Simple />)\n  .add('vertical list with scroll (overflow: auto)', () => (\n    <SimpleWithScroll overflow=\"auto\" />\n  ))\n  .add('vertical list with scroll (overflow: scroll)', () => (\n    <SimpleWithScroll overflow=\"scroll\" />\n  ))\n  .add('with mixed spacing', () => <WithMixedSpacing />);\n"
  },
  {
    "path": "stories/21-change-on-drag-start.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport {\n  DragDropContext,\n  Droppable,\n  Draggable,\n  type DropResult,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type DroppableProvided,\n  type DroppableStateSnapshot,\n} from '../src';\n\ntype Item = {|\n  id: string,\n  content: string,\n|};\n\n// fake data generator\nconst getItems = (count: number): Item[] =>\n  Array.from({ length: count }, (v, k) => k).map((k) => ({\n    id: `item-${k}`,\n    content: `item ${k}`,\n  }));\n\n// a little function to help us with reordering the result\nconst reorder = (list, startIndex, endIndex) => {\n  const result = Array.from(list);\n  const [removed] = result.splice(startIndex, 1);\n  result.splice(endIndex, 0, removed);\n\n  return result;\n};\n\nconst grid: number = 8;\n\nconst getItemStyle = (isDragging, draggableStyle) => ({\n  // some basic styles to make the items look a bit nicer\n  userSelect: 'none',\n  padding: grid * 2,\n  margin: `0 ${grid}px 0 0`,\n\n  // change background colour if dragging\n  background: isDragging ? 'lightgreen' : 'grey',\n\n  // styles we need to apply on draggables\n  ...draggableStyle,\n});\n\nconst getListStyle = (isDraggingOver) => ({\n  background: isDraggingOver ? 'lightblue' : 'lightgrey',\n  padding: grid,\n  overflow: 'auto',\n});\n\ntype State = {|\n  items: Item[],\n  isDropDisabled: boolean,\n|};\n\nclass App extends React.Component<*, State> {\n  state: State = {\n    items: getItems(6),\n    isDropDisabled: false,\n  };\n\n  onDragStart = () => {\n    this.setState({ isDropDisabled: !this.state.isDropDisabled });\n  };\n\n  onDragEnd = (result: DropResult) => {\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    const items = reorder(\n      this.state.items,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      items,\n    });\n  };\n\n  // Normally you would want to split things out into separate components.\n  // But in this example everything is just done in one place for simplicity\n  render() {\n    return (\n      <DragDropContext\n        onDragStart={this.onDragStart}\n        onDragEnd={this.onDragEnd}\n      >\n        <Droppable\n          droppableId=\"droppable\"\n          isDropDisabled={this.state.isDropDisabled}\n        >\n          {(provided: DroppableProvided, snapshot: DroppableStateSnapshot) => (\n            <div\n              ref={provided.innerRef}\n              style={getListStyle(snapshot.isDraggingOver)}\n              {...provided.droppableProps}\n            >\n              {this.state.items.map((item, index) => (\n                <Draggable key={item.id} draggableId={item.id} index={index}>\n                  {(\n                    draggableProvided: DraggableProvided,\n                    draggableSnapshot: DraggableStateSnapshot,\n                  ) => (\n                    <div\n                      ref={draggableProvided.innerRef}\n                      {...draggableProvided.draggableProps}\n                      {...draggableProvided.dragHandleProps}\n                      style={getItemStyle(\n                        draggableSnapshot.isDragging,\n                        draggableProvided.draggableProps.style,\n                      )}\n                    >\n                      {item.content}\n                    </div>\n                  )}\n                </Draggable>\n              ))}\n              {provided.placeholder}\n            </div>\n          )}\n        </Droppable>\n        <div style={{ marginTop: grid * 2 }}>\n          Is drop disabled? {this.state.isDropDisabled ? 'yes' : 'no'}\n        </div>\n      </DragDropContext>\n    );\n  }\n}\n\nstoriesOf('onDragStart', module).add(\n  'toggle isDropDisabled onDragStart',\n  () => <App />,\n);\n"
  },
  {
    "path": "stories/25-fixed-list.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport WithFixedSidebar from './src/fixed-list/fixed-sidebar';\n\nstoriesOf('fixed list', module).add('with fixed sidebar', () => (\n  <WithFixedSidebar />\n));\n"
  },
  {
    "path": "stories/3-board.stories.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport Board from './src/board/board';\nimport { authorQuoteMap, generateQuoteMap } from './src/data';\n\nconst data = {\n  medium: generateQuoteMap(100),\n  large: generateQuoteMap(500),\n};\n\nstoriesOf('board', module)\n  .add('simple', () => <Board initial={authorQuoteMap} />)\n  .add('dragging a clone', () => <Board initial={authorQuoteMap} useClone />)\n  .add('medium data set', () => <Board initial={data.medium} />)\n  .add('large data set', () => <Board initial={data.large} />)\n  .add('long lists in a short container', () => (\n    <Board initial={data.medium} containerHeight=\"60vh\" />\n  ))\n  .add('scrollable columns', () => (\n    <Board initial={authorQuoteMap} withScrollableColumns />\n  ))\n  .add('with combining', () => (\n    <Board initial={authorQuoteMap} isCombineEnabled />\n  ))\n  .add('with combining and cloning', () => (\n    <Board initial={authorQuoteMap} isCombineEnabled useClone />\n  ));\n"
  },
  {
    "path": "stories/30-custom-drop.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport FunnyDrop from './src/custom-drop/funny-drop';\nimport NoDrop from './src/custom-drop/no-drop';\n\nstoriesOf('Custom drop animation', module)\n  .add('funny drop animation', () => <FunnyDrop />)\n  .add('no drop animation', () => <NoDrop />);\n"
  },
  {
    "path": "stories/35-function-component.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport QuoteApp from './src/function-component/quote-app';\n\nstoriesOf(\n  'Function component usage',\n  module,\n).add('using rbd with function components and hooks', () => <QuoteApp />);\n"
  },
  {
    "path": "stories/4-complex-vertical-list.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport NestedQuoteApp from './src/vertical-nested/quote-app';\nimport GroupedQuoteApp from './src/vertical-grouped/quote-app';\nimport { authorQuoteMap } from './src/data';\n\nstoriesOf('complex vertical list', module)\n  .add('grouped', () => <GroupedQuoteApp initial={authorQuoteMap} />)\n  // this is kind of strange - but hey, if you want to!\n  .add('nested vertical lists', () => <NestedQuoteApp />);\n"
  },
  {
    "path": "stories/40-programmatic.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport WithControls from './src/programmatic/with-controls';\nimport Runsheet from './src/programmatic/runsheet';\nimport { quotes } from './src/data';\n\nstoriesOf('Programmatic dragging', module)\n  .add('with controls', () => <WithControls initial={quotes.slice(0, 3)} />)\n  .add('with runsheet', () => <Runsheet initial={quotes} />);\n"
  },
  {
    "path": "stories/45-virtual.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport ReactWindowList from './src/virtual/react-window/list';\nimport ReactVirtualizedList from './src/virtual/react-virtualized/list';\nimport { getQuotes } from './src/data';\nimport ReactWindowBoard from './src/virtual/react-window/board';\nimport ReactVirtualizedBoard from './src/virtual/react-virtualized/board';\nimport ReactVirtualizedWindowList from './src/virtual/react-virtualized/window-list';\n\nstoriesOf('Virtual: react-window', module)\n  .add('list', () => <ReactWindowList initial={getQuotes(1000)} />)\n  .add('board', () => <ReactWindowBoard />);\n\nstoriesOf('Virtual: react-virtualized', module)\n  .add('list', () => <ReactVirtualizedList initial={getQuotes(1000)} />)\n  .add('board', () => <ReactVirtualizedBoard />)\n  .add('window list', () => (\n    <ReactVirtualizedWindowList initial={getQuotes(1000)} />\n  ));\n"
  },
  {
    "path": "stories/5-multiple-vertical-lists.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport QuoteApp from './src/multiple-vertical/quote-app';\nimport { getQuotes } from './src/data';\nimport type { QuoteMap } from './src/types';\n\nconst alpha: string = 'alpha';\nconst beta: string = 'beta';\nconst gamma: string = 'gamma';\nconst delta: string = 'delta';\nconst epsilon: string = 'epsilon';\nconst zeta: string = 'zeta';\nconst eta: string = 'eta';\nconst theta: string = 'theta';\nconst iota: string = 'iota';\nconst kappa: string = 'kappa';\n\nconst quoteMap: QuoteMap = {\n  [alpha]: getQuotes(7),\n  [beta]: getQuotes(3),\n  [gamma]: getQuotes(7),\n  [delta]: getQuotes(2),\n  [epsilon]: getQuotes(10),\n  [zeta]: getQuotes(5),\n  [eta]: getQuotes(5),\n  [theta]: getQuotes(5),\n  [iota]: getQuotes(20),\n  [kappa]: getQuotes(5),\n};\n\nstoriesOf('multiple vertical lists', module).add('stress test', () => (\n  <QuoteApp initial={quoteMap} />\n));\n"
  },
  {
    "path": "stories/50-multiple-contexts.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport MultipleContexts from './src/programmatic/multiple-contexts';\n\nstoriesOf('Multiple contexts', module).add('with multiple contexts', () => (\n  <MultipleContexts />\n));\n"
  },
  {
    "path": "stories/55-mixed-sizes.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport MixedSizedItems from './src/mixed-sizes/mixed-size-items';\nimport MixedSizedLists from './src/mixed-sizes/mixed-size-lists';\nimport Experiment from './src/mixed-sizes/mixed-size-lists-experiment';\n\nstoriesOf('mixed sizes', module)\n  .add('with large draggable size variance', () => <MixedSizedItems />)\n  .add('with large droppable size variance', () => <MixedSizedLists />)\n  .add('with large droppable size variance (experiment)', () => <Experiment />);\n"
  },
  {
    "path": "stories/6-multiple-horizontal-lists.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport QuoteApp from './src/multiple-horizontal/quote-app';\nimport { getQuotes } from './src/data';\nimport type { QuoteMap } from './src/types';\n\nconst alpha: string = 'alpha';\nconst beta: string = 'beta';\nconst gamma: string = 'gamma';\n\nconst quoteMap: QuoteMap = {\n  [alpha]: getQuotes(20),\n  [beta]: getQuotes(18),\n  [gamma]: getQuotes(22),\n};\n\nstoriesOf('multiple horizontal lists', module).add('stress test', () => (\n  <QuoteApp initial={quoteMap} />\n));\n"
  },
  {
    "path": "stories/7-interactive-elements.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport InteractiveElementsApp from './src/interactive-elements/interactive-elements-app';\n\nstoriesOf('nested interative elements', module).add('stress test', () => (\n  <InteractiveElementsApp />\n));\n"
  },
  {
    "path": "stories/8-accessibility.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport TaskApp from './src/accessible/task-app';\n\nstoriesOf('Accessibility', module).add('single list', () => <TaskApp />);\n"
  },
  {
    "path": "stories/9-multi-drag.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\nimport TaskApp from './src/multi-drag/task-app';\n\nstoriesOf('Multi drag', module).add('pattern', () => <TaskApp />);\n"
  },
  {
    "path": "stories/99-debug.stories.js",
    "content": "// @flow\nimport React from 'react';\nimport { storiesOf } from '@storybook/react';\n// import { Draggable, Droppable, DragDropContext } from '../src';\n\nclass App extends React.Component<*> {\n  render() {\n    return 'Used for debugging codesandbox examples (copy paste them into this file)';\n  }\n}\n\nstoriesOf('Troubleshoot example', module).add('debug example', () => <App />);\n"
  },
  {
    "path": "stories/src/accessible/blur-context.js",
    "content": "// @flow\nimport React from 'react';\n\nconst BlurContext = React.createContext<number>(0);\n\nexport default BlurContext;\n"
  },
  {
    "path": "stories/src/accessible/data.js",
    "content": "// @flow\nimport type { Task } from '../types';\n\nconst tasks: Task[] = [\n  {\n    id: '1',\n    content: 'Eat lunch',\n  },\n  {\n    id: '2',\n    content: 'Finish that book I have been reading',\n  },\n  {\n    id: '3',\n    content: 'Go to the store',\n  },\n];\n\nexport default tasks;\n"
  },
  {
    "path": "stories/src/accessible/task-app.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport TaskList from './task-list';\nimport initial from './data';\nimport reorder from '../reorder';\nimport { grid } from '../constants';\nimport { DragDropContext } from '../../../src';\nimport BlurContext from './blur-context';\nimport type {\n  Announce,\n  DragStart,\n  DragUpdate,\n  DropResult,\n  DraggableLocation,\n  ResponderProvided,\n} from '../../../src';\nimport type { Task } from '../types';\n\ntype State = {|\n  tasks: Task[],\n  blur: number,\n|};\n\nconst Container = styled.div`\n  padding-top: 20vh;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n`;\n\nconst BlurControls = styled.div`\n  display: flex;\n  align-items: center;\n  font-size: 20px;\n  margin-top: 20vh;\n`;\n\nconst BlurTitle = styled.h4`\n  margin: 0;\n`;\n\nconst Button = styled.button`\n  height: ${grid * 5}px;\n  width: ${grid * 5}px;\n  font-size: 20px;\n  justify-content: center;\n  margin: 0 ${grid * 2}px;\n  cursor: pointer;\n`;\n\nexport default class TaskApp extends Component<*, State> {\n  state: State = {\n    tasks: initial,\n    blur: 0,\n  };\n\n  // in?\n  onDragStart = (start: DragStart, provided: ResponderProvided): void =>\n    provided.announce(`\n    You have lifted a task.\n    It is in position ${start.source.index + 1} of ${\n      this.state.tasks.length\n    } in the list.\n    Use the arrow keys to move, space bar to drop, and escape to cancel.\n  `);\n\n  onDragUpdate = (update: DragUpdate, provided: ResponderProvided): void => {\n    const announce: Announce = provided.announce;\n    if (!update.destination) {\n      announce('You are currently not dragging over any droppable area');\n      return;\n    }\n    announce(\n      `You have moved the task to position ${update.destination.index + 1}`,\n    );\n  };\n\n  onDragEnd = (result: DropResult, provided: ResponderProvided): void => {\n    const announce: Announce = provided.announce;\n    // TODO: not being called on cancel!!!\n    if (result.reason === 'CANCEL') {\n      announce(`\n        Movement cancelled.\n        The task has returned to its starting position of ${\n          result.source.index + 1\n        }\n      `);\n      return;\n    }\n\n    const destination: ?DraggableLocation = result.destination;\n\n    if (!destination) {\n      announce(`\n        The task has been dropped while not over a location.\n        The task has returned to its starting position of ${\n          result.source.index + 1\n        }\n      `);\n      return;\n    }\n\n    const tasks: Task[] = reorder(\n      this.state.tasks,\n      result.source.index,\n      destination.index,\n    );\n\n    this.setState({\n      tasks,\n    });\n\n    announce(`\n      You have dropped the task.\n      It has moved from position ${result.source.index + 1} to ${\n      destination.index + 1\n    }\n    `);\n  };\n\n  render() {\n    return (\n      <DragDropContext\n        onDragStart={this.onDragStart}\n        onDragUpdate={this.onDragUpdate}\n        onDragEnd={this.onDragEnd}\n      >\n        <Container>\n          <BlurContext.Provider value={this.state.blur}>\n            <TaskList title=\"Todo\" tasks={this.state.tasks} />\n          </BlurContext.Provider>\n          <BlurControls>\n            <Button\n              aria-label=\"remove blur\"\n              onClick={() =>\n                this.setState({ blur: Math.max(0, this.state.blur - 1) })\n              }\n            >\n              -\n            </Button>\n            <BlurTitle>Blur</BlurTitle>\n            <Button\n              aria-label=\"add blur\"\n              onClick={() =>\n                this.setState({ blur: Math.min(this.state.blur + 1, 10) })\n              }\n            >\n              +\n            </Button>\n          </BlurControls>\n        </Container>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/accessible/task-list.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { Droppable } from '../../../src';\nimport Task from './task';\nimport type { DroppableProvided } from '../../../src';\nimport type { Task as TaskType } from '../types';\nimport { grid, borderRadius } from '../constants';\nimport BlurContext from './blur-context';\n\ntype Props = {|\n  tasks: TaskType[],\n  title: string,\n|};\n\nconst Container = styled.div`\n  width: 300px;\n  background-color: ${colors.N100};\n  border-radius: ${borderRadius}px;\n  filter: blur(${(props) => props.blur}px);\n`;\n\nconst Title = styled.h3`\n  font-weight: bold;\n  padding: ${grid}px;\n`;\n\nconst List = styled.div`\n  padding: ${grid}px;\n  padding-bottom: 0;\n  display: flex;\n  flex-direction: column;\n`;\n\nexport default class TaskList extends Component<Props> {\n  render() {\n    return (\n      <Droppable droppableId=\"list\">\n        {(provided: DroppableProvided) => (\n          <BlurContext.Consumer>\n            {(blur: number) => (\n              <Container\n                ref={provided.innerRef}\n                {...provided.droppableProps}\n                blur={blur}\n              >\n                <Title>{this.props.title}</Title>\n                <List>\n                  {this.props.tasks.map((task: TaskType, index: number) => (\n                    <Task key={task.id} task={task} index={index} />\n                  ))}\n                </List>\n                {provided.placeholder}\n              </Container>\n            )}\n          </BlurContext.Consumer>\n        )}\n      </Droppable>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/accessible/task.jsx",
    "content": "// @flow\nimport React, { Component, type Node } from 'react';\nimport ReactDOM from 'react-dom';\nimport memoizeOne from 'memoize-one';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { invariant } from '../../../src/invariant';\nimport { Draggable } from '../../../src';\nimport type { DraggableProvided, DraggableStateSnapshot } from '../../../src';\nimport type { Task as TaskType } from '../types';\nimport { grid, borderRadius } from '../constants';\nimport BlurContext from './blur-context';\n\ntype Props = {|\n  task: TaskType,\n  index: number,\n|};\n\nconst Container = styled.div`\n  border-bottom: 1px solid #ccc;\n  background: ${colors.N0};\n  padding: ${grid}px;\n  margin-bottom: ${grid}px;\n  border-radius: ${borderRadius}px;\n  font-size: 18px;\n  filter: blur(${(props) => props.blur}px);\n  ${({ isDragging }) =>\n    isDragging ? 'box-shadow: 1px 1px 1px grey; background: lightblue' : ''};\n`;\n\nconst getPortal = memoizeOne((): HTMLElement => {\n  invariant(document);\n  const body: ?HTMLBodyElement = document.body;\n  invariant(body);\n  const el: HTMLElement = document.createElement('div');\n  el.className = 'rbd-portal';\n  body.appendChild(el);\n  return el;\n});\n\nexport default class Task extends Component<Props> {\n  render() {\n    const task: TaskType = this.props.task;\n    const index: number = this.props.index;\n\n    return (\n      <BlurContext.Consumer>\n        {(blur: number) => (\n          <Draggable draggableId={task.id} index={index}>\n            {(\n              provided: DraggableProvided,\n              snapshot: DraggableStateSnapshot,\n            ) => {\n              const child: Node = (\n                <Container\n                  ref={provided.innerRef}\n                  isDragging={snapshot.isDragging}\n                  {...provided.draggableProps}\n                  {...provided.dragHandleProps}\n                  blur={blur}\n                >\n                  {this.props.task.content}\n                </Container>\n              );\n\n              if (!snapshot.isDragging) {\n                return child;\n              }\n\n              return ReactDOM.createPortal(child, getPortal());\n            }}\n          </Draggable>\n        )}\n      </BlurContext.Consumer>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/board/board.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { Global, css } from '@emotion/core';\nimport { colors } from '@atlaskit/theme';\nimport type {\n  DropResult,\n  DraggableLocation,\n  DroppableProvided,\n} from '../../../src';\nimport type { QuoteMap, Quote } from '../types';\nimport Column from './column';\nimport reorder, { reorderQuoteMap } from '../reorder';\nimport { DragDropContext, Droppable } from '../../../src';\n\nconst ParentContainer = styled.div`\n  height: ${({ height }) => height};\n  overflow-x: hidden;\n  overflow-y: auto;\n`;\n\nconst Container = styled.div`\n  background-color: ${colors.B100};\n  min-height: 100vh;\n  /* like display:flex but will allow bleeding over the window width */\n  min-width: 100vw;\n  display: inline-flex;\n`;\n\ntype Props = {|\n  initial: QuoteMap,\n  withScrollableColumns?: boolean,\n  isCombineEnabled?: boolean,\n  containerHeight?: string,\n  useClone?: boolean,\n|};\n\ntype State = {|\n  columns: QuoteMap,\n  ordered: string[],\n|};\n\nexport default class Board extends Component<Props, State> {\n  /* eslint-disable react/sort-comp */\n  static defaultProps = {\n    isCombineEnabled: false,\n  };\n\n  state: State = {\n    columns: this.props.initial,\n    ordered: Object.keys(this.props.initial),\n  };\n\n  boardRef: ?HTMLElement;\n\n  onDragEnd = (result: DropResult) => {\n    if (result.combine) {\n      if (result.type === 'COLUMN') {\n        const shallow: string[] = [...this.state.ordered];\n        shallow.splice(result.source.index, 1);\n        this.setState({ ordered: shallow });\n        return;\n      }\n\n      const column: Quote[] = this.state.columns[result.source.droppableId];\n      const withQuoteRemoved: Quote[] = [...column];\n      withQuoteRemoved.splice(result.source.index, 1);\n      const columns: QuoteMap = {\n        ...this.state.columns,\n        [result.source.droppableId]: withQuoteRemoved,\n      };\n      this.setState({ columns });\n      return;\n    }\n\n    // dropped nowhere\n    if (!result.destination) {\n      return;\n    }\n\n    const source: DraggableLocation = result.source;\n    const destination: DraggableLocation = result.destination;\n\n    // did not move anywhere - can bail early\n    if (\n      source.droppableId === destination.droppableId &&\n      source.index === destination.index\n    ) {\n      return;\n    }\n\n    // reordering column\n    if (result.type === 'COLUMN') {\n      const ordered: string[] = reorder(\n        this.state.ordered,\n        source.index,\n        destination.index,\n      );\n\n      this.setState({\n        ordered,\n      });\n\n      return;\n    }\n\n    const data = reorderQuoteMap({\n      quoteMap: this.state.columns,\n      source,\n      destination,\n    });\n\n    this.setState({\n      columns: data.quoteMap,\n    });\n  };\n\n  render() {\n    const columns: QuoteMap = this.state.columns;\n    const ordered: string[] = this.state.ordered;\n    const {\n      containerHeight,\n      useClone,\n      isCombineEnabled,\n      withScrollableColumns,\n    } = this.props;\n\n    const board = (\n      <Droppable\n        droppableId=\"board\"\n        type=\"COLUMN\"\n        direction=\"horizontal\"\n        ignoreContainerClipping={Boolean(containerHeight)}\n        isCombineEnabled={isCombineEnabled}\n      >\n        {(provided: DroppableProvided) => (\n          <Container ref={provided.innerRef} {...provided.droppableProps}>\n            {ordered.map((key: string, index: number) => (\n              <Column\n                key={key}\n                index={index}\n                title={key}\n                quotes={columns[key]}\n                isScrollable={withScrollableColumns}\n                isCombineEnabled={isCombineEnabled}\n                useClone={useClone}\n              />\n            ))}\n            {provided.placeholder}\n          </Container>\n        )}\n      </Droppable>\n    );\n\n    return (\n      <React.Fragment>\n        <DragDropContext onDragEnd={this.onDragEnd}>\n          {containerHeight ? (\n            <ParentContainer height={containerHeight}>{board}</ParentContainer>\n          ) : (\n            board\n          )}\n        </DragDropContext>\n        <Global\n          styles={css`\n            body {\n              background: ${colors.B200};\n            }\n          `}\n        />\n      </React.Fragment>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/board/column.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { grid, borderRadius } from '../constants';\nimport { Draggable } from '../../../src';\nimport type { DraggableProvided, DraggableStateSnapshot } from '../../../src';\nimport QuoteList from '../primatives/quote-list';\nimport Title from '../primatives/title';\nimport type { Quote } from '../types';\n\nconst Container = styled.div`\n  margin: ${grid}px;\n  display: flex;\n  flex-direction: column;\n`;\n\nconst Header = styled.div`\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  border-top-left-radius: ${borderRadius}px;\n  border-top-right-radius: ${borderRadius}px;\n  background-color: ${({ isDragging }) =>\n    isDragging ? colors.G50 : colors.N30};\n  transition: background-color 0.2s ease;\n\n  &:hover {\n    background-color: ${colors.G50};\n  }\n`;\n\ntype Props = {|\n  title: string,\n  quotes: Quote[],\n  index: number,\n  isScrollable?: boolean,\n  isCombineEnabled?: boolean,\n  useClone?: boolean,\n|};\n\nexport default class Column extends Component<Props> {\n  render() {\n    const title: string = this.props.title;\n    const quotes: Quote[] = this.props.quotes;\n    const index: number = this.props.index;\n    return (\n      <Draggable draggableId={title} index={index}>\n        {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n          <Container ref={provided.innerRef} {...provided.draggableProps}>\n            <Header isDragging={snapshot.isDragging}>\n              <Title\n                isDragging={snapshot.isDragging}\n                {...provided.dragHandleProps}\n                aria-label={`${title} quote list`}\n              >\n                {title}\n              </Title>\n            </Header>\n            <QuoteList\n              listId={title}\n              listType=\"QUOTE\"\n              style={{\n                backgroundColor: snapshot.isDragging ? colors.G50 : null,\n              }}\n              quotes={quotes}\n              internalScroll={this.props.isScrollable}\n              isCombineEnabled={Boolean(this.props.isCombineEnabled)}\n              useClone={Boolean(this.props.useClone)}\n            />\n          </Container>\n        )}\n      </Draggable>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/constants.js",
    "content": "// @flow\n\nexport const grid: number = 8;\nexport const borderRadius: number = 2;\n"
  },
  {
    "path": "stories/src/custom-drop/funny-drop.jsx",
    "content": "// @flow\nimport React from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { grid } from '../constants';\nimport reorder from '../reorder';\nimport {\n  DragDropContext,\n  Draggable,\n  Droppable,\n  type DroppableProvided,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type DraggableStyle,\n  type DropAnimation,\n  type DropResult,\n} from '../../../src';\n\ntype Task = {|\n  id: string,\n  content: string,\n|};\n\ntype TaskItemProps = {|\n  task: Task,\n  index: number,\n|};\n\nconst Canvas = styled.div`\n  padding: ${grid}px;\n  background: ${(props) => (props.isDragging ? colors.G50 : colors.B50)};\n  margin-bottom: ${grid}px;\n  border-radius: 3px;\n`;\n\nconst getStyle = (\n  style: ?DraggableStyle,\n  snapshot: DraggableStateSnapshot,\n): ?Object => {\n  const dropping: ?DropAnimation = snapshot.dropAnimation;\n  if (!dropping) {\n    return style;\n  }\n  const { moveTo, curve, duration } = dropping;\n  const translate = `translate(${moveTo.x}px, ${moveTo.y}px)`;\n  const rotate = 'rotate(1turn)';\n  return {\n    ...style,\n    transform: `${translate} ${rotate}`,\n    // slowing down the drop\n    transition: `all ${curve} ${duration + 1}s`,\n  };\n};\n\nclass TaskItem extends React.Component<TaskItemProps> {\n  render() {\n    const task: Task = this.props.task;\n    return (\n      <Draggable draggableId={task.id} index={this.props.index}>\n        {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n          <Canvas\n            ref={provided.innerRef}\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n            isDragging={snapshot.isDragging && !snapshot.isDropAnimating}\n            style={getStyle(provided.draggableProps.style, snapshot)}\n          >\n            {task.content}\n          </Canvas>\n        )}\n      </Draggable>\n    );\n  }\n}\n\nconst List = styled.div`\n  font-size: 16px;\n  line-height: 1.5;\n  width: 200px;\n  margin: ${grid}px;\n`;\nconst initial: Task[] = Array.from({ length: 10 }, (v, k): Task => ({\n  id: `task-${k}`,\n  content: `Task ${k}`,\n}));\n\ntype State = {|\n  tasks: Task[],\n|};\nexport default class App extends React.Component<*, State> {\n  state: State = {\n    tasks: initial,\n  };\n\n  onDragEnd = (result: DropResult) => {\n    if (!result.destination) {\n      return;\n    }\n    this.setState({\n      tasks: reorder(\n        this.state.tasks,\n        result.source.index,\n        result.destination.index,\n      ),\n    });\n  };\n\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Droppable droppableId=\"droppable\">\n          {(provided: DroppableProvided) => (\n            <List ref={provided.innerRef} {...provided.droppableProps}>\n              {this.state.tasks.map((task: Task, index: number) => (\n                <TaskItem task={task} index={index} key={task.id} />\n              ))}\n            </List>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/custom-drop/no-drop.jsx",
    "content": "// @flow\nimport React from 'react';\nimport styled from '@emotion/styled';\nimport { grid } from '../constants';\nimport reorder from '../reorder';\nimport {\n  DragDropContext,\n  Draggable,\n  Droppable,\n  type DroppableProvided,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type DraggableStyle,\n  type DropResult,\n} from '../../../src';\n\ntype Task = {|\n  id: string,\n  content: string,\n|};\n\ntype TaskItemProps = {|\n  task: Task,\n  index: number,\n|};\n\nconst Canvas = styled.div`\n  padding: ${grid}px;\n  background: lightgrey;\n  margin-bottom: ${grid}px;\n  border-radius: 3px;\n`;\n\nconst getStyle = (\n  style: ?DraggableStyle,\n  snapshot: DraggableStateSnapshot,\n): ?Object => {\n  if (!snapshot.isDropAnimating) {\n    return style;\n  }\n  return {\n    ...style,\n    transitionDuration: `0.001s`,\n  };\n};\n\nclass TaskItem extends React.Component<TaskItemProps> {\n  render() {\n    const task: Task = this.props.task;\n    return (\n      <Draggable draggableId={task.id} index={this.props.index}>\n        {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n          <Canvas\n            ref={provided.innerRef}\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n            style={getStyle(provided.draggableProps.style, snapshot)}\n          >\n            {task.content}\n          </Canvas>\n        )}\n      </Draggable>\n    );\n  }\n}\n\nconst List = styled.div`\n  font-size: 16px;\n  line-height: 1.5;\n  width: 200px;\n  margin: ${grid}px;\n`;\nconst initial: Task[] = Array.from({ length: 10 }, (v, k): Task => ({\n  id: `task-${k}`,\n  content: `Task ${k}`,\n}));\n\ntype State = {|\n  tasks: Task[],\n|};\nexport default class App extends React.Component<*, State> {\n  state: State = {\n    tasks: initial,\n  };\n\n  onDragEnd = (result: DropResult) => {\n    if (!result.destination) {\n      return;\n    }\n    this.setState({\n      tasks: reorder(\n        this.state.tasks,\n        result.source.index,\n        result.destination.index,\n      ),\n    });\n  };\n\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Droppable droppableId=\"droppable\">\n          {(provided: DroppableProvided) => (\n            <List ref={provided.innerRef} {...provided.droppableProps}>\n              {this.state.tasks.map((task: Task, index: number) => (\n                <TaskItem task={task} index={index} key={task.id} />\n              ))}\n            </List>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/data.js",
    "content": "// @flow\nimport { colors } from '@atlaskit/theme';\nimport type { Author, Quote, QuoteMap } from './types';\nimport finnImg from '../static/media/finn-min.png';\nimport bmoImg from '../static/media/bmo-min.png';\nimport princessImg from '../static/media/princess-min.png';\nimport jakeImg from '../static/media/jake-min.png';\n\nconst jake: Author = {\n  id: '1',\n  name: 'Jake',\n  url: 'http://adventuretime.wikia.com/wiki/Jake',\n  avatarUrl: jakeImg,\n  colors: {\n    soft: colors.Y50,\n    hard: colors.N400A,\n  },\n};\n\nconst BMO: Author = {\n  id: '2',\n  name: 'BMO',\n  url: 'http://adventuretime.wikia.com/wiki/BMO',\n  avatarUrl: bmoImg,\n  colors: {\n    soft: colors.G50,\n    hard: colors.N400A,\n  },\n};\n\nconst finn: Author = {\n  id: '3',\n  name: 'Finn',\n  url: 'http://adventuretime.wikia.com/wiki/Finn',\n  avatarUrl: finnImg,\n  colors: {\n    soft: colors.B50,\n    hard: colors.N400A,\n  },\n};\n\nconst princess: Author = {\n  id: '4',\n  name: 'Princess bubblegum',\n  url: 'http://adventuretime.wikia.com/wiki/Princess_Bubblegum',\n  avatarUrl: princessImg,\n  colors: {\n    soft: colors.P50,\n    hard: colors.N400A,\n  },\n};\n\nexport const authors: Author[] = [jake, BMO, finn, princess];\n\nexport const quotes: Quote[] = [\n  {\n    id: '1',\n    content: 'Sometimes life is scary and dark',\n    author: BMO,\n  },\n  {\n    id: '2',\n    content:\n      'Sucking at something is the first step towards being sorta good at something.',\n    author: jake,\n  },\n  {\n    id: '3',\n    content: \"You got to focus on what's real, man\",\n    author: jake,\n  },\n  {\n    id: '4',\n    content: 'Is that where creativity comes from? From sad biz?',\n    author: finn,\n  },\n  {\n    id: '5',\n    content: 'Homies help homies. Always',\n    author: finn,\n  },\n  {\n    id: '6',\n    content: 'Responsibility demands sacrifice',\n    author: princess,\n  },\n  {\n    id: '7',\n    content: \"That's it! The answer was so simple, I was too smart to see it!\",\n    author: princess,\n  },\n  {\n    id: '8',\n    content:\n      \"People make mistakes. It's all a part of growing up and you never really stop growing\",\n    author: finn,\n  },\n  {\n    id: '9',\n    content: \"Don't you always call sweatpants 'give up on life pants,' Jake?\",\n    author: finn,\n  },\n  {\n    id: '10',\n    content: 'I should not have drunk that much tea!',\n    author: princess,\n  },\n  {\n    id: '11',\n    content: 'Please! I need the real you!',\n    author: princess,\n  },\n  {\n    id: '12',\n    content: \"Haven't slept for a solid 83 hours, but, yeah, I'm good.\",\n    author: princess,\n  },\n];\n\n// So we do not have any clashes with our hardcoded ones\nlet idCount: number = quotes.length + 1;\n\nexport const getQuotes = (count: number): Quote[] =>\n  Array.from({ length: count }, (v, k) => k).map(() => {\n    const random: Quote = quotes[Math.floor(Math.random() * quotes.length)];\n\n    const custom: Quote = {\n      ...random,\n      id: `G${idCount++}`,\n    };\n\n    return custom;\n  });\n\nexport const getAuthors = (count: number): Author[] =>\n  Array.from({ length: count }, (v, k) => k).map(() => {\n    const random: Author = authors[Math.floor(Math.random() * authors.length)];\n\n    const custom: Author = {\n      ...random,\n      id: `author-${idCount++}`,\n    };\n\n    return custom;\n  });\n\nconst getByAuthor = (author: Author, items: Quote[]): Quote[] =>\n  items.filter((quote: Quote) => quote.author === author);\n\nexport const authorQuoteMap: QuoteMap = authors.reduce(\n  (previous: QuoteMap, author: Author) => ({\n    ...previous,\n    [author.name]: getByAuthor(author, quotes),\n  }),\n  {},\n);\n\nexport const generateQuoteMap = (quoteCount: number): QuoteMap =>\n  authors.reduce(\n    (previous: QuoteMap, author: Author) => ({\n      ...previous,\n      [author.name]: getQuotes(quoteCount / authors.length),\n    }),\n    {},\n  );\n"
  },
  {
    "path": "stories/src/dynamic/lazy-loading.jsx",
    "content": "// @flow\nimport React from 'react';\nimport QuoteList from '../primatives/quote-list';\nimport { DragDropContext } from '../../../src';\nimport type {\n  DropResult,\n  DragUpdate,\n  DraggableLocation,\n} from '../../../src/types';\nimport type { Quote } from '../types';\nimport { quotes as initial, getQuotes } from '../data';\nimport reorder from '../reorder';\n\ntype State = {|\n  quotes: Quote[],\n  isLoading: boolean,\n|};\n\nexport default class LazyLoading extends React.Component<*, State> {\n  // eslint-disable-next-line react/sort-comp\n  timerId: ?TimeoutID = null;\n  state: State = {\n    quotes: initial,\n    isLoading: false,\n  };\n\n  onDragUpdate = (update: DragUpdate) => {\n    const destination: ?DraggableLocation = update.destination;\n    if (!destination) {\n      return;\n    }\n\n    const lastIndex: number = this.state.quotes.length - 1;\n    const startLoadingFrom: number = lastIndex - 5;\n\n    if (destination.index < startLoadingFrom) {\n      return;\n    }\n\n    this.startLazyLoading();\n  };\n\n  onDragEnd = (result: DropResult) => {\n    // Stop any pending lazy loads\n    if (this.timerId) {\n      clearTimeout(this.timerId);\n      this.timerId = null;\n    }\n    this.setState({\n      isLoading: false,\n    });\n\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    const quotes = reorder(\n      this.state.quotes,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      quotes,\n    });\n  };\n\n  startLazyLoading = () => {\n    if (this.state.isLoading) {\n      return;\n    }\n\n    this.timerId = setTimeout(() => {\n      this.timerId = null;\n\n      const additions: Quote[] = getQuotes(4);\n      const quotes: Quote[] = [...this.state.quotes, ...additions];\n      this.setState({\n        quotes,\n        isLoading: false,\n      });\n    }, 10);\n\n    this.setState({\n      isLoading: true,\n    });\n  };\n\n  render() {\n    return (\n      <DragDropContext\n        onDragUpdate={this.onDragUpdate}\n        onDragEnd={this.onDragEnd}\n      >\n        <QuoteList quotes={this.state.quotes} internalScroll />\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/dynamic/with-controls.jsx",
    "content": "/* eslint-disable no-restricted-syntax */\n// @flow\nimport React from 'react';\nimport styled from '@emotion/styled';\nimport QuoteList from '../primatives/quote-list';\nimport { DragDropContext } from '../../../src';\nimport { generateQuoteMap, authors } from '../data';\nimport { reorderQuoteMap } from '../reorder';\nimport { grid } from '../constants';\nimport type { Quote, QuoteMap, Author } from '../types';\nimport type { DropResult, DragUpdate } from '../../../src/types';\n\nconst initial: QuoteMap = generateQuoteMap(0);\n\nconst ControlSection = styled.div`\n  margin: ${grid * 4}px;\n`;\n\nclass Controls extends React.Component<{|\n  changeBy: number,\n  isCombineEnabled: boolean,\n  onChangeByChange: (changeBy: number) => void,\n  onCombineChange: () => void,\n|}> {\n  render() {\n    return (\n      <ControlSection>\n        <h2>Add or remove items</h2>\n        <ul>\n          <li>\n            <strong>\n              <kbd>b</kbd>\n            </strong>\n            : add to <strong>start</strong> of list\n          </li>\n          <li>\n            <strong>\n              <kbd>a</kbd>\n            </strong>\n            : add to <strong>end</strong> of list\n          </li>\n          <li>\n            <strong>\n              <kbd>s</kbd>\n            </strong>\n            : remove from <strong>start</strong> of list\n          </li>\n          <li>\n            <strong>\n              <kbd>d</kbd>\n            </strong>\n            : remove from <strong>end</strong> of list\n          </li>\n        </ul>\n        <br />\n        Change by:{' '}\n        <input\n          type=\"number\"\n          min=\"1\"\n          max=\"10\"\n          value={this.props.changeBy}\n          onChange={(event: SyntheticInputEvent<HTMLInputElement>) =>\n            this.props.onChangeByChange(Number(event.target.value))\n          }\n        />\n        <h2>Combine items</h2>\n        <p>\n          Can items be combined?{' '}\n          <input\n            type=\"checkbox\"\n            checked={this.props.isCombineEnabled}\n            onChange={this.props.onCombineChange}\n          />\n        </p>\n      </ControlSection>\n    );\n  }\n}\n\ntype State = {|\n  quoteMap: QuoteMap,\n  changeBy: number,\n  isCombineEnabled: boolean,\n|};\n\nconst Container = styled.div`\n  display: flex;\n  align-items: flex-start;\n`;\n\nconst createQuote = (() => {\n  let count: number = 0;\n\n  return (): Quote => {\n    const id: string = `generated-${++count}`;\n    const author: Author = authors[count % authors.length];\n\n    const quote: Quote = {\n      id,\n      content: 'Generated',\n      author,\n    };\n\n    return quote;\n  };\n})();\n\nexport default class WithControls extends React.Component<*, State> {\n  state: State = {\n    quoteMap: initial,\n    changeBy: 2,\n    isCombineEnabled: false,\n  };\n\n  componentDidMount() {\n    window.addEventListener('keydown', this.onWindowKeyDown);\n  }\n\n  componentWillUnmount() {\n    window.removeEventListener('keydown', this.onWindowKeyDown);\n  }\n\n  onWindowKeyDown = (event: KeyboardEvent) => {\n    // Event used as a part of drag and drop\n    if (event.defaultPrevented) {\n      return;\n    }\n\n    const quoteMap: QuoteMap = this.state.quoteMap;\n\n    // eslint-disable-next-line no-console\n    console.log('event.key', event.key);\n\n    // Add quote to start of list ('before')\n    if (event.key === 'b') {\n      // eslint-disable-next-line no-console\n      console.log(`Adding ${this.state.changeBy} to start`);\n      const map: QuoteMap = Object.keys(quoteMap).reduce(\n        (previous: QuoteMap, key: string): QuoteMap => {\n          const quotes: Quote[] = quoteMap[key];\n          const additions: Quote[] = Array.from(\n            { length: this.state.changeBy },\n            () => createQuote(),\n          );\n          previous[key] = [...additions, ...quotes];\n          return previous;\n        },\n        {},\n      );\n\n      this.setState({\n        quoteMap: map,\n      });\n      return;\n    }\n\n    // Add quote to end of list ('after')\n    if (event.key === 'a') {\n      // eslint-disable-next-line no-console\n      console.log(`Adding ${this.state.changeBy} to end`);\n      const map: QuoteMap = Object.keys(quoteMap).reduce(\n        (previous: QuoteMap, key: string): QuoteMap => {\n          const quotes: Quote[] = quoteMap[key];\n          const additions: Quote[] = Array.from(\n            { length: this.state.changeBy },\n            () => createQuote(),\n          );\n          previous[key] = [...quotes, ...additions];\n          return previous;\n        },\n        {},\n      );\n\n      this.setState({\n        quoteMap: map,\n      });\n      return;\n    }\n\n    // Remove quote from end of list\n    if (event.key === 'd') {\n      // eslint-disable-next-line no-console\n      console.log(`Removing ${this.state.changeBy} from end`);\n      const map: QuoteMap = Object.keys(quoteMap).reduce(\n        (previous: QuoteMap, key: string): QuoteMap => {\n          const quotes: Quote[] = quoteMap[key];\n          previous[key] = quotes.length\n            ? quotes.slice(0, quotes.length - this.state.changeBy)\n            : [];\n          return previous;\n        },\n        {},\n      );\n\n      this.setState({\n        quoteMap: map,\n      });\n      return;\n    }\n\n    // Remove quote from start of list\n    if (event.key === 's') {\n      // eslint-disable-next-line no-console\n      console.log(`Removing ${this.state.changeBy} from start`);\n      const map: QuoteMap = Object.keys(quoteMap).reduce(\n        (previous: QuoteMap, key: string): QuoteMap => {\n          const quotes: Quote[] = quoteMap[key];\n          previous[key] = quotes.length\n            ? quotes.slice(this.state.changeBy, quotes.length)\n            : [];\n          return previous;\n        },\n        {},\n      );\n\n      this.setState({\n        quoteMap: map,\n      });\n    }\n  };\n\n  onDragUpdate = (update: DragUpdate) => {\n    // eslint-disable-next-line no-console\n    console.log(\n      'Update: current index =>',\n      update.destination ? update.destination.index : null,\n    );\n  };\n\n  onDragEnd = (result: DropResult) => {\n    if (!result.destination) {\n      return;\n    }\n\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    this.setState(\n      reorderQuoteMap({\n        quoteMap: this.state.quoteMap,\n        source: result.source,\n        destination: result.destination,\n      }),\n    );\n  };\n\n  render() {\n    const { quoteMap, isCombineEnabled, changeBy } = this.state;\n    return (\n      <DragDropContext\n        onDragEnd={this.onDragEnd}\n        onDragUpdate={this.onDragUpdate}\n      >\n        <Controls\n          changeBy={changeBy}\n          isCombineEnabled={isCombineEnabled}\n          onChangeByChange={(value: number) =>\n            this.setState({ changeBy: value })\n          }\n          onCombineChange={() =>\n            this.setState({ isCombineEnabled: !this.state.isCombineEnabled })\n          }\n        />\n        <Container>\n          {Object.keys(quoteMap).map((key: string) => (\n            <QuoteList\n              key={key}\n              listId={key}\n              quotes={quoteMap[key]}\n              style={{ border: '3px solid blue', paddingBottom: grid }}\n              scrollContainerStyle={{ height: 300, border: '3px solid green' }}\n              internalScroll\n              isCombineEnabled={isCombineEnabled}\n            />\n          ))}\n        </Container>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/fixed-list/fixed-sidebar.jsx",
    "content": "// @flow\nimport React, { type Node } from 'react';\nimport ReactDOM from 'react-dom';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport type { Quote } from '../types';\nimport { grid } from '../constants';\nimport { getQuotes } from '../data';\nimport QuoteItem from '../primatives/quote-item';\nimport {\n  DragDropContext,\n  Draggable,\n  Droppable,\n  type DropResult,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type DroppableProvided,\n} from '../../../src';\n\nconst sidebarWidth: number = 300;\n\nconst Title = styled.h2`\n  text-align: center;\n  padding-top: ${grid * 3}px;\n  margin-bottom: ${grid * 3}px;\n`;\n\nconst SidebarContainer = styled.div`\n  width: ${sidebarWidth}px;\n  height: 100vh;\n  overflow: auto;\n  background-color: ${colors.B50};\n  position: fixed;\n`;\n\ntype ListProps = {|\n  quotes: Quote[],\n|};\n\nconst sidebarPortal: HTMLElement = document.createElement('div');\nsidebarPortal.classList.add('sidebar-portal');\n\nif (!document.body) {\n  throw new Error('body not ready for portal creation!');\n}\n\ndocument.body.appendChild(sidebarPortal);\n\nclass Sidebar extends React.Component<ListProps> {\n  render() {\n    return (\n      <SidebarContainer>\n        <Title>Fixed sidebar</Title>\n        <Droppable droppableId=\"sidebar\">\n          {(droppableProvided: DroppableProvided) => (\n            <div\n              {...droppableProvided.droppableProps}\n              ref={droppableProvided.innerRef}\n            >\n              {this.props.quotes.map((quote: Quote, index: number) => (\n                <Draggable draggableId={quote.id} index={index} key={quote.id}>\n                  {(\n                    draggableProvided: DraggableProvided,\n                    draggableSnapshot: DraggableStateSnapshot,\n                  ) => {\n                    const usePortal: boolean = draggableSnapshot.isDragging;\n\n                    const child: Node = (\n                      <QuoteItem\n                        quote={quote}\n                        isDragging={draggableSnapshot.isDragging}\n                        provided={draggableProvided}\n                      />\n                    );\n                    if (!usePortal) {\n                      return child;\n                    }\n                    return ReactDOM.createPortal(child, sidebarPortal);\n                  }}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </SidebarContainer>\n    );\n  }\n}\n\nconst ContentContainer = styled.div`\n  margin-left: ${sidebarWidth}px;\n`;\n\nconst ContentList = styled.div`\n  width: ${sidebarWidth}px;\n  margin: 0 auto;\n`;\n\nclass Content extends React.Component<ListProps> {\n  render() {\n    return (\n      <ContentContainer>\n        <Title>Scrollable body</Title>\n        <p>Current limitation: they cannot be connected</p>\n        <Droppable droppableId=\"content\" type=\"fixed\">\n          {(droppableProvided: DroppableProvided) => (\n            <ContentList\n              {...droppableProvided.droppableProps}\n              ref={droppableProvided.innerRef}\n            >\n              {this.props.quotes.map((quote: Quote, index: number) => (\n                <Draggable draggableId={quote.id} index={index} key={quote.id}>\n                  {(\n                    draggableProvided: DraggableProvided,\n                    draggableSnapshot: DraggableStateSnapshot,\n                  ) => (\n                    <QuoteItem\n                      quote={quote}\n                      isDragging={draggableSnapshot.isDragging}\n                      provided={draggableProvided}\n                    />\n                  )}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder}\n            </ContentList>\n          )}\n        </Droppable>\n      </ContentContainer>\n    );\n  }\n}\n\ntype State = {|\n  inSidebar: Quote[],\n  inContent: Quote[],\n|};\n\nconst initial: State = {\n  inSidebar: getQuotes(40),\n  inContent: getQuotes(100),\n};\n\nexport default class App extends React.Component<*, State> {\n  state: State = initial;\n\n  onDragEnd = (result: DropResult) => {\n    // eslint-disable-next-line no-console\n    console.log('TODO: reorder', result);\n  };\n\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <React.Fragment>\n          <Sidebar quotes={this.state.inSidebar} />\n          <Content quotes={this.state.inContent} />\n        </React.Fragment>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/function-component/quote-app.jsx",
    "content": "// @flow\nimport React, { useState } from 'react';\nimport styled from '@emotion/styled';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\nimport type {\n  DropResult,\n  DraggableProvided,\n  DroppableProvided,\n} from '../../../src';\nimport type { Quote as QuoteType } from '../types';\nimport { quotes as initial } from '../data';\nimport reorder from '../reorder';\nimport { grid } from '../constants';\n\ntype QuoteProps = {|\n  quote: QuoteType,\n  index: number,\n|};\n\nconst QuoteItem = styled.div`\n  width: 200px;\n  border: 1px solid grey;\n  margin-bottom: ${grid}px;\n  background-color: lightblue;\n  padding: ${grid}px;\n`;\n\nfunction Quote({ quote, index }: QuoteProps) {\n  return (\n    <Draggable draggableId={quote.id} index={index}>\n      {(provided: DraggableProvided) => (\n        <QuoteItem\n          ref={provided.innerRef}\n          {...provided.draggableProps}\n          {...provided.dragHandleProps}\n        >\n          {quote.content}\n        </QuoteItem>\n      )}\n    </Draggable>\n  );\n}\n\ntype QuoteListProps = {|\n  quotes: QuoteType[],\n|};\n\n// Ensuring the whole list does not re-render when the droppable re-renders\nconst QuoteList = React.memo(function QuoteList({ quotes }: QuoteListProps) {\n  return quotes.map((quote: QuoteType, index: number) => (\n    <Quote quote={quote} index={index} key={quote.id} />\n  ));\n});\n\nfunction QuoteApp() {\n  const [quotes, setQuotes] = useState(initial);\n\n  function onDragEnd(result: DropResult) {\n    if (!result.destination) {\n      return;\n    }\n\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    const newQuotes = reorder(\n      quotes,\n      result.source.index,\n      result.destination.index,\n    );\n\n    setQuotes(newQuotes);\n  }\n\n  return (\n    <DragDropContext onDragEnd={onDragEnd}>\n      <Droppable droppableId=\"list\">\n        {(provided: DroppableProvided) => (\n          <div ref={provided.innerRef} {...provided.droppableProps}>\n            <QuoteList quotes={quotes} />\n            {provided.placeholder}\n          </div>\n        )}\n      </Droppable>\n    </DragDropContext>\n  );\n}\n\nexport default QuoteApp;\n"
  },
  {
    "path": "stories/src/horizontal/author-app.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { DragDropContext } from '../../../src';\nimport type { DropResult } from '../../../src';\nimport type { Quote } from '../types';\nimport AuthorList from '../primatives/author-list';\nimport reorder from '../reorder';\nimport { grid } from '../constants';\n\ntype Props = {|\n  initial: Quote[],\n  internalScroll?: boolean,\n  isCombineEnabled?: boolean,\n|};\n\ntype State = {|\n  quotes: Quote[],\n|};\n\nconst Root = styled.div`\n  padding: ${grid}px;\n  background: ${colors.B50};\n`;\n\nexport default class AuthorApp extends Component<Props, State> {\n  /* eslint-disable react/sort-comp */\n  static defaultProps = {\n    isCombineEnabled: false,\n  };\n\n  state: State = {\n    quotes: this.props.initial,\n  };\n  /* eslint-enable react/sort-comp */\n\n  onDragEnd = (result: DropResult) => {\n    // super simple, just removing the dragging item\n    if (result.combine) {\n      const quotes: Quote[] = [...this.state.quotes];\n      quotes.splice(result.source.index, 1);\n      this.setState({ quotes });\n      return;\n    }\n\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    const quotes = reorder(\n      this.state.quotes,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      quotes,\n    });\n  };\n\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Root>\n          <AuthorList\n            listId=\"AUTHOR\"\n            internalScroll={this.props.internalScroll}\n            isCombineEnabled={this.props.isCombineEnabled}\n            quotes={this.state.quotes}\n          />\n        </Root>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/interactive-elements/interactive-elements-app.jsx",
    "content": "// @flow\nimport React, { type Node } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\nimport { grid } from '../constants';\nimport reorder from '../reorder';\nimport type {\n  DropResult,\n  DroppableProvided,\n  DraggableProvided,\n} from '../../../src';\n\ntype ItemType = {|\n  id: string,\n  component: Node,\n|};\n\nconst initial: ItemType[] = [\n  {\n    id: 'button',\n    component: (\n      <div>\n        <p>Standard</p>\n        <button type=\"button\">hello world</button>\n        <br />\n        <p>\n          With child{' '}\n          <a\n            href=\"https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Phrasing_content\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            phrasing content\n          </a>\n        </p>\n        <button type=\"button\">\n          why{' '}\n          <strong>\n            hello <em>there!</em>\n          </strong>\n        </button>\n        <p>\n          With child{' '}\n          <a\n            href=\"https://developer.mozilla.org/en-US/docs/Web/API/SVGElement\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            SVGElement\n          </a>\n        </p>\n        <button type=\"button\">\n          My circle <br />\n          <svg width=\"40\" height=\"40\">\n            <circle cx=\"20\" cy=\"20\" r=\"20\" />\n          </svg>\n        </button>\n      </div>\n    ),\n  },\n  {\n    id: 'select',\n    component: (\n      <select>\n        <option>Option 1</option>\n        <option>Option 2</option>\n        <option>Option 3</option>\n      </select>\n    ),\n  },\n  {\n    id: 'textarea',\n    component: <textarea placeholder=\"type some text here\" />,\n  },\n  {\n    id: 'input',\n    component: (\n      <div>\n        <input type=\"text\" placeholder=\"text input\" />\n      </div>\n    ),\n  },\n  {\n    id: 'checkbox',\n    component: (\n      <div>\n        <label htmlFor=\"myCheckbox1\">\n          <input id=\"myCheckbox1\" type=\"checkbox\" name=\"myCheckbox\" />\n          Checkbox 1\n        </label>\n        <br />\n        <label htmlFor=\"myCheckbox2\">\n          <input id=\"myCheckbox2\" type=\"checkbox\" name=\"myCheckbox\" />\n          Checkbox 2\n        </label>\n      </div>\n    ),\n  },\n  {\n    id: 'radio',\n    component: (\n      <div>\n        <label htmlFor=\"myRadio\">\n          <input id=\"myRadio1\" type=\"radio\" name=\"myRadio\" />\n          Option 1\n        </label>\n        <br />\n        <label htmlFor=\"myRadio\">\n          <input id=\"myRadio2\" type=\"radio\" name=\"myRadio\" />\n          Option 2\n        </label>\n      </div>\n    ),\n  },\n  {\n    id: 'range',\n    component: <input type=\"range\" min=\"1\" max=\"100\" />,\n  },\n  {\n    id: 'content editable',\n    component: (\n      <div\n        contentEditable\n        // eslint-disable-next-line react/no-danger\n        dangerouslySetInnerHTML={{\n          __html: `\n            A content editable with\n            <strong>my super cool content</strong>\n          `,\n        }}\n      />\n    ),\n  },\n];\n\nconst List = styled.div`\n  width: 250px;\n  background-color: ${colors.B200};\n  padding: ${grid * 2}px;\n`;\n\nconst Item = styled.div`\n  min-height: 80px;\n  background-color: ${colors.N0};\n  border: 1px solid ${colors.N100};\n  padding: ${grid}px;\n  margin-bottom: ${grid}px;\n`;\n\nconst Container = styled.div`\n  display: flex;\n`;\n\nconst Controls = styled.div`\n  padding: ${grid * 2}px;\n  width: 250px;\n`;\n\nconst Status = styled.strong`\n  color: ${({ isEnabled }) => (isEnabled ? colors.B200 : colors.P100)};\n`;\n\ntype State = {|\n  canDragInteractiveElements: boolean,\n  items: ItemType[],\n|};\n\nexport default class InteractiveElementsApp extends React.Component<*, State> {\n  state: State = {\n    items: initial,\n    canDragInteractiveElements: false,\n  };\n\n  onDragEnd = (result: DropResult) => {\n    if (!result.destination) {\n      return;\n    }\n\n    if (result.source.index === result.destination.index) {\n      return;\n    }\n\n    const items = reorder(\n      this.state.items,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      items,\n    });\n  };\n\n  toggleBlocking = () => {\n    this.setState({\n      canDragInteractiveElements: !this.state.canDragInteractiveElements,\n    });\n  };\n\n  render() {\n    const { canDragInteractiveElements } = this.state;\n\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Container>\n          <Droppable droppableId=\"droppable\">\n            {(droppableProvided: DroppableProvided) => (\n              <List\n                ref={droppableProvided.innerRef}\n                {...droppableProvided.droppableProps}\n              >\n                {this.state.items.map((item: ItemType, index: number) => (\n                  <Draggable\n                    key={item.id}\n                    draggableId={item.id}\n                    disableInteractiveElementBlocking={\n                      canDragInteractiveElements\n                    }\n                    index={index}\n                  >\n                    {(draggableProvided: DraggableProvided) => (\n                      <Item\n                        ref={draggableProvided.innerRef}\n                        {...draggableProvided.draggableProps}\n                        {...draggableProvided.dragHandleProps}\n                      >\n                        {item.component}\n                      </Item>\n                    )}\n                  </Draggable>\n                ))}\n                {droppableProvided.placeholder}\n              </List>\n            )}\n          </Droppable>\n          <Controls>\n            <p>\n              Dragging from interactive elements is{' '}\n              <Status isEnabled={canDragInteractiveElements}>\n                {canDragInteractiveElements ? 'enabled' : 'disabled'}\n              </Status>\n            </p>\n            <button type=\"button\" onClick={this.toggleBlocking}>\n              toggle\n            </button>\n          </Controls>\n        </Container>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/mixed-sizes/mixed-size-items.jsx",
    "content": "// @flow\nimport React, { useState } from 'react';\nimport { quotes as initial } from '../data';\nimport type { Quote } from '../types';\nimport QuoteList from '../primatives/quote-list';\nimport { DragDropContext, type DropResult } from '../../../src';\nimport reorder from '../reorder';\n\nfunction getQuotes() {\n  const large: Quote = {\n    ...initial[0],\n    content: Array.from({ length: 20 })\n      .map(() => 'some really long text')\n      .join(' '),\n  };\n\n  const quotes: Quote[] = [large, ...initial.slice(1)];\n  return quotes;\n}\n\nexport default function App() {\n  const [quotes, setQuotes] = useState(() => getQuotes());\n  const [isCombineEnabled, setIsCombineEnabled] = useState(false);\n  function onDragEnd(result: DropResult) {\n    if (!result.destination) {\n      return;\n    }\n    setQuotes(reorder(quotes, result.source.index, result.destination.index));\n  }\n  return (\n    <DragDropContext onDragEnd={onDragEnd}>\n      <button\n        type=\"button\"\n        onClick={() => setIsCombineEnabled((value) => !value)}\n      >\n        Combining <strong>{isCombineEnabled ? 'enabled' : 'disabled'}</strong>\n      </button>\n      <QuoteList quotes={quotes} isCombineEnabled={isCombineEnabled} />\n    </DragDropContext>\n  );\n}\n"
  },
  {
    "path": "stories/src/mixed-sizes/mixed-size-lists-experiment.jsx",
    "content": "// @flow\nimport React, { useState, useEffect, useRef, useContext } from 'react';\nimport { getBox, type Position, type BoxModel } from 'css-box-model';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { getQuotes } from '../data';\nimport { type Quote } from '../types';\nimport {\n  DragDropContext,\n  type BeforeCapture,\n  type DropResult,\n  Droppable,\n  Draggable,\n} from '../../../src';\nimport bindEvents from '../../../src/view/event-bindings/bind-events';\nimport { grid } from '../constants';\nimport reorder, { moveBetween } from '../reorder';\n\nconst UseTrimmingContext = React.createContext<boolean>(false);\n\nconst Parent = styled.div`\n  display: flex;\n`;\n\ntype Width = 'small' | 'large';\n\ntype ItemProps = {|\n  quote: Quote,\n  index: number,\n  shouldAllowTrimming: boolean,\n|};\n\nconst StyledItem = styled.div`\n  border: 1px solid ${colors.N100};\n  background: ${colors.G50};\n  padding: ${grid}px;\n  margin-bottom: ${grid}px;\n  user-select: none;\n`;\n\nfunction Item(props: ItemProps) {\n  const { quote, index } = props;\n  const ref = useRef<?HTMLElement>(null);\n  const useTrimming: boolean = useContext(UseTrimmingContext);\n\n  useEffect(() => {\n    const unsubscribe = bindEvents(window, [\n      {\n        eventName: 'onBeforeCapture',\n        fn: (event: CustomEvent) => {\n          if (!useTrimming) {\n            return;\n          }\n          if (!props.shouldAllowTrimming) {\n            return;\n          }\n\n          const before: BeforeCapture = event.detail.before;\n          const clientSelection: Position = event.detail.clientSelection;\n\n          if (before.mode !== 'FLUID') {\n            return;\n          }\n\n          if (before.draggableId !== quote.id) {\n            return;\n          }\n\n          const el: ?HTMLElement = ref.current;\n\n          if (!el) {\n            return;\n          }\n\n          const box: BoxModel = getBox(el);\n\n          // want to shrink the item to 200px wide.\n          // want it to be centered as much as possible to the cursor\n          const targetWidth: number = 250;\n          const halfWidth: number = targetWidth / 2;\n          const distanceToLeft: number = Math.max(\n            clientSelection.x - box.borderBox.left,\n            0,\n          );\n\n          el.style.width = `${targetWidth}px`;\n\n          // Nothing left to do\n          if (distanceToLeft < halfWidth) {\n            return;\n          }\n\n          // what the new left will be\n          const proposedLeftOffset: number = distanceToLeft - halfWidth;\n          // what the raw right value would be\n          const targetRight: number =\n            box.borderBox.left + proposedLeftOffset + targetWidth;\n\n          // how much we would be going past the right value\n          const rightOverlap: number = Math.max(\n            targetRight - box.borderBox.right,\n            0,\n          );\n\n          // need to ensure that we don't pull the element past\n          // it's resting right position\n          const leftOffset: number = proposedLeftOffset - rightOverlap;\n\n          el.style.position = 'relative';\n          el.style.left = `${leftOffset}px`;\n        },\n      },\n    ]);\n\n    return unsubscribe;\n  }, [props.shouldAllowTrimming, quote.id, useTrimming]);\n\n  return (\n    <Draggable draggableId={quote.id} index={index}>\n      {(provided) => (\n        <StyledItem\n          {...provided.draggableProps}\n          {...provided.dragHandleProps}\n          ref={(node: ?HTMLElement) => {\n            provided.innerRef(node);\n            ref.current = node;\n          }}\n          shouldAllowTrimming={props.shouldAllowTrimming}\n        >\n          {quote.content}\n        </StyledItem>\n      )}\n    </Draggable>\n  );\n}\n\ntype ListProps = {|\n  listId: string,\n  quotes: Quote[],\n  width: Width,\n|};\n\nconst StyledList = styled.div`\n  border: 1px solid ${colors.N100};\n  margin: ${grid}px;\n  padding: ${grid}px;\n  box-sizing: border-box;\n  background-color: ${(props) =>\n    props.isDraggingOver ? colors.B100 : 'inherit'};\n  width: ${(props) => (props.width === 'large' ? 800 : 200)}px;\n`;\n\nfunction List(props: ListProps) {\n  return (\n    <Droppable droppableId={props.listId}>\n      {(provided, snapshot) => (\n        <StyledList\n          {...provided.droppableProps}\n          ref={provided.innerRef}\n          isDraggingOver={snapshot.isDraggingOver}\n          width={props.width}\n        >\n          {props.quotes.map((quote: Quote, index: number) => (\n            <Item\n              key={quote.id}\n              quote={quote}\n              index={index}\n              shouldAllowTrimming={props.width === 'large'}\n            />\n          ))}\n          {provided.placeholder}\n        </StyledList>\n      )}\n    </Droppable>\n  );\n}\n\nexport default function App() {\n  const [first, setFirst] = useState(() => getQuotes(3));\n  const [second, setSecond] = useState(() => getQuotes(3));\n  const [useTrimming, setUseTrimming] = useState(false);\n  const clientSelectionRef = useRef<Position>({ x: 0, y: 0 });\n\n  function onDragEnd(result: DropResult) {\n    const { source, destination } = result;\n    if (!destination) {\n      return;\n    }\n    if (source.droppableId === destination.droppableId) {\n      if (source.droppableId === 'first') {\n        setFirst(reorder(first, source.index, destination.index));\n      } else {\n        setSecond(reorder(second, source.index, destination.index));\n      }\n      return;\n    }\n\n    const { list1, list2 } = moveBetween({\n      list1: {\n        id: 'first',\n        values: first,\n      },\n      list2: {\n        id: 'second',\n        values: second,\n      },\n      source,\n      destination,\n    });\n\n    setFirst(list1.values);\n    setSecond(list2.values);\n  }\n\n  useEffect(() => {\n    const unsubscribe = bindEvents(window, [\n      {\n        eventName: 'mousemove',\n        fn: (event: MouseEvent) => {\n          const current: Position = {\n            x: event.clientX,\n            y: event.clientY,\n          };\n          clientSelectionRef.current = current;\n        },\n        options: { passive: true },\n      },\n    ]);\n    return unsubscribe;\n  });\n\n  function onBeforeCapture(before: BeforeCapture) {\n    window.dispatchEvent(\n      new CustomEvent('onBeforeCapture', {\n        detail: { before, clientSelection: clientSelectionRef.current },\n      }),\n    );\n  }\n  return (\n    <UseTrimmingContext.Provider value={useTrimming}>\n      <DragDropContext onBeforeCapture={onBeforeCapture} onDragEnd={onDragEnd}>\n        <Parent>\n          <List listId=\"first\" quotes={first} width=\"small\" />\n          <List listId=\"second\" quotes={second} width=\"large\" />\n        </Parent>\n        Item trimming experiment:{' '}\n        <strong>{useTrimming ? 'enabled' : 'disabled'}</strong>\n        <button\n          type=\"button\"\n          onClick={() => setUseTrimming((value: boolean) => !value)}\n        >\n          {useTrimming ? 'disable' : 'enable'}\n        </button>\n      </DragDropContext>\n    </UseTrimmingContext.Provider>\n  );\n}\n"
  },
  {
    "path": "stories/src/mixed-sizes/mixed-size-lists.jsx",
    "content": "// @flow\nimport { colors } from '@atlaskit/theme';\nimport styled from '@emotion/styled';\nimport React, { useState } from 'react';\nimport { useMemo } from 'use-memo-one';\nimport {\n  DragDropContext,\n  Draggable,\n  Droppable,\n  type DropResult,\n} from '../../../src';\nimport type { Quote } from '../types';\nimport { grid } from '../constants';\nimport { authorQuoteMap } from '../data';\nimport reorder, { reorderQuoteMap } from '../reorder';\n\nconst Parent = styled.div`\n  display: flex;\n`;\n\ntype Width = 'small' | 'large';\n\ntype ItemProps = {|\n  quote: Quote,\n  index: number,\n|};\n\nconst StyledItem = styled.div`\n  border: 1px solid ${colors.N100};\n  background: ${colors.G50};\n  padding: ${grid}px;\n  margin-bottom: ${grid}px;\n  user-select: none;\n`;\n\nfunction Item(props: ItemProps) {\n  const { quote, index } = props;\n\n  return (\n    <Draggable draggableId={quote.id} index={index}>\n      {(provided) => (\n        <StyledItem\n          {...provided.draggableProps}\n          {...provided.dragHandleProps}\n          ref={provided.innerRef}\n        >\n          {quote.content}\n        </StyledItem>\n      )}\n    </Draggable>\n  );\n}\n\ntype ListProps = {|\n  listId: string,\n  quotes: Quote[],\n|};\n\nconst ListContainer = styled.div`\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n`;\n\nconst Controls = styled.div``;\n\nconst StyledList = styled.div`\n  border: 1px solid ${colors.N100};\n  margin: ${grid}px;\n  padding: ${grid}px;\n  box-sizing: border-box;\n  background-color: ${(props) =>\n    props.isDraggingOver ? colors.B100 : 'inherit'};\n  width: ${(props) => (props.width === 'large' ? 800 : 200)}px;\n`;\n\nfunction List(props: ListProps) {\n  const [width, setWidth] = useState<Width>('small');\n  return (\n    <ListContainer>\n      <Controls>\n        <button type=\"button\" onClick={() => setWidth('small')}>\n          Small\n        </button>\n        <button type=\"button\" onClick={() => setWidth('large')}>\n          Large\n        </button>\n      </Controls>\n      <Droppable droppableId={props.listId}>\n        {(provided, snapshot) => (\n          <StyledList\n            {...provided.droppableProps}\n            ref={provided.innerRef}\n            isDraggingOver={snapshot.isDraggingOver}\n            width={width}\n          >\n            {props.quotes.map((quote: Quote, index: number) => (\n              <Item key={quote.id} quote={quote} index={index} />\n            ))}\n            {provided.placeholder}\n          </StyledList>\n        )}\n      </Droppable>\n    </ListContainer>\n  );\n}\n\nexport default function App() {\n  const [columns, setColumns] = useState(authorQuoteMap);\n  const ordered = useMemo(() => Object.keys(columns), [columns]);\n\n  function onDragEnd(result: DropResult) {\n    const { source, destination } = result;\n\n    if (!destination) {\n      return;\n    }\n\n    // reordering in same list\n    if (source.droppableId === destination.droppableId) {\n      const newQuotes: Quote[] = reorder(\n        columns[source.droppableId],\n        source.index,\n        destination.index,\n      );\n      setColumns({\n        ...columns,\n        [source.droppableId]: newQuotes,\n      });\n      return;\n    }\n\n    // moving between columns\n\n    // remove item from source list\n    const newColumns = reorderQuoteMap({\n      quoteMap: columns,\n      source,\n      destination,\n    });\n\n    setColumns(newColumns.quoteMap);\n  }\n\n  return (\n    <DragDropContext onDragEnd={onDragEnd}>\n      <Parent>\n        {ordered.map((key: string) => (\n          <List listId={key} quotes={columns[key]} key={key} />\n        ))}\n      </Parent>\n    </DragDropContext>\n  );\n}\n"
  },
  {
    "path": "stories/src/multi-drag/column.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport memoizeOne from 'memoize-one';\nimport { colors } from '@atlaskit/theme';\nimport { Droppable } from '../../../src';\nimport { grid, borderRadius } from '../constants';\nimport Task from './task';\nimport type { DroppableProvided, DroppableStateSnapshot } from '../../../src';\nimport type { Column as ColumnType } from './types';\nimport type { Task as TaskType, Id } from '../types';\n\ntype Props = {|\n  column: ColumnType,\n  tasks: TaskType[],\n  selectedTaskIds: Id[],\n  draggingTaskId: ?Id,\n  toggleSelection: (taskId: Id) => void,\n  toggleSelectionInGroup: (taskId: Id) => void,\n  multiSelectTo: (taskId: Id) => void,\n|};\n\n// $ExpectError - not sure why\nconst Container = styled.div`\n  width: 300px;\n  margin: ${grid}px;\n  border-radius: ${borderRadius}px;\n  border: 1px solid ${colors.N100};\n  background-color: ${colors.N50};\n\n  /* we want the column to take up its full height */\n  display: flex;\n  flex-direction: column;\n`;\n\nconst Title = styled.h3`\n  font-weight: bold;\n  padding: ${grid}px;\n`;\n\nconst TaskList = styled.div`\n  padding: ${grid}px;\n  min-height: 200px;\n  flex-grow: 1;\n  transition: background-color 0.2s ease;\n  ${(props) =>\n    props.isDraggingOver ? `background-color: ${colors.N200}` : ''};\n`;\n\ntype TaskIdMap = {\n  [taskId: Id]: true,\n};\n\nconst getSelectedMap = memoizeOne((selectedTaskIds: Id[]) =>\n  selectedTaskIds.reduce((previous: TaskIdMap, current: Id): TaskIdMap => {\n    previous[current] = true;\n    return previous;\n  }, {}),\n);\n\nexport default class Column extends Component<Props> {\n  render() {\n    const column: ColumnType = this.props.column;\n    const tasks: TaskType[] = this.props.tasks;\n    const selectedTaskIds: Id[] = this.props.selectedTaskIds;\n    const draggingTaskId: ?Id = this.props.draggingTaskId;\n    return (\n      <Container>\n        <Title>{column.title}</Title>\n        <Droppable droppableId={column.id}>\n          {(provided: DroppableProvided, snapshot: DroppableStateSnapshot) => (\n            <TaskList\n              ref={provided.innerRef}\n              isDraggingOver={snapshot.isDraggingOver}\n              {...provided.droppableProps}\n            >\n              {tasks.map((task: TaskType, index: number) => {\n                const isSelected: boolean = Boolean(\n                  getSelectedMap(selectedTaskIds)[task.id],\n                );\n                const isGhosting: boolean =\n                  isSelected &&\n                  Boolean(draggingTaskId) &&\n                  draggingTaskId !== task.id;\n                return (\n                  <Task\n                    task={task}\n                    index={index}\n                    key={task.id}\n                    isSelected={isSelected}\n                    isGhosting={isGhosting}\n                    selectionCount={selectedTaskIds.length}\n                    toggleSelection={this.props.toggleSelection}\n                    toggleSelectionInGroup={this.props.toggleSelectionInGroup}\n                    multiSelectTo={this.props.multiSelectTo}\n                  />\n                );\n              })}\n              {provided.placeholder}\n            </TaskList>\n          )}\n        </Droppable>\n      </Container>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/multi-drag/data.js",
    "content": "// @flow\nimport type { Column, Entities, TaskMap } from './types';\nimport type { Task, Id } from '../types';\n\nconst tasks: Task[] = Array.from({ length: 20 }, (v, k) => k).map(\n  (val: number): Task => ({\n    id: `task-${val}`,\n    content: `Task ${val}`,\n  }),\n);\n\nconst taskMap: TaskMap = tasks.reduce(\n  (previous: TaskMap, current: Task): TaskMap => {\n    previous[current.id] = current;\n    return previous;\n  },\n  {},\n);\n\nconst todo: Column = {\n  id: 'todo',\n  title: 'To do',\n  taskIds: tasks.map((task: Task): Id => task.id),\n};\n\nconst done: Column = {\n  id: 'done',\n  title: 'Done',\n  taskIds: [],\n};\n\nconst entities: Entities = {\n  columnOrder: [todo.id, done.id],\n  columns: {\n    [todo.id]: todo,\n    [done.id]: done,\n  },\n  tasks: taskMap,\n};\n\nexport default entities;\n"
  },
  {
    "path": "stories/src/multi-drag/task-app.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { DragDropContext } from '../../../src';\nimport initial from './data';\nimport Column from './column';\nimport type { Result as ReorderResult } from './utils';\nimport { mutliDragAwareReorder, multiSelectTo as multiSelect } from './utils';\nimport type { DragStart, DropResult, DraggableLocation } from '../../../src';\nimport type { Task, Id } from '../types';\nimport type { Entities } from './types';\n\nconst Container = styled.div`\n  display: flex;\n  user-select: none;\n`;\n\ntype State = {|\n  entities: Entities,\n  selectedTaskIds: Id[],\n  // sad times\n  draggingTaskId: ?Id,\n|};\n\nconst getTasks = (entities: Entities, columnId: Id): Task[] =>\n  entities.columns[columnId].taskIds.map(\n    (taskId: Id): Task => entities.tasks[taskId],\n  );\nexport default class TaskApp extends Component<*, State> {\n  state: State = {\n    entities: initial,\n    selectedTaskIds: [],\n    draggingTaskId: null,\n  };\n\n  componentDidMount() {\n    window.addEventListener('click', this.onWindowClick);\n    window.addEventListener('keydown', this.onWindowKeyDown);\n    window.addEventListener('touchend', this.onWindowTouchEnd);\n  }\n\n  componentWillUnmount() {\n    window.removeEventListener('click', this.onWindowClick);\n    window.removeEventListener('keydown', this.onWindowKeyDown);\n    window.removeEventListener('touchend', this.onWindowTouchEnd);\n  }\n\n  onDragStart = (start: DragStart) => {\n    const id: string = start.draggableId;\n    const selected: ?Id = this.state.selectedTaskIds.find(\n      (taskId: Id): boolean => taskId === id,\n    );\n\n    // if dragging an item that is not selected - unselect all items\n    if (!selected) {\n      this.unselectAll();\n    }\n    this.setState({\n      draggingTaskId: start.draggableId,\n    });\n  };\n\n  onDragEnd = (result: DropResult) => {\n    const destination: ?DraggableLocation = result.destination;\n    const source: DraggableLocation = result.source;\n\n    // nothing to do\n    if (!destination || result.reason === 'CANCEL') {\n      this.setState({\n        draggingTaskId: null,\n      });\n      return;\n    }\n\n    const processed: ReorderResult = mutliDragAwareReorder({\n      entities: this.state.entities,\n      selectedTaskIds: this.state.selectedTaskIds,\n      source,\n      destination,\n    });\n\n    this.setState({\n      ...processed,\n      draggingTaskId: null,\n    });\n  };\n\n  onWindowKeyDown = (event: KeyboardEvent) => {\n    if (event.defaultPrevented) {\n      return;\n    }\n\n    if (event.key === 'Escape') {\n      this.unselectAll();\n    }\n  };\n\n  onWindowClick = (event: KeyboardEvent) => {\n    if (event.defaultPrevented) {\n      return;\n    }\n    this.unselectAll();\n  };\n\n  onWindowTouchEnd = (event: TouchEvent) => {\n    if (event.defaultPrevented) {\n      return;\n    }\n    this.unselectAll();\n  };\n\n  toggleSelection = (taskId: Id) => {\n    const selectedTaskIds: Id[] = this.state.selectedTaskIds;\n    const wasSelected: boolean = selectedTaskIds.includes(taskId);\n\n    const newTaskIds: Id[] = (() => {\n      // Task was not previously selected\n      // now will be the only selected item\n      if (!wasSelected) {\n        return [taskId];\n      }\n\n      // Task was part of a selected group\n      // will now become the only selected item\n      if (selectedTaskIds.length > 1) {\n        return [taskId];\n      }\n\n      // task was previously selected but not in a group\n      // we will now clear the selection\n      return [];\n    })();\n\n    this.setState({\n      selectedTaskIds: newTaskIds,\n    });\n  };\n\n  toggleSelectionInGroup = (taskId: Id) => {\n    const selectedTaskIds: Id[] = this.state.selectedTaskIds;\n    const index: number = selectedTaskIds.indexOf(taskId);\n\n    // if not selected - add it to the selected items\n    if (index === -1) {\n      this.setState({\n        selectedTaskIds: [...selectedTaskIds, taskId],\n      });\n      return;\n    }\n\n    // it was previously selected and now needs to be removed from the group\n    const shallow: Id[] = [...selectedTaskIds];\n    shallow.splice(index, 1);\n    this.setState({\n      selectedTaskIds: shallow,\n    });\n  };\n\n  // This behaviour matches the MacOSX finder selection\n  multiSelectTo = (newTaskId: Id) => {\n    const updated: ?(Id[]) = multiSelect(\n      this.state.entities,\n      this.state.selectedTaskIds,\n      newTaskId,\n    );\n\n    if (updated == null) {\n      return;\n    }\n\n    this.setState({\n      selectedTaskIds: updated,\n    });\n  };\n\n  unselect = () => {\n    this.unselectAll();\n  };\n\n  unselectAll = () => {\n    this.setState({\n      selectedTaskIds: [],\n    });\n  };\n\n  render() {\n    const entities: Entities = this.state.entities;\n    const selected: Id[] = this.state.selectedTaskIds;\n    return (\n      <DragDropContext\n        onDragStart={this.onDragStart}\n        onDragEnd={this.onDragEnd}\n      >\n        <Container>\n          {entities.columnOrder.map((columnId: Id) => (\n            <Column\n              column={entities.columns[columnId]}\n              tasks={getTasks(entities, columnId)}\n              selectedTaskIds={selected}\n              key={columnId}\n              draggingTaskId={this.state.draggingTaskId}\n              toggleSelection={this.toggleSelection}\n              toggleSelectionInGroup={this.toggleSelectionInGroup}\n              multiSelectTo={this.multiSelectTo}\n            />\n          ))}\n        </Container>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/multi-drag/task.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { Draggable } from '../../../src';\nimport { grid, borderRadius } from '../constants';\nimport type { DraggableProvided, DraggableStateSnapshot } from '../../../src';\nimport type { Id, Task as TaskType } from '../types';\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button\nconst primaryButton = 0;\n\ntype Props = {|\n  task: TaskType,\n  index: number,\n  isSelected: boolean,\n  isGhosting: boolean,\n  selectionCount: number,\n  toggleSelection: (taskId: Id) => void,\n  toggleSelectionInGroup: (taskId: Id) => void,\n  multiSelectTo: (taskId: Id) => void,\n|};\n\ntype GetBackgroundColorArgs = {|\n  isSelected: boolean,\n  isDragging: boolean,\n  isGhosting: boolean,\n|};\n\nconst getBackgroundColor = ({\n  isSelected,\n  isGhosting,\n}: GetBackgroundColorArgs): string => {\n  if (isGhosting) {\n    return colors.N10;\n  }\n\n  if (isSelected) {\n    return colors.B50;\n  }\n\n  return colors.N10;\n};\n\nconst getColor = ({ isSelected, isGhosting }): string => {\n  if (isGhosting) {\n    return 'darkgrey';\n  }\n  if (isSelected) {\n    return colors.B200;\n  }\n  return colors.N900;\n};\n\nconst Container = styled.div`\n  background-color: ${(props) => getBackgroundColor(props)};\n  color: ${(props) => getColor(props)};\n  padding: ${grid}px;\n  margin-bottom: ${grid}px;\n  border-radius: ${borderRadius}px;\n  font-size: 18px;\n  border: 3px solid ${colors.N90};\n  ${(props) =>\n    props.isDragging ? `box-shadow: 2px 2px 1px ${colors.N90};` : ''} ${(\n    props,\n  ) =>\n    props.isGhosting\n      ? 'opacity: 0.8;'\n      : ''}\n\n  /* needed for SelectionCount */\n  position: relative;\n\n  /* avoid default outline which looks lame with the position: absolute; */\n  &:focus {\n    outline: none;\n    border-color: ${colors.G200};\n  }\n`;\n/* stylelint-disable block-no-empty */\nconst Content = styled.div``;\n/* stylelint-enable */\nconst size: number = 30;\n\nconst SelectionCount = styled.div`\n  right: -${grid}px;\n  top: -${grid}px;\n  color: ${colors.N0};\n  background: ${colors.N200};\n  border-radius: 50%;\n  height: ${size}px;\n  width: ${size}px;\n  line-height: ${size}px;\n  position: absolute;\n  text-align: center;\n  font-size: 0.8rem;\n`;\n\nconst keyCodes = {\n  enter: 13,\n  escape: 27,\n  arrowDown: 40,\n  arrowUp: 38,\n  tab: 9,\n};\n\nexport default class Task extends Component<Props> {\n  onKeyDown = (\n    event: KeyboardEvent,\n    provided: DraggableProvided,\n    snapshot: DraggableStateSnapshot,\n  ) => {\n    if (event.defaultPrevented) {\n      return;\n    }\n\n    if (snapshot.isDragging) {\n      return;\n    }\n\n    if (event.keyCode !== keyCodes.enter) {\n      return;\n    }\n\n    // we are using the event for selection\n    event.preventDefault();\n\n    this.performAction(event);\n  };\n\n  // Using onClick as it will be correctly\n  // preventing if there was a drag\n  onClick = (event: MouseEvent) => {\n    if (event.defaultPrevented) {\n      return;\n    }\n\n    if (event.button !== primaryButton) {\n      return;\n    }\n\n    // marking the event as used\n    event.preventDefault();\n\n    this.performAction(event);\n  };\n\n  onTouchEnd = (event: TouchEvent) => {\n    if (event.defaultPrevented) {\n      return;\n    }\n\n    // marking the event as used\n    // we would also need to add some extra logic to prevent the click\n    // if this element was an anchor\n    event.preventDefault();\n    this.props.toggleSelectionInGroup(this.props.task.id);\n  };\n\n  // Determines if the platform specific toggle selection in group key was used\n  wasToggleInSelectionGroupKeyUsed = (event: MouseEvent | KeyboardEvent) => {\n    const isUsingWindows = navigator.platform.indexOf('Win') >= 0;\n    return isUsingWindows ? event.ctrlKey : event.metaKey;\n  };\n\n  // Determines if the multiSelect key was used\n  wasMultiSelectKeyUsed = (event: MouseEvent | KeyboardEvent) => event.shiftKey;\n\n  performAction = (event: MouseEvent | KeyboardEvent) => {\n    const {\n      task,\n      toggleSelection,\n      toggleSelectionInGroup,\n      multiSelectTo,\n    } = this.props;\n\n    if (this.wasToggleInSelectionGroupKeyUsed(event)) {\n      toggleSelectionInGroup(task.id);\n      return;\n    }\n\n    if (this.wasMultiSelectKeyUsed(event)) {\n      multiSelectTo(task.id);\n      return;\n    }\n\n    toggleSelection(task.id);\n  };\n\n  render() {\n    const task: TaskType = this.props.task;\n    const index: number = this.props.index;\n    const isSelected: boolean = this.props.isSelected;\n    const selectionCount: number = this.props.selectionCount;\n    const isGhosting: boolean = this.props.isGhosting;\n    return (\n      <Draggable draggableId={task.id} index={index}>\n        {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => {\n          const shouldShowSelection: boolean =\n            snapshot.isDragging && selectionCount > 1;\n\n          return (\n            <Container\n              ref={provided.innerRef}\n              {...provided.draggableProps}\n              {...provided.dragHandleProps}\n              onClick={this.onClick}\n              onTouchEnd={this.onTouchEnd}\n              onKeyDown={(event: KeyboardEvent) =>\n                this.onKeyDown(event, provided, snapshot)\n              }\n              isDragging={snapshot.isDragging}\n              isSelected={isSelected}\n              isGhosting={isGhosting}\n            >\n              <Content>{task.content}</Content>\n              {shouldShowSelection ? (\n                <SelectionCount>{selectionCount}</SelectionCount>\n              ) : null}\n            </Container>\n          );\n        }}\n      </Draggable>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/multi-drag/types.js",
    "content": "// @flow\nimport type { Id, Task } from '../types';\n\nexport type Column = {|\n  id: Id,\n  title: string,\n  taskIds: Id[],\n|};\n\nexport type ColumnMap = {\n  [columnId: Id]: Column,\n};\n\nexport type TaskMap = {\n  [taskId: Id]: Task,\n};\n\nexport type Entities = {|\n  columnOrder: Id[],\n  columns: ColumnMap,\n  tasks: TaskMap,\n|};\n"
  },
  {
    "path": "stories/src/multi-drag/utils.js",
    "content": "// @flow\nimport type { Column, ColumnMap, Entities } from './types';\nimport type { Id } from '../types';\nimport { invariant } from '../../../src/invariant';\nimport type { DraggableLocation } from '../../../src/types';\nimport reorder from '../reorder';\n\ntype Args = {|\n  entities: Entities,\n  selectedTaskIds: Id[],\n  source: DraggableLocation,\n  destination: DraggableLocation,\n|};\n\nexport type Result = {|\n  entities: Entities,\n  // a drop operations can change the order of the selected task array\n  selectedTaskIds: Id[],\n|};\n\nconst withNewTaskIds = (column: Column, taskIds: Id[]): Column => ({\n  id: column.id,\n  title: column.title,\n  taskIds,\n});\n\nconst reorderSingleDrag = ({\n  entities,\n  selectedTaskIds,\n  source,\n  destination,\n}: Args): Result => {\n  // moving in the same list\n  if (source.droppableId === destination.droppableId) {\n    const column: Column = entities.columns[source.droppableId];\n    const reordered: Id[] = reorder(\n      column.taskIds,\n      source.index,\n      destination.index,\n    );\n\n    const updated: Entities = {\n      ...entities,\n      columns: {\n        ...entities.columns,\n        [column.id]: withNewTaskIds(column, reordered),\n      },\n    };\n\n    return {\n      entities: updated,\n      selectedTaskIds,\n    };\n  }\n\n  // moving to a new list\n  const home: Column = entities.columns[source.droppableId];\n  const foreign: Column = entities.columns[destination.droppableId];\n\n  // the id of the task to be moved\n  const taskId: Id = home.taskIds[source.index];\n\n  // remove from home column\n  const newHomeTaskIds: Id[] = [...home.taskIds];\n  newHomeTaskIds.splice(source.index, 1);\n\n  // add to foreign column\n  const newForeignTaskIds: Id[] = [...foreign.taskIds];\n  newForeignTaskIds.splice(destination.index, 0, taskId);\n\n  const updated: Entities = {\n    ...entities,\n    columns: {\n      ...entities.columns,\n      [home.id]: withNewTaskIds(home, newHomeTaskIds),\n      [foreign.id]: withNewTaskIds(foreign, newForeignTaskIds),\n    },\n  };\n\n  return {\n    entities: updated,\n    selectedTaskIds,\n  };\n};\n\ntype TaskId = Id;\n\nexport const getHomeColumn = (entities: Entities, taskId: TaskId): Column => {\n  const columnId: ?Id = entities.columnOrder.find((id: Id) => {\n    const column: Column = entities.columns[id];\n    return column.taskIds.includes(taskId);\n  });\n\n  invariant(columnId, 'Count not find column for task');\n\n  return entities.columns[columnId];\n};\n\nconst reorderMultiDrag = ({\n  entities,\n  selectedTaskIds,\n  source,\n  destination,\n}: Args): Result => {\n  const start: Column = entities.columns[source.droppableId];\n  const dragged: TaskId = start.taskIds[source.index];\n\n  const insertAtIndex: number = (() => {\n    const destinationIndexOffset: number = selectedTaskIds.reduce(\n      (previous: number, current: TaskId): number => {\n        if (current === dragged) {\n          return previous;\n        }\n\n        const final: Column = entities.columns[destination.droppableId];\n        const column: Column = getHomeColumn(entities, current);\n\n        if (column !== final) {\n          return previous;\n        }\n\n        const index: number = column.taskIds.indexOf(current);\n\n        if (index >= destination.index) {\n          return previous;\n        }\n\n        // the selected item is before the destination index\n        // we need to account for this when inserting into the new location\n        return previous + 1;\n      },\n      0,\n    );\n\n    const result: number = destination.index - destinationIndexOffset;\n    return result;\n  })();\n\n  // doing the ordering now as we are required to look up columns\n  // and know original ordering\n  const orderedSelectedTaskIds: TaskId[] = [...selectedTaskIds];\n  orderedSelectedTaskIds.sort((a: TaskId, b: TaskId): number => {\n    // moving the dragged item to the top of the list\n    if (a === dragged) {\n      return -1;\n    }\n    if (b === dragged) {\n      return 1;\n    }\n\n    // sorting by their natural indexes\n    const columnForA: Column = getHomeColumn(entities, a);\n    const indexOfA: number = columnForA.taskIds.indexOf(a);\n    const columnForB: Column = getHomeColumn(entities, b);\n    const indexOfB: number = columnForB.taskIds.indexOf(b);\n\n    if (indexOfA !== indexOfB) {\n      return indexOfA - indexOfB;\n    }\n\n    // sorting by their order in the selectedTaskIds list\n    return -1;\n  });\n\n  // we need to remove all of the selected tasks from their columns\n  const withRemovedTasks: ColumnMap = entities.columnOrder.reduce(\n    (previous: ColumnMap, columnId: Id): ColumnMap => {\n      const column: Column = entities.columns[columnId];\n\n      // remove the id's of the items that are selected\n      const remainingTaskIds: TaskId[] = column.taskIds.filter(\n        (id: TaskId): boolean => !selectedTaskIds.includes(id),\n      );\n\n      previous[column.id] = withNewTaskIds(column, remainingTaskIds);\n      return previous;\n    },\n    entities.columns,\n  );\n\n  const final: Column = withRemovedTasks[destination.droppableId];\n  const withInserted: TaskId[] = (() => {\n    const base: TaskId[] = [...final.taskIds];\n    base.splice(insertAtIndex, 0, ...orderedSelectedTaskIds);\n    return base;\n  })();\n\n  // insert all selected tasks into final column\n  const withAddedTasks: ColumnMap = {\n    ...withRemovedTasks,\n    [final.id]: withNewTaskIds(final, withInserted),\n  };\n\n  const updated: Entities = {\n    ...entities,\n    columns: withAddedTasks,\n  };\n\n  return {\n    entities: updated,\n    selectedTaskIds: orderedSelectedTaskIds,\n  };\n};\n\nexport const mutliDragAwareReorder = (args: Args): Result => {\n  if (args.selectedTaskIds.length > 1) {\n    return reorderMultiDrag(args);\n  }\n  return reorderSingleDrag(args);\n};\n\nexport const multiSelectTo = (\n  entities: Entities,\n  selectedTaskIds: Id[],\n  newTaskId: TaskId,\n): ?(Id[]) => {\n  // Nothing already selected\n  if (!selectedTaskIds.length) {\n    return [newTaskId];\n  }\n\n  const columnOfNew: Column = getHomeColumn(entities, newTaskId);\n  const indexOfNew: number = columnOfNew.taskIds.indexOf(newTaskId);\n\n  const lastSelected: Id = selectedTaskIds[selectedTaskIds.length - 1];\n  const columnOfLast: Column = getHomeColumn(entities, lastSelected);\n  const indexOfLast: number = columnOfLast.taskIds.indexOf(lastSelected);\n\n  // multi selecting to another column\n  // select everything up to the index of the current item\n  if (columnOfNew !== columnOfLast) {\n    return columnOfNew.taskIds.slice(0, indexOfNew + 1);\n  }\n\n  // multi selecting in the same column\n  // need to select everything between the last index and the current index inclusive\n\n  // nothing to do here\n  if (indexOfNew === indexOfLast) {\n    return null;\n  }\n\n  const isSelectingForwards: boolean = indexOfNew > indexOfLast;\n  const start: number = isSelectingForwards ? indexOfLast : indexOfNew;\n  const end: number = isSelectingForwards ? indexOfNew : indexOfLast;\n\n  const inBetween: Id[] = columnOfNew.taskIds.slice(start, end + 1);\n\n  // everything inbetween needs to have it's selection toggled.\n  // with the exception of the start and end values which will always be selected\n\n  const toAdd: Id[] = inBetween.filter((taskId: Id): boolean => {\n    // if already selected: then no need to select it again\n    if (selectedTaskIds.includes(taskId)) {\n      return false;\n    }\n    return true;\n  });\n\n  const sorted: Id[] = isSelectingForwards ? toAdd : [...toAdd].reverse();\n  const combined: Id[] = [...selectedTaskIds, ...sorted];\n\n  return combined;\n};\n"
  },
  {
    "path": "stories/src/multiple-horizontal/quote-app.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { DragDropContext } from '../../../src';\nimport AuthorList from '../primatives/author-list';\nimport { grid } from '../constants';\nimport { reorderQuoteMap } from '../reorder';\nimport type { ReorderQuoteMapResult } from '../reorder';\nimport type { QuoteMap } from '../types';\nimport type { DropResult } from '../../../src/types';\n\nconst Root = styled.div`\n  background-color: ${colors.B200};\n  box-sizing: border-box;\n  padding: ${grid * 2}px;\n  min-height: 100vh;\n\n  /* flexbox */\n  display: flex;\n  flex-direction: column;\n`;\n\ntype Props = {|\n  initial: QuoteMap,\n|};\n\ntype State = ReorderQuoteMapResult;\n\nexport default class QuoteApp extends Component<Props, State> {\n  /* eslint-disable react/sort-comp */\n\n  state: State = {\n    quoteMap: this.props.initial,\n  };\n\n  onDragEnd = (result: DropResult) => {\n    // // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    this.setState(\n      reorderQuoteMap({\n        quoteMap: this.state.quoteMap,\n        source: result.source,\n        destination: result.destination,\n      }),\n    );\n  };\n\n  render() {\n    const { quoteMap } = this.state;\n\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Root>\n          {Object.keys(quoteMap).map((key: string) => (\n            <AuthorList\n              internalScroll\n              key={key}\n              listId={key}\n              listType=\"CARD\"\n              quotes={quoteMap[key]}\n            />\n          ))}\n        </Root>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/multiple-vertical/quote-app.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { DragDropContext } from '../../../src';\nimport QuoteList from '../primatives/quote-list';\nimport { grid } from '../constants';\nimport { reorderQuoteMap } from '../reorder';\nimport type { ReorderQuoteMapResult } from '../reorder';\nimport type { QuoteMap } from '../types';\nimport type { DropResult, DraggableLocation } from '../../../src/types';\n\nconst Root = styled.div`\n  background-color: ${colors.B200};\n  box-sizing: border-box;\n  padding: ${grid * 2}px;\n  min-height: 100vh;\n\n  /* flexbox */\n  display: flex;\n  justify-content: center;\n  align-items: flex-start;\n`;\n\nconst Column = styled.div`\n  margin: 0 ${grid * 2}px;\n`;\n\nconst HorizontalScrollContainer = styled.div`\n  display: flex;\n  justify-content: flex-start;\n  align-items: flex-start;\n  background: rgba(0, 0, 0, 0.1);\n  padding: ${grid}px;\n  max-width: 400px;\n  overflow: auto;\n`;\n\nconst VerticalScrollContainer = styled.div`\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-start;\n  align-items: flex-start;\n  background: rgba(0, 0, 0, 0.1);\n  padding: ${grid}px;\n  max-height: 800px;\n  overflow: auto;\n`;\n\nconst PushDown = styled.div`\n  height: 200px;\n`;\n\ntype Props = {|\n  initial: QuoteMap,\n|};\n\ntype State = ReorderQuoteMapResult;\n\nexport default class QuoteApp extends Component<Props, State> {\n  /* eslint-disable react/sort-comp */\n\n  state: State = {\n    quoteMap: this.props.initial,\n  };\n\n  onDragEnd = (result: DropResult) => {\n    // dropped nowhere\n    if (!result.destination) {\n      return;\n    }\n\n    const source: DraggableLocation = result.source;\n    const destination: DraggableLocation = result.destination;\n\n    this.setState(\n      reorderQuoteMap({\n        quoteMap: this.state.quoteMap,\n        source,\n        destination,\n      }),\n    );\n  };\n\n  // TODO\n  getDisabledDroppable = (sourceDroppable: ?string) => {\n    if (!sourceDroppable) {\n      return null;\n    }\n\n    const droppables: string[] = ['alpha', 'beta', 'gamma', 'delta'];\n    const sourceIndex = droppables.indexOf(sourceDroppable);\n    const disabledDroppableIndex = (sourceIndex + 1) % droppables.length;\n\n    return droppables[disabledDroppableIndex];\n  };\n\n  render() {\n    const { quoteMap } = this.state;\n    const disabledDroppable = 'TODO';\n\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Root>\n          <HorizontalScrollContainer>\n            <Column>\n              <QuoteList\n                title=\"alpha\"\n                listId=\"alpha\"\n                listType=\"card\"\n                isDropDisabled={disabledDroppable === 'alpha'}\n                quotes={quoteMap.alpha}\n              />\n            </Column>\n            <Column>\n              <QuoteList\n                title=\"beta\"\n                listId=\"beta\"\n                listType=\"card\"\n                isDropDisabled={disabledDroppable === 'beta'}\n                quotes={quoteMap.beta}\n              />\n            </Column>\n            <Column>\n              <QuoteList\n                title=\"gamma\"\n                listId=\"gamma\"\n                listType=\"card\"\n                isDropDisabled={disabledDroppable === 'gamma'}\n                quotes={quoteMap.gamma}\n              />\n            </Column>\n          </HorizontalScrollContainer>\n          <Column>\n            <PushDown />\n            <QuoteList\n              title=\"delta\"\n              listId=\"delta\"\n              listType=\"card\"\n              isDropDisabled={disabledDroppable === 'delta'}\n              quotes={quoteMap.delta}\n            />\n            <QuoteList\n              title=\"epsilon\"\n              listId=\"epsilon\"\n              listType=\"card\"\n              internalScroll\n              isDropDisabled={disabledDroppable === 'epsilon'}\n              quotes={quoteMap.epsilon}\n            />\n          </Column>\n          <VerticalScrollContainer>\n            <Column>\n              <QuoteList\n                title=\"zeta\"\n                listId=\"zeta\"\n                listType=\"card\"\n                isDropDisabled={disabledDroppable === 'zeta'}\n                quotes={quoteMap.zeta}\n              />\n            </Column>\n            <Column>\n              <QuoteList\n                title=\"eta\"\n                listId=\"eta\"\n                listType=\"card\"\n                isDropDisabled={disabledDroppable === 'eta'}\n                quotes={quoteMap.eta}\n              />\n            </Column>\n            <Column>\n              <QuoteList\n                title=\"theta\"\n                listId=\"theta\"\n                listType=\"card\"\n                isDropDisabled={disabledDroppable === 'theta'}\n                quotes={quoteMap.theta}\n              />\n            </Column>\n          </VerticalScrollContainer>\n          <Column>\n            <QuoteList\n              title=\"iota\"\n              listId=\"iota\"\n              listType=\"card\"\n              isDropDisabled={disabledDroppable === 'iota'}\n              quotes={quoteMap.iota}\n            />\n          </Column>\n          <Column>\n            <QuoteList\n              title=\"kappa\"\n              listId=\"kappa\"\n              listType=\"card\"\n              internalScroll\n              isDropDisabled={disabledDroppable === 'kappa'}\n              quotes={quoteMap.kappa}\n            />\n          </Column>\n        </Root>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/on-before-capture/adding-things.jsx",
    "content": "// @flow\nimport React, { useState } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport type { Task } from '../types';\nimport {\n  DragDropContext,\n  Droppable,\n  Draggable,\n  type DropResult,\n} from '../../../src';\nimport { grid } from '../constants';\nimport reorder, { moveBetween } from '../reorder';\n\nlet uniqueId = 0;\nfunction getTasks(count: number): Task[] {\n  return Array.from({ length: count }, (): Task => {\n    const id: string = `${uniqueId++}`;\n\n    return {\n      id,\n      content: `task: ${id}`,\n    };\n  });\n}\n\nconst Item = styled.div`\n  padding: ${grid}px;\n  border: 1px solid ${colors.N30};\n  background-color: ${(props) => (props.isDragging ? colors.G100 : colors.N30)};\n  margin-top: ${grid}px;\n  margin-left: ${grid}px;\n  margin-right: ${grid}px;\n`;\n\nfunction renderTasks(\n  tasks: Task[],\n  options?: { isDragEnabled: boolean } = { isDragEnabled: true },\n) {\n  return tasks.map((task: Task, index: number) => {\n    return (\n      <Draggable\n        draggableId={task.id}\n        index={index}\n        key={task.id}\n        isDragDisabled={!options.isDragEnabled}\n      >\n        {(provided, snapshot) => (\n          <Item\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n            isDragging={snapshot.isDragging}\n            ref={provided.innerRef}\n          >\n            Task id: {task.id}\n          </Item>\n        )}\n      </Draggable>\n    );\n  });\n}\n\nconst App = styled.div`\n  display: flex;\n  /* not going to force them to grow to the same size when the drag starts */\n  align-items: start;\n  user-select: none;\n`;\n\nconst List = styled.div`\n  border: 1px solid ${colors.G200};\n  margin: ${grid}px;\n  text-align: center;\n  padding-bottom: ${grid}px;\n`;\n\nconst Bin = styled(List)`\n  border-color: ${colors.R200};\n`;\n\nconst Tasks = styled(List)``;\n\nconst ListTitle = styled.h3`\n  padding: ${grid}px;\n  width: 250px;\n`;\n\nexport default function AddingThings() {\n  const [isShowingBin, setIsShowingBin] = useState(false);\n  const [tasks, setTasks] = useState(() => getTasks(10));\n  const [trash, setTrash] = useState(() => getTasks(2));\n\n  function onBeforeCapture() {\n    setIsShowingBin(true);\n  }\n\n  function onDragEnd(result: DropResult) {\n    setIsShowingBin(false);\n    const { destination, source } = result;\n\n    if (!destination) {\n      return;\n    }\n\n    if (source.droppableId === destination.droppableId) {\n      if (source.droppableId === 'tasks') {\n        setTasks(reorder(tasks, source.index, destination.index));\n      }\n      // In our current UI it won't be possible to reorder trash\n      return;\n    }\n\n    const { list1, list2 } = moveBetween({\n      list1: {\n        id: 'tasks',\n        values: tasks,\n      },\n      list2: {\n        id: 'trash',\n        values: trash,\n      },\n      source,\n      destination,\n    });\n\n    setTasks(list1.values);\n    setTrash(list2.values);\n  }\n\n  return (\n    <DragDropContext onBeforeCapture={onBeforeCapture} onDragEnd={onDragEnd}>\n      <App>\n        <Tasks>\n          <ListTitle>\n            Tasks{' '}\n            <span role=\"img\" aria-label=\"book\">\n              📘\n            </span>\n          </ListTitle>\n          <Droppable droppableId=\"tasks\">\n            {(provided) => (\n              <div ref={provided.innerRef} {...provided.droppableProps}>\n                {renderTasks(tasks)}\n                {provided.placeholder}\n              </div>\n            )}\n          </Droppable>\n        </Tasks>\n        {isShowingBin ? (\n          <Bin>\n            <ListTitle>\n              Trash{' '}\n              <span role=\"img\" aria-label=\"trash\">\n                🗑\n              </span>\n            </ListTitle>\n            <Droppable droppableId=\"bin\">\n              {(provided) => (\n                <div ref={provided.innerRef} {...provided.droppableProps}>\n                  {renderTasks(trash, { isDragEnabled: false })}\n                  {provided.placeholder}\n                </div>\n              )}\n            </Droppable>\n          </Bin>\n        ) : null}\n      </App>\n    </DragDropContext>\n  );\n}\n"
  },
  {
    "path": "stories/src/portal/portal-app.jsx",
    "content": "// @flow\nimport React, { Component, type Node } from 'react';\nimport ReactDOM from 'react-dom';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\nimport reorder from '../reorder';\nimport { grid } from '../constants';\nimport type { Quote } from '../types';\nimport type {\n  DropResult,\n  DroppableProvided,\n  DraggableProvided,\n  DraggableStateSnapshot,\n} from '../../../src';\n\ntype ItemProps = {|\n  provided: DraggableProvided,\n  snapshot: DraggableStateSnapshot,\n  quote: Quote,\n|};\n\nconst portal: HTMLElement = document.createElement('div');\nportal.classList.add('my-super-cool-portal');\n\nif (!document.body) {\n  throw new Error('body not ready for portal creation!');\n}\n\ndocument.body.appendChild(portal);\n\nconst SimpleQuote = styled.div`\n  padding: ${grid}px;\n  margin-bottom: ${grid}px;\n  background-color: ${colors.B50};\n  border: 1px solid ${colors.B200};\n\n  /* used for positioning the after content */\n  position: relative;\n\n  /* stylelint-disable  comment-empty-line-before */\n  /* add little portal indicator when in a portal */\n  ${(props) =>\n    props.inPortal\n      ? `\n    ::after {\n      position: absolute;\n      background: lightgreen;\n      padding: ${grid}px;\n      bottom: 0;\n      right: 0;\n      content: \"in portal\";\n    }\n  `\n      : ''}/* stylelint-enable */;\n`;\n\nclass PortalAwareItem extends Component<ItemProps> {\n  render() {\n    const provided: DraggableProvided = this.props.provided;\n    const snapshot: DraggableStateSnapshot = this.props.snapshot;\n    const quote: Quote = this.props.quote;\n\n    const usePortal: boolean = snapshot.isDragging;\n\n    const child: Node = (\n      <SimpleQuote\n        ref={provided.innerRef}\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        inPortal={usePortal}\n      >\n        {quote.content} <small>- {quote.author.name}</small>\n      </SimpleQuote>\n    );\n\n    if (!usePortal) {\n      return child;\n    }\n\n    // if dragging - put the item in a portal\n    return ReactDOM.createPortal(child, portal);\n  }\n}\n\ntype AppProps = {|\n  initial: Quote[],\n|};\n\ntype AppState = {|\n  quotes: Quote[],\n|};\n\nconst Container = styled.div`\n  margin: 0 auto;\n  width: 300px;\n`;\n\nexport default class PortalApp extends Component<AppProps, AppState> {\n  state: AppState = {\n    quotes: this.props.initial,\n  };\n\n  onDragEnd = (result: DropResult) => {\n    // dropped outside the list\n    if (\n      !result.destination ||\n      result.destination.index === result.source.index\n    ) {\n      return;\n    }\n\n    // no movement\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    const quotes = reorder(\n      this.state.quotes,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      quotes,\n    });\n  };\n\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided: DroppableProvided) => (\n            <Container\n              ref={droppableProvided.innerRef}\n              {...droppableProvided.droppableProps}\n            >\n              {this.state.quotes.map((quote: Quote, index: number) => (\n                <Draggable draggableId={quote.id} index={index} key={quote.id}>\n                  {(\n                    draggableProvided: DraggableProvided,\n                    draggableSnapshot: DraggableStateSnapshot,\n                  ) => (\n                    <PortalAwareItem\n                      quote={quote}\n                      provided={draggableProvided}\n                      snapshot={draggableSnapshot}\n                    />\n                  )}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder}\n            </Container>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/primatives/author-item.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { grid } from '../constants';\nimport type { DraggableProvided, DraggableStateSnapshot } from '../../../src';\nimport type { Author } from '../types';\n\n// $ExpectError - not sure why\nconst Avatar = styled.img`\n  width: 60px;\n  height: 60px;\n  border-radius: 50%;\n  flex-shrink: 0;\n  margin-right: ${grid}px;\n  border-color: ${({ isDragging }) => (isDragging ? colors.G50 : colors.N0)};\n  border-style: solid;\n  border-width: ${grid}px;\n  box-shadow: ${({ isDragging }) =>\n    isDragging ? `2px 2px 1px ${colors.N200}` : 'none'};\n\n  &:focus {\n    /* disable standard focus color */\n    outline: none;\n\n    /* use our own awesome one */\n    border-color: ${({ isDragging }) =>\n      isDragging ? colors.G50 : colors.B200};\n  }\n`;\n\ntype Props = {|\n  author: Author,\n  provided: DraggableProvided,\n  snapshot: DraggableStateSnapshot,\n|};\n\nexport default class AuthorItem extends Component<Props> {\n  render() {\n    const author: Author = this.props.author;\n    const provided: DraggableProvided = this.props.provided;\n    const snapshot: DraggableStateSnapshot = this.props.snapshot;\n\n    return (\n      <Avatar\n        ref={(ref) => provided.innerRef(ref)}\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        src={author.avatarUrl}\n        alt={author.name}\n        isDragging={snapshot.isDragging}\n      />\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/primatives/author-list.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { Droppable, Draggable } from '../../../src';\nimport Author from './author-item';\nimport { grid } from '../constants';\nimport type { Quote } from '../types';\nimport type {\n  DroppableProvided,\n  DroppableStateSnapshot,\n  DraggableProvided,\n  DraggableStateSnapshot,\n} from '../../../src';\n\nconst Wrapper = styled.div`\n  background-color: ${({ isDraggingOver }) =>\n    isDraggingOver ? colors.B50 : colors.B75};\n  display: flex;\n  flex-direction: column;\n  padding: ${grid}px;\n  user-select: none;\n  transition: background-color 0.1s ease;\n  margin: ${grid}px 0;\n`;\n\nconst DropZone = styled.div`\n  display: flex;\n\n  /*\n    Needed to avoid growth in list due to lifting the first item\n    Caused by display: inline-flex strangeness\n  */\n  align-items: start;\n\n  /* stop the list collapsing when empty */\n  min-width: 600px;\n\n  /* stop the list collapsing when it has no items */\n  min-height: 60px;\n`;\n\nconst ScrollContainer = styled.div`\n  overflow: auto;\n`;\n\n// $ExpectError - not sure why\nconst Container = styled.div`\n  /* flex child */\n  flex-grow: 1;\n\n  /*\n    flex parent\n    needed to allow width to grow greater than body\n  */\n  display: inline-flex;\n`;\n\ntype Props = {|\n  quotes: Quote[],\n  listId: string,\n  listType?: string,\n  internalScroll?: boolean,\n  isCombineEnabled?: boolean,\n|};\n\nexport default class AuthorList extends Component<Props> {\n  static defaultProps = {\n    isCombineEnabled: false,\n  };\n  renderBoard = (dropProvided: DroppableProvided) => {\n    const { quotes } = this.props;\n\n    return (\n      <Container>\n        <DropZone ref={dropProvided.innerRef}>\n          {quotes.map((quote: Quote, index: number) => (\n            <Draggable key={quote.id} draggableId={quote.id} index={index}>\n              {(\n                dragProvided: DraggableProvided,\n                dragSnapshot: DraggableStateSnapshot,\n              ) => (\n                <Author\n                  author={quote.author}\n                  provided={dragProvided}\n                  snapshot={dragSnapshot}\n                />\n              )}\n            </Draggable>\n          ))}\n          {dropProvided.placeholder}\n        </DropZone>\n      </Container>\n    );\n  };\n\n  render() {\n    const { listId, listType, internalScroll, isCombineEnabled } = this.props;\n\n    return (\n      <Droppable\n        droppableId={listId}\n        type={listType}\n        direction=\"horizontal\"\n        isCombineEnabled={isCombineEnabled}\n      >\n        {(\n          dropProvided: DroppableProvided,\n          dropSnapshot: DroppableStateSnapshot,\n        ) => (\n          <Wrapper\n            isDraggingOver={dropSnapshot.isDraggingOver}\n            {...dropProvided.droppableProps}\n          >\n            {internalScroll ? (\n              <ScrollContainer>\n                {this.renderBoard(dropProvided)}\n              </ScrollContainer>\n            ) : (\n              this.renderBoard(dropProvided)\n            )}\n          </Wrapper>\n        )}\n      </Droppable>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/primatives/quote-item.jsx",
    "content": "// @flow\nimport React from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { borderRadius, grid } from '../constants';\nimport type { Quote, AuthorColors } from '../types';\nimport type { DraggableProvided } from '../../../src';\n\ntype Props = {\n  quote: Quote,\n  isDragging: boolean,\n  provided: DraggableProvided,\n  isClone?: boolean,\n  isGroupedOver?: boolean,\n  style?: Object,\n  index?: number,\n};\n\nconst getBackgroundColor = (\n  isDragging: boolean,\n  isGroupedOver: boolean,\n  authorColors: AuthorColors,\n) => {\n  if (isDragging) {\n    return authorColors.soft;\n  }\n\n  if (isGroupedOver) {\n    return colors.N30;\n  }\n\n  return colors.N0;\n};\n\nconst getBorderColor = (isDragging: boolean, authorColors: AuthorColors) =>\n  isDragging ? authorColors.hard : 'transparent';\n\nconst imageSize: number = 40;\n\nconst CloneBadge = styled.div`\n  background: ${colors.G100};\n  bottom: ${grid / 2}px;\n  border: 2px solid ${colors.G200};\n  border-radius: 50%;\n  box-sizing: border-box;\n  font-size: 10px;\n  position: absolute;\n  right: -${imageSize / 3}px;\n  top: -${imageSize / 3}px;\n  transform: rotate(40deg);\n\n  height: ${imageSize}px;\n  width: ${imageSize}px;\n\n  display: flex;\n  justify-content: center;\n  align-items: center;\n`;\n\nconst Container = styled.a`\n  border-radius: ${borderRadius}px;\n  border: 2px solid transparent;\n  border-color: ${(props) => getBorderColor(props.isDragging, props.colors)};\n  background-color: ${(props) =>\n    getBackgroundColor(props.isDragging, props.isGroupedOver, props.colors)};\n  box-shadow: ${({ isDragging }) =>\n    isDragging ? `2px 2px 1px ${colors.N70}` : 'none'};\n  box-sizing: border-box;\n  padding: ${grid}px;\n  min-height: ${imageSize}px;\n  margin-bottom: ${grid}px;\n  user-select: none;\n\n  /* anchor overrides */\n  color: ${colors.N900};\n\n  &:hover,\n  &:active {\n    color: ${colors.N900};\n    text-decoration: none;\n  }\n\n  &:focus {\n    outline: none;\n    border-color: ${(props) => props.colors.hard};\n    box-shadow: none;\n  }\n\n  /* flexbox */\n  display: flex;\n`;\n\nconst Avatar = styled.img`\n  width: ${imageSize}px;\n  height: ${imageSize}px;\n  border-radius: 50%;\n  margin-right: ${grid}px;\n  flex-shrink: 0;\n  flex-grow: 0;\n`;\n\nconst Content = styled.div`\n  /* flex child */\n  flex-grow: 1;\n\n  /*\n    Needed to wrap text in ie11\n    https://stackoverflow.com/questions/35111090/why-ie11-doesnt-wrap-the-text-in-flexbox\n  */\n  flex-basis: 100%;\n\n  /* flex parent */\n  display: flex;\n  flex-direction: column;\n`;\n\nconst BlockQuote = styled.div`\n  &::before {\n    content: open-quote;\n  }\n\n  &::after {\n    content: close-quote;\n  }\n`;\n\nconst Footer = styled.div`\n  display: flex;\n  margin-top: ${grid}px;\n  align-items: center;\n`;\n\nconst Author = styled.small`\n  color: ${(props) => props.colors.hard};\n  flex-grow: 0;\n  margin: 0;\n  background-color: ${(props) => props.colors.soft};\n  border-radius: ${borderRadius}px;\n  font-weight: normal;\n  padding: ${grid / 2}px;\n`;\n\nconst QuoteId = styled.small`\n  flex-grow: 1;\n  flex-shrink: 1;\n  margin: 0;\n  font-weight: normal;\n  text-overflow: ellipsis;\n  text-align: right;\n`;\n\nfunction getStyle(provided: DraggableProvided, style: ?Object) {\n  if (!style) {\n    return provided.draggableProps.style;\n  }\n\n  return {\n    ...provided.draggableProps.style,\n    ...style,\n  };\n}\n\n// Previously this extended React.Component\n// That was a good thing, because using React.PureComponent can hide\n// issues with the selectors. However, moving it over does can considerable\n// performance improvements when reordering big lists (400ms => 200ms)\n// Need to be super sure we are not relying on PureComponent here for\n// things we should be doing in the selector as we do not know if consumers\n// will be using PureComponent\nfunction QuoteItem(props: Props) {\n  const {\n    quote,\n    isDragging,\n    isGroupedOver,\n    provided,\n    style,\n    isClone,\n    index,\n  } = props;\n\n  return (\n    <Container\n      href={quote.author.url}\n      isDragging={isDragging}\n      isGroupedOver={isGroupedOver}\n      isClone={isClone}\n      colors={quote.author.colors}\n      ref={provided.innerRef}\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n      style={getStyle(provided, style)}\n      data-is-dragging={isDragging}\n      data-testid={quote.id}\n      data-index={index}\n      aria-label={`${quote.author.name} quote ${quote.content}`}\n    >\n      <Avatar src={quote.author.avatarUrl} alt={quote.author.name} />\n      {isClone ? <CloneBadge>Clone</CloneBadge> : null}\n      <Content>\n        <BlockQuote>{quote.content}</BlockQuote>\n        <Footer>\n          <Author colors={quote.author.colors}>{quote.author.name}</Author>\n          <QuoteId>id:{quote.id}</QuoteId>\n        </Footer>\n      </Content>\n    </Container>\n  );\n}\n\nexport default React.memo<Props>(QuoteItem);\n"
  },
  {
    "path": "stories/src/primatives/quote-list.jsx",
    "content": "// @flow\nimport React from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { Droppable, Draggable } from '../../../src';\nimport QuoteItem from './quote-item';\nimport { grid } from '../constants';\nimport Title from './title';\nimport type { Quote } from '../types';\nimport type {\n  DroppableProvided,\n  DroppableStateSnapshot,\n  DraggableProvided,\n  DraggableStateSnapshot,\n} from '../../../src';\n\nexport const getBackgroundColor = (\n  isDraggingOver: boolean,\n  isDraggingFrom: boolean,\n): string => {\n  if (isDraggingOver) {\n    return colors.R50;\n  }\n  if (isDraggingFrom) {\n    return colors.T50;\n  }\n  return colors.N30;\n};\n\nconst Wrapper = styled.div`\n  background-color: ${(props) =>\n    getBackgroundColor(props.isDraggingOver, props.isDraggingFrom)};\n  display: flex;\n  flex-direction: column;\n  opacity: ${({ isDropDisabled }) => (isDropDisabled ? 0.5 : 'inherit')};\n  padding: ${grid}px;\n  border: ${grid}px;\n  padding-bottom: 0;\n  transition: background-color 0.2s ease, opacity 0.1s ease;\n  user-select: none;\n  width: 250px;\n`;\n\nconst scrollContainerHeight: number = 250;\n\nconst DropZone = styled.div`\n  /* stop the list collapsing when empty */\n  min-height: ${scrollContainerHeight}px;\n\n  /*\n    not relying on the items for a margin-bottom\n    as it will collapse when the list is empty\n  */\n  padding-bottom: ${grid}px;\n`;\n\nconst ScrollContainer = styled.div`\n  overflow-x: hidden;\n  overflow-y: auto;\n  max-height: ${scrollContainerHeight}px;\n`;\n\n/* stylelint-disable block-no-empty */\nconst Container = styled.div``;\n/* stylelint-enable */\n\ntype Props = {|\n  listId?: string,\n  listType?: string,\n  quotes: Quote[],\n  title?: string,\n  internalScroll?: boolean,\n  scrollContainerStyle?: Object,\n  isDropDisabled?: boolean,\n  isCombineEnabled?: boolean,\n  style?: Object,\n  // may not be provided - and might be null\n  ignoreContainerClipping?: boolean,\n\n  useClone?: boolean,\n|};\n\ntype QuoteListProps = {|\n  quotes: Quote[],\n|};\n\nconst InnerQuoteList = React.memo(function InnerQuoteList(\n  props: QuoteListProps,\n) {\n  return props.quotes.map((quote: Quote, index: number) => (\n    <Draggable key={quote.id} draggableId={quote.id} index={index}>\n      {(\n        dragProvided: DraggableProvided,\n        dragSnapshot: DraggableStateSnapshot,\n      ) => (\n        <QuoteItem\n          key={quote.id}\n          quote={quote}\n          isDragging={dragSnapshot.isDragging}\n          isGroupedOver={Boolean(dragSnapshot.combineTargetFor)}\n          provided={dragProvided}\n        />\n      )}\n    </Draggable>\n  ));\n});\n\ntype InnerListProps = {|\n  dropProvided: DroppableProvided,\n  quotes: Quote[],\n  title: ?string,\n|};\n\nfunction InnerList(props: InnerListProps) {\n  const { quotes, dropProvided } = props;\n  const title = props.title ? <Title>{props.title}</Title> : null;\n\n  return (\n    <Container>\n      {title}\n      <DropZone ref={dropProvided.innerRef}>\n        <InnerQuoteList quotes={quotes} />\n        {dropProvided.placeholder}\n      </DropZone>\n    </Container>\n  );\n}\n\nexport default function QuoteList(props: Props) {\n  const {\n    ignoreContainerClipping,\n    internalScroll,\n    scrollContainerStyle,\n    isDropDisabled,\n    isCombineEnabled,\n    listId = 'LIST',\n    listType,\n    style,\n    quotes,\n    title,\n    useClone,\n  } = props;\n\n  return (\n    <Droppable\n      droppableId={listId}\n      type={listType}\n      ignoreContainerClipping={ignoreContainerClipping}\n      isDropDisabled={isDropDisabled}\n      isCombineEnabled={isCombineEnabled}\n      renderClone={\n        useClone\n          ? (provided, snapshot, descriptor) => (\n              <QuoteItem\n                quote={quotes[descriptor.source.index]}\n                provided={provided}\n                isDragging={snapshot.isDragging}\n                isClone\n              />\n            )\n          : null\n      }\n    >\n      {(\n        dropProvided: DroppableProvided,\n        dropSnapshot: DroppableStateSnapshot,\n      ) => (\n        <Wrapper\n          style={style}\n          isDraggingOver={dropSnapshot.isDraggingOver}\n          isDropDisabled={isDropDisabled}\n          isDraggingFrom={Boolean(dropSnapshot.draggingFromThisWith)}\n          {...dropProvided.droppableProps}\n        >\n          {internalScroll ? (\n            <ScrollContainer style={scrollContainerStyle}>\n              <InnerList\n                quotes={quotes}\n                title={title}\n                dropProvided={dropProvided}\n              />\n            </ScrollContainer>\n          ) : (\n            <InnerList\n              quotes={quotes}\n              title={title}\n              dropProvided={dropProvided}\n            />\n          )}\n        </Wrapper>\n      )}\n    </Droppable>\n  );\n}\n"
  },
  {
    "path": "stories/src/primatives/title.jsx",
    "content": "// @flow\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { grid } from '../constants';\n\n// $ExpectError - not sure why\nexport default styled.h4`\n  padding: ${grid}px;\n  transition: background-color ease 0.2s;\n  flex-grow: 1;\n  user-select: none;\n  position: relative;\n\n  &:focus {\n    outline: 2px solid ${colors.P100};\n    outline-offset: 2px;\n  }\n`;\n"
  },
  {
    "path": "stories/src/programmatic/multiple-contexts.jsx",
    "content": "/* eslint-disable no-console */\n/* eslint-disable no-await-in-loop */\n// @flow\nimport React, { useState, useEffect } from 'react';\nimport styled from '@emotion/styled';\nimport { useCallback } from 'use-memo-one';\nimport type { Quote } from '../types';\nimport type {\n  DropResult,\n  PreDragActions,\n  SnapDragActions,\n  Sensor,\n  SensorAPI,\n} from '../../../src/types';\nimport { quotes as initial } from '../data';\nimport { DragDropContext } from '../../../src';\nimport QuoteList from '../primatives/quote-list';\nimport reorder from '../reorder';\nimport bindEvents from '../../../src/view/event-bindings/bind-events';\nimport { grid } from '../constants';\n\nfunction sleep(fn: Function, time?: number = 300) {\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      fn();\n      resolve();\n    }, time);\n  });\n}\n\nfunction getSensor(delay: number): Sensor {\n  return function useCustomSensor(api: SensorAPI) {\n    const start = useCallback(\n      async function start() {\n        const preDrag: ?PreDragActions = api.tryGetLock('1', () => {});\n\n        if (!preDrag) {\n          console.warn('unable to start drag');\n          return;\n        }\n\n        const actions: SnapDragActions = preDrag.snapLift();\n        const { moveDown, moveUp, drop, isActive, cancel } = actions;\n\n        const unbind = bindEvents(window, [\n          {\n            eventName: 'resize',\n            fn: cancel,\n            options: { once: true },\n          },\n        ]);\n\n        for (let i = 0; i < 20 && isActive(); i++) {\n          await sleep(() => {\n            // might no longer be active after delay\n            if (!isActive()) {\n              return;\n            }\n            if (i % 2 === 0) {\n              moveDown();\n            } else {\n              moveUp();\n            }\n          }, delay);\n        }\n\n        if (isActive()) {\n          await sleep(drop, delay);\n        }\n\n        unbind();\n      },\n      [api],\n    );\n\n    useEffect(() => {\n      start();\n    }, [start]);\n  };\n}\n\ntype Props = {|\n  initial: Quote[],\n  sensors?: Sensor[],\n|};\n\nfunction QuoteApp(props: Props) {\n  const [quotes, setQuotes] = useState(props.initial);\n\n  const onDragEnd = useCallback(\n    function onDragEnd(result: DropResult) {\n      // dropped outside the list\n      if (!result.destination) {\n        return;\n      }\n\n      if (result.destination.index === result.source.index) {\n        return;\n      }\n\n      const newQuotes = reorder(\n        quotes,\n        result.source.index,\n        result.destination.index,\n      );\n\n      setQuotes(newQuotes);\n    },\n    [quotes],\n  );\n\n  return (\n    <DragDropContext onDragEnd={onDragEnd} sensors={props.sensors}>\n      <QuoteList listId=\"list\" quotes={quotes} />\n    </DragDropContext>\n  );\n}\n\n// $ExpectError - not sure why\nconst Root = styled.div`\n  display: flex;\n  justify-content: space-evenly;\n`;\n\nconst Column = styled.div``;\n\nconst Title = styled.h3`\n  text-align: center;\n  padding: ${grid * 2}px;\n`;\n\nexport default function App() {\n  return (\n    <Root>\n      <Column>\n        <Title>\n          Programmatic #1{' '}\n          <span role=\"img\" aria-label=\"controller\">\n            🎮\n          </span>\n        </Title>\n        <QuoteApp initial={initial} sensors={[getSensor(300)]} />\n      </Column>\n      <Column>\n        <Title>\n          Programmatic #2{' '}\n          <span role=\"img\" aria-label=\"controller\">\n            🎮\n          </span>\n        </Title>\n        <QuoteApp initial={initial} sensors={[getSensor(400)]} />\n      </Column>\n      <Column>\n        <Title>\n          User controlled{' '}\n          <span role=\"img\" aria-label=\"hand\">\n            🤚\n          </span>\n        </Title>\n        <QuoteApp initial={initial} />\n      </Column>\n    </Root>\n  );\n}\n"
  },
  {
    "path": "stories/src/programmatic/runsheet.jsx",
    "content": "// @flow\n/* eslint-disable no-console */\nimport React, { useState, useCallback, useEffect } from 'react';\nimport type { Quote } from '../types';\nimport type {\n  DropResult,\n  PreDragActions,\n  SnapDragActions,\n  SensorAPI,\n} from '../../../src/types';\nimport { DragDropContext } from '../../../src';\nimport QuoteList from '../primatives/quote-list';\nimport reorder from '../reorder';\n\nfunction delay(fn: Function, time?: number = 300) {\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      fn();\n      resolve();\n    }, time);\n  });\n}\n\nfunction noop() {}\n\nfunction useDemoSensor(api: SensorAPI) {\n  const start = useCallback(\n    async function start() {\n      const preDrag: ?PreDragActions = api.tryGetLock('1', noop);\n\n      if (!preDrag) {\n        console.warn('unable to start drag');\n        return;\n      }\n      console.warn('starting drag');\n\n      const actions: SnapDragActions = preDrag.snapLift();\n      const { moveDown, moveUp, drop } = actions;\n\n      await delay(moveDown);\n      await delay(moveDown);\n      await delay(moveDown);\n      await delay(moveDown);\n      await delay(moveDown);\n      await delay(moveDown);\n      await delay(moveDown);\n      await delay(moveDown);\n      await delay(moveDown);\n      await delay(moveUp);\n      await delay(moveUp);\n      await delay(drop);\n    },\n    [api],\n  );\n\n  useEffect(() => {\n    start();\n  }, [start]);\n}\n\ntype Props = {|\n  initial: Quote[],\n|};\n\nexport default function QuoteApp(props: Props) {\n  const [quotes, setQuotes] = useState(props.initial);\n\n  const onDragEnd = useCallback(\n    function onDragEnd(result: DropResult) {\n      // dropped outside the list\n      if (!result.destination) {\n        return;\n      }\n\n      if (result.destination.index === result.source.index) {\n        return;\n      }\n\n      const newQuotes = reorder(\n        quotes,\n        result.source.index,\n        result.destination.index,\n      );\n\n      setQuotes(newQuotes);\n    },\n    [quotes],\n  );\n\n  return (\n    <DragDropContext onDragEnd={onDragEnd} sensors={[useDemoSensor]}>\n      <QuoteList listId=\"list\" quotes={quotes} />\n    </DragDropContext>\n  );\n}\n"
  },
  {
    "path": "stories/src/programmatic/with-controls.jsx",
    "content": "// @flow\n/* eslint-disable no-console */\nimport React, { useRef, createRef, useState, useCallback } from 'react';\nimport styled from '@emotion/styled';\nimport type { Quote } from '../types';\nimport type {\n  DropResult,\n  PreDragActions,\n  SnapDragActions,\n  SensorAPI,\n} from '../../../src/types';\nimport { DragDropContext } from '../../../src';\nimport QuoteList from '../primatives/quote-list';\nimport reorder from '../reorder';\nimport { grid, borderRadius } from '../constants';\n\ntype ControlProps = {|\n  quotes: Quote[],\n  canLift: boolean,\n  isDragging: boolean,\n  lift: (quoteId: string) => ?SnapDragActions,\n|};\n\nfunction noop() {}\n\nconst ControlBox = styled.div`\n  display: flex;\n  flex-direction: column;\n`;\n\nconst ArrowBox = styled.div`\n  margin-top: ${grid * 4}px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n`;\n\nconst Button = styled.button`\n  --off-white: hsla(60, 100%, 98%, 1);\n  --dark-off-white: #efefe3;\n  --darker-off-white: #d6d6cb;\n  --border-width: 4px;\n\n  background: var(--off-white);\n  border-radius: ${borderRadius}px;\n  cursor: ${(props) => (props.disabled ? 'not-allowed' : 'pointer')};\n  font-size: 16px;\n  position: relative;\n  box-sizing: border-box;\n  border: var(--border-width) solid var(--dark-off-white);\n  box-shadow: 0 0 0 1px var(--darker-off-white);\n  margin: 2px;\n\n  ::before {\n    position: absolute;\n    content: ' ';\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n    border: 1px solid var(--dark-off-white);\n  }\n\n  :active {\n    border-width: 3px;\n  }\n`;\n\nconst ArrowButton = styled(Button)`\n  width: 40px;\n  height: 40px;\n`;\n\n// locking the height so that the border width change\n// does not change the size of the button\nconst ActionButton = styled(Button)`\n  height: 40px;\n`;\n\nfunction Controls(props: ControlProps) {\n  const { quotes, canLift, isDragging, lift } = props;\n  const actionsRef = useRef<?SnapDragActions>(null);\n\n  const selectRef = createRef();\n\n  function maybe(fn: (callbacks: SnapDragActions) => void) {\n    if (actionsRef.current) {\n      fn(actionsRef.current);\n    }\n  }\n\n  return (\n    <ControlBox>\n      <select disabled={!canLift} ref={selectRef}>\n        {quotes.map((quote: Quote) => (\n          <option key={quote.id} value={quote.id}>\n            id: {quote.id}\n          </option>\n        ))}\n      </select>\n      <ActionButton\n        type=\"button\"\n        disabled={!canLift}\n        onClick={() => {\n          const select: ?HTMLSelectElement = selectRef.current;\n          if (!select) {\n            return;\n          }\n\n          actionsRef.current = lift(select.value);\n        }}\n      >\n        Lift{' '}\n        <span role=\"img\" aria-label=\"lift\">\n          🏋️‍♀️\n        </span>\n      </ActionButton>\n      <ActionButton\n        type=\"button\"\n        onClick={() =>\n          maybe((callbacks: SnapDragActions) => {\n            actionsRef.current = null;\n            callbacks.drop();\n          })\n        }\n        disabled={!isDragging}\n      >\n        Drop{' '}\n        <span role=\"img\" aria-label=\"drop\">\n          🤾‍♂️\n        </span>\n      </ActionButton>\n      <ArrowBox>\n        <ArrowButton\n          type=\"button\"\n          onClick={() =>\n            maybe((callbacks: SnapDragActions) => callbacks.moveUp())\n          }\n          disabled={!isDragging}\n          label=\"up\"\n        >\n          ↑\n        </ArrowButton>\n        <div>\n          <ArrowButton type=\"button\" disabled={!isDragging} label=\"left\">\n            ←\n          </ArrowButton>\n          <ArrowButton\n            type=\"button\"\n            onClick={() =>\n              maybe((callbacks: SnapDragActions) => callbacks.moveDown())\n            }\n            disabled={!isDragging}\n            label=\"down\"\n          >\n            ↓\n          </ArrowButton>\n          <ArrowButton type=\"button\" disabled={!isDragging} label=\"right\">\n            →\n          </ArrowButton>\n        </div>\n      </ArrowBox>\n    </ControlBox>\n  );\n}\n\nconst Layout = styled.div`\n  display: flex;\n  justify-content: center;\n  margin-top: ${grid * 4}px;\n\n  > * {\n    margin: ${grid}px;\n  }\n`;\n\ntype Props = {|\n  initial: Quote[],\n|};\n\nexport default function QuoteApp(props: Props) {\n  const [quotes, setQuotes] = useState(props.initial);\n  const [isDragging, setIsDragging] = useState(false);\n  const [isControlDragging, setIsControlDragging] = useState(false);\n  const sensorAPIRef = useRef<?SensorAPI>(null);\n\n  const onDragEnd = useCallback(\n    function onDragEnd(result: DropResult) {\n      setIsDragging(false);\n      setIsControlDragging(false);\n      // dropped outside the list\n      if (!result.destination) {\n        return;\n      }\n\n      if (result.destination.index === result.source.index) {\n        return;\n      }\n\n      const newQuotes = reorder(\n        quotes,\n        result.source.index,\n        result.destination.index,\n      );\n\n      setQuotes(newQuotes);\n    },\n    [quotes],\n  );\n\n  function lift(quoteId: string): ?SnapDragActions {\n    if (isDragging) {\n      return null;\n    }\n\n    const api: ?SensorAPI = sensorAPIRef.current;\n\n    if (!api) {\n      console.warn('unable to find sensor api');\n      return null;\n    }\n\n    const preDrag: ?PreDragActions = api.tryGetLock(quoteId, noop);\n\n    if (!preDrag) {\n      console.log('unable to start capturing');\n      return null;\n    }\n    setIsControlDragging(true);\n    return preDrag.snapLift();\n  }\n\n  return (\n    <DragDropContext\n      onDragStart={() => setIsDragging(true)}\n      onDragEnd={onDragEnd}\n      sensors={[\n        (api) => {\n          sensorAPIRef.current = api;\n        },\n      ]}\n    >\n      <Layout>\n        <QuoteList listId=\"list\" quotes={quotes} />\n        <Controls\n          quotes={quotes}\n          canLift={!isDragging}\n          isDragging={isControlDragging}\n          lift={lift}\n        />\n      </Layout>\n    </DragDropContext>\n  );\n}\n"
  },
  {
    "path": "stories/src/reorder.js",
    "content": "// @flow\nimport type { Quote, QuoteMap } from './types';\nimport type { DraggableLocation } from '../../src/types';\n\n// a little function to help us with reordering the result\nconst reorder = (list: any[], startIndex: number, endIndex: number): any[] => {\n  const result = Array.from(list);\n  const [removed] = result.splice(startIndex, 1);\n  result.splice(endIndex, 0, removed);\n\n  return result;\n};\n\nexport default reorder;\n\ntype ReorderQuoteMapArgs = {|\n  quoteMap: QuoteMap,\n  source: DraggableLocation,\n  destination: DraggableLocation,\n|};\n\nexport type ReorderQuoteMapResult = {|\n  quoteMap: QuoteMap,\n|};\n\nexport const reorderQuoteMap = ({\n  quoteMap,\n  source,\n  destination,\n}: ReorderQuoteMapArgs): ReorderQuoteMapResult => {\n  const current: Quote[] = [...quoteMap[source.droppableId]];\n  const next: Quote[] = [...quoteMap[destination.droppableId]];\n  const target: Quote = current[source.index];\n\n  // moving to same list\n  if (source.droppableId === destination.droppableId) {\n    const reordered: Quote[] = reorder(\n      current,\n      source.index,\n      destination.index,\n    );\n    const result: QuoteMap = {\n      ...quoteMap,\n      [source.droppableId]: reordered,\n    };\n    return {\n      quoteMap: result,\n    };\n  }\n\n  // moving to different list\n\n  // remove from original\n  current.splice(source.index, 1);\n  // insert into next\n  next.splice(destination.index, 0, target);\n\n  const result: QuoteMap = {\n    ...quoteMap,\n    [source.droppableId]: current,\n    [destination.droppableId]: next,\n  };\n\n  return {\n    quoteMap: result,\n  };\n};\n\ntype List<T> = {|\n  id: string,\n  values: T[],\n|};\n\ntype MoveBetweenArgs<T> = {|\n  list1: List<T>,\n  list2: List<T>,\n  source: DraggableLocation,\n  destination: DraggableLocation,\n|};\n\ntype MoveBetweenResult<T> = {|\n  list1: List<T>,\n  list2: List<T>,\n|};\n\nexport function moveBetween<T>({\n  list1,\n  list2,\n  source,\n  destination,\n}: MoveBetweenArgs<T>): MoveBetweenResult<T> {\n  const newFirst = Array.from(list1.values);\n  const newSecond = Array.from(list2.values);\n\n  const moveFrom = source.droppableId === list1.id ? newFirst : newSecond;\n  const moveTo = moveFrom === newFirst ? newSecond : newFirst;\n\n  const [moved] = moveFrom.splice(source.index, 1);\n  moveTo.splice(destination.index, 0, moved);\n\n  return {\n    list1: {\n      ...list1,\n      values: newFirst,\n    },\n    list2: {\n      ...list2,\n      values: newSecond,\n    },\n  };\n}\n"
  },
  {
    "path": "stories/src/simple/simple-mixed-spacing.jsx",
    "content": "// disabling flowtype to keep this example super simple\n// It matches\n/* eslint-disable flowtype/require-valid-file-annotation */\n\nimport React, { Component } from 'react';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\n\n// fake data generator\nconst getItems = (count) =>\n  Array.from({ length: count }, (v, k) => k).map((k) => ({\n    id: `item-${k}`,\n    content: `item ${k}`,\n  }));\n\n// a little function to help us with reordering the result\nconst reorder = (list, startIndex, endIndex) => {\n  const result = Array.from(list);\n  const [removed] = result.splice(startIndex, 1);\n  result.splice(endIndex, 0, removed);\n\n  return result;\n};\n\nconst withAssortedSpacing = () => ({\n  // margin\n  marginTop: 10,\n  // not allowing margin collapsing\n  // marginBottom: 20,\n  marginLeft: 30,\n  marginRight: 40,\n  // padding\n  paddingTop: 10,\n  paddingBottom: 20,\n  paddingLeft: 30,\n  paddingRight: 40,\n  // border\n  borderStyle: 'solid',\n  borderColor: 'purple',\n  borderTopWidth: 2,\n  borderBottomWidth: 4,\n  borderLeftWidth: 6,\n  borderRightWidth: 8,\n});\n\nconst getItemStyle = (isDragging, draggableStyle) => ({\n  // some basic styles to make the items look a bit nicer\n  userSelect: 'none',\n  ...withAssortedSpacing(),\n\n  // change background colour if dragging\n  background: isDragging ? 'lightgreen' : 'pink',\n\n  // styles we need to apply on draggables\n  ...draggableStyle,\n});\n\nexport default class App extends Component {\n  constructor(props, context) {\n    super(props, context);\n    this.state = {\n      items: getItems(10),\n    };\n    this.onDragEnd = this.onDragEnd.bind(this);\n  }\n\n  onDragEnd(result) {\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    const items = reorder(\n      this.state.items,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      items,\n    });\n  }\n\n  // Normally you would want to split things out into separate components.\n  // But in this example everything is just done in one place for simplicity\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided) => (\n            <div\n              ref={droppableProvided.innerRef}\n              style={{\n                width: 250,\n                background: 'lightblue',\n\n                ...withAssortedSpacing(),\n                // no margin collapsing\n                marginTop: 0,\n              }}\n            >\n              {this.state.items.map((item, index) => (\n                <Draggable key={item.id} draggableId={item.id} index={index}>\n                  {(draggableProvided, draggableSnapshot) => (\n                    <div\n                      ref={draggableProvided.innerRef}\n                      {...draggableProvided.draggableProps}\n                      {...draggableProvided.dragHandleProps}\n                      style={getItemStyle(\n                        draggableSnapshot.isDragging,\n                        draggableProvided.draggableProps.style,\n                      )}\n                    >\n                      {item.content}\n                    </div>\n                  )}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/simple/simple-scrollable.jsx",
    "content": "// disabling flowtype to keep this example super simple\n/* eslint-disable flowtype/require-valid-file-annotation */\n\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\n\n// fake data generator\nconst getItems = (count) =>\n  Array.from({ length: count }, (v, k) => k).map((k) => ({\n    id: `item-${k}`,\n    content: `item ${k}`,\n  }));\n\n// a little function to help us with reordering the result\nconst reorder = (list, startIndex, endIndex) => {\n  const result = Array.from(list);\n  const [removed] = result.splice(startIndex, 1);\n  result.splice(endIndex, 0, removed);\n\n  return result;\n};\n\nconst grid = 8;\n\nconst getItemStyle = (isDragging, draggableStyle) => ({\n  // some basic styles to make the items look a bit nicer\n  userSelect: 'none',\n  padding: grid * 2,\n  margin: `0 0 ${grid}px 0`,\n  border: '5px solid yellow',\n  height: 30,\n\n  // change background colour if dragging\n  background: isDragging ? 'lightgreen' : 'red',\n\n  // styles we need to apply on draggables\n  ...draggableStyle,\n});\n\nconst getListStyle = (isDraggingOver, overflow) => ({\n  background: isDraggingOver ? 'lightblue' : 'grey',\n  padding: grid,\n  border: '5px solid pink',\n  width: 250,\n  maxHeight: '50vh',\n  overflow,\n});\n\nexport default class App extends Component {\n  static propTypes = {\n    overflow: PropTypes.string,\n  };\n  static defaultProps = {\n    overflow: 'auto',\n  };\n\n  constructor(props, context) {\n    super(props, context);\n    this.state = {\n      items: getItems(10),\n    };\n    this.onDragEnd = this.onDragEnd.bind(this);\n  }\n\n  onDragEnd(result) {\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    const items = reorder(\n      this.state.items,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      items,\n    });\n  }\n\n  // Normally you would want to split things out into separate components.\n  // But in this example everything is just done in one place for simplicity\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided, droppableSnapshot) => (\n            <div\n              ref={droppableProvided.innerRef}\n              style={getListStyle(\n                droppableSnapshot.isDraggingOver,\n                this.props.overflow,\n              )}\n              onScroll={(e) =>\n                // eslint-disable-next-line no-console\n                console.log('current scrollTop', e.currentTarget.scrollTop)\n              }\n            >\n              {this.state.items.map((item, index) => (\n                <Draggable key={item.id} draggableId={item.id} index={index}>\n                  {(draggableProvided, draggableSnapshot) => (\n                    <div\n                      ref={draggableProvided.innerRef}\n                      {...draggableProvided.draggableProps}\n                      {...draggableProvided.dragHandleProps}\n                      style={getItemStyle(\n                        draggableSnapshot.isDragging,\n                        draggableProvided.draggableProps.style,\n                      )}\n                    >\n                      {item.content}\n                    </div>\n                  )}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/simple/simple.jsx",
    "content": "// disabling flowtype to keep this example super simple\n// It matches\n/* eslint-disable flowtype/require-valid-file-annotation */\n\nimport React, { Component } from 'react';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\n\n// fake data generator\nconst getItems = (count) =>\n  Array.from({ length: count }, (v, k) => k).map((k) => ({\n    id: `item-${k}`,\n    content: `item ${k}`,\n  }));\n\n// a little function to help us with reordering the result\nconst reorder = (list, startIndex, endIndex) => {\n  const result = Array.from(list);\n  const [removed] = result.splice(startIndex, 1);\n  result.splice(endIndex, 0, removed);\n\n  return result;\n};\n\nconst grid = 8;\n\nconst getItemStyle = (isDragging, draggableStyle) => ({\n  // some basic styles to make the items look a bit nicer\n  userSelect: 'none',\n  padding: grid * 2,\n  margin: `0 0 ${grid}px 0`,\n\n  // change background colour if dragging\n  background: isDragging ? 'lightgreen' : 'red',\n\n  // styles we need to apply on draggables\n  ...draggableStyle,\n});\n\nconst getListStyle = (isDraggingOver) => ({\n  background: isDraggingOver ? 'lightblue' : 'grey',\n  padding: grid,\n  width: 250,\n});\n\nexport default class App extends Component {\n  constructor(props, context) {\n    super(props, context);\n    // eslint-disable-next-line react/state-in-constructor\n    this.state = {\n      items: getItems(10),\n    };\n    this.onDragEnd = this.onDragEnd.bind(this);\n  }\n\n  onDragEnd(result) {\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    const items = reorder(\n      this.state.items,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      items,\n    });\n  }\n\n  // Normally you would want to split things out into separate components.\n  // But in this example everything is just done in one place for simplicity\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided, droppableSnapshot) => (\n            <div\n              ref={droppableProvided.innerRef}\n              style={getListStyle(droppableSnapshot.isDraggingOver)}\n            >\n              {this.state.items.map((item, index) => (\n                <Draggable key={item.id} draggableId={item.id} index={index}>\n                  {(draggableProvided, draggableSnapshot) => (\n                    <div\n                      ref={draggableProvided.innerRef}\n                      {...draggableProvided.draggableProps}\n                      {...draggableProvided.dragHandleProps}\n                      style={getItemStyle(\n                        draggableSnapshot.isDragging,\n                        draggableProvided.draggableProps.style,\n                      )}\n                    >\n                      {item.content}\n                    </div>\n                  )}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/table/with-clone.jsx",
    "content": "// @flow\n/* eslint-disable react/sort-comp */\nimport React, { Component, Fragment, type Node } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport {\n  DragDropContext,\n  Droppable,\n  Draggable,\n  type DropResult,\n  type DroppableProvided,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type DraggableRubric,\n} from '../../../src';\nimport reorder from '../reorder';\nimport { grid } from '../constants';\nimport type { Quote } from '../types';\n\nconst Table = styled.table`\n  width: 500px;\n  margin: 0 auto;\n  table-layout: ${(props) => props.layout};\n`;\n\nconst TBody = styled.tbody`\n  border: 0;\n`;\n\nconst THead = styled.thead`\n  border: 0;\n  border-bottom: none;\n  background-color: ${colors.N20};\n`;\n\nconst Row = styled.tr`\n  ${(props) => (props.isDragging ? `background: ${colors.G50};` : '')};\n`;\n\nconst Cell = styled.td`\n  box-sizing: border-box;\n  padding: ${grid}px;\n`;\n\ntype TableCellProps = {|\n  children: Node,\n  isDragOccurring: boolean,\n  isDragging: boolean,\n  cellId: string,\n|};\n\ntype TableCellSnapshot = {|\n  width: number,\n  height: number,\n|};\n\ntype SnapshotMap = {\n  [cellId: string]: TableCellSnapshot,\n};\n\nconst snapshotMap: SnapshotMap = {};\n\nclass TableCell extends React.Component<TableCellProps> {\n  ref: ?HTMLElement;\n\n  componentDidMount() {\n    const cellId: string = this.props.cellId;\n    if (!snapshotMap[cellId]) {\n      return;\n    }\n\n    if (!this.props.isDragging) {\n      // cleanup the map if it is not being used\n      delete snapshotMap[cellId];\n      return;\n    }\n\n    this.applySnapshot(snapshotMap[cellId]);\n  }\n\n  getSnapshotBeforeUpdate(prevProps: TableCellProps): ?TableCellSnapshot {\n    // we will be locking the dimensions of the dragging item on mount\n    if (this.props.isDragging) {\n      return null;\n    }\n\n    const isDragStarting: boolean =\n      this.props.isDragOccurring && !prevProps.isDragOccurring;\n\n    if (!isDragStarting) {\n      return null;\n    }\n\n    return this.getSnapshot();\n  }\n\n  componentDidUpdate(\n    prevProps: TableCellProps,\n    prevState: mixed,\n    snapshot: ?TableCellSnapshot,\n  ) {\n    const ref: ?HTMLElement = this.ref;\n    if (!ref) {\n      return;\n    }\n\n    if (snapshot) {\n      this.applySnapshot(snapshot);\n      return;\n    }\n\n    if (this.props.isDragOccurring) {\n      return;\n    }\n\n    // inline styles not applied\n    if (ref.style.width == null) {\n      return;\n    }\n\n    // no snapshot and drag is finished - clear the inline styles\n    ref.style.removeProperty('height');\n    ref.style.removeProperty('width');\n  }\n\n  componentWillUnmount() {\n    const snapshot: ?TableCellSnapshot = this.getSnapshot();\n    if (!snapshot) {\n      return;\n    }\n    snapshotMap[this.props.cellId] = snapshot;\n  }\n\n  getSnapshot = (): ?TableCellSnapshot => {\n    if (!this.ref) {\n      return null;\n    }\n\n    const { width, height } = this.ref.getBoundingClientRect();\n\n    const snapshot: TableCellSnapshot = {\n      width,\n      height,\n    };\n\n    return snapshot;\n  };\n\n  applySnapshot = (snapshot: TableCellSnapshot) => {\n    const ref: ?HTMLElement = this.ref;\n\n    if (!ref) {\n      return;\n    }\n\n    if (ref.style.width === snapshot.width) {\n      return;\n    }\n\n    ref.style.width = `${snapshot.width}px`;\n    ref.style.height = `${snapshot.height}px`;\n  };\n\n  setRef = (ref: ?HTMLElement) => {\n    this.ref = ref;\n  };\n\n  render() {\n    return <Cell ref={this.setRef}>{this.props.children}</Cell>;\n  }\n}\n\ntype TableRowProps = {|\n  quote: Quote,\n  provided: DraggableProvided,\n  snapshot: DraggableStateSnapshot,\n|};\n\n// Using a table as the portal so that we do not get react\n// warnings when mounting a tr element\nconst table: HTMLElement = document.createElement('table');\ntable.classList.add('my-super-cool-table-portal');\nObject.assign(table.style, {\n  margin: '0',\n  padding: '0',\n  border: '0',\n  height: '0',\n  width: '0',\n});\nconst tbody: HTMLElement = document.createElement('tbody');\ntable.appendChild(tbody);\n\nif (!document.body) {\n  throw new Error('document.body required for example');\n}\ndocument.body.appendChild(table);\n\nconst IsDraggingContext = React.createContext<boolean>(false);\n\nclass TableRow extends Component<TableRowProps> {\n  render() {\n    const { snapshot, quote, provided } = this.props;\n    const child: Node = (\n      <IsDraggingContext.Consumer>\n        {(isDragging: boolean) => (\n          <Row\n            ref={provided.innerRef}\n            isDragging={snapshot.isDragging}\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n          >\n            <TableCell\n              isDragOccurring={isDragging}\n              isDragging={snapshot.isDragging}\n              cellId=\"name\"\n            >\n              {quote.author.name}\n            </TableCell>\n            <TableCell\n              isDragOccurring={isDragging}\n              isDragging={snapshot.isDragging}\n              cellId=\"content\"\n            >\n              {quote.content}\n            </TableCell>\n          </Row>\n        )}\n      </IsDraggingContext.Consumer>\n    );\n\n    return child;\n  }\n}\n\n// TODO: make this look nicer!\nconst Header = styled.header`\n  display: flex;\n  flex-direction: column;\n  width: 500px;\n  margin: 0 auto;\n  margin-bottom: ${grid * 2}px;\n`;\n\n/* stylelint-disable block-no-empty */\nconst LayoutControl = styled.div``;\n\nconst CopyTableButton = styled.button``;\n/* stylelint-enable */\n\ntype AppProps = {|\n  initial: Quote[],\n|};\n\ntype AppState = {|\n  quotes: Quote[],\n  layout: 'fixed' | 'auto',\n  isDragging: boolean,\n|};\nexport default class TableApp extends Component<AppProps, AppState> {\n  tableRef: ?HTMLElement;\n\n  state: AppState = {\n    quotes: this.props.initial,\n    layout: 'auto',\n    isDragging: false,\n  };\n\n  onBeforeDragStart = () => {\n    this.setState({\n      isDragging: true,\n    });\n  };\n\n  onDragEnd = (result: DropResult) => {\n    this.setState({\n      isDragging: false,\n    });\n\n    // dropped outside the list\n    if (\n      !result.destination ||\n      result.destination.index === result.source.index\n    ) {\n      return;\n    }\n\n    // no movement\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    const quotes = reorder(\n      this.state.quotes,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      quotes,\n    });\n  };\n\n  toggleTableLayout = () => {\n    this.setState({\n      layout: this.state.layout === 'auto' ? 'fixed' : 'auto',\n    });\n  };\n\n  copyTableToClipboard = () => {\n    const tableRef: ?HTMLElement = this.tableRef;\n    if (tableRef == null) {\n      return;\n    }\n\n    const range: Range = document.createRange();\n    range.selectNode(tableRef);\n    window.getSelection().addRange(range);\n\n    const wasCopied: boolean = (() => {\n      try {\n        const result: boolean = document.execCommand('copy');\n        return result;\n      } catch (e) {\n        return false;\n      }\n    })();\n\n    // eslint-disable-next-line no-console\n    console.log('was copied?', wasCopied);\n\n    // clear selection\n    window.getSelection().removeAllRanges();\n  };\n\n  render() {\n    return (\n      <IsDraggingContext.Provider value={this.state.isDragging}>\n        <DragDropContext\n          onBeforeDragStart={this.onBeforeDragStart}\n          onDragEnd={this.onDragEnd}\n        >\n          <Fragment>\n            <Header>\n              <LayoutControl>\n                Current layout: <code>{this.state.layout}</code>\n                <button type=\"button\" onClick={this.toggleTableLayout}>\n                  Toggle\n                </button>\n              </LayoutControl>\n              <div>\n                Copy table to clipboard:\n                <CopyTableButton onClick={this.copyTableToClipboard}>\n                  Copy\n                </CopyTableButton>\n              </div>\n            </Header>\n            <Table layout={this.state.layout}>\n              <THead>\n                <tr>\n                  <th>Author</th>\n                  <th>Content</th>\n                </tr>\n              </THead>\n              <Droppable\n                droppableId=\"table\"\n                renderClone={(\n                  provided: DraggableProvided,\n                  snapshot: DraggableStateSnapshot,\n                  rubric: DraggableRubric,\n                ) => (\n                  <TableRow\n                    provided={provided}\n                    snapshot={snapshot}\n                    quote={this.state.quotes[rubric.source.index]}\n                  />\n                )}\n                getContainerForClone={() => tbody}\n              >\n                {(droppableProvided: DroppableProvided) => (\n                  <TBody\n                    ref={(ref: ?HTMLElement) => {\n                      this.tableRef = ref;\n                      droppableProvided.innerRef(ref);\n                    }}\n                    {...droppableProvided.droppableProps}\n                  >\n                    {this.state.quotes.map((quote: Quote, index: number) => (\n                      <Draggable\n                        draggableId={quote.id}\n                        index={index}\n                        key={quote.id}\n                      >\n                        {(\n                          provided: DraggableProvided,\n                          snapshot: DraggableStateSnapshot,\n                        ) => (\n                          <TableRow\n                            provided={provided}\n                            snapshot={snapshot}\n                            quote={quote}\n                          />\n                        )}\n                      </Draggable>\n                    ))}\n                    {droppableProvided.placeholder}\n                  </TBody>\n                )}\n              </Droppable>\n            </Table>\n          </Fragment>\n        </DragDropContext>\n      </IsDraggingContext.Provider>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/table/with-dimension-locking.jsx",
    "content": "// @flow\n/* eslint-disable react/sort-comp */\nimport React, { Component, Fragment, type Node } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\nimport reorder from '../reorder';\nimport { grid } from '../constants';\nimport type { Quote } from '../types';\nimport type {\n  DropResult,\n  DroppableProvided,\n  DraggableProvided,\n  DraggableStateSnapshot,\n} from '../../../src';\n\nconst Table = styled.table`\n  width: 500px;\n  margin: 0 auto;\n  table-layout: ${(props) => props.layout};\n`;\n\nconst TBody = styled.tbody`\n  border: 0;\n`;\n\nconst THead = styled.thead`\n  border: 0;\n  border-bottom: none;\n  background-color: ${colors.N10};\n`;\n\nconst Row = styled.tr`\n  ${(props) => (props.isDragging ? `background: ${colors.G100};` : '')};\n`;\n\nconst Cell = styled.td`\n  box-sizing: border-box;\n  padding: ${grid}px;\n`;\n\ntype TableCellProps = {|\n  children: Node,\n  isDragOccurring: boolean,\n|};\n\ntype TableCellSnapshot = {|\n  width: number,\n  height: number,\n|};\nclass TableCell extends React.Component<TableCellProps> {\n  ref: ?HTMLElement;\n\n  getSnapshotBeforeUpdate(prevProps: TableCellProps): ?TableCellSnapshot {\n    if (!this.ref) {\n      return null;\n    }\n\n    const isDragStarting: boolean =\n      this.props.isDragOccurring && !prevProps.isDragOccurring;\n\n    if (!isDragStarting) {\n      return null;\n    }\n\n    const { width, height } = this.ref.getBoundingClientRect();\n\n    const snapshot: TableCellSnapshot = {\n      width,\n      height,\n    };\n\n    return snapshot;\n  }\n\n  componentDidUpdate(\n    prevProps: TableCellProps,\n    prevState: mixed,\n    snapshot: ?TableCellSnapshot,\n  ) {\n    const ref: ?HTMLElement = this.ref;\n    if (!ref) {\n      return;\n    }\n\n    if (snapshot) {\n      if (ref.style.width === snapshot.width) {\n        return;\n      }\n      ref.style.width = `${snapshot.width}px`;\n      ref.style.height = `${snapshot.height}px`;\n      return;\n    }\n\n    if (this.props.isDragOccurring) {\n      return;\n    }\n\n    // inline styles not applied\n    if (ref.style.width == null) {\n      return;\n    }\n\n    // no snapshot and drag is finished - clear the inline styles\n    ref.style.removeProperty('height');\n    ref.style.removeProperty('width');\n  }\n\n  setRef = (ref: ?HTMLElement) => {\n    this.ref = ref;\n  };\n\n  render() {\n    return <Cell ref={this.setRef}>{this.props.children}</Cell>;\n  }\n}\n\ntype TableRowProps = {|\n  quote: Quote,\n  provided: DraggableProvided,\n  snapshot: DraggableStateSnapshot,\n|};\n\nconst IsDraggingContext = React.createContext<boolean>(false);\n\nclass TableRow extends Component<TableRowProps> {\n  render() {\n    const { snapshot, quote, provided } = this.props;\n    return (\n      <IsDraggingContext.Consumer>\n        {(isDragging: boolean) => (\n          <Row\n            ref={provided.innerRef}\n            isDragging={snapshot.isDragging}\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n          >\n            <TableCell isDragOccurring={isDragging}>\n              {quote.author.name}\n            </TableCell>\n            <TableCell isDragOccurring={isDragging}>{quote.content}</TableCell>\n          </Row>\n        )}\n      </IsDraggingContext.Consumer>\n    );\n  }\n}\n\n// TODO: make this look nicer!\nconst Header = styled.header`\n  display: flex;\n  flex-direction: column;\n  width: 500px;\n  margin: 0 auto;\n  margin-bottom: ${grid * 2}px;\n`;\n\n/* stylelint-disable block-no-empty */\nconst LayoutControl = styled.div``;\n\nconst CopyTableButton = styled.button``;\n/* stylelint-enable */\n\ntype AppProps = {|\n  initial: Quote[],\n|};\n\ntype AppState = {|\n  quotes: Quote[],\n  layout: 'fixed' | 'auto',\n  isDragging: boolean,\n|};\nexport default class TableApp extends Component<AppProps, AppState> {\n  tableRef: ?HTMLElement;\n\n  state: AppState = {\n    quotes: this.props.initial,\n    layout: 'auto',\n    isDragging: false,\n  };\n\n  onBeforeDragStart = () => {\n    this.setState({\n      isDragging: true,\n    });\n  };\n\n  onDragEnd = (result: DropResult) => {\n    this.setState({\n      isDragging: false,\n    });\n\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    // no movement\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    const quotes = reorder(\n      this.state.quotes,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      quotes,\n    });\n  };\n\n  toggleTableLayout = () => {\n    this.setState({\n      layout: this.state.layout === 'auto' ? 'fixed' : 'auto',\n    });\n  };\n\n  copyTableToClipboard = () => {\n    const tableRef: ?HTMLElement = this.tableRef;\n    if (tableRef == null) {\n      return;\n    }\n\n    const range: Range = document.createRange();\n    range.selectNode(tableRef);\n    window.getSelection().addRange(range);\n\n    const wasCopied: boolean = (() => {\n      try {\n        const result: boolean = document.execCommand('copy');\n        return result;\n      } catch (e) {\n        return false;\n      }\n    })();\n\n    // eslint-disable-next-line no-console\n    console.log('was copied?', wasCopied);\n\n    // clear selection\n    window.getSelection().removeAllRanges();\n  };\n\n  render() {\n    return (\n      <IsDraggingContext.Provider value={this.state.isDragging}>\n        <DragDropContext\n          onBeforeDragStart={this.onBeforeDragStart}\n          onDragEnd={this.onDragEnd}\n        >\n          <Fragment>\n            <Header>\n              <LayoutControl>\n                Current layout: <code>{this.state.layout}</code>\n                <button type=\"button\" onClick={this.toggleTableLayout}>\n                  Toggle\n                </button>\n              </LayoutControl>\n              <div>\n                Copy table to clipboard:\n                <CopyTableButton onClick={this.copyTableToClipboard}>\n                  Copy\n                </CopyTableButton>\n              </div>\n            </Header>\n            <Table layout={this.state.layout}>\n              <THead>\n                <tr>\n                  <th>Author</th>\n                  <th>Content</th>\n                </tr>\n              </THead>\n              <Droppable droppableId=\"table\">\n                {(droppableProvided: DroppableProvided) => (\n                  <TBody\n                    ref={(ref: ?HTMLElement) => {\n                      this.tableRef = ref;\n                      droppableProvided.innerRef(ref);\n                    }}\n                    {...droppableProvided.droppableProps}\n                  >\n                    {this.state.quotes.map((quote: Quote, index: number) => (\n                      <Draggable\n                        draggableId={quote.id}\n                        index={index}\n                        key={quote.id}\n                      >\n                        {(\n                          provided: DraggableProvided,\n                          snapshot: DraggableStateSnapshot,\n                        ) => (\n                          <TableRow\n                            provided={provided}\n                            snapshot={snapshot}\n                            quote={quote}\n                          />\n                        )}\n                      </Draggable>\n                    ))}\n                    {droppableProvided.placeholder}\n                  </TBody>\n                )}\n              </Droppable>\n            </Table>\n          </Fragment>\n        </DragDropContext>\n      </IsDraggingContext.Provider>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/table/with-fixed-columns.jsx",
    "content": "// @flow\nimport React, { Component, Fragment } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\nimport reorder from '../reorder';\nimport { grid } from '../constants';\nimport type { Quote } from '../types';\nimport type {\n  DropResult,\n  DroppableProvided,\n  DraggableProvided,\n  DraggableStateSnapshot,\n} from '../../../src';\n\nconst Table = styled.table`\n  width: 500px;\n  margin: 0 auto;\n  table-layout: ${(props) => props.layout};\n`;\n\nconst TBody = styled.tbody`\n  border: 0;\n`;\n\nconst THead = styled.thead`\n  border: 0;\n  border-bottom: none;\n  background-color: ${colors.N50};\n`;\n\nconst Row = styled.tr`\n  /* stylelint-disable comment-empty-line-before */\n  ${(props) =>\n    props.isDragging\n      ? `\n    background: ${colors.G100};\n\n    /* maintain cell width while dragging */\n    display: table;\n  `\n      : ''}/* stylelint-enable */;\n`;\n\nconst Cell = styled.td`\n  box-sizing: border-box;\n  padding: ${grid}px;\n\n  /* locking the width of the cells */\n  width: 50%;\n`;\n\ntype TableRowProps = {|\n  quote: Quote,\n  provided: DraggableProvided,\n  snapshot: DraggableStateSnapshot,\n|};\n\nclass TableRow extends Component<TableRowProps> {\n  render() {\n    const { snapshot, quote, provided } = this.props;\n    return (\n      <Row\n        ref={provided.innerRef}\n        isDragging={snapshot.isDragging}\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n      >\n        <Cell>{quote.author.name}</Cell>\n        <Cell>{quote.content}</Cell>\n      </Row>\n    );\n  }\n}\n\nconst Header = styled.header`\n  display: flex;\n  flex-direction: column;\n  width: 500px;\n  margin: 0 auto;\n  margin-bottom: ${grid * 2}px;\n`;\n\n/* stylelint-disable block-no-empty */\nconst LayoutControl = styled.div``;\n\nconst CopyTableButton = styled.button``;\n/* stylelint-enable */\n\ntype AppProps = {|\n  initial: Quote[],\n|};\n\ntype AppState = {|\n  quotes: Quote[],\n  layout: 'fixed' | 'auto',\n|};\nexport default class TableApp extends Component<AppProps, AppState> {\n  // eslint-disable-next-line react/sort-comp\n  tableRef: ?HTMLElement;\n\n  state: AppState = {\n    quotes: this.props.initial,\n    layout: 'auto',\n  };\n\n  onDragEnd = (result: DropResult) => {\n    // dropped outside the list\n    if (\n      !result.destination ||\n      result.destination.index === result.source.index\n    ) {\n      return;\n    }\n\n    // no movement\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    const quotes = reorder(\n      this.state.quotes,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      quotes,\n    });\n  };\n\n  toggleTableLayout = () => {\n    this.setState({\n      layout: this.state.layout === 'auto' ? 'fixed' : 'auto',\n    });\n  };\n\n  copyTableToClipboard = () => {\n    const tableRef: ?HTMLElement = this.tableRef;\n    if (tableRef == null) {\n      return;\n    }\n\n    const range: Range = document.createRange();\n    range.selectNode(tableRef);\n    window.getSelection().addRange(range);\n\n    const wasCopied: boolean = (() => {\n      try {\n        const result: boolean = document.execCommand('copy');\n        return result;\n      } catch (e) {\n        return false;\n      }\n    })();\n\n    // eslint-disable-next-line no-console\n    console.log('was copied?', wasCopied);\n\n    // clear selection\n    window.getSelection().removeAllRanges();\n  };\n\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Fragment>\n          <Header>\n            <LayoutControl>\n              Current layout: <code>{this.state.layout}</code>\n              <button type=\"button\" onClick={this.toggleTableLayout}>\n                Toggle\n              </button>\n            </LayoutControl>\n            <div>\n              Copy table to clipboard:\n              <CopyTableButton onClick={this.copyTableToClipboard}>\n                Copy\n              </CopyTableButton>\n            </div>\n          </Header>\n          <Table layout={this.state.layout}>\n            <THead>\n              <tr>\n                <th>Author</th>\n                <th>Content</th>\n              </tr>\n            </THead>\n            <Droppable droppableId=\"table\">\n              {(droppableProvided: DroppableProvided) => (\n                <TBody\n                  ref={(ref: ?HTMLElement) => {\n                    this.tableRef = ref;\n                    droppableProvided.innerRef(ref);\n                  }}\n                  {...droppableProvided.droppableProps}\n                >\n                  {this.state.quotes.map((quote: Quote, index: number) => (\n                    <Draggable\n                      draggableId={quote.id}\n                      index={index}\n                      key={quote.id}\n                    >\n                      {(\n                        provided: DraggableProvided,\n                        snapshot: DraggableStateSnapshot,\n                      ) => (\n                        <TableRow\n                          provided={provided}\n                          snapshot={snapshot}\n                          quote={quote}\n                        />\n                      )}\n                    </Draggable>\n                  ))}\n                  {droppableProvided.placeholder}\n                </TBody>\n              )}\n            </Droppable>\n          </Table>\n        </Fragment>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/table/with-portal.jsx",
    "content": "// @flow\n/* eslint-disable react/sort-comp */\nimport React, { Component, Fragment, type Node } from 'react';\nimport ReactDOM from 'react-dom';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\nimport reorder from '../reorder';\nimport { grid } from '../constants';\nimport type { Quote } from '../types';\nimport type {\n  DropResult,\n  DroppableProvided,\n  DraggableProvided,\n  DraggableStateSnapshot,\n} from '../../../src';\n\nconst Table = styled.table`\n  width: 500px;\n  margin: 0 auto;\n  table-layout: ${(props) => props.layout};\n`;\n\nconst TBody = styled.tbody`\n  border: 0;\n`;\n\nconst THead = styled.thead`\n  border: 0;\n  border-bottom: none;\n  background-color: ${colors.N20};\n`;\n\nconst Row = styled.tr`\n  ${(props) => (props.isDragging ? `background: ${colors.G50};` : '')};\n`;\n\nconst Cell = styled.td`\n  box-sizing: border-box;\n  padding: ${grid}px;\n`;\n\ntype TableCellProps = {|\n  children: Node,\n  isDragOccurring: boolean,\n  isDragging: boolean,\n  cellId: string,\n|};\n\ntype TableCellSnapshot = {|\n  width: number,\n  height: number,\n|};\n\ntype SnapshotMap = {\n  [cellId: string]: TableCellSnapshot,\n};\n\nconst snapshotMap: SnapshotMap = {};\n\nclass TableCell extends React.Component<TableCellProps> {\n  ref: ?HTMLElement;\n\n  componentDidMount() {\n    const cellId: string = this.props.cellId;\n    if (!snapshotMap[cellId]) {\n      return;\n    }\n\n    if (!this.props.isDragging) {\n      // cleanup the map if it is not being used\n      delete snapshotMap[cellId];\n      return;\n    }\n\n    this.applySnapshot(snapshotMap[cellId]);\n  }\n\n  getSnapshotBeforeUpdate(prevProps: TableCellProps): ?TableCellSnapshot {\n    // we will be locking the dimensions of the dragging item on mount\n    if (this.props.isDragging) {\n      return null;\n    }\n\n    const isDragStarting: boolean =\n      this.props.isDragOccurring && !prevProps.isDragOccurring;\n\n    if (!isDragStarting) {\n      return null;\n    }\n\n    return this.getSnapshot();\n  }\n\n  componentDidUpdate(\n    prevProps: TableCellProps,\n    prevState: mixed,\n    snapshot: ?TableCellSnapshot,\n  ) {\n    const ref: ?HTMLElement = this.ref;\n    if (!ref) {\n      return;\n    }\n\n    if (snapshot) {\n      this.applySnapshot(snapshot);\n      return;\n    }\n\n    if (this.props.isDragOccurring) {\n      return;\n    }\n\n    // inline styles not applied\n    if (ref.style.width == null) {\n      return;\n    }\n\n    // no snapshot and drag is finished - clear the inline styles\n    ref.style.removeProperty('height');\n    ref.style.removeProperty('width');\n  }\n\n  componentWillUnmount() {\n    const snapshot: ?TableCellSnapshot = this.getSnapshot();\n    if (!snapshot) {\n      return;\n    }\n    snapshotMap[this.props.cellId] = snapshot;\n  }\n\n  getSnapshot = (): ?TableCellSnapshot => {\n    if (!this.ref) {\n      return null;\n    }\n\n    const { width, height } = this.ref.getBoundingClientRect();\n\n    const snapshot: TableCellSnapshot = {\n      width,\n      height,\n    };\n\n    return snapshot;\n  };\n\n  applySnapshot = (snapshot: TableCellSnapshot) => {\n    const ref: ?HTMLElement = this.ref;\n\n    if (!ref) {\n      return;\n    }\n\n    if (ref.style.width === snapshot.width) {\n      return;\n    }\n\n    ref.style.width = `${snapshot.width}px`;\n    ref.style.height = `${snapshot.height}px`;\n  };\n\n  setRef = (ref: ?HTMLElement) => {\n    this.ref = ref;\n  };\n\n  render() {\n    return <Cell ref={this.setRef}>{this.props.children}</Cell>;\n  }\n}\n\ntype TableRowProps = {|\n  quote: Quote,\n  provided: DraggableProvided,\n  snapshot: DraggableStateSnapshot,\n|};\n\n// Using a table as the portal so that we do not get react\n// warnings when mounting a tr element\nconst table: HTMLElement = document.createElement('table');\ntable.classList.add('my-super-cool-table-portal');\nObject.assign(table.style, {\n  margin: '0',\n  padding: '0',\n  border: '0',\n  height: '0',\n  width: '0',\n});\nconst tbody: HTMLElement = document.createElement('tbody');\ntable.appendChild(tbody);\n\nif (!document.body) {\n  throw new Error('document.body required for example');\n}\ndocument.body.appendChild(table);\n\nconst IsDraggingContext = React.createContext<boolean>(false);\n\nclass TableRow extends Component<TableRowProps> {\n  render() {\n    const { snapshot, quote, provided } = this.props;\n    const child: Node = (\n      <IsDraggingContext.Consumer>\n        {(isDragging: boolean) => (\n          <Row\n            ref={provided.innerRef}\n            isDragging={snapshot.isDragging}\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n          >\n            <TableCell\n              isDragOccurring={isDragging}\n              isDragging={snapshot.isDragging}\n              cellId=\"name\"\n            >\n              {quote.author.name}\n            </TableCell>\n            <TableCell\n              isDragOccurring={isDragging}\n              isDragging={snapshot.isDragging}\n              cellId=\"content\"\n            >\n              {quote.content}\n            </TableCell>\n          </Row>\n        )}\n      </IsDraggingContext.Consumer>\n    );\n\n    if (!snapshot.isDragging) {\n      return child;\n    }\n\n    return ReactDOM.createPortal(child, tbody);\n  }\n}\n\n// TODO: make this look nicer!\nconst Header = styled.header`\n  display: flex;\n  flex-direction: column;\n  width: 500px;\n  margin: 0 auto;\n  margin-bottom: ${grid * 2}px;\n`;\n\n/* stylelint-disable block-no-empty */\nconst LayoutControl = styled.div``;\n\nconst CopyTableButton = styled.button``;\n/* stylelint-enable */\n\ntype AppProps = {|\n  initial: Quote[],\n|};\n\ntype AppState = {|\n  quotes: Quote[],\n  layout: 'fixed' | 'auto',\n  isDragging: boolean,\n|};\nexport default class TableApp extends Component<AppProps, AppState> {\n  tableRef: ?HTMLElement;\n\n  state: AppState = {\n    quotes: this.props.initial,\n    layout: 'auto',\n    isDragging: false,\n  };\n\n  onBeforeDragStart = () => {\n    this.setState({\n      isDragging: true,\n    });\n  };\n\n  onDragEnd = (result: DropResult) => {\n    this.setState({\n      isDragging: false,\n    });\n\n    // dropped outside the list\n    if (\n      !result.destination ||\n      result.destination.index === result.source.index\n    ) {\n      return;\n    }\n\n    // no movement\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    const quotes = reorder(\n      this.state.quotes,\n      result.source.index,\n      result.destination.index,\n    );\n\n    this.setState({\n      quotes,\n    });\n  };\n\n  toggleTableLayout = () => {\n    this.setState({\n      layout: this.state.layout === 'auto' ? 'fixed' : 'auto',\n    });\n  };\n\n  copyTableToClipboard = () => {\n    const tableRef: ?HTMLElement = this.tableRef;\n    if (tableRef == null) {\n      return;\n    }\n\n    const range: Range = document.createRange();\n    range.selectNode(tableRef);\n    window.getSelection().addRange(range);\n\n    const wasCopied: boolean = (() => {\n      try {\n        const result: boolean = document.execCommand('copy');\n        return result;\n      } catch (e) {\n        return false;\n      }\n    })();\n\n    // eslint-disable-next-line no-console\n    console.log('was copied?', wasCopied);\n\n    // clear selection\n    window.getSelection().removeAllRanges();\n  };\n\n  render() {\n    return (\n      <IsDraggingContext.Provider value={this.state.isDragging}>\n        <DragDropContext\n          onBeforeDragStart={this.onBeforeDragStart}\n          onDragEnd={this.onDragEnd}\n        >\n          <Fragment>\n            <Header>\n              <LayoutControl>\n                Current layout: <code>{this.state.layout}</code>\n                <button type=\"button\" onClick={this.toggleTableLayout}>\n                  Toggle\n                </button>\n              </LayoutControl>\n              <div>\n                Copy table to clipboard:\n                <CopyTableButton onClick={this.copyTableToClipboard}>\n                  Copy\n                </CopyTableButton>\n              </div>\n            </Header>\n            <Table layout={this.state.layout}>\n              <THead>\n                <tr>\n                  <th>Author</th>\n                  <th>Content</th>\n                </tr>\n              </THead>\n              <Droppable droppableId=\"table\">\n                {(droppableProvided: DroppableProvided) => (\n                  <TBody\n                    ref={(ref: ?HTMLElement) => {\n                      this.tableRef = ref;\n                      droppableProvided.innerRef(ref);\n                    }}\n                    {...droppableProvided.droppableProps}\n                  >\n                    {this.state.quotes.map((quote: Quote, index: number) => (\n                      <Draggable\n                        draggableId={quote.id}\n                        index={index}\n                        key={quote.id}\n                      >\n                        {(\n                          provided: DraggableProvided,\n                          snapshot: DraggableStateSnapshot,\n                        ) => (\n                          <TableRow\n                            provided={provided}\n                            snapshot={snapshot}\n                            quote={quote}\n                          />\n                        )}\n                      </Draggable>\n                    ))}\n                    {droppableProvided.placeholder}\n                  </TBody>\n                )}\n              </Droppable>\n            </Table>\n          </Fragment>\n        </DragDropContext>\n      </IsDraggingContext.Provider>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/types.js",
    "content": "// @flow\nimport type { DraggableId, DraggableLocation } from '../../src/types';\n\nexport type Id = string;\n\nexport type AuthorColors = {|\n  soft: string,\n  hard: string,\n|};\n\nexport type Author = {|\n  id: Id,\n  name: string,\n  avatarUrl: string,\n  url: string,\n  colors: AuthorColors,\n|};\n\nexport type Quote = {|\n  id: Id,\n  content: string,\n  author: Author,\n|};\n\nexport type Dragging = {|\n  id: DraggableId,\n  location: DraggableLocation,\n|};\n\nexport type QuoteMap = {\n  [key: string]: Quote[],\n};\n\nexport type Task = {|\n  id: Id,\n  content: string,\n|};\n"
  },
  {
    "path": "stories/src/vertical/quote-app.jsx",
    "content": "// @flow\nimport React, { useState } from 'react';\nimport styled from '@emotion/styled';\nimport type { Quote } from '../types';\nimport type { DropResult } from '../../../src/types';\nimport { DragDropContext } from '../../../src';\nimport QuoteList from '../primatives/quote-list';\nimport reorder from '../reorder';\nimport { grid } from '../constants';\n\nconst Root = styled.div`\n  /* flexbox */\n  padding-top: ${grid * 2}px;\n  display: flex;\n  justify-content: center;\n  align-items: flex-start;\n`;\n\ntype Props = {|\n  initial: Quote[],\n  isCombineEnabled?: boolean,\n  listStyle?: Object,\n|};\n\nexport default function QuoteApp(props: Props) {\n  const [quotes, setQuotes] = useState(() => props.initial);\n\n  function onDragStart() {\n    // Add a little vibration if the browser supports it.\n    // Add's a nice little physical feedback\n    if (window.navigator.vibrate) {\n      window.navigator.vibrate(100);\n    }\n  }\n\n  function onDragEnd(result: DropResult) {\n    // combining item\n    if (result.combine) {\n      // super simple: just removing the dragging item\n      const newQuotes: Quote[] = [...quotes];\n      newQuotes.splice(result.source.index, 1);\n      setQuotes(newQuotes);\n      return;\n    }\n\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    if (result.destination.index === result.source.index) {\n      return;\n    }\n\n    const newQuotes = reorder(\n      quotes,\n      result.source.index,\n      result.destination.index,\n    );\n\n    setQuotes(newQuotes);\n  }\n\n  return (\n    <DragDropContext onDragStart={onDragStart} onDragEnd={onDragEnd}>\n      <Root>\n        <QuoteList\n          listId=\"list\"\n          style={props.listStyle}\n          quotes={quotes}\n          isCombineEnabled={props.isCombineEnabled}\n        />\n      </Root>\n    </DragDropContext>\n  );\n}\n"
  },
  {
    "path": "stories/src/vertical-grouped/quote-app.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { DragDropContext } from '../../../src';\nimport QuoteList from '../primatives/quote-list';\nimport { grid } from '../constants';\nimport { reorderQuoteMap } from '../reorder';\nimport type { QuoteMap } from '../types';\nimport type { DropResult } from '../../../src/types';\n\nconst Root = styled.div`\n  background: ${colors.B200};\n  display: flex;\n`;\n\nconst Column = styled.div`\n  background-color: ${colors.B50};\n\n  /* make the column a scroll container */\n  height: 100vh;\n  overflow: auto;\n\n  /* flexbox */\n  display: flex;\n  flex-direction: column;\n`;\n\nconst Group = styled.div`\n  margin-top: ${grid * 2}px;\n`;\n\nconst Title = styled.h4`\n  margin: ${grid}px;\n`;\n\ntype Props = {|\n  initial: QuoteMap,\n|};\n\ntype State = {|\n  quoteMap: QuoteMap,\n|};\n\nexport default class QuoteApp extends Component<Props, State> {\n  /* eslint-disable react/sort-comp */\n\n  state: State = {\n    quoteMap: this.props.initial,\n  };\n\n  onDragEnd = (result: DropResult) => {\n    if (!result.destination) {\n      return;\n    }\n\n    const { quoteMap } = reorderQuoteMap({\n      quoteMap: this.state.quoteMap,\n      source: result.source,\n      destination: result.destination,\n    });\n\n    this.setState({ quoteMap });\n  };\n\n  render() {\n    const { quoteMap } = this.state;\n\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Root>\n          <Column>\n            {Object.keys(quoteMap).map((key: string) => (\n              <Group key={key}>\n                <Title>{key}</Title>\n                <QuoteList quotes={quoteMap[key]} listId={key} listType={key} />\n              </Group>\n            ))}\n          </Column>\n        </Root>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/vertical-nested/quote-app.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { invariant } from '../../../src/invariant';\nimport { DragDropContext } from '../../../src';\nimport { grid } from '../constants';\nimport QuoteList from './quote-list';\nimport reorder from '../reorder';\nimport { getQuotes } from '../data';\nimport type { Quote } from '../types';\nimport type { NestedQuoteList } from './types';\nimport type { DropResult } from '../../../src/types';\n\nconst quotes: Quote[] = getQuotes(10);\n\nconst initialList: NestedQuoteList = {\n  id: 'first-level',\n  title: 'top level',\n  children: [\n    ...quotes.slice(0, 2),\n    {\n      id: 'second-level',\n      title: 'second level',\n      children: quotes.slice(3, 5),\n    },\n    ...quotes.slice(6, 9),\n  ],\n};\n\nconst Root = styled.div`\n  background-color: ${colors.B200};\n  box-sizing: border-box;\n  padding: ${grid * 2}px;\n  min-height: 100vh;\n\n  /* flexbox */\n  display: flex;\n  justify-content: center;\n  align-items: flex-start;\n`;\n\ntype State = {|\n  list: NestedQuoteList,\n|};\n\nexport default class QuoteApp extends Component<*, State> {\n  /* eslint-disable react/sort-comp */\n  state: State = {\n    list: initialList,\n  };\n  /* eslint-enable */\n\n  onDragEnd = (result: DropResult) => {\n    // dropped outside the list\n    if (!result.destination) {\n      return;\n    }\n\n    if (result.type === 'first-level') {\n      const children = reorder(\n        this.state.list.children,\n        result.source.index,\n        result.destination.index,\n      );\n\n      const list: NestedQuoteList = {\n        ...this.state.list,\n        children,\n      };\n\n      this.setState({\n        list,\n      });\n      return;\n    }\n\n    if (result.type === 'second-level') {\n      const nested: ?NestedQuoteList = (this.state.list.children.filter(\n        (item: mixed): boolean =>\n          Object.prototype.hasOwnProperty.call(item, 'children'),\n      )[0]: any);\n\n      invariant(nested, 'could not find nested list');\n\n      const updated: NestedQuoteList = {\n        ...nested,\n        children: reorder(\n          nested.children,\n          result.source.index,\n          // $ExpectError - already checked for null\n          result.destination.index,\n        ),\n      };\n\n      const nestedIndex = this.state.list.children.indexOf(nested);\n      const children = Array.from(this.state.list.children);\n      children[nestedIndex] = updated;\n\n      const list: NestedQuoteList = {\n        ...this.state.list,\n        children,\n      };\n\n      this.setState({\n        list,\n      });\n    }\n  };\n\n  render() {\n    const { list } = this.state;\n\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Root>\n          <QuoteList list={list} />\n        </Root>\n      </DragDropContext>\n    );\n  }\n}\n"
  },
  {
    "path": "stories/src/vertical-nested/quote-list.jsx",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport styled from '@emotion/styled';\nimport { colors } from '@atlaskit/theme';\nimport { Droppable, Draggable } from '../../../src';\nimport QuoteItem from '../primatives/quote-item';\nimport Title from '../primatives/title';\nimport { grid } from '../constants';\nimport type { Quote } from '../types';\nimport type { NestedQuoteList } from './types';\nimport type {\n  DroppableProvided,\n  DroppableStateSnapshot,\n  DraggableProvided,\n  DraggableStateSnapshot,\n} from '../../../src';\n\n// $ExpectError - not sure why\nconst Root = styled.div`\n  width: 250px;\n`;\n\nconst Container = styled.div`\n  background-color: ${({ isDraggingOver }) =>\n    isDraggingOver ? colors.B50 : colors.B75};\n  display: flex;\n  flex-direction: column;\n  padding: ${grid}px;\n  padding-bottom: 0;\n  user-select: none;\n  transition: background-color 0.1s ease;\n\n  &:focus {\n    outline: 2px solid ${colors.P200};\n    outline-offset: 2px;\n  }\n`;\n\nconst NestedContainer = styled(Container)`\n  padding: 0;\n  margin-bottom: ${grid}px;\n`;\n\nexport default class QuoteList extends Component<{ list: NestedQuoteList }> {\n  renderQuote = (quote: Quote, index: number) => (\n    <Draggable key={quote.id} draggableId={quote.id} index={index}>\n      {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n        <QuoteItem\n          quote={quote}\n          isDragging={snapshot.isDragging}\n          provided={provided}\n        />\n      )}\n    </Draggable>\n  );\n\n  renderList = (list: NestedQuoteList, level?: number = 0) => (\n    <Droppable droppableId={list.id} type={list.id} key={list.id}>\n      {(\n        dropProvided: DroppableProvided,\n        dropSnapshot: DroppableStateSnapshot,\n      ) => (\n        <Container\n          ref={dropProvided.innerRef}\n          isDraggingOver={dropSnapshot.isDraggingOver}\n          {...dropProvided.droppableProps}\n        >\n          <Title>{list.title}</Title>\n          {list.children.map((item: Quote | NestedQuoteList, index: number) =>\n            !item.children ? (\n              this.renderQuote((item: any), index)\n            ) : (\n              <Draggable draggableId={item.id} key={item.id} index={index}>\n                {(\n                  dragProvided: DraggableProvided,\n                  dragSnapshot: DraggableStateSnapshot,\n                ) => (\n                  <NestedContainer\n                    ref={dragProvided.innerRef}\n                    isDragging={dragSnapshot.isDragging}\n                    {...dragProvided.draggableProps}\n                    {...dragProvided.dragHandleProps}\n                  >\n                    {this.renderList((item: any), level + 1)}\n                  </NestedContainer>\n                )}\n              </Draggable>\n            ),\n          )}\n          {dropProvided.placeholder}\n        </Container>\n      )}\n    </Droppable>\n  );\n\n  render() {\n    return <Root>{this.renderList(this.props.list)}</Root>;\n  }\n}\n"
  },
  {
    "path": "stories/src/vertical-nested/types.js",
    "content": "// @flow\n\nexport type NestedQuoteList = {|\n  id: string,\n  title: string,\n  children: Array<any>,\n|};\n"
  },
  {
    "path": "stories/src/virtual/quote-count-chooser.jsx",
    "content": "// @flow\nimport React from 'react';\nimport { css } from '@emotion/core';\nimport { colors } from '@atlaskit/theme';\nimport { grid, borderRadius } from '../constants';\n\ntype Props = {|\n  library: string,\n  count: number,\n  onCountChange: (count: number) => void,\n|};\n\ntype Option = {|\n  name: string,\n  value: number,\n|};\n\nconst options: Option[] = [\n  { name: 'Small', value: 8 },\n  { name: 'Medium', value: 500 },\n  { name: 'Large', value: 10000 },\n];\n\nexport default function QuoteCountChooser(props: Props) {\n  function onChange(event: SyntheticInputEvent<HTMLSelectElement>) {\n    const value: number = Number(event.target.value);\n    props.onCountChange(value);\n  }\n\n  return (\n    <div\n      css={css`\n        background-color: ${colors.N0};\n        padding: ${grid}px;\n        border-radius: ${borderRadius}px;\n        width: 200px;\n        display: flex;\n        flex-direction: column;\n        margin-left: ${grid}px;\n      `}\n    >\n      <h4\n        css={css`\n          margin-bottom: ${grid}px;\n        `}\n      >\n        <code>{props.library}</code>\n      </h4>\n      <select\n        onChange={onChange}\n        value={props.count}\n        css={css`\n          font-size: 16px;\n        `}\n      >\n        {options.map((option: Option) => (\n          <option key={option.name} value={option.value}>\n            {option.name} ({option.value})\n          </option>\n        ))}\n      </select>\n    </div>\n  );\n}\n"
  },
  {
    "path": "stories/src/virtual/react-virtualized/board.jsx",
    "content": "// @flow\nimport React, { useReducer } from 'react';\nimport ReactDOM from 'react-dom';\nimport 'react-virtualized/styles.css';\nimport { List } from 'react-virtualized';\nimport styled from '@emotion/styled';\nimport { Global, css } from '@emotion/core';\nimport { colors } from '@atlaskit/theme';\nimport type {\n  DropResult,\n  DraggableLocation,\n  DraggableProvided,\n  DraggableStateSnapshot,\n  DroppableProvided,\n  DroppableStateSnapshot,\n  DraggableRubric,\n} from '../../../../src';\nimport type { QuoteMap, Quote } from '../../types';\nimport Title from '../../primatives/title';\nimport { reorderQuoteMap } from '../../reorder';\nimport { DragDropContext, Droppable, Draggable } from '../../../../src';\nimport QuoteItem from '../../primatives/quote-item';\nimport { grid, borderRadius } from '../../constants';\nimport { getBackgroundColor } from '../../primatives/quote-list';\nimport QuoteCountSlider from '../quote-count-chooser';\nimport { generateQuoteMap } from '../../data';\n\nconst Container = styled.div`\n  display: flex;\n`;\n\ntype RowProps = {\n  index: number,\n  style: Object,\n};\n\n// Using a higher order function so that we can look up the quotes data to retrieve\n// our quote from within the rowRender function\nconst getRowRender = (quotes: Quote[]) => ({ index, style }: RowProps) => {\n  const quote: ?Quote = quotes[index];\n\n  // We are rendering an extra item for the placeholder\n  // Do do this we increased our data set size to include one 'fake' item\n  if (!quote) {\n    return null;\n  }\n\n  // Faking some nice spacing around the items\n  const patchedStyle = {\n    ...style,\n    left: style.left + grid,\n    top: style.top + grid,\n    width: `calc(${style.width} - ${grid * 2}px)`,\n    height: style.height - grid,\n  };\n\n  return (\n    <Draggable draggableId={quote.id} index={index} key={quote.id}>\n      {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n        <QuoteItem\n          provided={provided}\n          quote={quote}\n          isDragging={snapshot.isDragging}\n          style={patchedStyle}\n        />\n      )}\n    </Draggable>\n  );\n};\n\ntype ColumnProps = {|\n  columnId: string,\n  quotes: Quote[],\n|};\n\nconst ColumnContainer = styled.div`\n  border-top-left-radius: ${borderRadius}px;\n  border-top-right-radius: ${borderRadius}px;\n  background-color: ${colors.N30};\n  flex-shrink: 0;\n  margin: ${grid}px;\n  display: flex;\n  flex-direction: column;\n`;\n\nconst Column = React.memo(function Column(props: ColumnProps) {\n  const { columnId, quotes } = props;\n\n  return (\n    <ColumnContainer>\n      <Title>{columnId}</Title>\n      <Droppable\n        droppableId={columnId}\n        mode=\"virtual\"\n        renderClone={(\n          provided: DraggableProvided,\n          snapshot: DraggableStateSnapshot,\n          rubric: DraggableRubric,\n        ) => (\n          <QuoteItem\n            provided={provided}\n            isDragging={snapshot.isDragging}\n            quote={quotes[rubric.source.index]}\n            style={{ margin: 0 }}\n          />\n        )}\n      >\n        {(\n          droppableProvided: DroppableProvided,\n          snapshot: DroppableStateSnapshot,\n        ) => {\n          const itemCount: number = snapshot.isUsingPlaceholder\n            ? quotes.length + 1\n            : quotes.length;\n\n          return (\n            <List\n              height={500}\n              rowCount={itemCount}\n              rowHeight={110}\n              width={300}\n              ref={(ref) => {\n                // react-virtualized has no way to get the list's ref that I can so\n                // So we use the `ReactDOM.findDOMNode(ref)` escape hatch to get the ref\n                if (ref) {\n                  // eslint-disable-next-line react/no-find-dom-node\n                  const whatHasMyLifeComeTo = ReactDOM.findDOMNode(ref);\n                  if (whatHasMyLifeComeTo instanceof HTMLElement) {\n                    droppableProvided.innerRef(whatHasMyLifeComeTo);\n                  }\n                }\n              }}\n              style={{\n                backgroundColor: getBackgroundColor(\n                  snapshot.isDraggingOver,\n                  Boolean(snapshot.draggingFromThisWith),\n                ),\n                transition: 'background-color 0.2s ease',\n              }}\n              rowRenderer={getRowRender(quotes)}\n            />\n          );\n        }}\n      </Droppable>\n    </ColumnContainer>\n  );\n});\n\ntype State = {|\n  itemCount: number,\n  quoteMap: QuoteMap,\n  columnKeys: string[],\n|};\n\nfunction getColumnKeys(quoteMap: QuoteMap): string[] {\n  return Object.keys(quoteMap).sort();\n}\n\nfunction getInitialState() {\n  const itemCount: number = 10000;\n  const quoteMap: QuoteMap = generateQuoteMap(itemCount);\n  const columnKeys: string[] = getColumnKeys(quoteMap);\n  return {\n    itemCount,\n    quoteMap,\n    columnKeys,\n  };\n}\n\ntype Action =\n  | {|\n      type: 'CHANGE_COUNT',\n      payload: number,\n    |}\n  | {|\n      type: 'REORDER',\n      payload: QuoteMap,\n    |};\n\nfunction reducer(state: State, action: Action) {\n  if (action.type === 'CHANGE_COUNT') {\n    const quoteMap: QuoteMap = generateQuoteMap(action.payload);\n    return {\n      itemCount: action.payload,\n      quoteMap,\n      columnKeys: getColumnKeys(quoteMap),\n    };\n  }\n  if (action.type === 'REORDER') {\n    return {\n      itemCount: state.itemCount,\n      quoteMap: action.payload,\n      columnKeys: getColumnKeys(action.payload),\n    };\n  }\n\n  return state;\n}\n\ntype Empty = {||};\n\n// eslint-disable-next-line no-unused-vars\nfunction Board(props: Empty) {\n  const [state, dispatch] = useReducer(reducer, undefined, getInitialState);\n\n  function onDragEnd(result: DropResult) {\n    if (!result.destination) {\n      return;\n    }\n    const source: DraggableLocation = result.source;\n    const destination: DraggableLocation = result.destination;\n\n    // did not move anywhere - can bail early\n    if (\n      source.droppableId === destination.droppableId &&\n      source.index === destination.index\n    ) {\n      return;\n    }\n\n    const updated = reorderQuoteMap({\n      quoteMap: state.quoteMap,\n      source,\n      destination,\n    });\n\n    dispatch({ type: 'REORDER', payload: updated.quoteMap });\n  }\n\n  return (\n    <>\n      <DragDropContext onDragEnd={onDragEnd}>\n        <Container>\n          {state.columnKeys.map((key: string) => {\n            const quotes: Quote[] = state.quoteMap[key];\n\n            return <Column key={key} quotes={quotes} columnId={key} />;\n          })}\n        </Container>\n        <QuoteCountSlider\n          library=\"react-virtualized\"\n          count={state.itemCount}\n          onCountChange={(count: number) =>\n            dispatch({ type: 'CHANGE_COUNT', payload: count })\n          }\n        />\n      </DragDropContext>\n      <Global\n        styles={css`\n          body {\n            background: ${colors.B200} !important;\n          }\n        `}\n      />\n    </>\n  );\n}\n\nexport default Board;\n"
  },
  {
    "path": "stories/src/virtual/react-virtualized/list.jsx",
    "content": "// @flow\nimport React, { useState } from 'react';\nimport ReactDOM from 'react-dom';\nimport 'react-virtualized/styles.css';\nimport { List } from 'react-virtualized';\nimport type { Quote } from '../../types';\nimport {\n  Droppable,\n  Draggable,\n  DragDropContext,\n  type DroppableProvided,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type DraggableRubric,\n  type DropResult,\n} from '../../../../src';\nimport QuoteItem from '../../primatives/quote-item';\nimport reorder from '../../reorder';\n\ntype Props = {|\n  initial: Quote[],\n|};\n\ntype RowProps = {\n  index: number,\n  style: Object,\n};\n\n// Using a higher order function so that we can look up the quotes data to retrieve\n// our quote from within the rowRender function\nconst getRowRender = (quotes: Quote[]) => ({ index, style }: RowProps) => {\n  const quote: Quote = quotes[index];\n\n  return (\n    <Draggable draggableId={quote.id} index={index} key={quote.id}>\n      {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n        <QuoteItem\n          provided={provided}\n          quote={quote}\n          isDragging={snapshot.isDragging}\n          style={{ margin: 0, ...style }}\n          index={index}\n        />\n      )}\n    </Draggable>\n  );\n};\n\nfunction App(props: Props) {\n  const [quotes, setQuotes] = useState(() => props.initial);\n\n  function onDragEnd(result: DropResult) {\n    if (!result.destination) {\n      return;\n    }\n    if (result.source.index === result.destination.index) {\n      return;\n    }\n\n    const newQuotes: Quote[] = reorder(\n      quotes,\n      result.source.index,\n      result.destination.index,\n    );\n    setQuotes(newQuotes);\n  }\n\n  return (\n    <DragDropContext onDragEnd={onDragEnd}>\n      <Droppable\n        droppableId=\"droppable\"\n        mode=\"virtual\"\n        renderClone={(\n          provided: DraggableProvided,\n          snapshot: DraggableStateSnapshot,\n          rubric: DraggableRubric,\n        ) => (\n          <QuoteItem\n            provided={provided}\n            isDragging={snapshot.isDragging}\n            quote={quotes[rubric.source.index]}\n            style={{ margin: 0 }}\n            index={rubric.source.index}\n          />\n        )}\n      >\n        {(droppableProvided: DroppableProvided) => (\n          <List\n            height={500}\n            rowCount={quotes.length}\n            rowHeight={110}\n            width={300}\n            ref={(ref) => {\n              // react-virtualized has no way to get the list's ref that I can so\n              // So we use the `ReactDOM.findDOMNode(ref)` escape hatch to get the ref\n              if (ref) {\n                // eslint-disable-next-line react/no-find-dom-node\n                const whatHasMyLifeComeTo = ReactDOM.findDOMNode(ref);\n                if (whatHasMyLifeComeTo instanceof HTMLElement) {\n                  droppableProvided.innerRef(whatHasMyLifeComeTo);\n                }\n              }\n            }}\n            rowRenderer={getRowRender(quotes)}\n          />\n        )}\n      </Droppable>\n    </DragDropContext>\n  );\n}\n\nexport default App;\n"
  },
  {
    "path": "stories/src/virtual/react-virtualized/window-list.jsx",
    "content": "// @flow\nimport React, { useState } from 'react';\nimport ReactDOM from 'react-dom';\nimport 'react-virtualized/styles.css';\nimport { WindowScroller, List } from 'react-virtualized';\nimport type { Quote } from '../../types';\nimport {\n  Droppable,\n  Draggable,\n  DragDropContext,\n  type DroppableProvided,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type DraggableRubric,\n  type DropResult,\n} from '../../../../src';\nimport QuoteItem from '../../primatives/quote-item';\nimport reorder from '../../reorder';\n\ntype Props = {|\n  initial: Quote[],\n|};\n\ntype RowProps = {\n  index: number,\n  style: Object,\n};\n\n// Using a higher order function so that we can look up the quotes data to retrieve\n// our quote from within the rowRender function\nconst getRowRender = (quotes: Quote[]) => ({ index, style }: RowProps) => {\n  const quote: Quote = quotes[index];\n\n  return (\n    <Draggable draggableId={quote.id} index={index} key={quote.id}>\n      {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n        <QuoteItem\n          provided={provided}\n          quote={quote}\n          isDragging={snapshot.isDragging}\n          style={{ margin: 0, ...style }}\n          index={index}\n        />\n      )}\n    </Draggable>\n  );\n};\n\nfunction App(props: Props) {\n  const [quotes, setQuotes] = useState(() => props.initial);\n\n  function onDragEnd(result: DropResult) {\n    if (!result.destination) {\n      return;\n    }\n    if (result.source.index === result.destination.index) {\n      return;\n    }\n\n    const newQuotes: Quote[] = reorder(\n      quotes,\n      result.source.index,\n      result.destination.index,\n    );\n    setQuotes(newQuotes);\n  }\n\n  return (\n    <DragDropContext onDragEnd={onDragEnd}>\n      <Droppable\n        droppableId=\"droppable\"\n        mode=\"virtual\"\n        renderClone={(\n          provided: DraggableProvided,\n          snapshot: DraggableStateSnapshot,\n          rubric: DraggableRubric,\n        ) => (\n          <QuoteItem\n            provided={provided}\n            isDragging={snapshot.isDragging}\n            quote={quotes[rubric.source.index]}\n            style={{ margin: 0 }}\n            index={rubric.source.index}\n          />\n        )}\n      >\n        {(droppableProvided: DroppableProvided) => (\n          <WindowScroller>\n            {({ height, isScrolling, onChildScroll, scrollTop }) => (\n              <List\n                autoHeight\n                rowCount={quotes.length}\n                height={height}\n                isScrolling={isScrolling}\n                onScroll={onChildScroll}\n                scrollTop={scrollTop}\n                rowHeight={110}\n                width={300}\n                ref={(ref) => {\n                  // react-virtualized has no way to get the list's ref that I can so\n                  // So we use the `ReactDOM.findDOMNode(ref)` escape hatch to get the ref\n                  if (ref) {\n                    // eslint-disable-next-line react/no-find-dom-node\n                    const whatHasMyLifeComeTo = ReactDOM.findDOMNode(ref);\n                    if (whatHasMyLifeComeTo instanceof HTMLElement) {\n                      droppableProvided.innerRef(whatHasMyLifeComeTo);\n                    }\n                  }\n                }}\n                rowRenderer={getRowRender(quotes)}\n              />\n            )}\n          </WindowScroller>\n        )}\n      </Droppable>\n    </DragDropContext>\n  );\n}\n\nexport default App;\n"
  },
  {
    "path": "stories/src/virtual/react-window/board.jsx",
    "content": "// @flow\nimport React, { useReducer } from 'react';\nimport { FixedSizeList as List, areEqual } from 'react-window';\nimport styled from '@emotion/styled';\nimport { Global, css } from '@emotion/core';\nimport { colors } from '@atlaskit/theme';\nimport type {\n  DropResult,\n  DraggableLocation,\n  DraggableProvided,\n  DraggableStateSnapshot,\n  DroppableProvided,\n  DraggableRubric,\n  DroppableStateSnapshot,\n} from '../../../../src';\nimport type { QuoteMap, Quote } from '../../types';\nimport Title from '../../primatives/title';\nimport { reorderQuoteMap } from '../../reorder';\nimport { DragDropContext, Droppable, Draggable } from '../../../../src';\nimport QuoteItem from '../../primatives/quote-item';\nimport { grid, borderRadius } from '../../constants';\nimport { getBackgroundColor } from '../../primatives/quote-list';\nimport QuoteCountSlider from '../quote-count-chooser';\nimport { generateQuoteMap } from '../../data';\n\nconst Container = styled.div`\n  display: flex;\n`;\n\ntype RowProps = {\n  data: Quote[],\n  index: number,\n  style: Object,\n};\n\n// Memoizing row items for even better performance!\nconst Row = React.memo(({ data: quotes, index, style }: RowProps) => {\n  const quote: ?Quote = quotes[index];\n\n  // We are rendering an extra item for the placeholder\n  // Do do this we increased our data set size to include one 'fake' item\n  if (!quote) {\n    return null;\n  }\n\n  // Faking some nice spacing around the items\n  const patchedStyle = {\n    ...style,\n    left: style.left + grid,\n    top: style.top + grid,\n    width: `calc(${style.width} - ${grid * 2}px)`,\n    height: style.height - grid,\n  };\n\n  return (\n    <Draggable draggableId={quote.id} index={index} key={quote.id}>\n      {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n        <QuoteItem\n          provided={provided}\n          quote={quote}\n          isDragging={snapshot.isDragging}\n          style={patchedStyle}\n        />\n      )}\n    </Draggable>\n  );\n}, areEqual);\n\ntype ColumnProps = {|\n  columnId: string,\n  quotes: Quote[],\n|};\n\nconst ColumnContainer = styled.div`\n  border-top-left-radius: ${borderRadius}px;\n  border-top-right-radius: ${borderRadius}px;\n  background-color: ${colors.N30};\n  flex-shrink: 0;\n  margin: ${grid}px;\n  display: flex;\n  flex-direction: column;\n`;\n\nconst Column = React.memo(function Column(props: ColumnProps) {\n  const { columnId, quotes } = props;\n\n  return (\n    <ColumnContainer>\n      <Title>{columnId}</Title>\n      <Droppable\n        droppableId={columnId}\n        mode=\"virtual\"\n        renderClone={(\n          provided: DraggableProvided,\n          snapshot: DraggableStateSnapshot,\n          rubric: DraggableRubric,\n        ) => (\n          <QuoteItem\n            provided={provided}\n            isDragging={snapshot.isDragging}\n            quote={quotes[rubric.source.index]}\n            style={{ margin: 0 }}\n          />\n        )}\n      >\n        {(\n          droppableProvided: DroppableProvided,\n          snapshot: DroppableStateSnapshot,\n        ) => {\n          // Add an extra item to our list to make space for a dragging item\n          // Usually the DroppableProvided.placeholder does this, but that won't\n          // work in a virtual list\n          const itemCount: number = snapshot.isUsingPlaceholder\n            ? quotes.length + 1\n            : quotes.length;\n\n          return (\n            <List\n              height={500}\n              itemCount={itemCount}\n              itemSize={110}\n              width={300}\n              outerRef={droppableProvided.innerRef}\n              style={{\n                backgroundColor: getBackgroundColor(\n                  snapshot.isDraggingOver,\n                  Boolean(snapshot.draggingFromThisWith),\n                ),\n                transition: 'background-color 0.2s ease',\n                // We add this spacing so that when we drop into an empty list we will animate to the correct visual position.\n                padding: grid,\n              }}\n              itemData={quotes}\n            >\n              {Row}\n            </List>\n          );\n        }}\n      </Droppable>\n    </ColumnContainer>\n  );\n});\n\ntype State = {|\n  itemCount: number,\n  quoteMap: QuoteMap,\n  columnKeys: string[],\n|};\n\nfunction getColumnKeys(quoteMap: QuoteMap): string[] {\n  return Object.keys(quoteMap).sort();\n}\n\nfunction getInitialState() {\n  const itemCount: number = 10000;\n  const quoteMap: QuoteMap = generateQuoteMap(itemCount);\n  const columnKeys: string[] = getColumnKeys(quoteMap);\n  return {\n    itemCount,\n    quoteMap,\n    columnKeys,\n  };\n}\n\ntype Action =\n  | {|\n      type: 'CHANGE_COUNT',\n      payload: number,\n    |}\n  | {|\n      type: 'REORDER',\n      payload: QuoteMap,\n    |};\n\nfunction reducer(state: State, action: Action) {\n  if (action.type === 'CHANGE_COUNT') {\n    const quoteMap: QuoteMap = generateQuoteMap(action.payload);\n    return {\n      itemCount: action.payload,\n      quoteMap,\n      columnKeys: getColumnKeys(quoteMap),\n    };\n  }\n  if (action.type === 'REORDER') {\n    return {\n      itemCount: state.itemCount,\n      quoteMap: action.payload,\n      columnKeys: getColumnKeys(action.payload),\n    };\n  }\n\n  return state;\n}\n\ntype Empty = {||};\n\n// eslint-disable-next-line no-unused-vars\nfunction Board(props: Empty) {\n  const [state, dispatch] = useReducer(reducer, undefined, getInitialState);\n\n  function onDragEnd(result: DropResult) {\n    if (!result.destination) {\n      return;\n    }\n    const source: DraggableLocation = result.source;\n    const destination: DraggableLocation = result.destination;\n\n    // did not move anywhere - can bail early\n    if (\n      source.droppableId === destination.droppableId &&\n      source.index === destination.index\n    ) {\n      return;\n    }\n\n    const updated = reorderQuoteMap({\n      quoteMap: state.quoteMap,\n      source,\n      destination,\n    });\n\n    dispatch({ type: 'REORDER', payload: updated.quoteMap });\n  }\n\n  return (\n    <>\n      <DragDropContext onDragEnd={onDragEnd}>\n        <Container>\n          {state.columnKeys.map((key: string) => {\n            const quotes: Quote[] = state.quoteMap[key];\n\n            return <Column key={key} quotes={quotes} columnId={key} />;\n          })}\n        </Container>\n        <QuoteCountSlider\n          library=\"react-window\"\n          count={state.itemCount}\n          onCountChange={(count: number) =>\n            dispatch({ type: 'CHANGE_COUNT', payload: count })\n          }\n        />\n      </DragDropContext>\n      <Global\n        styles={css`\n          body {\n            background: ${colors.B200} !important;\n          }\n        `}\n      />\n    </>\n  );\n}\n\nexport default Board;\n"
  },
  {
    "path": "stories/src/virtual/react-window/list.jsx",
    "content": "// @flow\nimport React, { useState } from 'react';\nimport { FixedSizeList as List, areEqual } from 'react-window';\nimport type { Quote } from '../../types';\nimport {\n  Droppable,\n  Draggable,\n  DragDropContext,\n  type DroppableProvided,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type DraggableRubric,\n  type DropResult,\n} from '../../../../src';\nimport QuoteItem from '../../primatives/quote-item';\nimport reorder from '../../reorder';\n\ntype Props = {|\n  initial: Quote[],\n|};\n\ntype RowProps = {\n  data: Quote[],\n  index: number,\n  style: Object,\n};\n\nconst Row = React.memo(({ data: quotes, index, style }: RowProps) => {\n  const quote: Quote = quotes[index];\n\n  return (\n    <Draggable draggableId={quote.id} index={index} key={quote.id}>\n      {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n        <QuoteItem\n          provided={provided}\n          quote={quote}\n          isDragging={snapshot.isDragging}\n          isGroupedOver={Boolean(snapshot.combineTargetFor)}\n          style={{ margin: 0, ...style }}\n          index={index}\n        />\n      )}\n    </Draggable>\n  );\n}, areEqual);\n\nfunction App(props: Props) {\n  const [quotes, setQuotes] = useState(() => props.initial);\n\n  function onDragEnd(result: DropResult) {\n    if (!result.destination) {\n      return;\n    }\n    if (result.source.index === result.destination.index) {\n      return;\n    }\n\n    const newQuotes: Quote[] = reorder(\n      quotes,\n      result.source.index,\n      result.destination.index,\n    );\n    setQuotes(newQuotes);\n  }\n\n  return (\n    <DragDropContext onDragEnd={onDragEnd}>\n      <Droppable\n        droppableId=\"droppable\"\n        mode=\"virtual\"\n        renderClone={(\n          provided: DraggableProvided,\n          snapshot: DraggableStateSnapshot,\n          rubric: DraggableRubric,\n        ) => (\n          <QuoteItem\n            provided={provided}\n            isDragging={snapshot.isDragging}\n            quote={quotes[rubric.source.index]}\n            style={{ margin: 0 }}\n            index={rubric.source.index}\n          />\n        )}\n      >\n        {(droppableProvided: DroppableProvided) => (\n          <List\n            height={500}\n            itemCount={quotes.length}\n            itemSize={100}\n            width={300}\n            // you will want to use List.outerRef rather than List.innerRef as it has the correct height when the list is unpopulated\n            outerRef={droppableProvided.innerRef}\n            itemData={quotes}\n          >\n            {Row}\n          </List>\n        )}\n      </Droppable>\n    </DragDropContext>\n  );\n}\n\nexport default App;\n"
  },
  {
    "path": "test/.eslintrc.js",
    "content": "module.exports = {\n  rules: {\n    // allowing console.warn / console.error\n    // this is because we often mock console.warn and console.error and adding this rul\n    // avoids needing to constantly be opting out of the rule\n    'no-console': ['error', { allow: ['warn', 'error'] }],\n\n    // allowing useMemo and useCallback in tests\n    'no-restricted-imports': 'off',\n\n    // Allowing Array.from\n    'no-restricted-syntax': 'off',\n  },\n};\n"
  },
  {
    "path": "test/env-setup.js",
    "content": "/* eslint-disable global-require */\n/* eslint-disable flowtype/require-valid-file-annotation */\n\n// Replacing requestAnimationFrame\n// Adding window check because some tests do not\n// run with browser globals enabled\nif (typeof window !== 'undefined') {\n  require('raf-stub').replaceRaf([global, window]);\n\n  // overriding these properties in jsdom to allow them to be controlled\n\n  Object.defineProperties(document.documentElement, {\n    clientWidth: {\n      writable: true,\n      value: document.documentElement.clientWidth,\n    },\n    clientHeight: {\n      writable: true,\n      value: document.documentElement.clientHeight,\n    },\n    scrollWidth: {\n      writable: true,\n      value: document.documentElement.scrollWidth,\n    },\n    scrollHeight: {\n      writable: true,\n      value: document.documentElement.scrollHeight,\n    },\n  });\n}\n\n// Setting initial viewport\n// Need to set clientWidth and clientHeight as jsdom does not set these properties\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n  document.documentElement.clientWidth = window.innerWidth;\n  document.documentElement.clientHeight = window.innerHeight;\n}\n// setting up global enzyme\nconst Enzyme = require('enzyme');\n\nconst Adapter = require('enzyme-adapter-react-16');\n\nEnzyme.configure({ adapter: new Adapter() });\n"
  },
  {
    "path": "test/test-flow-types.js",
    "content": "// @flow\n/* eslint-disable */\n\nimport * as React from 'react';\nimport { DragDropContext, Droppable, Draggable } from '../src';\n\n// DragDropContext\n{\n  <React.Fragment>\n    <DragDropContext onDragEnd={() => {}}>{null}</DragDropContext>\n    {/* $ExpectError onDragEnd is required */}\n    <DragDropContext>{null}</DragDropContext>\n    {/* $ExpectError children is required */}\n    <DragDropContext onDragEnd={() => {}} />\n  </React.Fragment>;\n}\n\n// Droppable\n{\n  <React.Fragment>\n    <Droppable droppableId=\"\">{() => null}</Droppable>\n    {/* $ExpectError droppableId is required */}\n    <Droppable>{() => null}</Droppable>\n    {/* $ExpectError droppableId must be a string */}\n    <Droppable droppableId={3}>{() => null}</Droppable>\n    {/* $ExpectError children as function is required*/}\n    <Droppable droppableId=\"\" />\n  </React.Fragment>;\n}\n\n// Draggable\n{\n  <React.Fragment>\n    <Draggable draggableId=\"\" index={0}>\n      {() => null}\n    </Draggable>\n    {/* $ExpectError draggableId is required */}\n    <Draggable index={0}>{() => null}</Draggable>\n    {/* $ExpectError draggableId must be a string */}\n    <Draggable draggableId={2} index={0}>\n      {() => null}\n    </Draggable>\n    {/* $ExpectError index is required */}\n    <Draggable draggableId=\"\">{() => null}</Draggable>\n    {/* $ExpectError children as function is required*/}\n    <Draggable draggableId=\"\" index={0} />\n  </React.Fragment>;\n}\n"
  },
  {
    "path": "test/test-setup.js",
    "content": "// @flow\n\n// ensuring that each test has at least one assertion\nbeforeEach(expect.hasAssertions);\n\nif (typeof document !== 'undefined') {\n  // Simply importing this package will throw an error if document is not defined\n  // eslint-disable-next-line global-require\n  const { cleanup, fireEvent } = require('@testing-library/react');\n\n  // unmount any components mounted with react-testing-library\n  beforeAll(cleanup);\n  afterEach(() => {\n    cleanup();\n    // lots of tests can leave a post-drop click blocker\n    // this cleans it up before every test\n    fireEvent.click(window);\n\n    // Cleaning up any mocks\n\n    if (window.getComputedStyle.mockRestore) {\n      window.getComputedStyle.mockRestore();\n    }\n\n    if (Element.prototype.getBoundingClientRect.mockRestore) {\n      Element.prototype.getBoundingClientRect.mockRestore();\n    }\n  });\n}\n"
  },
  {
    "path": "test/unit/dev-warning.spec.js",
    "content": "// @flow\nimport { warning } from '../../src/dev-warning';\n\nconst warn = jest.spyOn(console, 'warn').mockImplementation(() => {});\n\nafterEach(() => {\n  warn.mockClear();\n});\n\nit('should log a warning to the console', () => {\n  warning('hey');\n\n  expect(warn).toHaveBeenCalled();\n});\n\nit('should not log a warning if warnings are disabled', () => {\n  window['__react-beautiful-dnd-disable-dev-warnings'] = true;\n\n  warning('hey');\n  warning('sup');\n  warning('hi');\n\n  expect(warn).not.toHaveBeenCalled();\n\n  // re-enable\n\n  window['__react-beautiful-dnd-disable-dev-warnings'] = false;\n\n  warning('hey');\n\n  expect(warn).toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/docs/content.spec.js",
    "content": "// @flow\nimport globby from 'globby';\nimport * as fs from 'fs-extra';\n// Disabling eslint design to prevent using regeneratorRuntime in distributions\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable no-await-in-loop */\n\nit('should end all nested docs with a link back to the documentation root', async () => {\n  const files: string[] = await globby('docs/**/*.md');\n  expect(files.length).toBeGreaterThan(0);\n  const backLink: string =\n    '[← Back to documentation](/README.md#documentation-)';\n\n  for (const file of files) {\n    const contents: string = await fs.readFile(file, 'utf8');\n\n    // Printing a nice message to allow for quick fixing\n    const endsWithBacklink: boolean = contents.trim().endsWith(backLink);\n\n    if (!endsWithBacklink) {\n      expect(`\n        File: \"${file}\"\n        Did not end with back link\n      `).toBe(true);\n    }\n\n    // need at least one assertion\n    expect(true).toBe(true);\n  }\n});\n\nit('should use correct wording', async () => {\n  const files: string[] = await globby(['**/*.md', '!node_modules/']);\n  expect(files.length).toBeGreaterThan(0);\n\n  for (const file of files) {\n    const contents: string = await fs.readFile(file, 'utf8');\n\n    // Expected: <Draggable />, <Droppable />, `<DragDropContext />`\n    expect(contents.includes('`Draggable`')).toBe(false);\n    expect(contents.includes('`Droppable`')).toBe(false);\n    expect(contents.includes('`DragDropContext`')).toBe(false);\n\n    // not enough whitespace\n    expect(contents.includes('`<Draggable/>`')).toBe(false);\n    expect(contents.includes('`<Droppable/>`')).toBe(false);\n    expect(contents.includes('`<DragDropContext/>`')).toBe(false);\n\n    // not a self closing tag\n    expect(contents.includes('`<Draggable>`')).toBe(false);\n    expect(contents.includes('`<Droppable>`')).toBe(false);\n    expect(contents.includes('`<DragDropContext>`')).toBe(false);\n  }\n});\n"
  },
  {
    "path": "test/unit/docs/no-broken-links.spec.js",
    "content": "// @flow\nimport globby from 'globby';\nimport * as fs from 'fs-extra';\nimport getProcessor from 'markdown-it';\n// Disabling eslint design to prevent using regeneratorRuntime in distributions\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable no-await-in-loop */\n\nconst markdown = getProcessor();\n\ntype Token = {|\n  type: string,\n  attrs: [string[]],\n  children?: Token[],\n|};\n\n// adding a forward slash to start of path\nconst withLeadingSlash = (file: string): string => {\n  if (file.startsWith('/')) {\n    return file;\n  }\n  return `/${file}`;\n};\n\nconst validate = (token: Token, currentFile: string, files: string[]) => {\n  const href: string = token.attrs[0][1];\n  // Not validating external links\n  if (href.startsWith('http')) {\n    return;\n  }\n\n  // not checking links within a file for now\n  if (href.startsWith('#')) {\n    return;\n  }\n\n  // not checking links to stories for now\n  if (href.startsWith('/stories')) {\n    return;\n  }\n\n  const withoutFragment: string = href.split('#')[0];\n\n  const isValid: boolean = files.some(\n    (filePath: string): boolean =>\n      withoutFragment === withLeadingSlash(filePath),\n  );\n\n  if (isValid) {\n    return;\n  }\n\n  const message: string = `\n    Dead link: ${withoutFragment}\n    Found in:  ${withLeadingSlash(currentFile)}\n  `;\n\n  expect(false).toBe(message);\n};\n\nconst parse = (token: Token, file: string, files: string[]) => {\n  if (token.type === 'link_open') {\n    validate(token, file, files);\n  }\n  if (token.children) {\n    token.children.forEach((child: Token) => parse(child, file, files));\n  }\n};\n\nit('should use have no dead links', async () => {\n  const files: string[] = await globby(['**/*.md', '!node_modules/']);\n  expect(files.length).toBeGreaterThan(0);\n\n  for (const file of files) {\n    const contents: string = await fs.readFile(file, 'utf8');\n\n    const tokens: Token[] = markdown.parse(contents, {});\n    expect(tokens.length).toBeGreaterThan(0);\n    tokens.forEach((token: Token) => parse(token, file, files));\n  }\n\n  // need at least one assertion\n  expect(true).toBe(true);\n});\n"
  },
  {
    "path": "test/unit/health/drop-dev-warnings-for-prod.spec.js",
    "content": "// @flow\n/**\n * @jest-environment node\n */\nimport child from 'child_process';\nimport fs from 'fs';\nimport { promisify } from 'util';\n\nconst exec = promisify(child.exec);\nconst readFile = promisify(fs.readFile);\n\n// 120 second timeout\njest.setTimeout(120 * 1000);\n\nasync function clean() {\n  await exec('yarn build:clean');\n}\n\nbeforeAll(async () => {\n  await clean();\n  await exec('yarn build');\n});\n\nafterAll(clean);\n\nit('should contain warnings in development', async () => {\n  const filePath: string = './dist/react-beautiful-dnd.js';\n  const contents: string = await readFile(filePath, 'utf-8');\n\n  expect(contents.includes('This is a development only message')).toBe(true);\n});\n\nit('should not contain warnings in production', async () => {\n  const filePath: string = './dist/react-beautiful-dnd.min.js';\n  const contents: string = await readFile(filePath, 'utf-8');\n\n  expect(contents.includes('This is a development only message')).toBe(false);\n\n  // Checking there are no console.* messages\n  // Using regex so we can get really nice error messages\n\n  // https://regexr.com/40pno\n  // .*? is a lazy match - will grab as little as possible\n  const regex: RegExp = /console\\.\\w+\\(.*?\\)/g;\n\n  const matches: ?(string[]) = contents.match(regex);\n  expect(matches).toEqual(null);\n});\n"
  },
  {
    "path": "test/unit/health/src-file-name-convention.spec.js",
    "content": "// @flow\nimport globby from 'globby';\nimport { invariant } from '../../../src/invariant';\nimport pkg from '../../../package.json';\n\n// Regex playground: https://regexr.com/40fin\nconst convention: RegExp = /^[a-z0-9\\-./]+$/;\nconst isSnakeCase = (filePath: string): boolean => convention.test(filePath);\n\nconst exceptions: string[] = [\n  'CHANGELOG.md',\n  'CODE_OF_CONDUCT.md',\n  'CONTRIBUTING.md',\n  'ISSUE_TEMPLATE.md',\n  'README.md',\n];\n\nit('should have every prettier target following the file name convention', async () => {\n  const targets: string[] = pkg.config.prettier_target.split(' ');\n  const paths: string[] = await globby(targets);\n\n  invariant(\n    paths.length,\n    'Could not find files to test against file name convention',\n  );\n\n  paths.forEach((filePath: string) => {\n    if (exceptions.includes(filePath)) {\n      return;\n    }\n\n    const isMatching: boolean = isSnakeCase(filePath);\n\n    invariant(\n      isMatching,\n      `${filePath} does not follow the file path convention (snake-case.js) ${convention.toString()}`,\n    );\n\n    expect(isMatching).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/accessibility/axe-audit.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, cleanup } from '@testing-library/react';\nimport { axe, toHaveNoViolations } from 'jest-axe';\n\nimport App from '../util/app';\n\nexpect.extend(toHaveNoViolations);\n\n// Need to investigate this further as it doesn't seem to pick up the same errors\n// which are found by react-axe.\nit('should not fail an aXe audit', async () => {\n  render(<App />);\n\n  const results = await axe(document.body);\n\n  // $FlowFixMe - flow doesn't know about hte custom validator\n  expect(results).toHaveNoViolations();\n\n  cleanup();\n});\n"
  },
  {
    "path": "test/unit/integration/body-removal-before-unmount.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { isDragging } from './util/helpers';\nimport App from './util/app';\nimport { forEachSensor, simpleLift, type Control } from './util/controls';\nimport getBodyElement from '../../../src/view/get-body-element';\n\nit('should have any errors when body is changed just before unmount', () => {\n  jest.useFakeTimers();\n  const { unmount } = render(<App />);\n\n  expect(() => {\n    getBodyElement().innerHTML = '';\n    unmount();\n    jest.runOnlyPendingTimers();\n  }).not.toThrow();\n\n  jest.useRealTimers();\n});\n\nforEachSensor((control: Control) => {\n  it('should have any errors when body is changed just before unmount: mid drag', () => {\n    const { unmount, getByText } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    // mid drag\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toEqual(true);\n\n    expect(() => {\n      getBodyElement().innerHTML = '';\n      unmount();\n      jest.runOnlyPendingTimers();\n    }).not.toThrow();\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/combine-on-start.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport * as keyCodes from '../../../src/view/key-codes';\nimport type {\n  DraggableProvided,\n  DroppableProvided,\n  DragStart,\n  DragUpdate,\n  DropResult,\n} from '../../../src';\nimport type { Responders } from '../../../src/types';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\nimport { simpleLift, keyboard } from './util/controls';\nimport { withPoorDimensionMocks } from './util/helpers';\n\ntype State = {|\n  isCombineEnabled: boolean,\n|};\n\nclass App extends React.Component<*, State> {\n  state: State = {\n    isCombineEnabled: false,\n  };\n\n  onDragStart = (start: DragStart) => {\n    this.props.onDragStart(start);\n    this.setState({ isCombineEnabled: true });\n  };\n\n  onDragUpdate = (update: DragUpdate) => {\n    this.props.onDragUpdate(update);\n  };\n\n  onDragEnd = (result: DropResult) => {\n    this.props.onDragEnd(result);\n    this.setState({ isCombineEnabled: false });\n  };\n  // Normally you would want to split things out into separate components.\n  // But in this example everything is just done in one place for simplicity\n  render() {\n    return (\n      <DragDropContext\n        onDragStart={this.onDragStart}\n        onDragUpdate={this.onDragUpdate}\n        onDragEnd={this.onDragEnd}\n      >\n        <Droppable\n          droppableId=\"droppable\"\n          isCombineEnabled={this.state.isCombineEnabled}\n        >\n          {(droppableProvided: DroppableProvided) => (\n            <div\n              ref={droppableProvided.innerRef}\n              {...droppableProvided.droppableProps}\n            >\n              <Draggable draggableId=\"0\" index={0}>\n                {(draggableProvided: DraggableProvided) => (\n                  <div\n                    ref={draggableProvided.innerRef}\n                    data-testid=\"0\"\n                    {...draggableProvided.draggableProps}\n                    {...draggableProvided.dragHandleProps}\n                  >\n                    First\n                  </div>\n                )}\n              </Draggable>\n              <Draggable draggableId=\"1\" index={1}>\n                {(draggableProvided: DraggableProvided) => (\n                  <div\n                    ref={draggableProvided.innerRef}\n                    data-testid=\"1\"\n                    {...draggableProvided.draggableProps}\n                    {...draggableProvided.dragHandleProps}\n                  >\n                    Second\n                  </div>\n                )}\n              </Draggable>\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n\njest.useFakeTimers();\nit('should allow the changing of combining in onDragStart', () => {\n  withPoorDimensionMocks(() => {\n    const responders: Responders = {\n      onDragStart: jest.fn(),\n      onDragUpdate: jest.fn(),\n      onDragEnd: jest.fn(),\n    };\n    const { getByTestId } = render(<App {...responders} />);\n\n    const handle: HTMLElement = getByTestId('0');\n    simpleLift(keyboard, handle);\n    // flush onDragStart  responder\n    jest.runOnlyPendingTimers();\n\n    const start: DragStart = {\n      draggableId: '0',\n      source: {\n        droppableId: 'droppable',\n        index: 0,\n      },\n      type: 'DEFAULT',\n      mode: 'SNAP',\n    };\n    expect(responders.onDragStart).toHaveBeenCalledWith(start);\n\n    // now moving down will cause a combine impact!\n    fireEvent.keyDown(handle, { keyCode: keyCodes.arrowDown });\n    jest.runOnlyPendingTimers();\n    const update: DragUpdate = {\n      ...start,\n      destination: null,\n      combine: {\n        draggableId: '1',\n        droppableId: 'droppable',\n      },\n    };\n    expect(responders.onDragUpdate).toHaveBeenCalledWith(update);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/disable-on-start.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { getRect } from 'css-box-model';\nimport { render } from '@testing-library/react';\nimport type {\n  DraggableProvided,\n  DroppableProvided,\n  DragStart,\n  DragUpdate,\n  DropResult,\n} from '../../../src';\nimport type { Responders } from '../../../src/types';\nimport { DragDropContext, Droppable, Draggable } from '../../../src';\nimport { getComputedSpacing } from '../../util/dimension';\nimport { simpleLift, keyboard } from './util/controls';\n\n// Both list and item will have the same dimensions\njest.spyOn(Element.prototype, 'getBoundingClientRect').mockImplementation(() =>\n  getRect({\n    top: 0,\n    left: 0,\n    right: 100,\n    bottom: 100,\n  }),\n);\n\n// Stubbing out totally - not including margins in this\njest\n  .spyOn(window, 'getComputedStyle')\n  .mockImplementation(() => getComputedSpacing({}));\n\ntype State = {|\n  isDropDisabled: boolean,\n|};\n\nclass App extends React.Component<*, State> {\n  state: State = {\n    isDropDisabled: false,\n  };\n\n  onDragStart = (start: DragStart) => {\n    this.props.onDragStart(start);\n    this.setState({ isDropDisabled: true });\n  };\n\n  onDragUpdate = (update: DragUpdate) => {\n    this.props.onDragUpdate(update);\n  };\n\n  onDragEnd = (result: DropResult) => {\n    this.props.onDragEnd(result);\n    this.setState({ isDropDisabled: false });\n  };\n  // Normally you would want to split things out into separate components.\n  // But in this example everything is just done in one place for simplicity\n  render() {\n    return (\n      <DragDropContext\n        onDragStart={this.onDragStart}\n        onDragUpdate={this.onDragUpdate}\n        onDragEnd={this.onDragEnd}\n      >\n        <Droppable\n          droppableId=\"droppable\"\n          direction=\"horizontal\"\n          isDropDisabled={this.state.isDropDisabled}\n        >\n          {(droppableProvided: DroppableProvided) => (\n            <div\n              ref={droppableProvided.innerRef}\n              {...droppableProvided.droppableProps}\n            >\n              <Draggable draggableId=\"draggable\" index={0}>\n                {(draggableProvided: DraggableProvided) => (\n                  <div\n                    ref={draggableProvided.innerRef}\n                    data-testid=\"drag-handle\"\n                    {...draggableProvided.draggableProps}\n                    {...draggableProvided.dragHandleProps}\n                  >\n                    Drag me!\n                  </div>\n                )}\n              </Draggable>\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n\njest.useFakeTimers();\n\nit('should allow the disabling of a droppable in onDragStart', () => {\n  const responders: Responders = {\n    onDragStart: jest.fn(),\n    onDragUpdate: jest.fn(),\n    onDragEnd: jest.fn(),\n  };\n  const { getByTestId } = render(<App {...responders} />);\n  const handle: HTMLElement = getByTestId('drag-handle');\n\n  simpleLift(keyboard, handle);\n  // flush responder\n  jest.runOnlyPendingTimers();\n\n  const start: DragStart = {\n    draggableId: 'draggable',\n    source: {\n      droppableId: 'droppable',\n      index: 0,\n    },\n    type: 'DEFAULT',\n    mode: 'SNAP',\n  };\n  expect(responders.onDragStart).toHaveBeenCalledWith(start);\n\n  // onDragUpdate will occur after setTimeout\n  expect(responders.onDragUpdate).not.toHaveBeenCalled();\n\n  jest.runOnlyPendingTimers();\n  // an update should be fired as the home location has changed\n  const update: DragUpdate = {\n    ...start,\n    // no destination as it is now disabled\n    destination: null,\n    combine: null,\n  };\n  expect(responders.onDragUpdate).toHaveBeenCalledWith(update);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-drop-context/check-doctype.spec.js",
    "content": "// @flow\nimport { JSDOM } from 'jsdom';\nimport checkDoctype from '../../../../src/view/drag-drop-context/check-doctype';\n\nconst warn = jest.spyOn(console, 'warn').mockImplementation(() => {});\n\nafterEach(() => {\n  warn.mockClear();\n});\n\nit('should pass if using a html doctype', () => {\n  const jsdom = new JSDOM(`<!doctype html><p>Hello world</p>`);\n\n  checkDoctype(jsdom.window.document);\n\n  expect(warn).not.toHaveBeenCalled();\n});\n\nit('should fail if there is no doctype', () => {\n  const jsdom = new JSDOM(`<html><body>Hello world</body></html>`);\n\n  checkDoctype(jsdom.window.document);\n\n  expect(warn).toHaveBeenCalled();\n});\n\nit('should fail if there is a non-html5 doctype', () => {\n  // HTML 4.01 Strict\n  const jsdom = new JSDOM(\n    `<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"><html><body>Hello world</body></html>`,\n  );\n\n  checkDoctype(jsdom.window.document);\n\n  expect(warn).toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-drop-context/check-react-version.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport checkReactVersion from '../../../../src/view/drag-drop-context/check-react-version';\nimport { peerDependencies } from '../../../../package.json';\n\nconst warn = jest.spyOn(console, 'warn').mockImplementation(() => {});\n\nafterEach(() => {\n  warn.mockClear();\n});\n\nit('should pass if the react peer dep version is met', () => {\n  const version: string = '1.3.4';\n\n  checkReactVersion(version, version);\n\n  expect(warn).not.toHaveBeenCalled();\n});\n\nit('should pass if the react peer dep version is passed', () => {\n  // patch\n  {\n    const peerDep: string = '1.3.4';\n    const actual: string = '1.3.5';\n\n    checkReactVersion(peerDep, actual);\n\n    expect(warn).not.toHaveBeenCalled();\n  }\n  // minor\n  {\n    const peerDep: string = '1.3.4';\n    const actual: string = '1.4.0';\n\n    checkReactVersion(peerDep, actual);\n\n    expect(warn).not.toHaveBeenCalled();\n  }\n  // major\n  {\n    const peerDep: string = '1.3.4';\n    const actual: string = '2.0.0';\n\n    checkReactVersion(peerDep, actual);\n\n    expect(warn).not.toHaveBeenCalled();\n  }\n});\n\nit('should fail if the react peer dep version is not met', () => {\n  // patch not met\n  {\n    const peerDep: string = '1.3.4';\n    const actual: string = '1.3.3';\n\n    checkReactVersion(peerDep, actual);\n\n    expect(warn).toHaveBeenCalledTimes(1);\n    warn.mockClear();\n  }\n  // minor not met\n  {\n    const peerDep: string = '1.3.4';\n    const actual: string = '1.2.4';\n\n    checkReactVersion(peerDep, actual);\n\n    expect(warn).toHaveBeenCalledTimes(1);\n    warn.mockClear();\n  }\n  // major not met\n  {\n    const peerDep: string = '1.3.4';\n    const actual: string = '0.3.4';\n\n    checkReactVersion(peerDep, actual);\n\n    expect(warn).toHaveBeenCalledTimes(1);\n    warn.mockClear();\n  }\n});\n\nit('should throw if unable to parse the react version', () => {\n  const peerDep: string = '1.3.4';\n  const actual: string = '1.x';\n\n  expect(() => checkReactVersion(peerDep, actual)).toThrow();\n});\n\nit('should throw if unable to parse the peer dep version', () => {\n  const peerDep: string = '1.x';\n  const actual: string = '1.2.3';\n\n  expect(() => checkReactVersion(peerDep, actual)).toThrow();\n});\n\nit('should allow pre release provided versions', () => {\n  const peerDep: string = '1.0.0';\n  const alpha: string = '1.2.3-alpha';\n  const beta: string = '1.2.3-beta';\n\n  checkReactVersion(peerDep, alpha);\n  checkReactVersion(peerDep, beta);\n\n  expect(warn).not.toHaveBeenCalled();\n});\n\n// actually an integration test, but this feels like the right place for it\nit('should pass on the current repo setup', () => {\n  const peerDep: string = peerDependencies.react;\n  const actual: string = React.version;\n\n  checkReactVersion(peerDep, actual);\n\n  expect(warn).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-drop-context/clashing-with-consumers-redux.spec.js",
    "content": "// @flow\n/* eslint-disable react/no-multi-comp */\nimport React, { Component } from 'react';\nimport { render } from '@testing-library/react';\nimport { Provider, connect } from 'react-redux';\nimport { createStore } from 'redux';\nimport { Droppable, Draggable, DragDropContext } from '../../../../src';\nimport type { DraggableProvided, DroppableProvided } from '../../../../src';\n\ntype AppState = {|\n  foo: string,\n  // Needed to appease react-redux connect type\n  // eslint-disable-next-line react/no-unused-prop-types\n  dispatch?: () => void,\n|};\nconst original: AppState = {\n  foo: 'bar',\n};\n// super boring reducer that always returns the same thing\nconst reducer = (state?: AppState = original) => state;\nconst store = createStore(reducer);\n\nclass Unconnected extends Component<AppState> {\n  render() {\n    return <div>{this.props.foo}</div>;\n  }\n}\n\nfunction mapStateToProps(state: AppState): AppState {\n  return state;\n}\n\nconst Connected = connect(mapStateToProps)(Unconnected);\n\nit('should avoid clashes with parent redux applications', () => {\n  class App extends Component<*> {\n    render() {\n      return (\n        <Provider store={store}>\n          <DragDropContext onDragEnd={() => {}}>\n            <Droppable droppableId=\"droppable\">\n              {(droppableProvided: DroppableProvided) => (\n                <div\n                  ref={droppableProvided.innerRef}\n                  {...droppableProvided.droppableProps}\n                >\n                  <Draggable draggableId=\"draggableId\" index={0}>\n                    {(draggableProvided: DraggableProvided) => (\n                      <div\n                        ref={draggableProvided.innerRef}\n                        {...draggableProvided.dragHandleProps}\n                        {...draggableProvided.draggableProps}\n                      >\n                        <Connected />\n                      </div>\n                    )}\n                  </Draggable>\n                  {droppableProvided.placeholder}\n                </div>\n              )}\n            </Droppable>\n          </DragDropContext>\n        </Provider>\n      );\n    }\n  }\n  const { container, unmount } = render(<App />);\n\n  expect(container.textContent).toBe(original.foo);\n\n  unmount();\n});\n\nit('should avoid clashes with child redux applications', () => {\n  class App extends Component<*> {\n    render() {\n      return (\n        <DragDropContext onDragEnd={() => {}}>\n          <Droppable droppableId=\"droppable\">\n            {(droppableProvided: DroppableProvided) => (\n              <div\n                ref={droppableProvided.innerRef}\n                {...droppableProvided.droppableProps}\n              >\n                <Draggable draggableId=\"draggableId\" index={0}>\n                  {(draggableProvided: DraggableProvided) => (\n                    <div\n                      ref={draggableProvided.innerRef}\n                      {...draggableProvided.dragHandleProps}\n                      {...draggableProvided.draggableProps}\n                    >\n                      <Provider store={store}>\n                        <Connected />\n                      </Provider>\n                    </div>\n                  )}\n                </Draggable>\n                {droppableProvided.placeholder}\n              </div>\n            )}\n          </Droppable>\n        </DragDropContext>\n      );\n    }\n  }\n  const { container } = render(<App />);\n\n  expect(container.textContent).toBe(original.foo);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-drop-context/error-handling/error-in-react-tree.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport App from '../../util/app';\nimport { simpleLift, keyboard } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\nimport { withError } from '../../../../util/console';\n\nit('should recover from rbd errors', () => {\n  let hasThrown: boolean = false;\n  function CanThrow(props: { shouldThrow: boolean }) {\n    if (!hasThrown && props.shouldThrow) {\n      hasThrown = true;\n      invariant(false, 'throwing');\n    }\n    return null;\n  }\n\n  const { rerender, getByTestId } = render(\n    <App anotherChild={<CanThrow shouldThrow={false} />} />,\n  );\n\n  simpleLift(keyboard, getByTestId('0'));\n  expect(isDragging(getByTestId('0'))).toBe(true);\n\n  withError(() => {\n    rerender(<App anotherChild={<CanThrow shouldThrow />} />);\n  });\n\n  expect(isDragging(getByTestId('0'))).toBe(false);\n});\n\nit('should not recover from non-rbd errors', () => {\n  let hasThrown: boolean = false;\n  function CanThrow(props: { shouldThrow: boolean }) {\n    if (!hasThrown && props.shouldThrow) {\n      hasThrown = true;\n      throw new Error('Boom');\n    }\n    return null;\n  }\n\n  const { rerender, getByTestId } = render(\n    <App anotherChild={<CanThrow shouldThrow={false} />} />,\n  );\n\n  simpleLift(keyboard, getByTestId('0'));\n  expect(isDragging(getByTestId('0'))).toBe(true);\n\n  withError(() => {\n    expect(() => {\n      rerender(<App anotherChild={<CanThrow shouldThrow />} />);\n    }).toThrow();\n  });\n});\n\nit('should not recover from runtime errors', () => {\n  let hasThrown: boolean = false;\n  function CanThrow(props: { shouldThrow: boolean }) {\n    if (!hasThrown && props.shouldThrow) {\n      hasThrown = true;\n      // Boom: TypeError\n      window.foo();\n    }\n    return null;\n  }\n\n  const { rerender, getByTestId } = render(\n    <App anotherChild={<CanThrow shouldThrow={false} />} />,\n  );\n\n  simpleLift(keyboard, getByTestId('0'));\n  expect(isDragging(getByTestId('0'))).toBe(true);\n\n  withError(() => {\n    expect(() => {\n      rerender(<App anotherChild={<CanThrow shouldThrow />} />);\n    }).toThrow();\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-drop-context/error-handling/error-on-window.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { RbdInvariant } from '../../../../../src/invariant';\nimport App from '../../util/app';\nimport { simpleLift, keyboard } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\nimport { withError, withWarn, withoutError } from '../../../../util/console';\nimport { getRuntimeError } from '../../../../util/cause-runtime-error';\n\nfunction getRbdErrorEvent(): Event {\n  return new window.ErrorEvent('error', {\n    error: new RbdInvariant('my invariant'),\n    cancelable: true,\n  });\n}\n\nit('should abort any active drag (rbd error)', () => {\n  const { getByTestId } = render(<App />);\n\n  simpleLift(keyboard, getByTestId('0'));\n  expect(isDragging(getByTestId('0'))).toBe(true);\n  const event: Event = getRbdErrorEvent();\n\n  withWarn(() => {\n    withError(() => {\n      window.dispatchEvent(event);\n    });\n  });\n\n  // drag aborted\n  expect(isDragging(getByTestId('0'))).toBe(false);\n  // error event prevented\n  expect(event.defaultPrevented).toBe(true);\n});\n\nit('should abort any active drag (non-rbd error)', () => {\n  const { getByTestId } = render(<App />);\n  simpleLift(keyboard, getByTestId('0'));\n  expect(isDragging(getByTestId('0'))).toBe(true);\n  const event: Event = getRuntimeError();\n\n  // not logging the raw error\n  withoutError(() => {\n    // logging that the drag was aborted\n    withWarn(() => {\n      window.dispatchEvent(event);\n    });\n  });\n\n  // drag aborted\n  expect(isDragging(getByTestId('0'))).toBe(false);\n  // error event not prevented\n  expect(event.defaultPrevented).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-drop-context/on-before-capture/additions.spec.js",
    "content": "// @flow\nimport React, { useState } from 'react';\nimport { render } from '@testing-library/react';\nimport App from '../../util/app';\nimport {\n  Droppable,\n  Draggable,\n  DragDropContext,\n  type DragStart,\n} from '../../../../../src';\nimport expandedMouse from '../../util/expanded-mouse';\nimport { isDragging } from '../../util/helpers';\nimport { withError } from '../../../../util/console';\nimport { noop } from '../../../../../src/empty';\n\nit('should allow for additions to be made', () => {\n  // adding a new Droppable and Draggable\n  function AnotherChunk() {\n    return (\n      <Droppable droppableId=\"addition\">\n        {(droppableProvided) => (\n          <div\n            {...droppableProvided.droppableProps}\n            ref={droppableProvided.innerRef}\n          >\n            <Draggable draggableId=\"addition-item\" index={0}>\n              {(provided) => (\n                <div\n                  {...provided.draggableProps}\n                  {...provided.dragHandleProps}\n                  ref={provided.innerRef}\n                >\n                  Drag me!\n                </div>\n              )}\n            </Draggable>\n            {droppableProvided.placeholder};\n          </div>\n        )}\n      </Droppable>\n    );\n  }\n\n  function Root() {\n    const [showAdditions, setShowAdditions] = useState(false);\n    function onBeforeCapture() {\n      setShowAdditions(true);\n    }\n\n    return (\n      <App\n        onBeforeCapture={onBeforeCapture}\n        anotherChild={showAdditions ? <AnotherChunk /> : null}\n      />\n    );\n  }\n\n  const { getByTestId } = render(<Root />);\n  const handle: HTMLElement = getByTestId('0');\n\n  // act(() => {}); is joining the two into one update which is\n  // causing unexpected mounting behaviour\n  withError(() => {\n    expandedMouse.rawPowerLift(handle, { x: 0, y: 0 });\n  });\n\n  expect(isDragging(handle)).toBe(true);\n});\n\nfunction getIndex(el: HTMLElement): number {\n  return Number(el.getAttribute('data-index'));\n}\n\nit('should adjust captured values for any changes that impact that dragging item', () => {\n  jest.useFakeTimers();\n  // 1. Changing the `type` of the Droppable\n  // 2. Adding and item before the dragging item to impact it's index\n  const onDragStart = jest.fn();\n\n  function Root() {\n    const [items, setItems] = useState(['initial']);\n    function onBeforeCapture() {\n      // adding the first item\n      setItems(['first', 'initial']);\n    }\n\n    return (\n      <DragDropContext\n        onDragEnd={noop}\n        onBeforeCapture={onBeforeCapture}\n        onDragStart={onDragStart}\n      >\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided) => (\n            <div\n              {...droppableProvided.droppableProps}\n              ref={droppableProvided.innerRef}\n            >\n              {items.map((item: string, index: number) => (\n                <Draggable draggableId={item} index={index} key={item}>\n                  {(provided, snapshot) => (\n                    <div\n                      {...provided.draggableProps}\n                      {...provided.dragHandleProps}\n                      data-index={index}\n                      data-testid={item}\n                      data-is-dragging={snapshot.isDragging}\n                      ref={provided.innerRef}\n                    >\n                      Drag me!\n                    </div>\n                  )}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder};\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n\n  const { getByTestId, queryByTestId } = render(<Root />);\n  const initial: HTMLElement = getByTestId('initial');\n\n  // initially it had an index of 1\n  expect(getIndex(initial)).toBe(0);\n  // first item does not exist yet\n  expect(queryByTestId('first')).toBe(null);\n\n  // act(() => {}); is joining the two into one update which is\n  // causing unexpected mounting behaviour\n  withError(() => {\n    expandedMouse.rawPowerLift(initial, { x: 0, y: 0 });\n  });\n\n  // first item has been added\n  expect(queryByTestId('first')).toBeTruthy();\n  // initial is now dragging\n  expect(isDragging(initial)).toBe(true);\n  // initial index accounts for addition\n  expect(getIndex(initial)).toBe(1);\n\n  // flush onDragStart timer\n  jest.runOnlyPendingTimers();\n\n  // onDragStart called with correct new index\n  const expected: DragStart = {\n    draggableId: 'initial',\n    mode: 'FLUID',\n    type: 'DEFAULT',\n    source: {\n      index: 1,\n      droppableId: 'droppable',\n    },\n  };\n  expect(onDragStart.mock.calls[0][0]).toEqual(expected);\n\n  jest.useRealTimers();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-drop-context/on-before-capture/removals.spec.js",
    "content": "// @flow\nimport React, { useState } from 'react';\nimport { render } from '@testing-library/react';\nimport {\n  Droppable,\n  Draggable,\n  DragDropContext,\n  type DragStart,\n} from '../../../../../src';\nimport expandedMouse from '../../util/expanded-mouse';\nimport { isDragging } from '../../util/helpers';\nimport { withError } from '../../../../util/console';\nimport { noop } from '../../../../../src/empty';\n\nfunction getIndex(el: HTMLElement): number {\n  return Number(el.getAttribute('data-index'));\n}\n\nit('should adjust captured values for any changes that impact that dragging item', () => {\n  jest.useFakeTimers();\n  // 1. Changing the `type` of the Droppable\n  // 2. Adding and item before the dragging item to impact it's index\n  const onDragStart = jest.fn();\n\n  function Root() {\n    const [items, setItems] = useState(['first', 'second']);\n    function onBeforeCapture() {\n      // removing the first item\n      setItems(['second']);\n    }\n\n    return (\n      <DragDropContext\n        onDragEnd={noop}\n        onBeforeCapture={onBeforeCapture}\n        onDragStart={onDragStart}\n      >\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided) => (\n            <div\n              {...droppableProvided.droppableProps}\n              ref={droppableProvided.innerRef}\n            >\n              {items.map((item: string, index: number) => (\n                <Draggable draggableId={item} index={index} key={item}>\n                  {(provided, snapshot) => (\n                    <div\n                      {...provided.draggableProps}\n                      {...provided.dragHandleProps}\n                      data-index={index}\n                      data-testid={item}\n                      data-is-dragging={snapshot.isDragging}\n                      ref={provided.innerRef}\n                    >\n                      Drag me!\n                    </div>\n                  )}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder};\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n\n  const { getByTestId, queryByTestId } = render(<Root />);\n  const second: HTMLElement = getByTestId('second');\n\n  // initially it had an index of 1\n  expect(getIndex(second)).toBe(1);\n\n  // act(() => {}); is joining the two into one update which is\n  // causing unexpected mounting behaviour\n  withError(() => {\n    expandedMouse.rawPowerLift(getByTestId('second'), { x: 0, y: 0 });\n  });\n\n  // act(() => rerender());\n  // first item has been removed\n  expect(queryByTestId('first')).toBe(null);\n  // second is now dragging\n  expect(isDragging(second)).toBe(true);\n  // second index accounts for removal\n  expect(getIndex(second)).toBe(0);\n\n  // flush onDragStart timer\n  jest.runOnlyPendingTimers();\n\n  // onDragStart called with correct new index\n  const expected: DragStart = {\n    draggableId: 'second',\n    mode: 'FLUID',\n    type: 'DEFAULT',\n    source: {\n      index: 0,\n      droppableId: 'droppable',\n    },\n  };\n  expect(onDragStart.mock.calls[0][0]).toEqual(expected);\n\n  jest.useRealTimers();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-drop-context/reset-server-context.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport DragDropContext from '../../../../src/view/drag-drop-context';\nimport { resetServerContext } from '../../../../src';\nimport * as attributes from '../../../../src/view/data-attributes';\n\nconst doesStyleElementExist = (uniqueId: number): boolean =>\n  Boolean(\n    document.querySelector(`[${attributes.prefix}-always=\"${uniqueId}\"]`),\n  );\n\nit('should reset the style marshal context', () => {\n  expect(doesStyleElementExist(1)).toBe(false);\n\n  const wrapper1 = render(\n    <DragDropContext onDragEnd={() => {}}>{null}</DragDropContext>,\n  );\n  expect(doesStyleElementExist(0)).toBe(true);\n\n  const wrapper2 = render(\n    <DragDropContext onDragEnd={() => {}}>{null}</DragDropContext>,\n  );\n  expect(doesStyleElementExist(1)).toBe(true);\n\n  // not created yet\n  expect(doesStyleElementExist(2)).toBe(false);\n\n  // clearing away the old wrappers\n  wrapper1.unmount();\n  wrapper2.unmount();\n  resetServerContext();\n\n  // a new wrapper after the reset\n  const wrapper3 = render(\n    <DragDropContext onDragEnd={() => {}}>{null}</DragDropContext>,\n  );\n\n  // now only '0' exists\n  expect(doesStyleElementExist(0)).toBe(true);\n  expect(doesStyleElementExist(1)).toBe(false);\n\n  wrapper3.unmount();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-drop-context/unmount.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport DragDropContext from '../../../../src/view/drag-drop-context';\n\nit('should not throw when unmounting', () => {\n  const { unmount } = render(\n    <DragDropContext onDragEnd={() => {}}>{null}</DragDropContext>,\n  );\n\n  expect(() => unmount()).not.toThrow();\n});\n\nit('should clean up any window event handlers', () => {\n  jest.spyOn(window, 'addEventListener');\n  jest.spyOn(window, 'removeEventListener');\n\n  const { unmount } = render(\n    <DragDropContext onDragEnd={() => {}}>{null}</DragDropContext>,\n  );\n\n  unmount();\n\n  expect(window.addEventListener.mock.calls).toHaveLength(\n    window.removeEventListener.mock.calls.length,\n  );\n  // validation\n  expect(window.addEventListener).toHaveBeenCalled();\n  expect(window.removeEventListener).toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/keyboard-sensor/directional-movement.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { fireEvent, render, createEvent } from '@testing-library/react';\nimport * as keyCodes from '../../../../../src/view/key-codes';\nimport App from '../../util/app';\nimport { simpleLift, keyboard } from '../../util/controls';\n\njest.useFakeTimers();\n\nit('should move up when pressing the up arrow', () => {\n  const onDragUpdate = jest.fn();\n  const { getByText } = render(<App onDragUpdate={onDragUpdate} />);\n  const handle: HTMLElement = getByText('item: 1');\n\n  simpleLift(keyboard, handle);\n\n  const event: Event = createEvent.keyDown(handle, {\n    keyCode: keyCodes.arrowUp,\n  });\n  fireEvent(handle, event);\n\n  // flush async responder\n  jest.runOnlyPendingTimers();\n  expect(onDragUpdate).toHaveBeenCalled();\n  expect(onDragUpdate.mock.calls[0][0].destination.index).toBe(0);\n\n  // event consumed\n  expect(event.defaultPrevented).toBe(true);\n});\n\nit('should move down when pressing the down arrow', () => {\n  const onDragUpdate = jest.fn();\n  const { getByText } = render(<App onDragUpdate={onDragUpdate} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(keyboard, handle);\n\n  const event: Event = createEvent.keyDown(handle, {\n    keyCode: keyCodes.arrowDown,\n  });\n  fireEvent(handle, event);\n\n  // flush async responder\n  jest.runOnlyPendingTimers();\n  expect(onDragUpdate).toHaveBeenCalled();\n  expect(onDragUpdate.mock.calls[0][0].destination.index).toBe(1);\n\n  // event consumed\n  expect(event.defaultPrevented).toBe(true);\n});\n\nit('should move right when pressing the right arrow', () => {\n  const onDragUpdate = jest.fn();\n  const { getByText } = render(\n    <App onDragUpdate={onDragUpdate} direction=\"horizontal\" />,\n  );\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(keyboard, handle);\n\n  const event: Event = createEvent.keyDown(handle, {\n    keyCode: keyCodes.arrowRight,\n  });\n  fireEvent(handle, event);\n\n  // flush async responder\n  jest.runOnlyPendingTimers();\n  expect(onDragUpdate).toHaveBeenCalled();\n  expect(onDragUpdate.mock.calls[0][0].destination.index).toBe(1);\n\n  // event consumed\n  expect(event.defaultPrevented).toBe(true);\n});\n\nit('should move left when pressing the left arrow', () => {\n  const onDragUpdate = jest.fn();\n  const { getByText } = render(\n    <App onDragUpdate={onDragUpdate} direction=\"horizontal\" />,\n  );\n  const handle: HTMLElement = getByText('item: 1');\n\n  simpleLift(keyboard, handle);\n\n  const event: Event = createEvent.keyDown(handle, {\n    keyCode: keyCodes.arrowLeft,\n  });\n  fireEvent(handle, event);\n\n  // flush async responder\n  jest.runOnlyPendingTimers();\n  expect(onDragUpdate).toHaveBeenCalled();\n  expect(onDragUpdate.mock.calls[0][0].destination.index).toBe(0);\n\n  // event consumed\n  expect(event.defaultPrevented).toBe(true);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/keyboard-sensor/no-click-blocking.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, createEvent, fireEvent } from '@testing-library/react';\nimport App from '../../util/app';\nimport { simpleLift, keyboard } from '../../util/controls';\n\njest.useFakeTimers();\n\nit('should not prevent clicks after a drag', () => {\n  // clearing any pending listeners that have leaked from other tests\n  fireEvent.click(window);\n\n  const onDragStart = jest.fn();\n  const onDragEnd = jest.fn();\n  const { getByText } = render(\n    <App onDragStart={onDragStart} onDragEnd={onDragEnd} />,\n  );\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(keyboard, handle);\n\n  // flush start timer\n  jest.runOnlyPendingTimers();\n  expect(onDragStart).toHaveBeenCalled();\n  keyboard.drop(handle);\n\n  const event: Event = createEvent.click(handle);\n  fireEvent(handle, event);\n\n  // click not blocked\n  expect(event.defaultPrevented).toBe(false);\n  expect(onDragEnd).toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/keyboard-sensor/prevent-keyboard-scroll.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { createEvent, fireEvent, render } from '@testing-library/react';\nimport * as keyCodes from '../../../../../src/view/key-codes';\nimport App from '../../util/app';\nimport { simpleLift, keyboard } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\n\nit('should prevent using keyboard keys that modify scroll', () => {\n  const keys: number[] = [\n    keyCodes.pageUp,\n    keyCodes.pageDown,\n    keyCodes.home,\n    keyCodes.end,\n  ];\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(keyboard, handle);\n\n  keys.forEach((keyCode: number) => {\n    const event: Event = createEvent.keyDown(handle, { keyCode });\n    fireEvent(handle, event);\n\n    expect(event.defaultPrevented).toBe(true);\n    expect(isDragging(handle)).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/keyboard-sensor/prevent-standard-keys-while-dragging.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { createEvent, fireEvent, render } from '@testing-library/react';\nimport * as keyCodes from '../../../../../src/view/key-codes';\nimport App from '../../util/app';\nimport { isDragging } from '../../util/helpers';\nimport { simpleLift, keyboard } from '../../util/controls';\n\nit('should prevent enter or tab being pressed during a drag', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(keyboard, handle);\n  expect(isDragging(handle)).toBe(true);\n\n  [keyCodes.enter, keyCodes.tab].forEach((keyCode: number) => {\n    const event: Event = createEvent.keyDown(handle, { keyCode });\n    fireEvent(handle, event);\n    expect(event.defaultPrevented).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/keyboard-sensor/starting-a-drag.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, createEvent, fireEvent } from '@testing-library/react';\nimport App from '../../util/app';\nimport { isDragging } from '../../util/helpers';\nimport * as keyCodes from '../../../../../src/view/key-codes';\n\nit('should prevent the default keyboard action when lifting', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  const event: Event = createEvent.keyDown(handle, { keyCode: keyCodes.space });\n  fireEvent(handle, event);\n\n  expect(isDragging(handle)).toBe(true);\n  expect(event.defaultPrevented).toBe(true);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/keyboard-sensor/stopping-a-drag.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, createEvent, fireEvent } from '@testing-library/react';\nimport App from '../../util/app';\nimport { getDropReason, isDragging } from '../../util/helpers';\nimport * as keyCodes from '../../../../../src/view/key-codes';\nimport { simpleLift, keyboard } from '../../util/controls';\nimport supportedEventName from '../../../../../src/view/use-sensor-marshal/sensors/util/supported-page-visibility-event-name';\n\nit('should prevent default on the event that causes a drop', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(keyboard, handle);\n  expect(isDragging(handle)).toBe(true);\n\n  const event: Event = createEvent.keyDown(handle, { keyCode: keyCodes.space });\n  fireEvent(handle, event);\n\n  expect(event.defaultPrevented).toBe(true);\n  expect(getDropReason(onDragEnd)).toBe('DROP');\n});\n\nit('should prevent default on an escape press', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(keyboard, handle);\n  expect(isDragging(handle)).toBe(true);\n\n  const event: Event = createEvent.keyDown(handle, {\n    keyCode: keyCodes.escape,\n  });\n  fireEvent(handle, event);\n\n  expect(event.defaultPrevented).toBe(true);\n  expect(getDropReason(onDragEnd)).toBe('CANCEL');\n});\n\nit('should not prevent the default behaviour for an indirect cancel', () => {\n  [\n    'mousedown',\n    'mouseup',\n    'click',\n    'touchstart',\n    'resize',\n    'wheel',\n    supportedEventName,\n  ].forEach((eventName: string) => {\n    const onDragEnd = jest.fn();\n    const { getByText, unmount } = render(<App onDragEnd={onDragEnd} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(keyboard, handle);\n    expect(isDragging(handle)).toBe(true);\n\n    const event: Event = new Event(eventName, {\n      bubbles: true,\n      cancelable: true,\n      target: handle,\n    });\n\n    fireEvent(handle, event);\n\n    // not an explicit cancel\n    expect(event.defaultPrevented).toBe(false);\n    expect(getDropReason(onDragEnd)).toBe('CANCEL');\n\n    unmount();\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/mouse-sensor/cancel-while-pending.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport { sloppyClickThreshold } from '../../../../../src/view/use-sensor-marshal/sensors/use-mouse-sensor';\nimport App from '../../util/app';\nimport { isDragging } from '../../util/helpers';\nimport supportedEventName from '../../../../../src/view/use-sensor-marshal/sensors/util/supported-page-visibility-event-name';\nimport { mouse } from '../../util/controls';\n\nconst events: string[] = ['keydown', 'resize', supportedEventName];\n\nit(`should cancel a pending drag on events: [${events.join(', ')}]`, () => {\n  events.forEach((eventName: string) => {\n    const { getByText, unmount } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    mouse.preLift(handle);\n\n    const event: Event = new Event(eventName, {\n      bubbles: true,\n      cancelable: true,\n    });\n    fireEvent(handle, event);\n\n    // not an explicit cancel - so event not consumed\n    expect(event.defaultPrevented).toBe(false);\n\n    // would normally start\n    mouse.lift(handle);\n\n    // drag not started\n    expect(isDragging(handle)).toBe(false);\n\n    unmount();\n  });\n});\n\nit('should abort when there is a window scroll', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  fireEvent.mouseDown(handle);\n\n  // abort\n  const event: Event = new Event('scroll', {\n    target: window,\n    bubbles: true,\n    cancelable: true,\n  });\n  fireEvent(window, event);\n\n  // would normally start\n  fireEvent.mouseMove(handle, {\n    clientX: 0,\n    clientY: sloppyClickThreshold,\n  });\n\n  // event not consumed as it is an indirect cancel\n  expect(event.defaultPrevented).toBe(false);\n  // drag not started\n  expect(isDragging(handle)).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/mouse-sensor/click-blocking.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { createEvent, fireEvent, render } from '@testing-library/react';\nimport * as keyCodes from '../../../../../src/view/key-codes';\nimport { sloppyClickThreshold } from '../../../../../src/view/use-sensor-marshal/sensors/use-mouse-sensor';\nimport App from '../../util/app';\nimport { isDragging, getDropReason } from '../../util/helpers';\nimport { simpleLift, mouse } from '../../util/controls';\n\nit('should not prevent a subsequent click if aborting during a pending drag', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  fireEvent.mouseDown(handle);\n\n  // abort\n  fireEvent.keyDown(handle, { keyCode: keyCodes.escape });\n\n  // would normally start\n  fireEvent.mouseMove(handle, {\n    clientX: 0,\n    clientY: sloppyClickThreshold,\n  });\n\n  // drag not started\n  expect(isDragging(handle)).toBe(false);\n\n  const click: Event = createEvent.click(handle);\n  fireEvent(handle, click);\n\n  expect(click.defaultPrevented).toBe(false);\n});\n\nit('should prevent a subsequent click if cancelling a drag', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(mouse, handle);\n  expect(isDragging(handle)).toBe(true);\n\n  // cancel\n  fireEvent.keyDown(handle, { keyCode: keyCodes.escape });\n\n  // drag cancelled\n  expect(getDropReason(onDragEnd)).toBe('CANCEL');\n  expect(isDragging(handle)).toBe(false);\n\n  // click event prevented\n  const click: Event = createEvent.click(handle);\n  fireEvent(handle, click);\n  expect(click.defaultPrevented).toBe(true);\n});\n\nit('should prevent a subsequent click if dropping a drag', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(mouse, handle);\n  expect(isDragging(handle)).toBe(true);\n\n  // cancel\n  fireEvent.mouseUp(handle);\n\n  expect(getDropReason(onDragEnd)).toBe('DROP');\n  expect(isDragging(handle)).toBe(false);\n\n  // click event prevented\n  const click: Event = createEvent.click(handle);\n  fireEvent(handle, click);\n  expect(click.defaultPrevented).toBe(true);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/mouse-sensor/force-press.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { mouse, simpleLift } from '../../util/controls';\nimport App, { type Item } from '../../util/app';\nimport { isDragging } from '../../util/helpers';\n\ndescribe('force press is not respected', () => {\n  it('should prevent the default of a `webkitmouseforcewillbegin` event', () => {\n    const { getByText } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    const event: Event = new Event('webkitmouseforcewillbegin', {\n      bubbles: true,\n      cancelable: true,\n    });\n    fireEvent(handle, event);\n\n    expect(event.defaultPrevented).toBe(true);\n\n    // lift not prevented\n    simpleLift(mouse, handle);\n    expect(isDragging(handle)).toBe(true);\n  });\n\n  it('should prevent the default of a `webkitmouseforcedown` event', () => {\n    const { getByText } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    // while pending\n    mouse.preLift(handle);\n    const first: Event = new Event('webkitmouseforcedown', {\n      bubbles: true,\n      cancelable: true,\n    });\n    fireEvent(handle, first);\n    expect(first.defaultPrevented).toBe(true);\n\n    // while dragging\n    mouse.lift(handle);\n    const second: Event = new Event('webkitmouseforcedown', {\n      bubbles: true,\n      cancelable: true,\n    });\n    fireEvent(handle, second);\n    expect(second.defaultPrevented).toBe(true);\n\n    // dragging not aborted\n    expect(isDragging(handle)).toBe(true);\n  });\n});\n\ndescribe('force press is respected', () => {\n  it('should not prevent the default of a `webkitmouseforcewillbegin` event', () => {\n    const items: Item[] = [{ id: '0', shouldRespectForcePress: true }];\n    const { getByText } = render(<App items={items} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    const event: Event = new Event('webkitmouseforcewillbegin', {\n      bubbles: true,\n      cancelable: true,\n    });\n    fireEvent(handle, event);\n\n    expect(event.defaultPrevented).toBe(false);\n  });\n\n  it('should cancel a pending drag with a webkitmouseforcedown event', () => {\n    const items: Item[] = [{ id: '0', shouldRespectForcePress: true }];\n    const { getByText } = render(<App items={items} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    // while pending\n    mouse.preLift(handle);\n    const event: Event = new Event('webkitmouseforcedown', {\n      bubbles: true,\n      cancelable: true,\n    });\n    fireEvent(handle, event);\n    expect(event.defaultPrevented).toBe(false);\n    // pre drag will be aborted\n\n    mouse.lift(handle);\n    expect(isDragging(handle)).toBe(false);\n  });\n\n  it('should cancel an active drag with a webkitmouseforcedown event', () => {\n    const items: Item[] = [{ id: '0', shouldRespectForcePress: true }];\n    const { getByText } = render(<App items={items} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(mouse, handle);\n    expect(isDragging(handle)).toBe(true);\n\n    const event: Event = new Event('webkitmouseforcedown', {\n      bubbles: true,\n      cancelable: true,\n    });\n    fireEvent(handle, event);\n    expect(event.defaultPrevented).toBe(false);\n\n    expect(isDragging(handle)).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/mouse-sensor/prevent-standard-keys-while-dragging.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { createEvent, fireEvent, render } from '@testing-library/react';\nimport * as keyCodes from '../../../../../src/view/key-codes';\nimport App from '../../util/app';\nimport { isDragging } from '../../util/helpers';\nimport { simpleLift, mouse } from '../../util/controls';\n\nit('should prevent enter or tab being pressed during a drag', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(mouse, handle);\n  expect(isDragging(handle)).toBe(true);\n\n  [keyCodes.enter, keyCodes.tab].forEach((keyCode: number) => {\n    const event: Event = createEvent.keyDown(handle, { keyCode });\n    fireEvent(handle, event);\n    expect(event.defaultPrevented).toBe(true);\n    expect(isDragging(handle)).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/mouse-sensor/starting-a-dragging.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport type { Position } from 'css-box-model';\nimport { render, fireEvent, createEvent } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport {\n  sloppyClickThreshold,\n  primaryButton,\n} from '../../../../../src/view/use-sensor-marshal/sensors/use-mouse-sensor';\nimport { isDragging } from '../../util/helpers';\nimport App from '../../util/app';\n// blocking announcement messages\njest.spyOn(console, 'warn').mockImplementation((message: string) => {\n  invariant(\n    message.includes('Message not passed to screen reader'),\n    `Unexpected console.warn(\"${message}\")`,\n  );\n});\n\nit('should start a drag after sufficient movement', () => {\n  const valid: Position[] = [\n    { x: 0, y: sloppyClickThreshold },\n    { x: 0, y: -sloppyClickThreshold },\n    { x: sloppyClickThreshold, y: 0 },\n    { x: -sloppyClickThreshold, y: 0 },\n  ];\n\n  valid.forEach((point: Position) => {\n    const { getByText, unmount } = render(<App />);\n\n    const handle: HTMLElement = getByText('item: 0');\n\n    const mouseDown: MouseEvent = createEvent.mouseDown(handle);\n\n    fireEvent(handle, mouseDown);\n    // important that this is called to prevent focus\n    expect(mouseDown.defaultPrevented).toBe(true);\n\n    // not dragging yet\n    expect(isDragging(handle)).toBe(false);\n\n    // mouse move to start drag\n\n    const mouseMove: MouseEvent = createEvent.mouseMove(handle, {\n      clientX: point.x,\n      clientY: point.y,\n    });\n    fireEvent(window, mouseMove);\n    // we are using the event - so prevent default is called\n    expect(mouseMove.defaultPrevented).toBe(true);\n\n    // now dragging\n    expect(isDragging(handle)).toBe(true);\n\n    unmount();\n  });\n});\n\nit('should allow standard click events', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  const click: MouseEvent = createEvent.click(handle);\n  fireEvent(handle, click);\n\n  expect(click.defaultPrevented).toBe(false);\n});\n\nit('should not call preventDefault on mouse movements while we are not sure if a drag is starting', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  // start pending\n  fireEvent.mouseDown(handle, {\n    clientX: 0,\n    clientY: 0,\n    button: primaryButton,\n  });\n\n  // not dragging yet\n  const mouseMove: MouseEvent = createEvent.mouseMove(handle, {\n    clientX: 0,\n    clientY: sloppyClickThreshold - 1,\n  });\n  fireEvent(handle, mouseMove);\n\n  expect(isDragging(handle)).toBe(false);\n  expect(mouseMove.defaultPrevented).toBe(false);\n});\n\nit('should call preventDefault on the initial mousedown event to prevent the element gaining focus', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  const mouseDown: MouseEvent = createEvent.mouseDown(handle);\n  fireEvent(handle, mouseDown);\n\n  expect(mouseDown.defaultPrevented).toBe(true);\n});\n\nit('should allow multiple false starts', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  Array.from({ length: 5 }).forEach(() => {\n    fireEvent.mouseDown(handle);\n    fireEvent.mouseUp(handle);\n\n    expect(isDragging(handle)).toBe(false);\n  });\n\n  fireEvent.mouseDown(handle);\n  fireEvent.mouseMove(handle, {\n    clientX: 0,\n    clientY: sloppyClickThreshold,\n  });\n\n  expect(isDragging(handle)).toBe(true);\n});\n\nit('should not start a drag if there was too little mouse movement while mouse was pressed', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  fireEvent.mouseDown(handle);\n  fireEvent.mouseMove(handle, {\n    clientX: 0,\n    clientY: sloppyClickThreshold - 1,\n  });\n\n  expect(isDragging(handle)).toBe(false);\n});\n\nit('should not start a drag if not using the primary mouse button', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  const mouseDown: Event = createEvent.mouseDown(handle, {\n    button: primaryButton + 1,\n  });\n  fireEvent(handle, mouseDown);\n  fireEvent.mouseMove(handle, {\n    clientX: 0,\n    clientY: sloppyClickThreshold,\n  });\n\n  expect(isDragging(handle)).toBe(false);\n});\n\nit('should not start a drag if a modifier key was used while pressing the mouse down', () => {\n  // if any drag is started with these keys pressed then we do not start a drag\n  const keys: string[] = ['ctrlKey', 'altKey', 'shiftKey', 'metaKey'];\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  keys.forEach((key: string) => {\n    const mouseDown: MouseEvent = createEvent.mouseDown(handle, {\n      [key]: true,\n    });\n    fireEvent(handle, mouseDown);\n    fireEvent.mouseMove(handle, {\n      clientX: 0,\n      clientY: sloppyClickThreshold,\n    });\n\n    expect(isDragging(handle)).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/mouse-sensor/stopping-a-drag.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, createEvent, fireEvent } from '@testing-library/react';\nimport App from '../../util/app';\nimport { getDropReason } from '../../util/helpers';\nimport * as keyCodes from '../../../../../src/view/key-codes';\nimport { simpleLift, mouse } from '../../util/controls';\nimport supportedEventName from '../../../../../src/view/use-sensor-marshal/sensors/util/supported-page-visibility-event-name';\n\nit('should prevent default on the event that causes a drop', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(mouse, handle);\n\n  const event: Event = createEvent.mouseUp(handle);\n  fireEvent(handle, event);\n\n  expect(event.defaultPrevented).toBe(true);\n  expect(getDropReason(onDragEnd)).toBe('DROP');\n});\n\nit('should prevent default on an escape press', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(mouse, handle);\n\n  const event: Event = createEvent.keyDown(handle, {\n    keyCode: keyCodes.escape,\n  });\n  fireEvent(handle, event);\n\n  expect(event.defaultPrevented).toBe(true);\n  expect(getDropReason(onDragEnd)).toBe('CANCEL');\n});\n\nit('should not prevent the default behaviour for an indirect cancel', () => {\n  ['resize', supportedEventName].forEach((eventName: string) => {\n    const onDragEnd = jest.fn();\n    const { getByText, unmount } = render(<App onDragEnd={onDragEnd} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(mouse, handle);\n\n    const event: Event = new Event(eventName, {\n      bubbles: true,\n      cancelable: true,\n      target: handle,\n    });\n\n    fireEvent(handle, event);\n\n    // not an explicit cancel\n    expect(event.defaultPrevented).toBe(false);\n    expect(getDropReason(onDragEnd)).toBe('CANCEL');\n\n    unmount();\n  });\n});\n\nit('should cancel and prevent default on mousedown during a drag as it might be from a different button', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(mouse, handle);\n\n  const event: Event = createEvent.mouseDown(handle);\n  fireEvent(handle, event);\n\n  expect(event.defaultPrevented).toBe(true);\n  expect(getDropReason(onDragEnd)).toBe('CANCEL');\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/sensor-marshal/click-blocking.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, fireEvent, createEvent } from '@testing-library/react';\nimport { act } from 'react-dom/test-utils';\nimport { invariant } from '../../../../../src/invariant';\nimport type {\n  SensorAPI,\n  Sensor,\n  PreDragActions,\n  SnapDragActions,\n} from '../../../../../src/types';\nimport App from '../../util/app';\n\nit('should block a single click if requested', () => {\n  let api: SensorAPI;\n  const sensor: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n\n  const { getByText } = render(\n    <React.Fragment>\n      <App sensors={[sensor]} />\n    </React.Fragment>,\n  );\n  const handle: HTMLElement = getByText('item: 0');\n  invariant(api);\n\n  // trigger a drop\n  const preDrag: ?PreDragActions = api.tryGetLock('0');\n  invariant(preDrag);\n  const drag: SnapDragActions = preDrag.snapLift();\n  act(() => drag.drop({ shouldBlockNextClick: true }));\n\n  // fire click\n  const first: MouseEvent = createEvent.click(handle);\n  const second: MouseEvent = createEvent.click(handle);\n  fireEvent(handle, first);\n  fireEvent(handle, second);\n\n  // only first click is prevented\n  expect(first.defaultPrevented).toBe(true);\n  expect(second.defaultPrevented).toBe(false);\n});\n\nit('should not block any clicks if not requested', () => {\n  let api: SensorAPI;\n\n  const a: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n\n  const { getByText } = render(\n    <React.Fragment>\n      <App sensors={[a]} />\n    </React.Fragment>,\n  );\n  const handle: HTMLElement = getByText('item: 0');\n  invariant(api);\n\n  // trigger a drop\n  const preDrag: ?PreDragActions = api.tryGetLock('0');\n  invariant(preDrag);\n  const drag: SnapDragActions = preDrag.snapLift();\n  act(() => drag.drop({ shouldBlockNextClick: false }));\n\n  // fire click\n  const first: MouseEvent = createEvent.click(handle);\n  fireEvent(handle, first);\n\n  // click not prevented\n  expect(first.defaultPrevented).toBe(false);\n});\n\nit('should not block any clicks after a timeout', () => {\n  jest.useFakeTimers();\n\n  let api: SensorAPI;\n  const sensor: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n\n  const { getByText } = render(\n    <React.Fragment>\n      <App sensors={[sensor]} />\n    </React.Fragment>,\n  );\n  const handle: HTMLElement = getByText('item: 0');\n  invariant(api);\n\n  // trigger a drop\n  const preDrag: ?PreDragActions = api.tryGetLock('0');\n  invariant(preDrag);\n  const drag: SnapDragActions = preDrag.snapLift();\n  act(() => drag.drop({ shouldBlockNextClick: true }));\n\n  jest.runTimersToTime(1);\n\n  // fire click\n  const first: MouseEvent = createEvent.click(handle);\n  fireEvent(handle, first);\n\n  // click not prevented\n  expect(first.defaultPrevented).toBe(false);\n\n  jest.useRealTimers();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/sensor-marshal/force-releasing-locks.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport type {\n  SensorAPI,\n  Sensor,\n  PreDragActions,\n} from '../../../../../src/types';\nimport App from '../../util/app';\n\nit('should correctly state whether a lock is claimed', () => {\n  let first: SensorAPI;\n  let second: SensorAPI;\n  const a: Sensor = (value: SensorAPI) => {\n    first = value;\n  };\n  const b: Sensor = (value: SensorAPI) => {\n    second = value;\n  };\n  const onForceStop = jest.fn();\n\n  render(\n    <React.Fragment>\n      <App sensors={[a, b]} />\n    </React.Fragment>,\n  );\n  invariant(first);\n  invariant(second);\n\n  const preDrag: ?PreDragActions = first.tryGetLock('0', onForceStop);\n  expect(preDrag).toBeTruthy();\n  expect(second.isLockClaimed()).toBe(true);\n\n  second.tryReleaseLock();\n  expect(onForceStop).toHaveBeenCalled();\n  // lock is gone\n  expect(second.isLockClaimed()).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/sensor-marshal/is-lock-claimed.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport type {\n  SensorAPI,\n  Sensor,\n  PreDragActions,\n} from '../../../../../src/types';\nimport App from '../../util/app';\n\nit('should correctly state whether a lock is claimed', () => {\n  let first: SensorAPI;\n  let second: SensorAPI;\n  const a: Sensor = (value: SensorAPI) => {\n    first = value;\n  };\n  const b: Sensor = (value: SensorAPI) => {\n    second = value;\n  };\n\n  render(\n    <React.Fragment>\n      <App sensors={[a, b]} />\n    </React.Fragment>,\n  );\n  invariant(first && second);\n\n  // both sensors know that the lock is not claimed\n  expect(first.isLockClaimed()).toBe(false);\n  expect(second.isLockClaimed()).toBe(false);\n\n  const preDrag: ?PreDragActions = first.tryGetLock('0');\n  expect(preDrag).toBeTruthy();\n\n  // both sensors can know if the lock is claimed\n  expect(first.isLockClaimed()).toBe(true);\n  expect(second.isLockClaimed()).toBe(true);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/sensor-marshal/lock-context-isolation.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport type { SensorAPI, Sensor } from '../../../../../src/types';\nimport App from '../../util/app';\n\nit('should allow different locks in different DragDropContexts', () => {\n  let first: SensorAPI;\n  let second: SensorAPI;\n\n  const a: Sensor = (value: SensorAPI) => {\n    first = value;\n  };\n  const b: Sensor = (value: SensorAPI) => {\n    second = value;\n  };\n\n  const { getAllByText } = render(\n    <React.Fragment>\n      <App sensors={[a]} />\n      <App sensors={[b]} />\n    </React.Fragment>,\n  );\n\n  const items: HTMLElement[] = getAllByText('item: 0');\n  expect(items).toHaveLength(2);\n  const [inFirst, inSecond] = items;\n  expect(inFirst).not.toBe(inSecond);\n\n  // each sensor can get a different lock\n  invariant(first, 'expected first to be set');\n  invariant(second, 'expected second to be set');\n  expect(first.tryGetLock('0')).toBeTruthy();\n  expect(second.tryGetLock('0')).toBeTruthy();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/sensor-marshal/move-throttling.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport type { Position } from 'css-box-model';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport type {\n  SensorAPI,\n  PreDragActions,\n  FluidDragActions,\n  Sensor,\n} from '../../../../../src/types';\nimport App from '../../util/app';\nimport { getOffset } from '../../util/helpers';\nimport { add } from '../../../../../src/state/position';\n\nfunction noop() {}\n\nit('should throttle move events by request animation frame', () => {\n  let api: SensorAPI;\n  const sensor: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n  const { getByText } = render(<App sensors={[sensor]} />);\n  invariant(api, 'expected getter to be set');\n  const handle: HTMLElement = getByText('item: 0');\n\n  const preDrag: ?PreDragActions = api.tryGetLock('0', noop);\n  invariant(preDrag);\n\n  const initial: Position = { x: 2, y: 3 };\n  const actions: FluidDragActions = preDrag.fluidLift(initial);\n  // has not moved yet\n  expect(getOffset(handle)).toEqual({ x: 0, y: 0 });\n\n  const offset: Position = { x: 1, y: 5 };\n  actions.move(add(initial, offset));\n  actions.move(add(initial, offset));\n  actions.move(add(initial, offset));\n\n  // still not moved\n  expect(getOffset(handle)).toEqual({ x: 0, y: 0 });\n\n  // moved after frame\n  requestAnimationFrame.step();\n  expect(getOffset(handle)).toEqual(offset);\n});\n\nit('should cancel any pending moves after a lock is released', () => {\n  let api: SensorAPI;\n  const a: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n  const { getByText } = render(<App sensors={[a]} />);\n  invariant(api, 'expected api to be set');\n  const handle: HTMLElement = getByText('item: 0');\n\n  const preDrag: ?PreDragActions = api.tryGetLock('0', noop);\n  invariant(preDrag);\n\n  const initial: Position = { x: 2, y: 3 };\n  const actions: FluidDragActions = preDrag.fluidLift(initial);\n  // has not moved yet\n  expect(getOffset(handle)).toEqual({ x: 0, y: 0 });\n\n  const offset: Position = { x: 1, y: 5 };\n  actions.move(add(initial, offset));\n  // not moved yet\n  expect(getOffset(handle)).toEqual({ x: 0, y: 0 });\n\n  actions.cancel();\n\n  // will not do anything\n  requestAnimationFrame.step();\n  expect(getOffset(handle)).toEqual({ x: 0, y: 0 });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/sensor-marshal/no-double-lift.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport type {\n  SensorAPI,\n  PreDragActions,\n  SnapDragActions,\n  Sensor,\n} from '../../../../../src/types';\nimport App from '../../util/app';\n\nit('should not allow double lifting', () => {\n  let api: SensorAPI;\n  const a: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n  render(<App sensors={[a]} />);\n  invariant(api, 'expected first to be set');\n\n  const preDrag: ?PreDragActions = api.tryGetLock('0');\n  invariant(preDrag);\n  // it is currently active\n  expect(preDrag.isActive()).toBe(true);\n\n  const drag: SnapDragActions = preDrag.snapLift();\n\n  expect(() => preDrag.fluidLift({ x: 0, y: 0 })).toThrow();\n  // original lock is gone\n  expect(drag.isActive()).toBe(false);\n\n  // yolo\n  expect(() => preDrag.snapLift()).toThrow();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/sensor-marshal/obtaining-lock.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, act } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport type {\n  SensorAPI,\n  PreDragActions,\n  FluidDragActions,\n  SnapDragActions,\n  Sensor,\n} from '../../../../../src/types';\nimport App from '../../util/app';\nimport { isDragging, isDropAnimating } from '../../util/helpers';\n\nfunction noop() {}\n\nit('should allow an exclusive lock for drag actions', () => {\n  let first: SensorAPI;\n  let second: SensorAPI;\n\n  const a: Sensor = (value: SensorAPI) => {\n    first = value;\n  };\n  const b: Sensor = (value: SensorAPI) => {\n    second = value;\n  };\n\n  render(<App sensors={[a, b]} />);\n  invariant(first, 'expected first to be set');\n  invariant(second, 'expected second to be set');\n\n  // first can get a lock\n  expect(first.tryGetLock('0')).toBeTruthy();\n\n  // second cannot get a lock\n  expect(second.tryGetLock('0')).toBe(null);\n\n  // first cannot get another lock on the same element\n  expect(first.tryGetLock('0')).toBe(null);\n\n  // nothing cannot get lock on a different element\n  expect(first.tryGetLock('1')).toBe(null);\n  expect(second.tryGetLock('1')).toBe(null);\n});\n\nit('should allow a lock to be released', () => {\n  let api: SensorAPI;\n  const sensor: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n\n  render(<App sensors={[sensor]} />);\n  invariant(api, 'expected getter to be set');\n\n  Array.from({ length: 4 }).forEach(() => {\n    // get the lock\n    const lock: ?PreDragActions = api.tryGetLock('0', noop);\n    expect(lock).toBeTruthy();\n    invariant(lock, 'Expected lock to be set');\n\n    // cannot get another lock\n    expect(api.tryGetLock('0')).toBe(null);\n\n    // release the lock\n    lock.abort();\n  });\n});\n\nit('should not allow a sensor to obtain a on a dropping item, but can claim one on something else while dragging', () => {\n  let api: SensorAPI;\n  const sensor: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n  const { getByText } = render(<App sensors={[sensor]} />);\n  invariant(api, 'expected getter to be set');\n  const handle: HTMLElement = getByText('item: 0');\n\n  const preDrag: ?PreDragActions = api.tryGetLock('0', noop);\n  invariant(preDrag, 'Expected to get lock');\n\n  // drag not started yet\n  expect(isDragging(handle)).toBe(false);\n  // start a drag\n  const actions: FluidDragActions = preDrag.fluidLift({ x: 0, y: 0 });\n  expect(isDragging(handle)).toBe(true);\n\n  // release the movement\n  actions.move({ x: 100, y: 100 });\n  requestAnimationFrame.flush();\n\n  actions.drop();\n  expect(isDropAnimating(handle)).toBe(true);\n\n  // lock is no longer active\n  expect(actions.isActive()).toBe(false);\n  expect(preDrag.isActive()).toBe(false);\n\n  // cannot get a new lock while still dropping\n  expect(api.tryGetLock('0', noop)).toBe(null);\n\n  // can get a lock on a handle that is not dropping - while the other is dropping\n  expect(api.tryGetLock('1', noop)).toBeTruthy();\n});\n\nit('should release a lock when aborting a pre drag', () => {\n  let api: SensorAPI;\n  const sensor: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n  render(<App sensors={[sensor]} />);\n  invariant(api, 'expected getter to be set');\n\n  const preDrag: ?PreDragActions = api.tryGetLock('0', noop);\n  invariant(preDrag, 'Expected to get lock');\n  expect(preDrag.isActive()).toBe(true);\n  // should release the lock\n  preDrag.abort();\n  expect(preDrag.isActive()).toBe(false);\n\n  // can get another lock\n  const second: ?PreDragActions = api.tryGetLock('1', noop);\n  expect(second).toBeTruthy();\n  invariant(second);\n  // need to release this one :)\n  second.abort();\n  expect(second.isActive()).toBe(false);\n});\n\nit('should release a lock when cancelling or dropping a drag', () => {\n  let api: SensorAPI;\n  const sensor: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n  render(<App sensors={[sensor]} />);\n  invariant(api, 'expected getter to be set');\n\n  ['cancel', 'drop'].forEach((property: string) => {\n    const preDrag: ?PreDragActions = api.tryGetLock('0', noop);\n    invariant(preDrag, 'Expected to get lock');\n    expect(preDrag.isActive()).toBe(true);\n\n    const drag: SnapDragActions = preDrag.snapLift();\n    expect(drag.isActive()).toBe(true);\n\n    // cannot get another lock\n    const second: ?PreDragActions = api.tryGetLock('1', noop);\n    expect(second).toBe(null);\n\n    // calling cancel or drop\n    act(() => {\n      drag[property]();\n    });\n\n    // can now get another lock\n    const third: ?PreDragActions = api.tryGetLock('1', noop);\n    expect(third).toBeTruthy();\n    // need to try to release it\n    invariant(third);\n    third.abort();\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/sensor-marshal/outdated-locks.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { act } from 'react-dom/test-utils';\nimport { invariant } from '../../../../../src/invariant';\nimport type {\n  SensorAPI,\n  PreDragActions,\n  SnapDragActions,\n  Sensor,\n} from '../../../../../src/types';\nimport App from '../../util/app';\n\nfunction noop() {}\n\nconst warn = jest.spyOn(console, 'warn').mockImplementation(noop);\n\nafterEach(() => {\n  warn.mockClear();\n});\n\nit('should not allow pre drag actions when in a dragging phase', () => {\n  let api: SensorAPI;\n  const a: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n  render(<App sensors={[a]} />);\n  invariant(api, 'expected api to be set');\n\n  const preDrag: ?PreDragActions = api.tryGetLock('0');\n  invariant(preDrag);\n  // it is currently active\n  expect(preDrag.isActive()).toBe(true);\n\n  const drag: SnapDragActions = preDrag.snapLift();\n\n  // pre drag now outdated\n  expect(preDrag.isActive()).toBe(false);\n  preDrag.abort();\n  expect(warn.mock.calls[0][0]).toEqual(\n    expect.stringContaining('Cannot perform action'),\n  );\n\n  // drag is active - not aborted by preDrag\n  expect(drag.isActive()).toBe(true);\n\n  // ending drag\n  warn.mockClear();\n  act(() => drag.drop());\n  expect(warn).not.toHaveBeenCalled();\n\n  // preDrag is still out of date\n  preDrag.abort();\n  expect(warn.mock.calls[0][0]).toEqual(\n    expect.stringContaining('Cannot perform action'),\n  );\n});\n\nit('should not allow drag actions after a drop', () => {\n  let api: SensorAPI;\n  const sensor: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n  render(<App sensors={[sensor]} />);\n  invariant(api, 'expected api to be set');\n\n  const preDrag: ?PreDragActions = api.tryGetLock('0');\n  invariant(preDrag);\n  expect(preDrag.isActive()).toBe(true);\n\n  const drag: SnapDragActions = preDrag.snapLift();\n  expect(drag.isActive()).toBe(true);\n\n  act(() => drag.cancel());\n\n  // no longer active\n  expect(drag.isActive()).toBe(false);\n  expect(warn).not.toHaveBeenCalled();\n\n  drag.moveUp();\n  expect(warn.mock.calls[0][0]).toEqual(\n    expect.stringContaining('Cannot perform action'),\n  );\n});\n\nit('should not allow drag actions after lock lost', () => {\n  let api: SensorAPI;\n  const sensor: Sensor = (value: SensorAPI) => {\n    api = value;\n  };\n  const { unmount } = render(<App sensors={[sensor]} />);\n  invariant(api, 'expected first to be set');\n\n  const preDrag: ?PreDragActions = api.tryGetLock('0');\n  invariant(preDrag);\n  expect(preDrag.isActive()).toBe(true);\n\n  // will cause all lock to be lost\n  unmount();\n\n  expect(preDrag.isActive()).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/abort-on-error.spec.js",
    "content": "// @flow\nimport React, { useState, useRef } from 'react';\nimport { render, act } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport { isDragging, getOffset } from '../../util/helpers';\nimport App from '../../util/app';\nimport { withError, withWarn } from '../../../../util/console';\nimport { forEachSensor, simpleLift, type Control } from '../../util/controls';\nimport causeRuntimeError from '../../../../util/cause-runtime-error';\n\ntype Props = {\n  throw: () => void,\n  setForceThrow: (fn: () => void) => void,\n};\n\nfunction Vomit(props: Props) {\n  const setShouldThrow = useState(0)[1];\n  const shouldThrowRef = useRef(false);\n\n  function chuck() {\n    shouldThrowRef.current = true;\n    setShouldThrow((current) => current + 1);\n  }\n\n  props.setForceThrow(chuck);\n\n  if (shouldThrowRef.current) {\n    shouldThrowRef.current = false;\n    props.throw();\n  }\n\n  return null;\n}\n\ntype Thrower = {|\n  setForceThrow: (fn: () => void) => void,\n  execute: () => void,\n|};\n\nfunction getThrower(): Thrower {\n  let current: ?() => void = null;\n  function setForceThrow(fn) {\n    current = fn;\n  }\n\n  function execute() {\n    withError(() => {\n      act(() => {\n        invariant(current, 'Expected throw callback to be set');\n        current();\n      });\n    });\n  }\n\n  return { setForceThrow, execute };\n}\n\nforEachSensor((control: Control) => {\n  it('should abort a drag if an invariant error occurs in the application', () => {\n    const thrower: Thrower = getThrower();\n    const { getByText } = render(\n      <App\n        anotherChild={\n          <Vomit\n            throw={() =>\n              invariant(false, 'Do not pass go, do not collect $200')\n            }\n            setForceThrow={thrower.setForceThrow}\n          />\n        }\n      />,\n    );\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toBe(true);\n\n    thrower.execute();\n\n    const newHandle: HTMLElement = getByText('item: 0');\n    // handle is now a new element\n    expect(handle).not.toBe(newHandle);\n    expect(isDragging(newHandle)).toBe(false);\n\n    // moving the handles around\n    expect(() => {\n      control.move(handle);\n      control.move(newHandle);\n      expect(getOffset(handle)).toEqual({ x: 0, y: 0 });\n      expect(getOffset(newHandle)).toEqual({ x: 0, y: 0 });\n    }).not.toThrow();\n  });\n\n  it('should abort a drag if an a non-invariant error occurs in the application', () => {\n    const thrower: Thrower = getThrower();\n    const { getByText, queryByText } = render(\n      <App\n        anotherChild={\n          <Vomit\n            throw={() => {\n              throw new Error('Raw error throw');\n            }}\n            setForceThrow={thrower.setForceThrow}\n          />\n        }\n      />,\n    );\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toBe(true);\n\n    expect(() => {\n      thrower.execute();\n    }).toThrow();\n\n    // handle is gone\n    expect(queryByText('item: 0')).toBe(null);\n\n    // strange - but firing events on old handle\n    expect(() => {\n      control.move(handle);\n      expect(getOffset(handle)).toEqual({ x: 0, y: 0 });\n    }).not.toThrow();\n  });\n\n  it('should abort a drag if a runtime error occurs', () => {\n    const thrower: Thrower = getThrower();\n    const { getByText } = render(\n      <App\n        anotherChild={\n          <Vomit\n            throw={() => {\n              causeRuntimeError();\n            }}\n            setForceThrow={thrower.setForceThrow}\n          />\n        }\n      />,\n    );\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toBe(true);\n\n    withWarn(() => {\n      thrower.execute();\n    });\n\n    expect(isDragging(getByText('item: 0'))).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/cancel-while-dragging.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { createEvent, fireEvent, render } from '@testing-library/react';\nimport * as keyCodes from '../../../../../src/view/key-codes';\nimport App from '../../util/app';\nimport { isDragging, getDropReason } from '../../util/helpers';\nimport supportedEventName from '../../../../../src/view/use-sensor-marshal/sensors/util/supported-page-visibility-event-name';\nimport { forEachSensor, simpleLift, type Control } from '../../util/controls';\n\nforEachSensor((control: Control) => {\n  it('should cancel when pressing escape', () => {\n    const onDragEnd = jest.fn();\n    const { getByText } = render(<App onDragEnd={onDragEnd} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toBe(true);\n\n    // cancel\n    const event: Event = createEvent.keyDown(handle, {\n      keyCode: keyCodes.escape,\n    });\n\n    fireEvent(handle, event);\n\n    // event consumed\n    expect(event.defaultPrevented).toBe(true);\n    // drag ended\n    expect(isDragging(handle)).toBe(false);\n    expect(onDragEnd.mock.calls[0][0].reason).toBe('CANCEL');\n  });\n\n  it('should cancel when window is resized', () => {\n    const onDragEnd = jest.fn();\n    const { getByText } = render(<App onDragEnd={onDragEnd} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toBe(true);\n\n    // cancel\n    const event: Event = new Event('resize', {\n      bubbles: true,\n      cancelable: true,\n    });\n\n    fireEvent(handle, event);\n\n    // event not consumed as it is an indirect cancel\n    expect(event.defaultPrevented).toBe(false);\n    // drag ended\n    expect(isDragging(handle)).toBe(false);\n    expect(onDragEnd.mock.calls[0][0].reason).toBe('CANCEL');\n  });\n\n  it('should cancel when there is a visibility change', () => {\n    const onDragEnd = jest.fn();\n    const { getByText } = render(<App onDragEnd={onDragEnd} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toBe(true);\n\n    // cancel\n    const event: Event = new Event(supportedEventName, {\n      bubbles: true,\n      cancelable: true,\n    });\n\n    fireEvent(handle, event);\n\n    // event not consumed as it is an indirect cancel\n    expect(event.defaultPrevented).toBe(false);\n    // drag ended\n    expect(isDragging(handle)).toBe(false);\n    expect(getDropReason(onDragEnd)).toBe('CANCEL');\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/cannot-start-when-disabled.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { isDragging } from '../../util/helpers';\nimport App, { type Item } from '../../util/app';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\n\nforEachSensor((control: Control) => {\n  it('should not start a drag if disabled', () => {\n    const items: Item[] = [{ id: '0', isEnabled: false }];\n\n    const { getByText } = render(<App items={items} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(control, handle);\n\n    expect(isDragging(handle)).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/cannot-start-when-something-else-has-lock.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport { isDragging } from '../../util/helpers';\nimport App from '../../util/app';\nimport type { SensorAPI } from '../../../../../src/types';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\n\nforEachSensor((control: Control) => {\n  it('should not start a drag if another sensor is capturing', () => {\n    let api: SensorAPI;\n    function greedy(value: SensorAPI) {\n      api = value;\n    }\n    const { getByText } = render(<App sensors={[greedy]} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    invariant(api, 'Expected function to be set');\n    api.tryGetLock('0');\n\n    // won't be able to lift as the lock is already claimed\n    simpleLift(control, handle);\n\n    expect(isDragging(handle)).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/cannot-start-when-unmounted.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { isDragging } from '../../util/helpers';\nimport App from '../../util/app';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\n\nforEachSensor((control: Control) => {\n  it('should not allow starting after the handle is unmounted', () => {\n    const { getByText, unmount } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    unmount();\n\n    simpleLift(control, handle);\n\n    expect(isDragging(handle)).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/cleanup.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { isDragging } from '../../util/helpers';\nimport App from '../../util/app';\nimport { forEachSensor, simpleLift, type Control } from '../../util/controls';\n\nfunction getCallCount(myMock): number {\n  return myMock.mock.calls.length;\n}\n\nforEachSensor((control: Control) => {\n  it('should remove all window listeners when unmounting', () => {\n    jest.spyOn(window, 'addEventListener');\n    jest.spyOn(window, 'removeEventListener');\n\n    const { unmount } = render(<App />);\n\n    unmount();\n\n    expect(getCallCount(window.addEventListener)).toEqual(\n      getCallCount(window.removeEventListener),\n    );\n  });\n\n  it('should remove all window listeners when unmounting mid drag', () => {\n    jest.spyOn(window, 'addEventListener');\n    jest.spyOn(window, 'removeEventListener');\n\n    const { unmount, getByText } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    // mid drag\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toEqual(true);\n\n    unmount();\n\n    expect(getCallCount(window.addEventListener)).toEqual(\n      getCallCount(window.removeEventListener),\n    );\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/contenteditable.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\nimport {\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n} from '../../../../../src';\nimport App, { type Item } from '../../util/app';\n\nforEachSensor((control: Control) => {\n  beforeEach(() => {\n    // using content editable in particular ways causes react logging\n    jest.spyOn(console, 'error').mockImplementation(() => {});\n  });\n  afterEach(() => {\n    // $ExpectError - mock\n    console.error.mockRestore();\n  });\n\n  it('should block the drag if the drag handle is itself contenteditable', () => {\n    const renderItem = (item: Item) => (\n      provided: DraggableProvided,\n      snapshot: DraggableStateSnapshot,\n    ) => (\n      <div\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        ref={provided.innerRef}\n        data-is-dragging={snapshot.isDragging}\n        data-testid={item.id}\n        contentEditable\n      />\n    );\n\n    const { getByTestId } = render(<App renderItem={renderItem} />);\n    const handle: HTMLElement = getByTestId('0');\n\n    simpleLift(control, handle);\n\n    expect(isDragging(handle)).toBe(false);\n  });\n\n  it('should block the drag if originated from a child contenteditable', () => {\n    const renderItem = (item: Item) => (\n      provided: DraggableProvided,\n      snapshot: DraggableStateSnapshot,\n    ) => (\n      <div\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        ref={provided.innerRef}\n        data-is-dragging={snapshot.isDragging}\n        data-testid={`handle-${item.id}`}\n      >\n        <div data-testid={`inner-${item.id}`} contentEditable />\n      </div>\n    );\n\n    const { getByTestId } = render(<App renderItem={renderItem} />);\n    const inner: HTMLElement = getByTestId('inner-0');\n    const handle: HTMLElement = getByTestId('handle-0');\n\n    simpleLift(control, inner);\n\n    expect(isDragging(handle)).toBe(false);\n  });\n\n  it('should block the drag if originated from a child of a child contenteditable', () => {\n    const renderItem = (item: Item) => (\n      provided: DraggableProvided,\n      snapshot: DraggableStateSnapshot,\n    ) => (\n      <div\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        ref={provided.innerRef}\n        data-is-dragging={snapshot.isDragging}\n        data-testid={`handle-${item.id}`}\n      >\n        <div contentEditable>\n          <p>hello there</p>\n          <span data-testid={`inner-${item.id}`}>Edit me!</span>\n        </div>\n      </div>\n    );\n\n    const { getByTestId } = render(<App renderItem={renderItem} />);\n    const inner: HTMLElement = getByTestId('inner-0');\n    const handle: HTMLElement = getByTestId('handle-0');\n\n    simpleLift(control, inner);\n\n    expect(isDragging(handle)).toBe(false);\n  });\n\n  it('should not block if contenteditable is set to false', () => {\n    const renderItem = (item: Item) => (\n      provided: DraggableProvided,\n      snapshot: DraggableStateSnapshot,\n    ) => (\n      <div\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        ref={provided.innerRef}\n        data-is-dragging={snapshot.isDragging}\n        data-testid={item.id}\n        contentEditable=\"false\"\n      />\n    );\n\n    const { getByTestId } = render(<App renderItem={renderItem} />);\n    const handle: HTMLElement = getByTestId('0');\n\n    simpleLift(control, handle);\n\n    expect(isDragging(handle)).toBe(true);\n  });\n\n  it('should not block a drag if dragging interactive elements is allowed', () => {\n    const items: Item[] = [{ id: '0', canDragInteractiveElements: true }];\n\n    const renderItem = (item: Item) => (\n      provided: DraggableProvided,\n      snapshot: DraggableStateSnapshot,\n    ) => (\n      <div\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        ref={provided.innerRef}\n        data-is-dragging={snapshot.isDragging}\n        data-testid={item.id}\n        contentEditable\n      />\n    );\n\n    const { getByTestId } = render(\n      <App items={items} renderItem={renderItem} />,\n    );\n    const handle: HTMLElement = getByTestId('0');\n\n    simpleLift(control, handle);\n\n    expect(isDragging(handle)).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/disable-default-sensors.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { isDragging } from '../../util/helpers';\nimport App from '../../util/app';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\n\nforEachSensor((control: Control) => {\n  it('should be able to start a drag if default sensors is disabled', () => {\n    const { getByText } = render(<App enableDefaultSensors={false} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/interactive-elements.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\nimport {\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n} from '../../../../../src';\nimport App, { type Item } from '../../util/app';\nimport { interactiveTagNames } from '../../../../../src/view/use-sensor-marshal/is-event-in-interactive-element';\n\nconst mixedCase = (obj: Object): string[] => [\n  ...Object.keys(obj).map((s) => s.toLowerCase()),\n  ...Object.keys(obj).map((s) => s.toUpperCase()),\n];\n\nconst forEachTagName = (fn: (tagName: string) => void) =>\n  mixedCase(interactiveTagNames).forEach(fn);\n\nforEachSensor((control: Control) => {\n  beforeEach(() => {\n    // react will log a warning if using upper case\n    jest.spyOn(console, 'error').mockImplementation(() => {});\n  });\n  afterEach(() => {\n    // $ExpectError - mock property\n    console.error.mockRestore();\n  });\n\n  it('should not drag if the handle is an interactive element', () => {\n    forEachTagName((tagName: string) => {\n      const renderItem = (item: Item) => (\n        provided: DraggableProvided,\n        snapshot: DraggableStateSnapshot,\n      ) => {\n        const TagName = tagName;\n        return (\n          <TagName\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n            ref={provided.innerRef}\n            data-is-dragging={snapshot.isDragging}\n            data-testid={item.id}\n          />\n        );\n      };\n\n      const { unmount, getByTestId } = render(<App renderItem={renderItem} />);\n      const handle: HTMLElement = getByTestId('0');\n\n      simpleLift(control, handle);\n\n      expect(isDragging(handle)).toBe(false);\n\n      unmount();\n    });\n  });\n\n  it('should allow dragging from an interactive handle if instructed', () => {\n    mixedCase(interactiveTagNames).forEach((tagName: string) => {\n      const items: Item[] = [{ id: '0', canDragInteractiveElements: true }];\n      const renderItem = (item: Item) => (\n        provided: DraggableProvided,\n        snapshot: DraggableStateSnapshot,\n      ) => {\n        const TagName = tagName;\n        return (\n          <TagName\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n            ref={provided.innerRef}\n            data-is-dragging={snapshot.isDragging}\n            data-testid={item.id}\n          />\n        );\n      };\n\n      const { unmount, getByTestId } = render(\n        <App items={items} renderItem={renderItem} />,\n      );\n      const handle: HTMLElement = getByTestId('0');\n\n      simpleLift(control, handle);\n\n      expect(isDragging(handle)).toBe(true);\n\n      unmount();\n    });\n  });\n\n  it('should not start a drag if the parent is interactive', () => {\n    forEachTagName((tagName: string) => {\n      const renderItem = (item: Item) => (\n        provided: DraggableProvided,\n        snapshot: DraggableStateSnapshot,\n      ) => {\n        const TagName = tagName;\n        return (\n          <div\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n            ref={provided.innerRef}\n            data-is-dragging={snapshot.isDragging}\n            data-testid={`handle-${item.id}`}\n          >\n            <TagName data-testid={`inner-${item.id}`} />\n          </div>\n        );\n      };\n\n      const { unmount, getByTestId } = render(<App renderItem={renderItem} />);\n      const inner: HTMLElement = getByTestId('inner-0');\n      const handle: HTMLElement = getByTestId('handle-0');\n\n      simpleLift(control, inner);\n\n      expect(isDragging(handle)).toBe(false);\n\n      unmount();\n    });\n  });\n\n  it('should allow dragging from with an interactive parent if instructed', () => {\n    forEachTagName((tagName: string) => {\n      const items: Item[] = [{ id: '0', canDragInteractiveElements: true }];\n      const renderItem = (item: Item) => (\n        provided: DraggableProvided,\n        snapshot: DraggableStateSnapshot,\n      ) => {\n        const TagName = tagName;\n        return (\n          <div\n            {...provided.draggableProps}\n            {...provided.dragHandleProps}\n            ref={provided.innerRef}\n            data-is-dragging={snapshot.isDragging}\n            data-testid={`handle-${item.id}`}\n          >\n            <TagName data-testid={`inner-${item.id}`} />\n          </div>\n        );\n      };\n\n      const { unmount, getByTestId } = render(\n        <App items={items} renderItem={renderItem} />,\n      );\n      const handle: HTMLElement = getByTestId('handle-0');\n      const inner: HTMLElement = getByTestId('inner-0');\n\n      simpleLift(control, inner);\n\n      expect(isDragging(handle)).toBe(true);\n\n      unmount();\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/lock-released-mid-drag.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport type { SensorAPI, Sensor } from '../../../../../src/types';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\nimport App from '../../util/app';\nimport { invariant } from '../../../../../src/invariant';\n\nforEachSensor((control: Control) => {\n  it('should cleanup a drag if a lock is forceably released mid drag', () => {\n    let api: SensorAPI;\n    const sensor: Sensor = (value: SensorAPI) => {\n      api = value;\n    };\n\n    const { getByText } = render(<App sensors={[sensor]} />);\n    const handle: HTMLElement = getByText('item: 0');\n    invariant(api);\n\n    simpleLift(control, handle);\n\n    expect(api.isLockClaimed()).toBe(true);\n    expect(isDragging(handle)).toBe(true);\n\n    api.tryReleaseLock();\n\n    expect(api.isLockClaimed()).toBe(false);\n    expect(isDragging(handle)).toBe(false);\n\n    // allowing reclaiming after\n    simpleLift(control, handle);\n\n    expect(api.isLockClaimed()).toBe(true);\n    expect(isDragging(handle)).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/lock-released-pre-drag.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport type { SensorAPI, Sensor } from '../../../../../src/types';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\nimport App from '../../util/app';\nimport { invariant } from '../../../../../src/invariant';\n\nforEachSensor((control: Control) => {\n  // keyboard has no pre lift\n  if (control.name === 'keyboard') {\n    return;\n  }\n\n  it('should cleanup a drag if a lock is forceably released mid drag', () => {\n    let api: SensorAPI;\n    const sensor: Sensor = (value: SensorAPI) => {\n      api = value;\n    };\n\n    const { getByText } = render(<App sensors={[sensor]} />);\n    const handle: HTMLElement = getByText('item: 0');\n    invariant(api);\n\n    control.preLift(handle);\n\n    // lock is claimed but not dragging yet\n    expect(api.isLockClaimed()).toBe(true);\n    expect(isDragging(handle)).toBe(false);\n\n    api.tryReleaseLock();\n\n    expect(isDragging(handle)).toBe(false);\n    expect(api.isLockClaimed()).toBe(false);\n\n    // a lift after a released lock can get the lock all good\n    simpleLift(control, handle);\n    expect(api.isLockClaimed()).toBe(true);\n    expect(isDragging(handle)).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/nested-handles.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\nimport Board from '../../util/board';\n\nforEachSensor((control: Control) => {\n  it('should not start a drag on a parent if a child drag handle has already received the event', () => {\n    const { getByTestId } = render(<Board />);\n    const cardHandle: HTMLElement = getByTestId('inhome1');\n    const columnHandle: HTMLElement = getByTestId('home');\n\n    simpleLift(control, cardHandle);\n\n    expect(isDragging(cardHandle)).toBe(true);\n    expect(isDragging(columnHandle)).toBe(false);\n  });\n  it('should start a drag on a pare~nt the event is trigged on the parent', () => {\n    const { getByTestId } = render(<Board />);\n    const cardHandle: HTMLElement = getByTestId('inhome1');\n    const columnHandle: HTMLElement = getByTestId('home');\n\n    simpleLift(control, columnHandle);\n\n    expect(isDragging(columnHandle)).toBe(true);\n    expect(isDragging(cardHandle)).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/no-dragging-svgs.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../../../src/invariant';\nimport { forEachSensor, type Control, simpleLift } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\nimport {\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n} from '../../../../../src';\nimport App, { type Item } from '../../util/app';\nimport { withWarn, withError } from '../../../../util/console';\n\nforEachSensor((control: Control) => {\n  it('should not start a drag from an SVG', () => {\n    const renderItem = (item: Item) => (\n      provided: DraggableProvided,\n      snapshot: DraggableStateSnapshot,\n    ) => (\n      <div\n        {...provided.draggableProps}\n        ref={provided.innerRef}\n        data-is-dragging={snapshot.isDragging}\n        data-testid={`draggable-${item.id}`}\n      >\n        <svg {...provided.dragHandleProps} data-testid={`handle-${item.id}`} />\n      </div>\n    );\n\n    let api;\n    // this is a setup problem: a drag handle cannot be a svg\n    withWarn(() => {\n      withError(() => {\n        api = render(<App renderItem={renderItem} />);\n      });\n    });\n    invariant(api);\n    const draggable = api.getByTestId('draggable-0');\n    const handle = api.getByTestId('handle-0');\n\n    withWarn(() => {\n      simpleLift(control, handle);\n    });\n\n    expect(isDragging(draggable)).toBe(false);\n  });\n\n  it('should allow an SVG within a draggable', () => {\n    const renderItem = (item: Item) => (\n      provided: DraggableProvided,\n      snapshot: DraggableStateSnapshot,\n    ) => (\n      <div\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n        ref={provided.innerRef}\n        data-is-dragging={snapshot.isDragging}\n        data-testid={`draggable-${item.id}`}\n      >\n        <svg data-testid={`svg-${item.id}`} />\n      </div>\n    );\n    const { getByTestId } = render(<App renderItem={renderItem} />);\n    const draggable = getByTestId('draggable-0');\n    const startFrom = getByTestId('svg-0');\n\n    simpleLift(control, startFrom);\n\n    expect(isDragging(draggable)).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/parent-rendering-should-not-kill-drag.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { isDragging } from '../../util/helpers';\nimport App from '../../util/app';\nimport { forEachSensor, simpleLift, type Control } from '../../util/controls';\n\nforEachSensor((control: Control) => {\n  it('should not abort a drag if a parent render occurs', () => {\n    const { getByText, rerender } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(control, handle);\n    expect(isDragging(handle)).toBe(true);\n\n    rerender(<App />);\n\n    // handle element is unchanged\n    expect(getByText('item: 0')).toBe(handle);\n    // it is still dragging\n    expect(isDragging(handle)).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/shared-behaviours/validate-controls.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { isDragging, getDropReason } from '../../util/helpers';\nimport App from '../../util/app';\nimport { forEachSensor, type Control } from '../../util/controls';\n\nforEachSensor((control: Control) => {\n  it('should control a successful drag through the sensor', () => {\n    const onDragStart = jest.fn();\n    const onDragEnd = jest.fn();\n    const { getByText } = render(\n      <App onDragStart={onDragStart} onDragEnd={onDragEnd} />,\n    );\n    const handle: HTMLElement = getByText('item: 0');\n\n    Array.from({ length: 4 }).forEach(() => {\n      control.preLift(handle);\n      expect(isDragging(handle)).toBe(false);\n\n      control.lift(handle);\n      expect(isDragging(handle)).toBe(true);\n\n      // on drag start is async\n      jest.runOnlyPendingTimers();\n      expect(onDragStart).toHaveBeenCalled();\n\n      // move\n      control.move(handle);\n      expect(isDragging(handle)).toBe(true);\n\n      // drop\n      expect(onDragEnd).not.toHaveBeenCalled();\n\n      control.drop(handle);\n      expect(isDragging(handle)).toBe(false);\n\n      expect(onDragEnd).toHaveBeenCalledTimes(1);\n      expect(getDropReason(onDragEnd)).toBe('DROP');\n\n      onDragEnd.mockClear();\n    });\n  });\n\n  it('should control a cancel through the sensor', () => {\n    const onDragStart = jest.fn();\n    const onDragEnd = jest.fn();\n    const { getByText } = render(\n      <App onDragStart={onDragStart} onDragEnd={onDragEnd} />,\n    );\n    const handle: HTMLElement = getByText('item: 0');\n\n    Array.from({ length: 4 }).forEach(() => {\n      control.preLift(handle);\n      expect(isDragging(handle)).toBe(false);\n\n      control.lift(handle);\n      expect(isDragging(handle)).toBe(true);\n\n      // on drag start is async\n      jest.runOnlyPendingTimers();\n      expect(onDragStart).toHaveBeenCalled();\n\n      // move\n      control.move(handle);\n      expect(isDragging(handle)).toBe(true);\n\n      control.cancel(handle);\n\n      expect(isDragging(handle)).toBe(false);\n      expect(onDragEnd).toHaveBeenCalledTimes(1);\n      expect(getDropReason(onDragEnd)).toBe('CANCEL');\n\n      onDragEnd.mockClear();\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/touch-sensor/cancel-while-pending.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport App from '../../util/app';\nimport { isDragging } from '../../util/helpers';\nimport supportedEventName from '../../../../../src/view/use-sensor-marshal/sensors/util/supported-page-visibility-event-name';\nimport { touch } from '../../util/controls';\n\njest.useFakeTimers();\n\nconst events: string[] = [\n  'orientationchange',\n  'keydown',\n  'resize',\n  supportedEventName,\n  // moving before a long press\n  'touchmove',\n];\n\nit(`should cancel a pending drag on events: [${events.join(', ')}]`, () => {\n  events.forEach((eventName: string) => {\n    const { getByText, unmount } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    touch.preLift(handle);\n\n    const event: Event = new Event(eventName, {\n      bubbles: true,\n      cancelable: true,\n    });\n    fireEvent(handle, event);\n\n    // not an explicit cancel - so event not consumed\n    expect(event.defaultPrevented).toBe(false);\n\n    // would normally start\n    touch.lift(handle);\n\n    // drag not started\n    expect(isDragging(handle)).toBe(false);\n\n    unmount();\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/touch-sensor/click-blocking.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { fireEvent, render, createEvent } from '@testing-library/react';\nimport { act } from 'react-dom/test-utils';\nimport App from '../../util/app';\nimport { touch, simpleLift } from '../../util/controls';\n\njest.useFakeTimers();\n\nit('should block a click after a drag', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(touch, handle);\n  act(() => touch.drop(handle));\n\n  const click: Event = createEvent.click(handle);\n  fireEvent(handle, click);\n\n  expect(click.defaultPrevented).toBe(true);\n});\n\nit('should not block a click after an aborted pending drag', () => {\n  const onDragStart = jest.fn();\n  const { getByText } = render(<App onDragStart={onDragStart} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  // aborted before getting to a drag\n  touch.preLift(handle);\n  act(() => touch.cancel(handle));\n\n  const click: Event = createEvent.click(handle);\n  fireEvent(handle, click);\n\n  expect(click.defaultPrevented).toBe(false);\n  expect(onDragStart).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/touch-sensor/context-menu-opt-out.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport App from '../../util/app';\nimport { touch } from '../../util/controls';\nimport { isDragging } from '../../util/helpers';\n\njest.useFakeTimers();\n\nit('should opt of a context menu', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  touch.preLift(handle);\n\n  // prevented during a pending drag\n  const first: Event = new Event('contextmenu', {\n    bubbles: true,\n    cancelable: true,\n  });\n  fireEvent(handle, first);\n  expect(first.defaultPrevented).toBe(true);\n\n  touch.lift(handle);\n\n  // prevented during a drag\n  const second: Event = new Event('contextmenu', {\n    bubbles: true,\n    cancelable: true,\n  });\n  fireEvent(handle, second);\n  expect(second.defaultPrevented).toBe(true);\n\n  expect(isDragging(handle)).toBe(true);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/touch-sensor/force-press.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport App, { type Item } from '../../util/app';\nimport { touch, simpleLift } from '../../util/controls';\nimport { forcePressThreshold } from '../../../../../src/view/use-sensor-marshal/sensors/use-touch-sensor';\nimport { isDragging } from '../../util/helpers';\n\njest.useFakeTimers();\n\nfunction getForceChange(force: number): Event {\n  const event: Event = new Event('touchforcechange', {\n    bubbles: true,\n    cancelable: true,\n  });\n  // $FlowFixMe - being amazing\n  event.touches = [\n    {\n      clientX: 0,\n      clientY: 0,\n      force,\n    },\n  ];\n  return event;\n}\n\n// Note: this behaviour is a bit strange as we are working around a safari issue\n// https://github.com/atlassian/react-beautiful-dnd/issues/1401\ndescribe('force press not respected (default)', () => {\n  it('should not abort presses that do not have enought pressure', () => {\n    const { getByText } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    touch.preLift(handle);\n\n    const first: Event = getForceChange(forcePressThreshold - 1);\n    fireEvent(handle, first);\n    expect(first.defaultPrevented).toBe(false);\n\n    touch.lift(handle);\n\n    const second: Event = getForceChange(forcePressThreshold - 1);\n    fireEvent(handle, second);\n    expect(second.defaultPrevented).toBe(false);\n\n    // force presses did not abort the pending or actual drag\n    expect(isDragging(handle)).toBe(true);\n  });\n\n  it('should not prevent a force press when pending (strange I know)', () => {\n    const { getByText } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    touch.preLift(handle);\n\n    const first: Event = getForceChange(forcePressThreshold);\n    fireEvent(handle, first);\n    expect(first.defaultPrevented).toBe(false);\n\n    touch.lift(handle);\n    // did not prevent lifting\n    expect(isDragging(handle)).toBe(true);\n  });\n\n  it('prevent a force press when dragging', () => {\n    const { getByText } = render(<App />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    touch.preLift(handle);\n\n    const first: Event = getForceChange(forcePressThreshold);\n    fireEvent(handle, first);\n    expect(first.defaultPrevented).toBe(false);\n\n    touch.lift(handle);\n    expect(isDragging(handle)).toBe(true);\n\n    // this force press will be prevented\n    const second: Event = getForceChange(forcePressThreshold);\n    fireEvent(handle, second);\n    expect(second.defaultPrevented).toBe(true);\n\n    // force presses did not abort the drag\n    expect(isDragging(handle)).toBe(true);\n  });\n});\n\ndescribe('force press respected', () => {\n  const items: Item[] = [{ id: '0', shouldRespectForcePress: true }];\n\n  it('should cancel a pending drag if a force press is registered', () => {\n    const { getByText } = render(<App items={items} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    touch.preLift(handle);\n\n    // indirect cancel so event is not consumed\n    const press: Event = getForceChange(forcePressThreshold);\n    fireEvent(handle, press);\n    expect(press.defaultPrevented).toBe(false);\n\n    touch.lift(handle);\n\n    expect(isDragging(handle)).toBe(false);\n  });\n\n  it('should cancel a drag if a force press is registered', () => {\n    const { getByText } = render(<App items={items} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(touch, handle);\n\n    // indirect cancel so event is not consumed\n    const press: Event = getForceChange(forcePressThreshold);\n    fireEvent(handle, press);\n    expect(press.defaultPrevented).toBe(false);\n\n    // drag is no more\n    expect(isDragging(handle)).toBe(false);\n  });\n\n  it('should abort a force press if dragging and some movement has occurred', () => {\n    const { getByText } = render(<App items={items} />);\n    const handle: HTMLElement = getByText('item: 0');\n\n    simpleLift(touch, handle);\n\n    fireEvent.touchMove(handle, { touches: [{ clientX: 0, clientY: 0 }] });\n\n    // consuming event and not cancelling after movement\n    const press: Event = getForceChange(forcePressThreshold);\n    fireEvent(handle, press);\n    expect(press.defaultPrevented).toBe(true);\n\n    expect(isDragging(handle)).toBe(true);\n  });\n});\n\nit('should not listen to force press changes after a drag has started', () => {\n  const withForcePress: Item[] = [{ id: '0', shouldRespectForcePress: true }];\n\n  const { getByText, rerender } = render(<App items={withForcePress} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(touch, handle);\n\n  // changing\n  const withoutForcePress: Item[] = [\n    { id: '0', shouldRespectForcePress: false },\n  ];\n  rerender(<App items={withoutForcePress} />);\n\n  // even though the shouldRespectForcePress value has changed it will still use the original\n  // this is important as during a drag the dragging item can be removed from the registry and we\n  // don't want to look it up\n  fireEvent(handle, getForceChange(forcePressThreshold));\n\n  // drag is no more\n  expect(isDragging(handle)).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/touch-sensor/starting-a-drag.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { createEvent, fireEvent, render } from '@testing-library/react';\nimport App from '../../util/app';\nimport { isDragging } from '../../util/helpers';\nimport { timeForLongPress } from '../../../../../src/view/use-sensor-marshal/sensors/use-touch-sensor';\n\njest.useFakeTimers();\n\nfunction getTouchStart(handle: HTMLElement): Event {\n  return createEvent.touchStart(handle, {\n    touches: [{ clientX: 0, clientY: 0 }],\n  });\n}\n\nit('should start dragging after a long press', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n  const touchStart: Event = getTouchStart(handle);\n\n  fireEvent(handle, touchStart);\n  // not calling event.preventDefault() to allow\n  // as many browser interactions as possible\n  expect(touchStart.defaultPrevented).toBe(false);\n\n  // not dragging yet\n  expect(isDragging(handle)).toBe(false);\n\n  // allow long press to run\n  jest.runOnlyPendingTimers();\n\n  // now dragging\n  expect(isDragging(handle)).toBe(true);\n});\n\nit('should not start dragging if finished before a long press', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n  const touchStart: Event = getTouchStart(handle);\n\n  fireEvent(handle, touchStart);\n  // not calling event.preventDefault() to allow\n  // as many browser interactions as possible\n  expect(touchStart.defaultPrevented).toBe(false);\n\n  // not dragging yet\n  expect(isDragging(handle)).toBe(false);\n\n  // allow long press to run\n  jest.advanceTimersByTime(timeForLongPress - 1);\n\n  // not dragging yet\n  expect(isDragging(handle)).toBe(false);\n\n  const touchEnd: Event = createEvent.touchEnd(handle);\n  fireEvent(handle, touchEnd);\n\n  // not a direct cancel\n  expect(touchEnd.defaultPrevented).toBe(false);\n\n  // flushing any timers\n  jest.runOnlyPendingTimers();\n\n  expect(isDragging(handle)).toBe(false);\n});\n\nit('should allow a false start', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  // a first attempt that is not successful\n  fireEvent(handle, getTouchStart(handle));\n  jest.advanceTimersByTime(timeForLongPress - 1);\n  fireEvent.touchEnd(handle);\n  expect(isDragging(handle)).toBe(false);\n\n  // Let's try again - this time we will wait\n\n  fireEvent(handle, getTouchStart(handle));\n  jest.advanceTimersByTime(timeForLongPress);\n  expect(isDragging(handle)).toBe(true);\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/touch-sensor/stopping-a-drag.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, createEvent, fireEvent } from '@testing-library/react';\nimport App from '../../util/app';\nimport { getDropReason } from '../../util/helpers';\nimport * as keyCodes from '../../../../../src/view/key-codes';\nimport { simpleLift, touch } from '../../util/controls';\nimport supportedEventName from '../../../../../src/view/use-sensor-marshal/sensors/util/supported-page-visibility-event-name';\n\njest.useFakeTimers();\n\nit('should prevent default on the event that causes a drop', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(touch, handle);\n\n  const event: Event = createEvent.touchEnd(handle);\n  fireEvent(handle, event);\n\n  expect(event.defaultPrevented).toBe(true);\n  expect(getDropReason(onDragEnd)).toBe('DROP');\n});\n\nit('should prevent default on an escape press', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(touch, handle);\n\n  const event: Event = createEvent.keyDown(handle, {\n    keyCode: keyCodes.escape,\n  });\n  fireEvent(handle, event);\n\n  expect(event.defaultPrevented).toBe(true);\n  expect(getDropReason(onDragEnd)).toBe('CANCEL');\n});\n\nit('should prevent default on a touchcancel', () => {\n  const onDragEnd = jest.fn();\n  const { getByText } = render(<App onDragEnd={onDragEnd} />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(touch, handle);\n\n  const event: Event = new Event('touchcancel', {\n    bubbles: true,\n    cancelable: true,\n  });\n  fireEvent(handle, event);\n\n  expect(event.defaultPrevented).toBe(true);\n  expect(getDropReason(onDragEnd)).toBe('CANCEL');\n});\n\nit('should not prevent the default behaviour for an indirect cancel', () => {\n  ['orientationchange', 'keydown', 'resize', supportedEventName].forEach(\n    (eventName: string) => {\n      const onDragEnd = jest.fn();\n      const { getByText, unmount } = render(<App onDragEnd={onDragEnd} />);\n      const handle: HTMLElement = getByText('item: 0');\n\n      simpleLift(touch, handle);\n\n      const event: Event = new Event(eventName, {\n        bubbles: true,\n        cancelable: true,\n        target: handle,\n      });\n\n      fireEvent(handle, event);\n\n      // not an explicit cancel\n      expect(event.defaultPrevented).toBe(false);\n      expect(getDropReason(onDragEnd)).toBe('CANCEL');\n\n      unmount();\n    },\n  );\n});\n"
  },
  {
    "path": "test/unit/integration/drag-handle/touch-sensor/unmounted-while-pending-timer-running.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport App from '../../util/app';\nimport { isDragging } from '../../util/helpers';\nimport { touch } from '../../util/controls';\nimport { noop } from '../../../../../src/empty';\n\njest.useFakeTimers();\n\nit('should cancel a pending drag when unmounted', () => {\n  const warn = jest.spyOn(console, 'warn').mockImplementation(noop);\n  const { getByText, unmount } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  touch.preLift(handle);\n\n  unmount();\n\n  // finish lift timer\n  jest.runOnlyPendingTimers();\n\n  expect(warn).not.toHaveBeenCalled();\n  expect(isDragging(handle)).toBe(false);\n  warn.mockRestore();\n});\n"
  },
  {
    "path": "test/unit/integration/draggable/combined-with.spec.js",
    "content": "// @flow\nimport { render } from '@testing-library/react';\nimport React from 'react';\nimport type { DraggableStateSnapshot } from '../../../../src';\nimport App, { type RenderItem } from '../util/app';\nimport expandedMouse from '../util/expanded-mouse';\nimport {\n  isDragging,\n  renderItemAndSpy,\n  withPoorDimensionMocks,\n  isCombining,\n  isCombineTarget,\n  getLast,\n  getSnapshotsFor,\n} from '../util/helpers';\n\nit('should update the snapshot of an item being combined with', () => {\n  withPoorDimensionMocks((preset) => {\n    const spy = jest.fn();\n    const renderItem: RenderItem = renderItemAndSpy(spy);\n    const { getByText } = render(\n      <App renderItem={renderItem} isCombineEnabled />,\n    );\n    const critical: HTMLElement = getByText('item: 0');\n    const after: HTMLElement = getByText('item: 1');\n    const criticalBox = preset.inHome1.client.borderBox;\n    const afterBox = preset.inHome2.client.borderBox;\n\n    expandedMouse.powerLift(critical, criticalBox.center);\n    expect(isDragging(critical)).toBe(true);\n\n    // will now be combining\n    expandedMouse.move(critical, afterBox.center);\n\n    expect(isCombining(critical)).toBe(true);\n    expect(isCombineTarget(after)).toBe(true);\n\n    const snapshot = getLast(getSnapshotsFor('1', spy));\n    const expected: DraggableStateSnapshot = {\n      isDragging: false,\n      isDropAnimating: false,\n      isClone: false,\n      dropAnimation: null,\n      draggingOver: null,\n      combineWith: null,\n      combineTargetFor: '0',\n      mode: null,\n    };\n    expect(snapshot).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/draggable/dragging.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport App, { type RenderItem } from '../util/app';\nimport { type DraggableStateSnapshot } from '../../../../src';\nimport { simpleLift, mouse, keyboard } from '../util/controls';\nimport expandedMouse from '../util/expanded-mouse';\nimport {\n  isDragging,\n  renderItemAndSpy,\n  withPoorDimensionMocks,\n  getSnapshotsFor,\n  getLast,\n} from '../util/helpers';\nimport { transitions, combine } from '../../../../src/animation';\nimport { zIndexOptions } from '../../../../src/view/draggable/get-style';\n\nit('should move to a provided offset', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(mouse, handle);\n  expect(isDragging(handle)).toBe(true);\n\n  // no transform as we are at {x: 0, y: 0}\n  expect(handle.style.transform).toBe('');\n  expect(handle.style.transition).toBe(transitions.fluid);\n  expect(handle.style.zIndex).toBe(`${zIndexOptions.dragging}`);\n\n  mouse.move(handle);\n\n  expect(handle.style.transform).toBe(`translate(0px, 1px)`);\n  expect(handle.style.transition).toBe(transitions.fluid);\n  expect(handle.style.zIndex).toBe(`${zIndexOptions.dragging}`);\n});\n\nit('should pass on the snapshot', () => {\n  const spy = jest.fn();\n  const renderItem: RenderItem = renderItemAndSpy(spy);\n\n  const { getByText } = render(<App renderItem={renderItem} />);\n  const handle: HTMLElement = getByText('item: 0');\n  expect(getSnapshotsFor('0', spy)).toHaveLength(1);\n\n  simpleLift(mouse, handle);\n  expect(isDragging(handle)).toBe(true);\n  expect(getSnapshotsFor('0', spy)).toHaveLength(2);\n\n  {\n    const snapshot = getLast(getSnapshotsFor('0', spy));\n    const lift: DraggableStateSnapshot = {\n      isDragging: true,\n      isDropAnimating: false,\n      isClone: false,\n      dropAnimation: null,\n      draggingOver: 'droppable',\n      combineWith: null,\n      combineTargetFor: null,\n      mode: 'FLUID',\n    };\n    expect(snapshot).toEqual(lift);\n  }\n\n  mouse.move(handle);\n\n  {\n    const snapshot = getLast(getSnapshotsFor('0', spy));\n    const move: DraggableStateSnapshot = {\n      isDragging: true,\n      isDropAnimating: false,\n      isClone: false,\n      dropAnimation: null,\n      // cleared because we are not setting any dimensions and we are\n      // no longer over anything\n      draggingOver: null,\n      combineWith: null,\n      combineTargetFor: null,\n      mode: 'FLUID',\n    };\n    expect(snapshot).toEqual(move);\n  }\n});\n\nit('should animate movements when in snap mode', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(keyboard, handle);\n\n  expect(isDragging(handle)).toBe(true);\n  expect(handle.style.transition).toBe(transitions.snap);\n});\n\nit('should update the snapshot and opacity when combining with another item', () => {\n  withPoorDimensionMocks((preset) => {\n    const spy = jest.fn();\n    const renderItem: RenderItem = renderItemAndSpy(spy);\n    const box1 = preset.inHome1.client.borderBox;\n    const box2 = preset.inHome2.client.borderBox;\n\n    const { getByText } = render(\n      <App renderItem={renderItem} isCombineEnabled />,\n    );\n    const handle: HTMLElement = getByText('item: 0');\n\n    expandedMouse.powerLift(handle, box1.center);\n\n    // this will combine with the second item\n    expandedMouse.move(handle, box2.center);\n\n    const snapshot = getLast(getSnapshotsFor('0', spy));\n\n    const expected: DraggableStateSnapshot = {\n      isDragging: true,\n      isDropAnimating: false,\n      isClone: false,\n      dropAnimation: null,\n      draggingOver: 'droppable',\n      // combining with #1\n      combineWith: '1',\n      combineTargetFor: null,\n      mode: 'FLUID',\n    };\n    expect(snapshot).toEqual(expected);\n    expect(handle.style.opacity).toBe(`${combine.opacity.combining}`);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/draggable/dropping.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { type Position } from 'css-box-model';\nimport App, { type RenderItem } from '../util/app';\nimport {\n  type DraggableStateSnapshot,\n  type DropAnimation,\n} from '../../../../src';\nimport { simpleLift, mouse, getTransitionEnd } from '../util/controls';\nimport expandedMouse from '../util/expanded-mouse';\nimport {\n  isDragging,\n  isDropAnimating,\n  isCombining,\n  renderItemAndSpy,\n  withPoorDimensionMocks,\n  getLast,\n  getSnapshotsFor,\n} from '../util/helpers';\nimport {\n  transitions,\n  timings,\n  curves,\n  combine,\n} from '../../../../src/animation';\nimport { zIndexOptions } from '../../../../src/view/draggable/get-style';\n\nit('should animate a drop to the required offset', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(mouse, handle);\n  expect(isDragging(handle)).toBe(true);\n\n  mouse.move(handle);\n\n  // start a drop\n  fireEvent.mouseUp(handle);\n  expect(isDropAnimating(handle)).toBe(true);\n  expect(handle.style.position).toBe('fixed');\n\n  // moving back to origin so no transform\n  expect(handle.style.transform).toBe('');\n  expect(handle.style.transition).toBe(transitions.drop(timings.minDropTime));\n  expect(handle.style.zIndex).toBe(`${zIndexOptions.dropAnimating}`);\n\n  // completing drop\n  fireEvent(handle, getTransitionEnd());\n  expect(isDropAnimating(handle)).toBe(false);\n  // transition cleared\n  expect(handle.style.transition).toBe('');\n  // position: fixed cleared\n  expect(handle.style.position).toBe('');\n});\n\nit('should provide the correct snapshot to consumers', () => {\n  const spy = jest.fn();\n  const renderItem: RenderItem = renderItemAndSpy(spy);\n\n  const { getByText } = render(<App renderItem={renderItem} />);\n  const handle: HTMLElement = getByText('item: 0');\n  expect(getSnapshotsFor('0', spy)).toHaveLength(1);\n\n  simpleLift(mouse, handle);\n  expect(isDragging(handle)).toBe(true);\n  expect(getSnapshotsFor('0', spy)).toHaveLength(2);\n\n  mouse.move(handle);\n\n  // start a drop\n  fireEvent.mouseUp(handle);\n  expect(isDropAnimating(handle)).toBe(true);\n\n  const snapshot = getLast(getSnapshotsFor('0', spy));\n\n  const dropping: DropAnimation = {\n    duration: timings.minDropTime,\n    curve: curves.drop,\n    moveTo: { x: 0, y: 0 },\n    opacity: null,\n    scale: null,\n  };\n  const expected: DraggableStateSnapshot = {\n    isDragging: true,\n    isDropAnimating: true,\n    isClone: false,\n    dropAnimation: dropping,\n    // due to the movement we are no longer over a droppable due\n    // do not dimensions being set\n    draggingOver: null,\n    combineWith: null,\n    combineTargetFor: null,\n    mode: 'FLUID',\n  };\n  expect(snapshot).toEqual(expected);\n});\n\nit('should animate scale and opacity when combining', () => {\n  withPoorDimensionMocks((preset) => {\n    const spy = jest.fn();\n    const renderItem: RenderItem = renderItemAndSpy(spy);\n    const box0 = preset.inHome1.client.borderBox;\n    const box1 = preset.inHome2.client.borderBox;\n\n    const { getByText } = render(\n      <App renderItem={renderItem} isCombineEnabled />,\n    );\n    const handle: HTMLElement = getByText('item: 0');\n\n    // lift\n    expandedMouse.powerLift(handle, box0.center);\n    expect(isDragging(handle)).toBe(true);\n\n    // move into combine\n    expandedMouse.move(handle, box1.center);\n    expect(isCombining(handle)).toBe(true);\n\n    expandedMouse.startDrop(handle);\n\n    {\n      const snapshot = getLast(getSnapshotsFor('0', spy));\n      const dropping: DropAnimation = {\n        // force cast to number :D\n        duration: ((expect.any(Number): any): number),\n        curve: curves.drop,\n        // will be moving to center\n        moveTo: ((expect.any(Object): any): Position),\n        opacity: 0,\n        scale: combine.scale.drop,\n      };\n      const expected: DraggableStateSnapshot = {\n        isDragging: true,\n        isDropAnimating: true,\n        isClone: false,\n        dropAnimation: dropping,\n        draggingOver: 'droppable',\n        combineWith: '1',\n        combineTargetFor: null,\n        mode: 'FLUID',\n      };\n      expect(snapshot).toEqual(expected);\n      expect(handle.style.opacity).toBe(`${combine.opacity.drop}`);\n      expect(handle.style.transition).toBe(transitions.drop(0.33));\n      expect(handle.style.transform).toEqual(\n        expect.stringContaining(`scale(${combine.scale.drop})`),\n      );\n    }\n\n    expandedMouse.finishDrop(handle);\n\n    {\n      const snapshot = getLast(getSnapshotsFor('0', spy));\n      const expected: DraggableStateSnapshot = {\n        isDragging: false,\n        isDropAnimating: false,\n        isClone: false,\n        dropAnimation: null,\n        draggingOver: null,\n        combineWith: null,\n        combineTargetFor: null,\n        mode: null,\n      };\n      expect(snapshot).toEqual(expected);\n      expect(handle.style.opacity).toBe('');\n      expect(handle.style.transition).toBe('');\n      expect(handle.style.transform).toEqual('');\n    }\n  });\n});\n\nit('should not trigger a drop animation finished if a transitionend occurs that is a non-primary property', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  simpleLift(mouse, handle);\n  expect(isDragging(handle)).toBe(true);\n\n  mouse.move(handle);\n\n  // start a drop\n  fireEvent.mouseUp(handle);\n  expect(isDropAnimating(handle)).toBe(true);\n\n  const event: Event = getTransitionEnd();\n  // $FlowFixMe - unknown property\n  event.propertyName = 'background';\n  fireEvent(handle, event);\n\n  // still drop animating!\n  expect(isDropAnimating(handle)).toBe(true);\n});\n\nit('should not trigger a drop if a transitionend event occurs when not dropping', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  mouse.preLift(handle);\n  fireEvent(handle, getTransitionEnd());\n\n  mouse.lift(handle);\n  fireEvent(handle, getTransitionEnd());\n  expect(isDragging(handle)).toBe(true);\n  expect(isDropAnimating(handle)).toBe(false);\n\n  mouse.move(handle);\n  expect(isDragging(handle)).toBe(true);\n  expect(isDropAnimating(handle)).toBe(false);\n\n  fireEvent.mouseUp(handle);\n  expect(isDragging(handle)).toBe(true);\n  expect(isDropAnimating(handle)).toBe(true);\n\n  fireEvent(handle, getTransitionEnd());\n  expect(isDragging(handle)).toBe(false);\n  expect(isDropAnimating(handle)).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/integration/draggable/moving-out-of-the-way.spec.js",
    "content": "// @flow\nimport { render } from '@testing-library/react';\nimport React from 'react';\nimport App from '../util/app';\nimport expandedMouse from '../util/expanded-mouse';\nimport {\n  isDragging,\n  renderItemAndSpy,\n  withPoorDimensionMocks,\n} from '../util/helpers';\n\nit('should move out of the way when requested', () => {\n  withPoorDimensionMocks((preset) => {\n    const spy = jest.fn();\n    const renderItem = renderItemAndSpy(spy);\n    const { getByText } = render(<App renderItem={renderItem} />);\n    const before: HTMLElement = getByText('item: 0');\n    const critical: HTMLElement = getByText('item: 1');\n    const after: HTMLElement = getByText('item: 2');\n    const criticalBox = preset.inHome2.client.borderBox;\n    const afterBox = preset.inHome3.client.borderBox;\n\n    expandedMouse.powerLift(critical, criticalBox.center);\n    expect(isDragging(critical)).toBe(true);\n\n    // before critical\n    expect(before.style.transform).toBe('');\n\n    // no movement yet so no transform\n    expect(critical.style.transform).toBe('');\n\n    // after critical is moved forward\n    expect(after.style.transform).toBe(\n      `translate(0px, ${preset.inHome2.displaceBy.y}px)`,\n    );\n\n    expandedMouse.move(critical, afterBox.center);\n\n    // still not moved\n    expect(after.style.transform).toBe('');\n\n    // critical has now moved\n    expect(critical.style.transform.startsWith('translate')).toBe(true);\n\n    // after no longer displaced (moved backwards)\n    expect(after.style.transform).toBe('');\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/draggable/portal.spec.js",
    "content": "// @flow\nimport React, { type Node } from 'react';\nimport ReactDOM from 'react-dom';\nimport { render } from '@testing-library/react';\nimport type {\n  DraggableProvided,\n  DraggableStateSnapshot,\n} from '../../../../src';\nimport getBodyElement from '../../../../src/view/get-body-element';\nimport App, { type Item } from '../util/app';\nimport { isDragging } from '../util/helpers';\nimport { simpleLift, mouse } from '../util/controls';\n\nconst portal: HTMLElement = document.createElement('div');\ngetBodyElement().appendChild(portal);\n\nafterAll(() => {\n  getBodyElement().removeChild(portal);\n});\n\nconst renderItem = (item: Item) => (\n  provided: DraggableProvided,\n  snapshot: DraggableStateSnapshot,\n) => {\n  const child: Node = (\n    <div\n      ref={provided.innerRef}\n      {...provided.draggableProps}\n      {...provided.dragHandleProps}\n      data-testid={item.id}\n      data-is-dragging={snapshot.isDragging}\n    >\n      Drag me!\n    </div>\n  );\n\n  if (!snapshot.isDragging) {\n    return child;\n  }\n\n  return ReactDOM.createPortal(child, portal);\n};\n\nit('should allow consumers to use their own portal', () => {\n  const { getByTestId } = render(<App renderItem={renderItem} />);\n  const before: HTMLElement = getByTestId('0');\n\n  // not in portal yet\n  expect(before.parentElement).not.toBe(portal);\n  expect(isDragging(before)).toBe(false);\n\n  // moved to portal after lift\n  simpleLift(mouse, before);\n  const inPortal: HTMLElement = getByTestId('0');\n  expect(inPortal.parentElement).toBe(portal);\n  expect(before).not.toBe(inPortal);\n  expect(isDragging(inPortal)).toBe(true);\n\n  // out of portal after drop\n  mouse.drop(inPortal);\n  const after: HTMLElement = getByTestId('0');\n  expect(after.parentElement).not.toBe(portal);\n  expect(after).not.toBe(inPortal);\n  expect(isDragging(after)).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/integration/draggable/resting.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport App, { type RenderItem, type Item } from '../util/app';\nimport type { DraggableRubric } from '../../../../src';\nimport {\n  renderItemAndSpy,\n  atRest,\n  getSnapshotsFor,\n  getRubricsFor,\n} from '../util/helpers';\n\nit('should have no movement when at rest', () => {\n  const { getByText } = render(<App />);\n  const handle: HTMLElement = getByText('item: 0');\n\n  expect(handle.style.transform).toBe('');\n  expect(handle.style.transition).toBe('');\n  expect(handle.style.zIndex).toBe('');\n});\n\nit('should have a resting snapshot', () => {\n  const snapshotSpy = jest.fn();\n  const renderItem: RenderItem = renderItemAndSpy(snapshotSpy);\n\n  render(<App renderItem={renderItem} />);\n\n  const snapshots = getSnapshotsFor('0', snapshotSpy);\n  expect(snapshots).toHaveLength(1);\n  expect(snapshots[0]).toEqual(atRest);\n});\n\nit('should be provided with its rubric', () => {\n  const watcher = jest.fn();\n  const items = Array.from({ length: 3 }, (v, k): Item => ({\n    id: `${k}`,\n  }));\n  const renderItem: RenderItem = renderItemAndSpy(watcher);\n\n  render(<App renderItem={renderItem} items={items} />);\n\n  items.forEach((item: Item, index: number) => {\n    const expected: DraggableRubric = {\n      draggableId: item.id,\n      type: 'DEFAULT',\n      source: {\n        droppableId: 'droppable',\n        index,\n      },\n    };\n    const rubrics: DraggableRubric[] = getRubricsFor(item.id, watcher);\n\n    expect(rubrics).toHaveLength(1);\n    expect(rubrics[0]).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/draggable/validation.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport {\n  DragDropContext,\n  Droppable,\n  Draggable,\n  type DroppableProvided,\n  type DraggableProvided,\n} from '../../../../src';\nimport { noop } from '../../../../src/empty';\n\nconst error = jest.spyOn(console, 'error').mockImplementation(noop);\nconst warn = jest.spyOn(console, 'warn').mockImplementation(noop);\n\nafterEach(() => {\n  error.mockClear();\n  warn.mockClear();\n});\n\ntype Props = {|\n  draggableId: any,\n  index: any,\n|};\n\nfunction WithCustomProps(props: Props) {\n  return (\n    <DragDropContext onDragEnd={() => {}}>\n      <Droppable droppableId=\"droppable\">\n        {(droppableProvided: DroppableProvided) => (\n          <div\n            ref={droppableProvided.innerRef}\n            {...droppableProvided.droppableProps}\n          >\n            <Draggable draggableId={props.draggableId} index={props.index}>\n              {(provided: DraggableProvided) => (\n                <div\n                  ref={provided.innerRef}\n                  {...provided.draggableProps}\n                  {...provided.dragHandleProps}\n                >\n                  Drag me!\n                </div>\n              )}\n            </Draggable>\n            {droppableProvided.placeholder}\n          </div>\n        )}\n      </Droppable>\n    </DragDropContext>\n  );\n}\n\nit('should log an error if draggableId is not a string', () => {\n  [1, undefined, false, {}].forEach((value: mixed) => {\n    const { unmount } = render(\n      <WithCustomProps draggableId={value} index={0} />,\n    );\n\n    expect(error).toHaveBeenCalled();\n\n    unmount();\n    error.mockClear();\n  });\n});\n\nit('should log an error if index is not an integer', () => {\n  ['1', 1.33, undefined, false, {}].forEach((value: mixed) => {\n    const { unmount } = render(\n      <WithCustomProps draggableId=\"draggable\" index={value} />,\n    );\n\n    expect(error).toHaveBeenCalled();\n\n    unmount();\n    error.mockClear();\n  });\n});\n\nit('should log an error if innerRef is not provided', () => {\n  function App() {\n    return (\n      <DragDropContext onDragEnd={() => {}}>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided: DroppableProvided) => (\n            <div\n              ref={droppableProvided.innerRef}\n              {...droppableProvided.droppableProps}\n            >\n              <Draggable draggableId=\"draggable\" index={0}>\n                {(provided: DraggableProvided) => (\n                  <div\n                    /* not providing a ref */\n                    /* ref={provided.innerRef} */\n                    {...provided.draggableProps}\n                    {...provided.dragHandleProps}\n                  >\n                    Drag me!\n                  </div>\n                )}\n              </Draggable>\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n\n  render(<App />);\n\n  expect(error).toHaveBeenCalled();\n});\n\nit('should log an error if innerRef is an SVG', () => {\n  function App() {\n    return (\n      <DragDropContext onDragEnd={() => {}}>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided: DroppableProvided) => (\n            <div\n              ref={droppableProvided.innerRef}\n              {...droppableProvided.droppableProps}\n            >\n              <Draggable draggableId=\"draggable\" index={0}>\n                {(provided: DraggableProvided) => (\n                  <svg\n                    // $ExpectError - invalid ref type\n                    ref={provided.innerRef}\n                    {...provided.draggableProps}\n                    {...provided.dragHandleProps}\n                  >\n                    Drag me!\n                  </svg>\n                )}\n              </Draggable>\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n\n  render(<App />);\n\n  expect(error).toHaveBeenCalled();\n});\n\nit('should log an error if no drag handle props are applied', () => {\n  function App() {\n    return (\n      <DragDropContext onDragEnd={() => {}}>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided: DroppableProvided) => (\n            <div\n              ref={droppableProvided.innerRef}\n              {...droppableProvided.droppableProps}\n            >\n              <Draggable draggableId=\"draggable\" index={0}>\n                {(provided: DraggableProvided) => (\n                  <div\n                    ref={provided.innerRef}\n                    {...provided.draggableProps}\n                    /* not being applied */\n                    /* {...dragProvided.dragHandleProps} */\n                  >\n                    Drag me!\n                  </div>\n                )}\n              </Draggable>\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n\n  render(<App />);\n\n  expect(error).toHaveBeenCalled();\n});\n\nit('should log an error if the draggable is disabled as there will be no drag handle', () => {\n  function App() {\n    return (\n      <DragDropContext onDragEnd={() => {}}>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided: DroppableProvided) => (\n            <div\n              ref={droppableProvided.innerRef}\n              {...droppableProvided.droppableProps}\n            >\n              <Draggable draggableId=\"draggable\" index={0} isDragDisabled>\n                {(provided: DraggableProvided) => (\n                  <div\n                    ref={provided.innerRef}\n                    {...provided.draggableProps}\n                    {...provided.dragHandleProps}\n                  >\n                    Drag me!\n                  </div>\n                )}\n              </Draggable>\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n\n  error.mockRestore();\n  render(<App />);\n\n  expect(error).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/integration/droppable/clone.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../../src/invariant';\nimport { type DraggableStateSnapshot } from '../../../../src';\nimport { simpleLift, keyboard } from '../util/controls';\nimport expandedMouse from '../util/expanded-mouse';\nimport getBodyElement from '../../../../src/view/get-body-element';\nimport {\n  withPoorDimensionMocks,\n  renderItemAndSpy,\n  isClone,\n  getCallsFor,\n  getLast,\n  type Call,\n  isDragging,\n  isDropAnimating,\n} from '../util/helpers';\nimport App, { type RenderItem } from '../util/app';\nimport { withError } from '../../../util/console';\n\nit('should no longer render the original draggable while dragging', () => {\n  const { getByTestId } = render(<App useClone />);\n\n  // doing this in a loop to ensure that multiple reorders is fine\n  Array.from({ length: 4 }).forEach(() => {\n    const beforeLift = getByTestId('0');\n    simpleLift(keyboard, beforeLift);\n    expect(isClone(beforeLift)).toBe(false);\n\n    // after lift there is still only one item - but it is different\n    const clone = getByTestId('0');\n    expect(clone).not.toBe(beforeLift);\n    expect(isDragging(clone)).toBe(true);\n    expect(isClone(clone)).toBe(true);\n\n    keyboard.drop(clone);\n\n    const finished = getByTestId('0');\n    expect(finished).not.toBe(clone);\n    expect(isClone(finished)).toBe(false);\n    expect(isDragging(finished)).toBe(false);\n  });\n});\n\nit('should render a dragging item into the container', () => {\n  const body = getBodyElement();\n  // default location is the body\n  {\n    const { unmount, getByTestId } = render(<App useClone />);\n    simpleLift(keyboard, getByTestId('0'));\n    expect(getByTestId('0').parentElement).toBe(body);\n    unmount();\n  }\n  {\n    const element: HTMLElement = document.createElement('div');\n    body.appendChild(element);\n    const { unmount, getByTestId } = render(\n      <App useClone getContainerForClone={() => element} />,\n    );\n    simpleLift(keyboard, getByTestId('0'));\n    expect(getByTestId('0').parentElement).toBe(element);\n    unmount();\n  }\n});\n\nit('should give the clone the starting location', () => {\n  const spy = jest.fn();\n  const renderItem: RenderItem = renderItemAndSpy(spy);\n  const { getByTestId } = render(<App renderItem={renderItem} useClone />);\n\n  simpleLift(keyboard, getByTestId('1'));\n\n  const last: ?Call = getLast(getCallsFor('1', spy));\n  invariant(last);\n  const expected: DraggableStateSnapshot = {\n    isClone: true,\n    isDragging: true,\n    isDropAnimating: false,\n    dropAnimation: null,\n    combineTargetFor: null,\n    combineWith: null,\n    draggingOver: 'droppable',\n    mode: 'SNAP',\n  };\n  expect(last[1]).toEqual(expected);\n});\n\n// this test is indirectly validating that a clone does not talk the registry or marshal\nit('should allow reordering other items when dropping', () => {\n  withPoorDimensionMocks((preset) => {\n    const { getByTestId } = render(<App useClone />);\n    const box0 = preset.inHome1.client.borderBox;\n    const box1 = preset.inHome2.client.borderBox;\n\n    expandedMouse.powerLift(getByTestId('0'), box0.center);\n\n    const clone: HTMLElement = getByTestId('0');\n    expect(isClone(clone)).toBe(true);\n    expect(isDragging(clone)).toBe(true);\n\n    // move item 0 to index 1\n    expandedMouse.move(clone, box1.center);\n\n    // drop started, but still occurring\n    expandedMouse.startDrop(clone);\n    expect(isDropAnimating(clone)).toBe(true);\n\n    // starting a new drag with item 1 (which is in index 0 visually now)\n    // using box0.center as the lifting point\n    // we are relying on a sync render from a dispatched action\n    // act(() => {}); is joining the two into one update which is\n    // causing unexpected mounting behaviour\n    withError(() => {\n      expandedMouse.rawPowerLift(getByTestId('1'), box0.center);\n    });\n\n    expect(isDragging(getByTestId('1'))).toBe(true);\n    expect(isDragging(getByTestId('0'))).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/droppable/placeholder.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { invariant } from '../../../../src/invariant';\nimport * as attributes from '../../../../src/view/data-attributes';\nimport type { DroppableId } from '../../../../src/types';\nimport { isOver, isDragging } from '../util/helpers';\nimport expandedMouse from '../util/expanded-mouse';\nimport Board, { withPoorBoardDimensions } from '../util/board';\nimport { toDroppableList } from '../../../../src/state/dimension-structures';\nimport { getTransitionEnd } from '../util/controls';\nimport { withWarn } from '../../../util/console';\n\nfunction findPlaceholder(\n  droppableId: DroppableId,\n  container: HTMLElement,\n): ?HTMLElement {\n  return container.querySelector(\n    `[${attributes.droppable.id}=\"${droppableId}\"] [${attributes.placeholder.contextId}]`,\n  );\n}\n\nfunction getPlaceholder(\n  droppableId: DroppableId,\n  container: HTMLElement,\n): HTMLElement {\n  const droppable: ?HTMLElement = findPlaceholder(droppableId, container);\n  invariant(droppable, 'Unable to find placeholder');\n  return droppable;\n}\n\nfunction hasPlaceholder(\n  droppableId: DroppableId,\n  container: HTMLElement,\n): boolean {\n  return Boolean(findPlaceholder(droppableId, container));\n}\n\nit('should not render a placeholder at rest', () => {\n  withPoorBoardDimensions((preset) => {\n    const { container } = render(<Board />);\n\n    toDroppableList(preset.droppables).forEach((droppable) => {\n      expect(hasPlaceholder(droppable.descriptor.id, container)).toBe(false);\n    });\n  });\n});\n\nit('should render a placeholder when dragging over', () => {\n  withPoorBoardDimensions((preset) => {\n    toDroppableList(preset.droppables).forEach((droppable) => {\n      const { container, getByTestId, unmount } = render(<Board />);\n      const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n      const box0 = preset.inHome1.client.borderBox;\n\n      expandedMouse.powerLift(handle, box0.center);\n      expandedMouse.move(handle, droppable.client.borderBox.center);\n\n      expect(isOver(handle)).toBe(droppable.descriptor.id);\n      expect(hasPlaceholder(droppable.descriptor.id, container)).toBe(true);\n\n      unmount();\n    });\n  });\n});\n\nit('should remove all placeholders if an error occurs while dragging', () => {\n  withPoorBoardDimensions((preset) => {\n    toDroppableList(preset.droppables).forEach((droppable) => {\n      const { container, getByTestId, unmount } = render(<Board />);\n      const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n      const box0 = preset.inHome1.client.borderBox;\n\n      expandedMouse.powerLift(handle, box0.center);\n      expandedMouse.move(handle, droppable.client.borderBox.center);\n\n      expect(isDragging(handle)).toBe(true);\n      expect(isOver(handle)).toBe(droppable.descriptor.id);\n      expect(hasPlaceholder(droppable.descriptor.id, container)).toBe(true);\n\n      withWarn(() => {\n        const event: Event = new Event('error');\n        fireEvent(window, event);\n      });\n\n      expect(isDragging(handle)).toBe(false);\n      expect(hasPlaceholder(droppable.descriptor.id, container)).toBe(false);\n\n      unmount();\n    });\n  });\n});\n\ndescribe('home list', () => {\n  it('should always render a placeholder while dragging', () => {\n    withPoorBoardDimensions((preset) => {\n      toDroppableList(preset.droppables).forEach((droppable) => {\n        const { container, getByTestId, unmount } = render(<Board />);\n        const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n        const box0 = preset.inHome1.client.borderBox;\n\n        expandedMouse.powerLift(handle, box0.center);\n        expandedMouse.move(handle, droppable.client.borderBox.center);\n\n        // doesn't matter what we are over\n        expect(isOver(handle)).toBe(droppable.descriptor.id);\n        // there is always a placeholder in home\n        expect(hasPlaceholder(preset.home.descriptor.id, container)).toBe(true);\n\n        unmount();\n      });\n    });\n  });\n\n  it('should immediately remove the home placeholder after dropping into any list', () => {\n    withPoorBoardDimensions((preset) => {\n      toDroppableList(preset.droppables).forEach((droppable) => {\n        const { container, getByTestId, unmount } = render(<Board />);\n        const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n\n        expandedMouse.powerLift(handle, preset.inHome1.client.borderBox.center);\n        expandedMouse.move(handle, droppable.client.borderBox.center);\n        expect(isOver(handle)).toBe(droppable.descriptor.id);\n\n        expandedMouse.startDrop(handle);\n        expect(hasPlaceholder(droppable.descriptor.id, container)).toBe(true);\n\n        // placeholder removed straight after drop\n        expandedMouse.finishDrop(handle);\n        expect(hasPlaceholder(droppable.descriptor.id, container)).toBe(false);\n\n        unmount();\n      });\n    });\n  });\n\n  it('should immediately remove the home placeholder after dropping nowhere', () => {\n    withPoorBoardDimensions((preset) => {\n      const { container, getByTestId } = render(<Board />);\n      const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n\n      expandedMouse.powerLift(handle, preset.inHome1.client.borderBox.center);\n      expandedMouse.move(handle, { x: 10000, y: 10000 });\n      expect(isOver(handle)).toBe(null);\n\n      // placeholder present when over nothing\n      expect(hasPlaceholder(preset.home.descriptor.id, container)).toBe(true);\n\n      // placeholder present when drop started\n      expandedMouse.startDrop(handle);\n      expect(hasPlaceholder(preset.home.descriptor.id, container)).toBe(true);\n\n      // placeholder gone after drop finished\n      expandedMouse.finishDrop(handle);\n      expect(hasPlaceholder(preset.home.descriptor.id, container)).toBe(false);\n    });\n  });\n\n  it('should animate the home placeholder closed after dropping into a foreign list', () => {\n    withPoorBoardDimensions((preset) => {\n      const { container, getByTestId } = render(<Board />);\n      const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n\n      expandedMouse.powerLift(handle, preset.inHome1.client.borderBox.center);\n      expandedMouse.move(handle, preset.inForeign1.client.borderBox.center);\n      expect(isOver(handle)).toBe(preset.foreign.descriptor.id);\n\n      expandedMouse.startDrop(handle);\n      // foreign placeholder remaining in place\n      expect(hasPlaceholder(preset.foreign.descriptor.id, container)).toBe(\n        true,\n      );\n      // home placeholder remaining in place\n      expect(hasPlaceholder(preset.home.descriptor.id, container)).toBe(true);\n\n      // gone after drop finished\n      expandedMouse.finishDrop(handle);\n\n      // foreign placeholder is now gone\n      expect(hasPlaceholder(preset.foreign.descriptor.id, container)).toBe(\n        false,\n      );\n      // home placeholder is still around and will now animate closed\n      expect(hasPlaceholder(preset.home.descriptor.id, container)).toBe(true);\n\n      // placeholder is now collapsing\n      const placeholder: HTMLElement = getPlaceholder(\n        preset.home.descriptor.id,\n        container,\n      );\n      expect(placeholder.style.height).toBe('0px');\n\n      // faking a transition end\n      fireEvent(placeholder, getTransitionEnd('height'));\n\n      // placeholder is gone\n      expect(hasPlaceholder(preset.home.descriptor.id, container)).toBe(false);\n    });\n  });\n\n  it('should flush a home placeholder collapse animation if starting a new drag', () => {\n    withPoorBoardDimensions((preset) => {\n      const { container, getByTestId } = render(<Board />);\n      {\n        const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n\n        expandedMouse.powerLift(handle, preset.inHome1.client.borderBox.center);\n        expandedMouse.move(handle, preset.inForeign1.client.borderBox.center);\n        expect(isOver(handle)).toBe(preset.foreign.descriptor.id);\n\n        expandedMouse.powerDrop(handle);\n        // placeholder still here + animating closed\n        expect(hasPlaceholder(preset.home.descriptor.id, container)).toBe(true);\n        const placeholder: HTMLElement = getPlaceholder(\n          preset.home.descriptor.id,\n          container,\n        );\n        // animating height closed\n        expect(placeholder.style.height).toBe('0px');\n      }\n      {\n        const handle: HTMLElement = getByTestId(\n          preset.inForeign1.descriptor.id,\n        );\n\n        // using raw power lift as we don't want to combine renders\n        // (we need a render to flush the placeholder out)\n        expandedMouse.rawPowerLift(\n          handle,\n          preset.inForeign1.client.borderBox.center,\n        );\n\n        // placeholder is gone from home (it got flushed)\n        expect(hasPlaceholder(preset.home.descriptor.id, container)).toBe(\n          false,\n        );\n      }\n    });\n  });\n});\n\ndescribe('foreign list', () => {\n  it('should not render a placeholder if not dragging over', () => {\n    withPoorBoardDimensions((preset) => {\n      const { container, getByTestId } = render(<Board />);\n      const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n      const box0 = preset.inHome1.client.borderBox;\n\n      expandedMouse.powerLift(handle, box0.center);\n\n      expect(isOver(handle)).toBe(preset.home.descriptor.id);\n      expect(hasPlaceholder(preset.foreign.descriptor.id, container)).toBe(\n        false,\n      );\n    });\n  });\n\n  it('should animate a placeholder closed when no longer dragging over', () => {\n    withPoorBoardDimensions((preset) => {\n      const { container, getByTestId } = render(<Board />);\n      const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n\n      expandedMouse.powerLift(handle, preset.inHome1.client.borderBox.center);\n      expandedMouse.move(handle, preset.foreign.client.borderBox.center);\n\n      expect(isOver(handle)).toBe(preset.foreign.descriptor.id);\n      expect(hasPlaceholder(preset.foreign.descriptor.id, container)).toBe(\n        true,\n      );\n\n      // moving back over home\n      expandedMouse.move(handle, preset.home.client.borderBox.center);\n      expect(isOver(handle)).toBe(preset.home.descriptor.id);\n\n      // foreign placeholder is now animating closed\n      const placeholder: HTMLElement = getPlaceholder(\n        preset.foreign.descriptor.id,\n        container,\n      );\n      expect(placeholder.style.height).toBe('0px');\n    });\n  });\n\n  it('should flush a foreign list collapsing animation if a new drag starts', () => {\n    withPoorBoardDimensions((preset) => {\n      const { container, getByTestId } = render(<Board />);\n      const handle: HTMLElement = getByTestId(preset.inHome1.descriptor.id);\n\n      expandedMouse.powerLift(handle, preset.inHome1.client.borderBox.center);\n      expandedMouse.move(handle, preset.foreign.client.borderBox.center);\n\n      expect(isOver(handle)).toBe(preset.foreign.descriptor.id);\n      expect(hasPlaceholder(preset.foreign.descriptor.id, container)).toBe(\n        true,\n      );\n\n      // moving back over home\n      expandedMouse.move(handle, preset.home.client.borderBox.center);\n      expect(isOver(handle)).toBe(preset.home.descriptor.id);\n\n      // foreign placeholder is now animating closed\n      const placeholder: HTMLElement = getPlaceholder(\n        preset.foreign.descriptor.id,\n        container,\n      );\n      expect(placeholder.style.height).toBe('0px');\n\n      // starting a drop into home\n      expandedMouse.startDrop(handle);\n      // placeholder still in foreign list\n      expect(hasPlaceholder(preset.foreign.descriptor.id, container)).toBe(\n        true,\n      );\n\n      const second: HTMLElement = getByTestId(preset.inHome2.descriptor.id);\n\n      // lifting item 2 while item 1 is dropping\n      expandedMouse.rawPowerLift(\n        second,\n        preset.inHome2.client.borderBox.center,\n      );\n      expect(isDragging(second)).toBe(true);\n      expect(isOver(second)).toBe(preset.home.descriptor.id);\n      expect(hasPlaceholder(preset.foreign.descriptor.id, container)).toBe(\n        false,\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/reorder-render-sync.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { getRect } from 'css-box-model';\n// import { mount, type ReactWrapper } from 'enzyme';\nimport { render, fireEvent } from '@testing-library/react';\nimport {\n  DragDropContext,\n  Draggable,\n  Droppable,\n  type DropResult,\n} from '../../../src';\nimport { getComputedSpacing } from '../../util/dimension';\nimport * as keyCodes from '../../../src/view/key-codes';\nimport { simpleLift, keyboard } from './util/controls';\nimport type { Provided as DraggableProvided } from '../../../src/view/draggable/draggable-types';\nimport type { Provided as DroppableProvided } from '../../../src/view/droppable/droppable-types';\n\nconst reorder = (list: any[], startIndex: number, endIndex: number): any[] => {\n  // eslint-disable-next-line no-restricted-syntax\n  const result = Array.from(list);\n  const [removed] = result.splice(startIndex, 1);\n  result.splice(endIndex, 0, removed);\n\n  return result;\n};\n\ntype Task = {|\n  id: string,\n  onRender: Function,\n  setRef: Function,\n|};\n\ntype TaskItemProps = {|\n  task: Task,\n  provided: DraggableProvided,\n|};\n\nclass TaskItem extends React.Component<TaskItemProps> {\n  render() {\n    const task: Task = this.props.task;\n    task.onRender();\n    const provided: DraggableProvided = this.props.provided;\n    return (\n      <div\n        data-testid=\"drag-handle\"\n        ref={(ref) => {\n          task.setRef(ref);\n          provided.innerRef(ref);\n        }}\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n      >\n        <h4>{task.id}</h4>\n      </div>\n    );\n  }\n}\n\ntype InnerListProps = {|\n  tasks: Task[],\n|};\n\nclass InnerList extends React.Component<InnerListProps> {\n  shouldComponentUpdate(props: InnerListProps) {\n    if (this.props.tasks === props.tasks) {\n      return false;\n    }\n    return true;\n  }\n  render() {\n    return this.props.tasks.map((task: Task, index: number) => (\n      <Draggable draggableId={task.id} index={index} key={task.id}>\n        {(draggableProvided: DraggableProvided) => (\n          <TaskItem task={task} provided={draggableProvided} />\n        )}\n      </Draggable>\n    ));\n  }\n}\n\n// Stubbing out totally - not including margins in this\njest\n  .spyOn(window, 'getComputedStyle')\n  .mockImplementation(() => getComputedSpacing({}));\n\nconst setDroppableBounds = (ref: ?HTMLElement) => {\n  if (!ref) {\n    return;\n  }\n  // $FlowFixMe - only reliable way to do this\n  ref.getBoundingClientRect = () =>\n    getRect({\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 300,\n    });\n};\ntype State = {|\n  tasks: Task[],\n|};\n\nconst first: Task = {\n  id: 'first',\n  onRender: jest.fn(),\n  setRef: (ref: ?HTMLElement) => {\n    if (!ref) {\n      return;\n    }\n    // $FlowFixMe - only reliable way to do this\n    ref.getBoundingClientRect = () =>\n      getRect({\n        top: 0,\n        left: 0,\n        right: 100,\n        bottom: 20,\n      });\n  },\n};\n\nconst second: Task = {\n  id: 'second',\n  onRender: jest.fn(),\n  setRef: (ref: ?HTMLElement) => {\n    if (!ref) {\n      return;\n    }\n    // $FlowFixMe - only reliable way to do this\n    ref.getBoundingClientRect = () =>\n      getRect({\n        top: 30,\n        left: 0,\n        right: 100,\n        bottom: 50,\n      });\n  },\n};\n\nconst initial: Task[] = [first, second];\n\nclass App extends React.Component<*, State> {\n  state: State = {\n    tasks: initial,\n  };\n\n  onDragEnd = (result: DropResult) => {\n    if (!result.destination) {\n      return;\n    }\n    this.setState({\n      tasks: reorder(\n        this.state.tasks,\n        result.source.index,\n        result.destination.index,\n      ),\n    });\n  };\n\n  render() {\n    return (\n      <DragDropContext onDragEnd={this.onDragEnd}>\n        <Droppable droppableId=\"droppable\">\n          {(droppableProvided: DroppableProvided) => (\n            <div\n              ref={(ref) => {\n                setDroppableBounds(ref);\n                droppableProvided.innerRef(ref);\n              }}\n              {...droppableProvided.droppableProps}\n            >\n              <InnerList tasks={this.state.tasks} />\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n\nit('should call the onBeforeDragStart before connected components are updated, and onDragStart after', () => {\n  jest.useFakeTimers();\n  const clearRenderMocks = () => {\n    first.onRender.mockClear();\n    second.onRender.mockClear();\n  };\n\n  const { getAllByTestId, unmount } = render(<App />);\n\n  // clearing the initial render before a drag\n  expect(first.onRender).toHaveBeenCalledTimes(1);\n  expect(second.onRender).toHaveBeenCalledTimes(1);\n  clearRenderMocks();\n\n  // start a drag\n  const handle: HTMLElement = getAllByTestId('drag-handle')[0];\n  simpleLift(keyboard, handle);\n\n  // flushing onDragStart\n  jest.runOnlyPendingTimers();\n\n  // initial lift will render the first item\n  expect(first.onRender).toHaveBeenCalledTimes(1);\n  // it will also render the second item as it needs to be pushed down\n  expect(second.onRender).toHaveBeenCalledTimes(1);\n  clearRenderMocks();\n\n  fireEvent.keyDown(handle, { keyCode: keyCodes.arrowDown });\n  // flushing keyboard movement\n  requestAnimationFrame.step();\n\n  // item1: moving down\n  // item2: moving up\n  expect(first.onRender).toHaveBeenCalledTimes(1);\n  expect(second.onRender).toHaveBeenCalledTimes(1);\n  clearRenderMocks();\n\n  // drop (there is no animation because already in the home spot)\n  keyboard.drop(handle);\n\n  // only a single render for the reorder and connected component update\n  expect(first.onRender).toHaveBeenCalledTimes(1);\n  expect(second.onRender).toHaveBeenCalledTimes(1);\n\n  // checking for no post renders\n  clearRenderMocks();\n  requestAnimationFrame.flush();\n  jest.runAllTimers();\n  expect(first.onRender).toHaveBeenCalledTimes(0);\n  expect(second.onRender).toHaveBeenCalledTimes(0);\n\n  unmount();\n});\n"
  },
  {
    "path": "test/unit/integration/responders-integration.spec.js",
    "content": "/* eslint-disable jest/expect-expect */\n// @flow\nimport React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { getRect, type Rect } from 'css-box-model';\nimport { invariant } from '../../../src/invariant';\nimport { DragDropContext, Draggable, Droppable } from '../../../src';\nimport { sloppyClickThreshold } from '../../../src/view/use-sensor-marshal/sensors/use-mouse-sensor';\nimport type {\n  Responders,\n  DraggableLocation,\n  DraggableId,\n  DroppableId,\n  DragStart,\n  DropResult,\n  BeforeCapture,\n} from '../../../src/types';\nimport type { Provided as DraggableProvided } from '../../../src/view/draggable/draggable-types';\nimport type { Provided as DroppableProvided } from '../../../src/view/droppable/droppable-types';\nimport { getComputedSpacing } from '../../util/dimension';\nimport tryCleanPrototypeStubs from '../../util/try-clean-prototype-stubs';\nimport { simpleLift, mouse } from './util/controls';\n\nconst draggableId: DraggableId = 'drag-1';\nconst droppableId: DroppableId = 'drop-1';\n\n// both our list and item have the same dimension for now\nconst borderBox: Rect = getRect({\n  top: 0,\n  right: 100,\n  bottom: 100,\n  left: 0,\n});\n\nconst setRefDimensions = (ref: ?HTMLElement) => {\n  if (!ref) {\n    return;\n  }\n\n  jest.spyOn(ref, 'getBoundingClientRect').mockImplementation(() => borderBox);\n\n  // Stubbing out totally - not including margins in this\n  jest\n    .spyOn(window, 'getComputedStyle')\n    .mockImplementation(() => getComputedSpacing({}));\n};\n\ntype Props = {|\n  responders: Responders,\n|};\nfunction App({ responders }: Props) {\n  return (\n    <DragDropContext\n      onBeforeCapture={responders.onBeforeCapture}\n      onBeforeDragStart={responders.onBeforeDragStart}\n      onDragStart={responders.onDragStart}\n      onDragUpdate={responders.onDragUpdate}\n      onDragEnd={responders.onDragEnd}\n    >\n      <Droppable droppableId={droppableId}>\n        {(droppableProvided: DroppableProvided) => (\n          <div\n            ref={(ref: ?HTMLElement) => {\n              setRefDimensions(ref);\n              droppableProvided.innerRef(ref);\n            }}\n            {...droppableProvided.droppableProps}\n          >\n            <h2>Droppable</h2>\n            <Draggable draggableId={draggableId} index={0}>\n              {(draggableProvided: DraggableProvided) => (\n                <div\n                  data-testid=\"drag-handle\"\n                  ref={(ref: ?HTMLElement) => {\n                    setRefDimensions(ref);\n                    draggableProvided.innerRef(ref);\n                  }}\n                  {...draggableProvided.draggableProps}\n                  {...draggableProvided.dragHandleProps}\n                >\n                  <h4>Draggable</h4>\n                </div>\n              )}\n            </Draggable>\n          </div>\n        )}\n      </Droppable>\n    </DragDropContext>\n  );\n}\n\ndescribe('responders integration', () => {\n  let responders: Responders;\n  let wrapper;\n\n  beforeEach(() => {\n    jest.useFakeTimers();\n    responders = {\n      onBeforeCapture: jest.fn(),\n      onBeforeDragStart: jest.fn(),\n      onDragStart: jest.fn(),\n      onDragUpdate: jest.fn(),\n      onDragEnd: jest.fn(),\n    };\n    wrapper = render(<App responders={responders} />);\n    // unmounting during a drag can cause a warning\n    jest.spyOn(console, 'warn').mockImplementation(() => {});\n  });\n\n  afterEach(() => {\n    // clean up any loose events\n    wrapper.unmount();\n    jest.useRealTimers();\n\n    // clean up any stubs\n    tryCleanPrototypeStubs();\n\n    // eslint-disable-next-line no-console\n    // $ExpectError - mock\n    console.warn.mockRestore();\n  });\n\n  const drag = (() => {\n    function getHandle(): HTMLElement {\n      const handle: HTMLElement = wrapper.getByTestId('drag-handle');\n      return handle;\n    }\n\n    const start = () => {\n      simpleLift(mouse, getHandle());\n\n      // drag start responder is scheduled with setTimeout\n      jest.runOnlyPendingTimers();\n    };\n\n    const move = () => {\n      fireEvent.mouseMove(getHandle(), {\n        x: 0,\n        y: sloppyClickThreshold + 2,\n      });\n\n      // movements are scheduled in an animation frame\n      requestAnimationFrame.step();\n      // responder updates are scheduled with setTimeout\n      jest.runOnlyPendingTimers();\n    };\n\n    const stop = () => {\n      mouse.drop(getHandle());\n    };\n\n    const cancel = () => {\n      mouse.cancel(getHandle());\n    };\n\n    const perform = () => {\n      start();\n      move();\n      stop();\n    };\n\n    return { start, move, stop, cancel, perform };\n  })();\n\n  const expected = (() => {\n    const source: DraggableLocation = {\n      droppableId,\n      index: 0,\n    };\n\n    const start: DragStart = {\n      draggableId,\n      type: 'DEFAULT',\n      source,\n      mode: 'FLUID',\n    };\n\n    // Unless we do some more hardcore stubbing\n    // both completed and cancelled look the same.\n    // Ideally we would move one item below another\n    const completed: DropResult = {\n      ...start,\n      // did not move anywhere\n      destination: source,\n      combine: null,\n      reason: 'DROP',\n    };\n\n    const cancelled: DropResult = {\n      ...start,\n      destination: null,\n      combine: null,\n      reason: 'CANCEL',\n    };\n\n    const beforeCapture: BeforeCapture = {\n      draggableId: start.draggableId,\n      mode: 'FLUID',\n    };\n\n    return { beforeCapture, start, completed, cancelled };\n  })();\n\n  const wasOnBeforeCaptureCalled = (\n    amountOfDrags?: number = 1,\n    provided?: Responders = responders,\n  ) => {\n    invariant(provided.onBeforeCapture);\n    expect(provided.onBeforeCapture).toHaveBeenCalledTimes(amountOfDrags);\n    // $ExpectError - mock property\n    expect(provided.onBeforeCapture.mock.calls[amountOfDrags - 1][0]).toEqual(\n      expected.beforeCapture,\n    );\n  };\n\n  const wasOnBeforeDragCalled = (\n    amountOfDrags?: number = 1,\n    provided?: Responders = responders,\n  ) => {\n    invariant(provided.onBeforeDragStart);\n    expect(provided.onBeforeDragStart).toHaveBeenCalledTimes(amountOfDrags);\n    // $ExpectError - mock property\n    expect(provided.onBeforeDragStart.mock.calls[amountOfDrags - 1][0]).toEqual(\n      expected.start,\n    );\n  };\n\n  const wasDragStarted = (\n    amountOfDrags?: number = 1,\n    provided?: Responders = responders,\n  ) => {\n    invariant(\n      provided.onDragStart,\n      'cannot validate if drag was started without onDragStart responder',\n    );\n    expect(provided.onDragStart).toHaveBeenCalledTimes(amountOfDrags);\n    // $ExpectError - mock property\n    expect(provided.onDragStart.mock.calls[amountOfDrags - 1][0]).toEqual(\n      expected.start,\n    );\n  };\n\n  const wasDragCompleted = (\n    amountOfDrags?: number = 1,\n    provided?: Responders = responders,\n  ) => {\n    expect(provided.onDragEnd).toHaveBeenCalledTimes(amountOfDrags);\n    // $ExpectError - mock\n    expect(provided.onDragEnd.mock.calls[amountOfDrags - 1][0]).toEqual(\n      expected.completed,\n    );\n  };\n\n  const wasDragCancelled = (amountOfDrags?: number = 1) => {\n    expect(responders.onDragEnd).toHaveBeenCalledTimes(amountOfDrags);\n    // $ExpectError - mock\n    expect(responders.onDragEnd.mock.calls[amountOfDrags - 1][0]).toEqual(\n      expected.cancelled,\n    );\n  };\n\n  describe('before capture', () => {\n    it('should call the onBeforeDragCapture responder just before the drag starts', () => {\n      drag.start();\n\n      wasOnBeforeCaptureCalled();\n\n      // cleanup\n      drag.stop();\n    });\n  });\n\n  describe('before drag start', () => {\n    it('should call the onBeforeDragStart responder just before the drag starts', () => {\n      drag.start();\n\n      wasOnBeforeDragCalled();\n\n      // cleanup\n      drag.stop();\n    });\n\n    it('should not call onDragStart while the drag is occurring', () => {\n      drag.start();\n\n      wasOnBeforeDragCalled();\n\n      drag.move();\n\n      // should not have called on drag start again\n      expect(responders.onBeforeDragStart).toHaveBeenCalledTimes(1);\n\n      // cleanup\n      drag.stop();\n    });\n  });\n\n  describe('drag start', () => {\n    it('should call the onDragStart responder when a drag starts', () => {\n      drag.start();\n\n      wasDragStarted();\n\n      // cleanup\n      drag.stop();\n    });\n\n    it('should not call onDragStart while the drag is occurring', () => {\n      drag.start();\n\n      wasDragStarted();\n\n      drag.move();\n\n      // should not have called on drag start again\n      expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n\n      // cleanup\n      drag.stop();\n    });\n  });\n\n  describe('drag end', () => {\n    it('should call the onDragEnd responder when a drag ends', () => {\n      drag.perform();\n\n      wasDragCompleted();\n    });\n\n    it('should call the onDragEnd responder when a drag ends when instantly stopped', () => {\n      drag.start();\n      drag.stop();\n\n      wasDragCompleted();\n    });\n  });\n\n  describe('drag cancel', () => {\n    it('should call onDragEnd when a drag is canceled', () => {\n      drag.start();\n      drag.move();\n      drag.cancel();\n\n      wasDragCancelled();\n    });\n\n    it('should call onDragEnd when a drag is canceled instantly', () => {\n      drag.start();\n      drag.cancel();\n\n      wasDragCancelled();\n    });\n  });\n\n  describe('unmounted mid drag', () => {\n    it('should cancel a drag if unmounted mid drag', () => {\n      drag.start();\n\n      wrapper.unmount();\n\n      wasDragCancelled();\n    });\n  });\n\n  describe('subsequent drags', () => {\n    it('should publish subsequent drags', () => {\n      drag.perform();\n      wasDragStarted(1);\n      wasDragCompleted(1);\n\n      drag.perform();\n      wasDragStarted(2);\n      wasDragCompleted(2);\n    });\n\n    it('should publish subsequent drags after a cancel', () => {\n      drag.start();\n      drag.cancel();\n      wasOnBeforeDragCalled(1);\n      wasDragStarted(1);\n      wasDragCancelled(1);\n\n      drag.perform();\n      wasOnBeforeDragCalled(2);\n      wasDragStarted(2);\n      wasDragCompleted(2);\n    });\n  });\n\n  describe('dynamic responders', () => {\n    const setResponders = (provided: Responders) => {\n      wrapper.rerender(<App responders={provided} />);\n    };\n\n    it('should allow you to change responders before a drag started', () => {\n      const newResponders: Responders = {\n        onDragStart: jest.fn(),\n        onDragEnd: jest.fn(),\n      };\n      setResponders(newResponders);\n\n      drag.perform();\n\n      // new responders called\n      wasDragStarted(1, newResponders);\n      wasDragCompleted(1, newResponders);\n      // original responders not called\n      expect(responders.onDragStart).not.toHaveBeenCalled();\n      expect(responders.onDragEnd).not.toHaveBeenCalled();\n    });\n\n    it('should allow you to change onDragEnd during a drag', () => {\n      const newResponders: Responders = {\n        onDragEnd: jest.fn(),\n      };\n\n      drag.start();\n      // changing the onDragEnd responder during a drag\n      setResponders(newResponders);\n      drag.stop();\n\n      wasDragStarted(1, responders);\n      // called the new responder that was changed during a drag\n      wasDragCompleted(1, newResponders);\n      // not calling original responder\n      expect(responders.onDragEnd).not.toHaveBeenCalled();\n    });\n\n    it('should allow you to change responders between drags', () => {\n      const newResponders: Responders = {\n        onDragStart: jest.fn(),\n        onDragEnd: jest.fn(),\n      };\n\n      // first drag\n      drag.perform();\n      wasDragStarted(1, responders);\n      wasDragCompleted(1, responders);\n\n      // second drag\n      setResponders(newResponders);\n      drag.perform();\n\n      // new responders called for second drag\n      wasDragStarted(1, newResponders);\n      wasDragCompleted(1, newResponders);\n      // original responders should not have been called again\n      wasDragStarted(1, responders);\n      wasDragCompleted(1, responders);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/integration/responders-timing.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { getRect } from 'css-box-model';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../src/invariant';\nimport { DragDropContext, Draggable, Droppable } from '../../../src';\nimport { getComputedSpacing } from '../../util/dimension';\nimport type { Provided as DraggableProvided } from '../../../src/view/draggable/draggable-types';\nimport type { Provided as DroppableProvided } from '../../../src/view/droppable/droppable-types';\nimport type { Responders } from '../../../src/types';\nimport { simpleLift, keyboard } from './util/controls';\n\ntype ItemProps = {|\n  provided: DraggableProvided,\n  onRender: Function,\n|};\n\nclass Item extends React.Component<ItemProps> {\n  render() {\n    this.props.onRender();\n    const provided: DraggableProvided = this.props.provided;\n    return (\n      <div\n        data-testid=\"drag-handle\"\n        ref={provided.innerRef}\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n      >\n        <h4>Draggable</h4>\n      </div>\n    );\n  }\n}\n\nbeforeEach(() => {\n  jest.useFakeTimers();\n});\nafterEach(() => {\n  jest.useRealTimers();\n});\n\nit('should call the onBeforeDragStart before connected components are updated, and onDragStart after', () => {\n  let onBeforeDragStartTime: ?DOMHighResTimeStamp = null;\n  let onDragStartTime: ?DOMHighResTimeStamp = null;\n  let renderTime: ?DOMHighResTimeStamp = null;\n  const responders: Responders = {\n    onBeforeDragStart: jest.fn().mockImplementation(() => {\n      invariant(!onBeforeDragStartTime, 'onBeforeDragStartTime already set');\n      onBeforeDragStartTime = performance.now();\n    }),\n    onDragStart: jest.fn().mockImplementation(() => {\n      invariant(!onDragStartTime, 'onDragStartTime already set');\n      onDragStartTime = performance.now();\n    }),\n    onDragEnd: jest.fn(),\n  };\n  const onItemRender = jest.fn().mockImplementation(() => {\n    invariant(!renderTime, 'renderTime already set');\n    renderTime = performance.now();\n  });\n  // Both list and item will have the same dimensions\n  jest\n    .spyOn(Element.prototype, 'getBoundingClientRect')\n    .mockImplementation(() =>\n      getRect({\n        top: 0,\n        left: 0,\n        right: 100,\n        bottom: 100,\n      }),\n    );\n\n  // Stubbing out totally - not including margins in this\n  jest\n    .spyOn(window, 'getComputedStyle')\n    .mockImplementation(() => getComputedSpacing({}));\n  const { getByTestId, unmount } = render(\n    <DragDropContext {...responders}>\n      <Droppable droppableId=\"droppable\">\n        {(droppableProvided: DroppableProvided) => (\n          <div\n            ref={droppableProvided.innerRef}\n            {...droppableProvided.droppableProps}\n          >\n            <h2>Droppable</h2>\n            <Draggable draggableId=\"draggable\" index={0}>\n              {(draggableProvided: DraggableProvided) => (\n                <Item onRender={onItemRender} provided={draggableProvided} />\n              )}\n            </Draggable>\n            {droppableProvided.placeholder}\n          </div>\n        )}\n      </Droppable>\n    </DragDropContext>,\n  );\n\n  // clearing the initial render before a drag\n  expect(onItemRender).toHaveBeenCalledTimes(1);\n  renderTime = null;\n  onItemRender.mockClear();\n\n  // start a drag\n  const handle: HTMLElement = getByTestId('drag-handle');\n  simpleLift(keyboard, handle);\n  // flushing onDragStart\n  jest.runOnlyPendingTimers();\n\n  // checking values are set\n  invariant(onBeforeDragStartTime, 'onBeforeDragStartTime should be set');\n  invariant(onDragStartTime, 'onDragStartTime should be set');\n  invariant(renderTime, 'renderTime should be set');\n\n  // expected order\n  // 1. onBeforeDragStart\n  // 2. item render\n  // 3. onDragStart\n  expect(onBeforeDragStartTime).toBeLessThan(renderTime);\n  expect(renderTime).toBeLessThan(onDragStartTime);\n\n  // validation\n  expect(responders.onBeforeDragStart).toHaveBeenCalledTimes(1);\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n  expect(onItemRender).toHaveBeenCalledTimes(1);\n  unmount();\n});\n"
  },
  {
    "path": "test/unit/integration/server-side-rendering/__snapshots__/server-rendering.spec.js.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`should support rendering to a string 1`] = `\"<main data-reactroot=\\\\\"\\\\\"><div data-rbd-droppable-id=\\\\\"droppable\\\\\" data-rbd-droppable-context-id=\\\\\"0\\\\\"><div data-rbd-draggable-context-id=\\\\\"0\\\\\" data-rbd-draggable-id=\\\\\"0\\\\\" tabindex=\\\\\"0\\\\\" role=\\\\\"button\\\\\" aria-describedby=\\\\\"rbd-hidden-text-0-hidden-text-0\\\\\" data-rbd-drag-handle-draggable-id=\\\\\"0\\\\\" data-rbd-drag-handle-context-id=\\\\\"0\\\\\" draggable=\\\\\"false\\\\\" data-is-dragging=\\\\\"false\\\\\" data-is-drop-animating=\\\\\"false\\\\\" data-is-combining=\\\\\"false\\\\\" data-is-combine-target=\\\\\"false\\\\\" data-is-clone=\\\\\"false\\\\\" data-testid=\\\\\"0\\\\\">item: <!-- -->0</div><div data-rbd-draggable-context-id=\\\\\"0\\\\\" data-rbd-draggable-id=\\\\\"1\\\\\" tabindex=\\\\\"0\\\\\" role=\\\\\"button\\\\\" aria-describedby=\\\\\"rbd-hidden-text-0-hidden-text-0\\\\\" data-rbd-drag-handle-draggable-id=\\\\\"1\\\\\" data-rbd-drag-handle-context-id=\\\\\"0\\\\\" draggable=\\\\\"false\\\\\" data-is-dragging=\\\\\"false\\\\\" data-is-drop-animating=\\\\\"false\\\\\" data-is-combining=\\\\\"false\\\\\" data-is-combine-target=\\\\\"false\\\\\" data-is-clone=\\\\\"false\\\\\" data-testid=\\\\\"1\\\\\">item: <!-- -->1</div><div data-rbd-draggable-context-id=\\\\\"0\\\\\" data-rbd-draggable-id=\\\\\"2\\\\\" tabindex=\\\\\"0\\\\\" role=\\\\\"button\\\\\" aria-describedby=\\\\\"rbd-hidden-text-0-hidden-text-0\\\\\" data-rbd-drag-handle-draggable-id=\\\\\"2\\\\\" data-rbd-drag-handle-context-id=\\\\\"0\\\\\" draggable=\\\\\"false\\\\\" data-is-dragging=\\\\\"false\\\\\" data-is-drop-animating=\\\\\"false\\\\\" data-is-combining=\\\\\"false\\\\\" data-is-combine-target=\\\\\"false\\\\\" data-is-clone=\\\\\"false\\\\\" data-testid=\\\\\"2\\\\\">item: <!-- -->2</div></div></main>\"`;\n\nexports[`should support rendering to static markup 1`] = `\"<main><div data-rbd-droppable-id=\\\\\"droppable\\\\\" data-rbd-droppable-context-id=\\\\\"0\\\\\"><div data-rbd-draggable-context-id=\\\\\"0\\\\\" data-rbd-draggable-id=\\\\\"0\\\\\" tabindex=\\\\\"0\\\\\" role=\\\\\"button\\\\\" aria-describedby=\\\\\"rbd-hidden-text-0-hidden-text-0\\\\\" data-rbd-drag-handle-draggable-id=\\\\\"0\\\\\" data-rbd-drag-handle-context-id=\\\\\"0\\\\\" draggable=\\\\\"false\\\\\" data-is-dragging=\\\\\"false\\\\\" data-is-drop-animating=\\\\\"false\\\\\" data-is-combining=\\\\\"false\\\\\" data-is-combine-target=\\\\\"false\\\\\" data-is-clone=\\\\\"false\\\\\" data-testid=\\\\\"0\\\\\">item: 0</div><div data-rbd-draggable-context-id=\\\\\"0\\\\\" data-rbd-draggable-id=\\\\\"1\\\\\" tabindex=\\\\\"0\\\\\" role=\\\\\"button\\\\\" aria-describedby=\\\\\"rbd-hidden-text-0-hidden-text-0\\\\\" data-rbd-drag-handle-draggable-id=\\\\\"1\\\\\" data-rbd-drag-handle-context-id=\\\\\"0\\\\\" draggable=\\\\\"false\\\\\" data-is-dragging=\\\\\"false\\\\\" data-is-drop-animating=\\\\\"false\\\\\" data-is-combining=\\\\\"false\\\\\" data-is-combine-target=\\\\\"false\\\\\" data-is-clone=\\\\\"false\\\\\" data-testid=\\\\\"1\\\\\">item: 1</div><div data-rbd-draggable-context-id=\\\\\"0\\\\\" data-rbd-draggable-id=\\\\\"2\\\\\" tabindex=\\\\\"0\\\\\" role=\\\\\"button\\\\\" aria-describedby=\\\\\"rbd-hidden-text-0-hidden-text-0\\\\\" data-rbd-drag-handle-draggable-id=\\\\\"2\\\\\" data-rbd-drag-handle-context-id=\\\\\"0\\\\\" draggable=\\\\\"false\\\\\" data-is-dragging=\\\\\"false\\\\\" data-is-drop-animating=\\\\\"false\\\\\" data-is-combining=\\\\\"false\\\\\" data-is-combine-target=\\\\\"false\\\\\" data-is-clone=\\\\\"false\\\\\" data-testid=\\\\\"2\\\\\">item: 2</div></div></main>\"`;\n"
  },
  {
    "path": "test/unit/integration/server-side-rendering/client-hydration.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport ReactDOMServer from 'react-dom/server';\nimport { invariant } from '../../../../src/invariant';\nimport { resetServerContext } from '../../../../src';\nimport App from '../util/app';\nimport { noop } from '../../../../src/empty';\nimport getBodyElement from '../../../../src/view/get-body-element';\n\nbeforeEach(() => {\n  // Reset server context between tests to prevent state being shared between them\n  resetServerContext();\n});\n\n// Checking that the browser globals are available in this test file\ninvariant(\n  typeof window !== 'undefined' && typeof document !== 'undefined',\n  'browser globals not found in jsdom test',\n);\n\nit('should support hydrating a server side rendered application', () => {\n  // would be done server side\n  // we need to mock out the warnings caused by useLayoutEffect\n  // This will not happen on the client as the string is rendered\n  // on the server\n  const error = jest.spyOn(console, 'error').mockImplementation(noop);\n\n  resetServerContext();\n  const serverHTML: string = ReactDOMServer.renderToString(<App />);\n\n  error.mock.calls.forEach((call) => {\n    expect(\n      call[0].includes('Warning: useLayoutEffect does nothing on the server'),\n    ).toBe(true);\n  });\n  error.mockRestore();\n\n  // would be done client side\n  // would have a fresh server context on the client\n  resetServerContext();\n  const el = document.createElement('div');\n  el.innerHTML = serverHTML;\n  getBodyElement().appendChild(el);\n\n  expect(() => ReactDOM.hydrate(<App />, el)).not.toThrow();\n});\n"
  },
  {
    "path": "test/unit/integration/server-side-rendering/server-rendering.spec.js",
    "content": "/**\n * @jest-environment node\n */\n// @flow\nimport React from 'react';\nimport { renderToString, renderToStaticMarkup } from 'react-dom/server';\nimport { invariant } from '../../../../src/invariant';\nimport { resetServerContext } from '../../../../src';\nimport App from '../util/app';\n\nconst consoleFunctions: string[] = ['warn', 'error', 'log'];\n\nbeforeEach(() => {\n  // Reset server context between tests to prevent state being shared between them\n  resetServerContext();\n  consoleFunctions.forEach((name: string) => {\n    jest.spyOn(console, name);\n  });\n});\n\nafterEach(() => {\n  consoleFunctions.forEach((name: string) => {\n    // eslint-disable-next-line no-console\n    console[name].mockRestore();\n  });\n});\n\nconst expectConsoleNotCalled = () => {\n  consoleFunctions.forEach((name: string) => {\n    // eslint-disable-next-line no-console\n    expect(console[name]).not.toHaveBeenCalled();\n  });\n};\n\n// Checking that the browser globals are not available in this test file\ninvariant(\n  typeof window === 'undefined' && typeof document === 'undefined',\n  'browser globals found in node test',\n);\n\nit('should support rendering to a string', () => {\n  const result: string = renderToString(<App />);\n\n  expect(result).toEqual(expect.any(String));\n  expect(result).toMatchSnapshot();\n  expectConsoleNotCalled();\n});\n\nit('should support rendering to static markup', () => {\n  const result: string = renderToStaticMarkup(<App />);\n\n  expect(result).toEqual(expect.any(String));\n  expect(result).toMatchSnapshot();\n  expectConsoleNotCalled();\n});\n\nit('should render identical content when resetting context between renders', () => {\n  const firstRender = renderToString(<App />);\n  const nextRenderBeforeReset = renderToString(<App />);\n  expect(firstRender).not.toEqual(nextRenderBeforeReset);\n\n  resetServerContext();\n  const nextRenderAfterReset = renderToString(<App />);\n  expect(firstRender).toEqual(nextRenderAfterReset);\n  expectConsoleNotCalled();\n});\n"
  },
  {
    "path": "test/unit/integration/util/app.jsx",
    "content": "// @flow\nimport React, { useState, type Node } from 'react';\nimport {\n  DragDropContext,\n  Droppable,\n  Draggable,\n  type DroppableProvided,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type Sensor,\n  type Direction,\n  type DraggableRubric,\n  type DropResult,\n} from '../../../../src';\nimport reorder from '../../../util/reorder';\nimport { noop } from '../../../../src/empty';\n\nexport type Item = {|\n  id: string,\n  // defaults to true\n  isEnabled?: boolean,\n  // defaults to false\n  canDragInteractiveElements?: boolean,\n  // defaults to false\n  shouldRespectForcePress?: boolean,\n|};\n\nexport type RenderItem = (\n  item: Item,\n) => (\n  provided: DraggableProvided,\n  snapshot: DraggableStateSnapshot,\n  rubric: DraggableRubric,\n) => Node;\n\nexport const defaultItemRender: RenderItem = (item: Item) => (\n  provided: DraggableProvided,\n  snapshot: DraggableStateSnapshot,\n) => (\n  <div\n    {...provided.draggableProps}\n    {...provided.dragHandleProps}\n    data-is-dragging={snapshot.isDragging}\n    data-is-drop-animating={snapshot.isDropAnimating}\n    data-is-combining={Boolean(snapshot.combineWith)}\n    data-is-combine-target={Boolean(snapshot.combineTargetFor)}\n    data-is-over={snapshot.draggingOver}\n    data-is-clone={snapshot.isClone}\n    data-testid={item.id}\n    ref={provided.innerRef}\n  >\n    item: {item.id}\n  </div>\n);\n\ntype Props = {|\n  onBeforeCapture?: Function,\n  onBeforeDragStart?: Function,\n  onDragStart?: Function,\n  onDragUpdate?: Function,\n  onDragEnd?: Function,\n  items?: Item[],\n  anotherChild?: Node,\n  renderItem?: RenderItem,\n\n  // droppable\n  direction?: Direction,\n  isCombineEnabled?: boolean,\n  getContainerForClone?: () => HTMLElement,\n  useClone?: boolean,\n\n  sensors?: Sensor[],\n  enableDefaultSensors?: boolean,\n|};\n\nfunction getItems() {\n  return Array.from({ length: 3 }, (v, k): Item => ({\n    id: `${k}`,\n  }));\n}\n\nfunction withDefaultBool(value: ?boolean, defaultValue: boolean) {\n  if (typeof value === 'boolean') {\n    return value;\n  }\n  return defaultValue;\n}\n\nexport default function App(props: Props) {\n  const [items, setItems] = useState(() => props.items || getItems());\n  const onBeforeCapture = props.onBeforeCapture || noop;\n  const onBeforeDragStart = props.onBeforeDragStart || noop;\n  const onDragStart = props.onDragStart || noop;\n  const onDragUpdate = props.onDragUpdate || noop;\n  const onDragEndProp = props.onDragEnd;\n\n  const onDragEnd = (result: DropResult) => {\n    if (result.destination) {\n      const reordered: Item[] = reorder(\n        items,\n        result.source.index,\n        result.destination.index,\n      );\n      setItems(reordered);\n    }\n\n    if (onDragEndProp) {\n      onDragEndProp(result);\n    }\n  };\n\n  const sensors: Sensor[] = props.sensors || [];\n  const render: RenderItem = props.renderItem || defaultItemRender;\n  const direction: Direction = props.direction || 'vertical';\n  const isCombineEnabled: boolean = withDefaultBool(\n    props.isCombineEnabled,\n    false,\n  );\n  const renderClone = (() => {\n    const useClone: boolean = withDefaultBool(props.useClone, false);\n    if (!useClone) {\n      return null;\n    }\n\n    return function result(\n      provided: DraggableProvided,\n      snapshot: DraggableStateSnapshot,\n      rubric: DraggableRubric,\n    ): Node {\n      const item: Item = items[rubric.source.index];\n      return render(item)(provided, snapshot, rubric);\n    };\n  })();\n\n  return (\n    <main>\n      <DragDropContext\n        onBeforeCapture={onBeforeCapture}\n        onBeforeDragStart={onBeforeDragStart}\n        onDragStart={onDragStart}\n        onDragUpdate={onDragUpdate}\n        onDragEnd={onDragEnd}\n        sensors={sensors}\n        enableDefaultSensors={props.enableDefaultSensors}\n      >\n        <Droppable\n          droppableId=\"droppable\"\n          direction={direction}\n          isCombineEnabled={isCombineEnabled}\n          renderClone={renderClone}\n          getContainerForClone={props.getContainerForClone}\n        >\n          {(droppableProvided: DroppableProvided) => (\n            <div\n              {...droppableProvided.droppableProps}\n              ref={droppableProvided.innerRef}\n            >\n              {items.map((item: Item, index: number) => (\n                <Draggable\n                  key={item.id}\n                  draggableId={item.id}\n                  index={index}\n                  isDragDisabled={item.isEnabled === false}\n                  disableInteractiveElementBlocking={withDefaultBool(\n                    item.canDragInteractiveElements,\n                    false,\n                  )}\n                  shouldRespectForcePress={withDefaultBool(\n                    item.shouldRespectForcePress,\n                    false,\n                  )}\n                >\n                  {render(item)}\n                </Draggable>\n              ))}\n              {droppableProvided.placeholder}\n            </div>\n          )}\n        </Droppable>\n        {props.anotherChild || null}\n      </DragDropContext>\n    </main>\n  );\n}\n"
  },
  {
    "path": "test/unit/integration/util/board.jsx",
    "content": "// @flow\nimport React from 'react';\nimport type { BoxModel } from 'css-box-model';\nimport { invariant } from '../../../../src/invariant';\nimport * as attributes from '../../../../src/view/data-attributes';\nimport {\n  DragDropContext,\n  Droppable,\n  Draggable,\n  type DroppableProvided,\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n} from '../../../../src';\nimport type {\n  DroppableDescriptor,\n  DraggableDescriptor,\n  DraggableId,\n  DroppableId,\n} from '../../../../src/types';\nimport { noop } from '../../../../src/empty';\nimport { getComputedSpacing, getPreset } from '../../../util/dimension';\nimport { toDroppableList } from '../../../../src/state/dimension-structures';\nimport getDraggablesInsideDroppable from '../../../../src/state/get-draggables-inside-droppable';\n\nconst preset = getPreset();\n\ntype CardProps = {|\n  index: number,\n  descriptor: DraggableDescriptor,\n|};\n\nfunction Card(props: CardProps) {\n  return (\n    <Draggable draggableId={props.descriptor.id} index={props.index}>\n      {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n        <div\n          {...provided.draggableProps}\n          {...provided.dragHandleProps}\n          ref={provided.innerRef}\n          data-testid={props.descriptor.id}\n          data-is-dragging={snapshot.isDragging}\n          data-is-over={snapshot.draggingOver}\n        />\n      )}\n    </Draggable>\n  );\n}\n\ntype ColumnProps = {|\n  index: number,\n  descriptor: DroppableDescriptor,\n|};\n\nfunction Column(props: ColumnProps) {\n  return (\n    <Draggable draggableId={props.descriptor.id} index={props.index}>\n      {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (\n        <div\n          {...provided.draggableProps}\n          {...provided.dragHandleProps}\n          ref={provided.innerRef}\n          data-testid={props.descriptor.id}\n          data-is-dragging={snapshot.isDragging}\n        >\n          <Droppable\n            droppableId={props.descriptor.id}\n            type={props.descriptor.type}\n          >\n            {(droppableProvided: DroppableProvided) => (\n              <div\n                {...droppableProvided.droppableProps}\n                ref={droppableProvided.innerRef}\n              >\n                {getDraggablesInsideDroppable(\n                  props.descriptor.id,\n                  preset.draggables,\n                ).map((draggable, index) => (\n                  <Card\n                    key={draggable.descriptor.id}\n                    descriptor={draggable.descriptor}\n                    index={index}\n                  />\n                ))}\n                {droppableProvided.placeholder}\n              </div>\n            )}\n          </Droppable>\n        </div>\n      )}\n    </Draggable>\n  );\n}\n\nexport default function Board() {\n  return (\n    <DragDropContext onDragEnd={noop}>\n      <Droppable droppableId=\"BOARD\" type=\"BOARD\" direction=\"horizontal\">\n        {(provided: DroppableProvided) => (\n          <div {...provided.droppableProps} ref={provided.innerRef}>\n            {toDroppableList(preset.droppables).map((droppable, index) => (\n              <Column\n                key={droppable.descriptor.id}\n                descriptor={droppable.descriptor}\n                index={index}\n              />\n            ))}\n            {provided.placeholder}\n          </div>\n        )}\n      </Droppable>\n    </DragDropContext>\n  );\n}\n\nexport function withPoorBoardDimensions(fn: (typeof preset) => void): void {\n  const protoSpy = jest\n    .spyOn(Element.prototype, 'getBoundingClientRect')\n    .mockImplementation(function fake() {\n      invariant(\n        this instanceof HTMLElement,\n        'Expected \"this\" to be a HTMLElement',\n      );\n\n      const el: HTMLElement = ((this: any): HTMLElement);\n\n      const droppableId: ?DroppableId = el.getAttribute(\n        attributes.droppable.id,\n      );\n      if (droppableId) {\n        return preset.droppables[droppableId].client.borderBox;\n      }\n\n      const draggableId: ?DraggableId = el.getAttribute(\n        attributes.draggable.id,\n      );\n      invariant(draggableId, 'Expected element to be a draggable');\n\n      return preset.draggables[draggableId].client.borderBox;\n    });\n\n  // Stubbing out totally - not including margins in this\n  const styleSpy = jest\n    .spyOn(window, 'getComputedStyle')\n    .mockImplementation(function fake(el: HTMLElement) {\n      function getSpacing(box: BoxModel) {\n        return getComputedSpacing({\n          margin: box.margin,\n          padding: box.padding,\n          border: box.border,\n        });\n      }\n\n      const droppableId: ?DroppableId = el.getAttribute(\n        attributes.droppable.id,\n      );\n\n      if (droppableId) {\n        if (droppableId === 'BOARD') {\n          return getComputedSpacing({});\n        }\n\n        return getSpacing(preset.droppables[droppableId].client);\n      }\n\n      const draggableId: ?DraggableId = el.getAttribute(\n        attributes.draggable.id,\n      );\n\n      // this can be the case when looking up the tree for a scroll container\n      if (!draggableId) {\n        return getComputedSpacing({});\n      }\n\n      if (preset.draggables[draggableId]) {\n        return getSpacing(preset.draggables[draggableId].client);\n      }\n\n      // columns are also draggables for our example\n      if (preset.droppables[draggableId]) {\n        return getSpacing(preset.droppables[draggableId].client);\n      }\n\n      throw new Error(`Unable to find spacing for draggable: ${draggableId}`);\n    });\n\n  try {\n    fn(preset);\n  } finally {\n    protoSpy.mockRestore();\n    styleSpy.mockRestore();\n  }\n}\n"
  },
  {
    "path": "test/unit/integration/util/controls.js",
    "content": "// @flow\nimport { fireEvent, act } from '@testing-library/react';\nimport { sloppyClickThreshold } from '../../../../src/view/use-sensor-marshal/sensors/use-mouse-sensor';\nimport { timeForLongPress } from '../../../../src/view/use-sensor-marshal/sensors/use-touch-sensor';\nimport * as keyCodes from '../../../../src/view/key-codes';\n\nexport type Control = {|\n  name: string,\n  preLift: (handle: HTMLElement) => void,\n  lift: (handle: HTMLElement) => void,\n  move: (handle: HTMLElement) => void,\n  drop: (handle: HTMLElement) => void,\n  cancel: (handle: HTMLElement) => void,\n|};\n\nexport function simpleLift(control: Control, handle: HTMLElement) {\n  control.preLift(handle);\n  control.lift(handle);\n}\n\nexport function getTransitionEnd(propertyName?: string = 'transform'): Event {\n  const event: Event = new Event('transitionend', {\n    bubbles: true,\n    cancelable: true,\n  });\n  // cheating and adding property to event as TransitionEvent constructor does not exist\n  // $ExpectError - being amazing\n  event.propertyName = propertyName;\n  return event;\n}\nexport const mouse: Control = {\n  name: 'mouse',\n  preLift: (handle: HTMLElement) => {\n    fireEvent.mouseDown(handle);\n  },\n  lift: (handle: HTMLElement) => {\n    fireEvent.mouseMove(handle, { clientX: 0, clientY: sloppyClickThreshold });\n  },\n  move: (handle: HTMLElement) => {\n    fireEvent.mouseMove(handle, {\n      clientX: 0,\n      clientY: sloppyClickThreshold + 1,\n    });\n    // movements are throttled by raf\n    act(() => {\n      requestAnimationFrame.step();\n    });\n  },\n  drop: (handle: HTMLElement) => {\n    fireEvent.mouseUp(handle);\n    fireEvent(handle, getTransitionEnd());\n  },\n  cancel: (handle: HTMLElement) => {\n    fireEvent.keyDown(handle, { keyCode: keyCodes.escape });\n    fireEvent(handle, getTransitionEnd());\n  },\n};\n\nexport const keyboard: Control = {\n  name: 'keyboard',\n  preLift: () => {},\n  lift: (handle: HTMLElement) => {\n    fireEvent.keyDown(handle, { keyCode: keyCodes.space });\n  },\n  move: (handle: HTMLElement) => {\n    fireEvent.keyDown(handle, {\n      keyCode: keyCodes.arrowDown,\n    });\n  },\n  drop: (handle: HTMLElement) => {\n    fireEvent.keyDown(handle, { keyCode: keyCodes.space });\n    // no drop animation\n  },\n  cancel: (handle: HTMLElement) => {\n    fireEvent.keyDown(handle, { keyCode: keyCodes.escape });\n  },\n};\n\nexport const touch: Control = {\n  name: 'touch',\n  preLift: (handle: HTMLElement) => {\n    fireEvent.touchStart(handle, { touches: [{ clientX: 0, clientY: 0 }] });\n  },\n  lift: () => {\n    act(() => {\n      jest.runTimersToTime(timeForLongPress);\n    });\n  },\n  move: (handle: HTMLElement) => {\n    fireEvent.touchMove(handle, {\n      touches: [{ clientX: 0, clientY: 1 }],\n    });\n    act(() => {\n      // movements are throttled by raf\n      requestAnimationFrame.step();\n    });\n  },\n  drop: (handle: HTMLElement) => {\n    fireEvent.touchEnd(handle);\n    // allow for drop animation\n    fireEvent(handle, getTransitionEnd());\n  },\n  cancel: (handle: HTMLElement) => {\n    fireEvent.keyDown(handle, { keyCode: keyCodes.escape });\n    fireEvent(handle, getTransitionEnd());\n  },\n};\n\nexport const controls: Control[] = [mouse, keyboard, touch];\n\nexport const forEachSensor = (tests: (control: Control) => void) => {\n  controls.forEach((control: Control) => {\n    describe(`with: ${control.name}`, () => {\n      beforeEach(() => {\n        jest.useFakeTimers();\n      });\n      afterEach(() => {\n        jest.clearAllTimers();\n        jest.useRealTimers();\n      });\n\n      tests(control);\n    });\n  });\n};\n"
  },
  {
    "path": "test/unit/integration/util/expanded-mouse.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { fireEvent, act } from '@testing-library/react';\nimport { mouse, getTransitionEnd } from './controls';\nimport { sloppyClickThreshold } from '../../../../src/view/use-sensor-marshal/sensors/use-mouse-sensor';\n\n// Not a 'control'. A little more extensible\nconst expandedMouse = {\n  name: 'mouse',\n  powerLift: (handle: HTMLElement, point: Position) => {\n    fireEvent.mouseDown(handle, { clientX: point.x, clientY: point.y });\n    fireEvent.mouseMove(handle, {\n      clientX: point.x,\n      clientY: point.y + sloppyClickThreshold,\n    });\n  },\n  // no batching of events with .act by testing libray\n  rawPowerLift: (handle: HTMLElement, point: Position) => {\n    const mousedown: MouseEvent = new MouseEvent('mousedown', {\n      bubbles: true,\n      cancelable: true,\n      clientX: point.x,\n      clientY: point.y,\n    });\n\n    handle.dispatchEvent(mousedown);\n\n    const mousemove: MouseEvent = new MouseEvent('mousemove', {\n      bubbles: true,\n      cancelable: true,\n      clientX: point.x,\n      clientY: point.y + sloppyClickThreshold,\n    });\n\n    handle.dispatchEvent(mousemove);\n  },\n  move: (handle: HTMLElement, point: Position) => {\n    fireEvent.mouseMove(handle, { clientX: point.x, clientY: point.y });\n    // movements are throttled by raf\n    act(() => {\n      requestAnimationFrame.step();\n    });\n  },\n  startDrop: (handle: HTMLElement) => {\n    fireEvent.mouseUp(handle);\n  },\n  finishDrop: (handle: HTMLElement) => {\n    fireEvent(handle, getTransitionEnd());\n  },\n  powerDrop: (handle: HTMLElement) => {\n    mouse.drop(handle);\n  },\n  cancel: (handle: HTMLElement) => {\n    mouse.cancel(handle);\n  },\n};\n\nexport default expandedMouse;\n"
  },
  {
    "path": "test/unit/integration/util/helpers.js",
    "content": "// @flow\nimport type { Position, BoxModel } from 'css-box-model';\nimport { invariant } from '../../../../src/invariant';\nimport type { DropReason } from '../../../../src/types';\nimport * as attributes from '../../../../src/view/data-attributes';\nimport { defaultItemRender, type RenderItem, type Item } from './app';\nimport {\n  type DraggableProvided,\n  type DraggableStateSnapshot,\n  type DraggableRubric,\n  type DraggableId,\n} from '../../../../src';\nimport { getComputedSpacing, getPreset } from '../../../util/dimension';\n\nexport function getOffset(el: HTMLElement): Position {\n  const style: CSSStyleDeclaration = el.style;\n\n  const transform: string = style.transform;\n  if (!transform) {\n    return { x: 0, y: 0 };\n  }\n\n  const regex: RegExp = /translate\\((\\d+)px, (\\d+)px\\)/;\n\n  const result = transform.match(regex);\n  invariant(result, `Unable to formate translate: ${transform}`);\n\n  return {\n    x: Number(result[1]),\n    y: Number(result[2]),\n  };\n}\n\nexport function getDropReason(onDragEnd: JestMockFn<*, *>): DropReason {\n  const calls = onDragEnd.mock.calls;\n\n  invariant(calls.length, 'There has been no calls to onDragEnd');\n\n  return calls[0][0].reason;\n}\nexport function isDragging(el: HTMLElement): boolean {\n  return el.getAttribute('data-is-dragging') === 'true';\n}\n\nexport function isDropAnimating(el: HTMLElement): boolean {\n  return el.getAttribute('data-is-drop-animating') === 'true';\n}\n\nexport function isCombining(el: HTMLElement): boolean {\n  return el.getAttribute('data-is-combining') === 'true';\n}\n\nexport function isCombineTarget(el: HTMLElement): boolean {\n  return el.getAttribute('data-is-combine-target') === 'true';\n}\n\nexport function isClone(el: HTMLElement): boolean {\n  return el.getAttribute('data-is-clone') === 'true';\n}\n\nexport function isOver(el: HTMLElement): ?string {\n  const value: ?string = el.getAttribute('data-is-over');\n  return value || null;\n}\n\nconst preset = getPreset();\n\nexport const renderItemAndSpy = (mock: JestMockFn<*, *>): RenderItem => (\n  item: Item,\n) => {\n  const render = defaultItemRender(item);\n  return (\n    provided: DraggableProvided,\n    snapshot: DraggableStateSnapshot,\n    rubric: DraggableRubric,\n  ) => {\n    mock(provided, snapshot, rubric);\n    return render(provided, snapshot, rubric);\n  };\n};\n\nexport type Call = [DraggableProvided, DraggableStateSnapshot, DraggableRubric];\n\nexport const getCallsFor = (\n  id: DraggableId,\n  mock: JestMockFn<*, *>,\n): Call[] => {\n  return mock.mock.calls.filter((call) => {\n    const provided: DraggableProvided = call[0];\n    return provided.draggableProps['data-rbd-draggable-id'] === id;\n  });\n};\n\nexport const getProvidedFor = (\n  id: DraggableId,\n  mock: JestMockFn<*, *>,\n): DraggableProvided[] => {\n  return getCallsFor(id, mock).map((call) => {\n    return call[0];\n  });\n};\n\nexport const getSnapshotsFor = (\n  id: DraggableId,\n  mock: JestMockFn<*, *>,\n): DraggableStateSnapshot[] => {\n  return getCallsFor(id, mock).map((call) => {\n    return call[1];\n  });\n};\n\nexport const getRubricsFor = (\n  id: DraggableId,\n  mock: JestMockFn<*, *>,\n): DraggableRubric[] => {\n  return getCallsFor(id, mock).map((call) => {\n    return call[2];\n  });\n};\n\nexport function getLast<T>(values: T[]): ?T {\n  return values[values.length - 1] || null;\n}\n\nconst dimensions = {\n  '0': preset.inHome1,\n  '1': preset.inHome2,\n  '2': preset.inHome3,\n  '3': preset.inHome4,\n};\n\nexport const withPoorDimensionMocks = (fn: (typeof preset) => void): void => {\n  // lists and all items will have the same dimensions\n  // This is so that when we move we are combining\n  const protoSpy = jest\n    .spyOn(Element.prototype, 'getBoundingClientRect')\n    .mockImplementation(function fake() {\n      invariant(\n        this instanceof HTMLElement,\n        'Expected \"this\" to be a HTMLElement',\n      );\n\n      const el: HTMLElement = ((this: any): HTMLElement);\n\n      if (el.getAttribute(attributes.droppable.id)) {\n        return preset.home.client.borderBox;\n      }\n\n      const id: ?DraggableId = el.getAttribute(attributes.draggable.id);\n      invariant(id, 'Expected element to be a draggable');\n\n      return dimensions[id].client.borderBox;\n    });\n\n  // Stubbing out totally - not including margins in this\n  const styleSpy = jest\n    .spyOn(window, 'getComputedStyle')\n    .mockImplementation(function fake(el: HTMLElement) {\n      function getSpacing(box: BoxModel) {\n        return getComputedSpacing({\n          margin: box.margin,\n          padding: box.padding,\n          border: box.border,\n        });\n      }\n\n      if (el.getAttribute(attributes.droppable.id)) {\n        return getSpacing(preset.home.client);\n      }\n\n      const id: ?DraggableId = el.getAttribute(attributes.draggable.id);\n\n      // this can happen when we search up the DOM for scroll containers\n      if (!id) {\n        return getComputedSpacing({});\n      }\n\n      return getSpacing(dimensions[id].client);\n    });\n\n  try {\n    fn(preset);\n  } finally {\n    protoSpy.mockRestore();\n    styleSpy.mockRestore();\n  }\n};\n\nexport const atRest: DraggableStateSnapshot = {\n  isClone: false,\n  isDragging: false,\n  isDropAnimating: false,\n  dropAnimation: null,\n  draggingOver: null,\n  combineWith: null,\n  combineTargetFor: null,\n  mode: null,\n};\n"
  },
  {
    "path": "test/unit/state/auto-scroll/can-scroll.spec.js",
    "content": "// @flow\nimport { getRect, type Position } from 'css-box-model';\nimport type { DroppableDimension, Viewport } from '../../../../src/types';\nimport {\n  canPartiallyScroll,\n  getOverlap,\n  getWindowOverlap,\n  getDroppableOverlap,\n  canScrollWindow,\n  canScrollDroppable,\n} from '../../../../src/state/auto-scroller/can-scroll';\nimport { add, subtract } from '../../../../src/state/position';\nimport {\n  getPreset,\n  getDroppableDimension,\n  getFrame,\n} from '../../../util/dimension';\nimport scrollDroppable from '../../../../src/state/droppable/scroll-droppable';\nimport { createViewport } from '../../../util/viewport';\nimport getMaxScroll from '../../../../src/state/get-max-scroll';\n\nconst origin: Position = { x: 0, y: 0 };\nconst preset = getPreset();\n\nconst scrollableScrollSize = {\n  scrollWidth: 200,\n  scrollHeight: 200,\n};\n\nconst scrollable: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'drop-1',\n    type: 'TYPE',\n    mode: 'standard',\n  },\n  borderBox: {\n    top: 0,\n    left: 0,\n    right: 100,\n    // bigger than the frame\n    bottom: 200,\n  },\n  closest: {\n    borderBox: {\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 100,\n    },\n    scrollSize: {\n      scrollWidth: scrollableScrollSize.scrollWidth,\n      scrollHeight: scrollableScrollSize.scrollHeight,\n    },\n    scroll: { x: 0, y: 0 },\n    shouldClipSubject: true,\n  },\n});\n\nconst customViewport: Viewport = createViewport({\n  frame: getRect({\n    top: 0,\n    left: 0,\n    right: 100,\n    bottom: 100,\n  }),\n  scroll: origin,\n  scrollHeight: 100,\n  scrollWidth: 100,\n});\n\ndescribe('can partially scroll', () => {\n  it('should return true if not scrolling anywhere', () => {\n    const result: boolean = canPartiallyScroll({\n      max: { x: 100, y: 100 },\n      current: { x: 0, y: 0 },\n      // not\n      change: origin,\n    });\n\n    expect(result).toBe(true);\n  });\n\n  it('should return true if scrolling to a boundary', () => {\n    const current: Position = origin;\n    const max: Position = { x: 100, y: 200 };\n\n    const corners: Position[] = [\n      // top left\n      { x: 0, y: 0 },\n      // top right\n      { x: max.x, y: 0 },\n      // bottom right\n      { x: max.x, y: max.y },\n      // bottom left\n      { x: 0, y: max.y },\n    ];\n\n    corners.forEach((corner: Position) => {\n      const result: boolean = canPartiallyScroll({\n        max,\n        current,\n        change: corner,\n      });\n\n      expect(result).toBe(true);\n    });\n  });\n\n  it('should return true if moving in any direction within the allowable scroll region', () => {\n    const max: Position = { x: 100, y: 100 };\n    const current: Position = { x: 50, y: 50 };\n\n    // all of these movements are totally possible\n    const changes: Position[] = [\n      // top left\n      { x: -10, y: 10 },\n      // top right\n      { x: 10, y: 10 },\n      // bottom right\n      { x: 10, y: -10 },\n      // bottom left\n      { x: -10, y: -10 },\n    ];\n\n    changes.forEach((point: Position) => {\n      const result: boolean = canPartiallyScroll({\n        max,\n        current,\n        change: point,\n      });\n\n      expect(result).toBe(true);\n    });\n  });\n\n  it('should return true if able to partially move in both directions', () => {\n    const max: Position = { x: 100, y: 100 };\n    const current: Position = { x: 50, y: 50 };\n\n    // all of these movements are partially possible\n    const changes: Position[] = [\n      // top left\n      { x: -200, y: 200 },\n      // top right\n      { x: 200, y: 200 },\n      // bottom right\n      { x: 200, y: -200 },\n      // bottom left\n      { x: -200, y: -200 },\n    ];\n\n    changes.forEach((point: Position) => {\n      const result: boolean = canPartiallyScroll({\n        max,\n        current,\n        change: point,\n      });\n\n      expect(result).toBe(true);\n    });\n  });\n\n  type Item = {|\n    current: Position,\n    change: Position,\n  |};\n\n  it('should return true if can only partially move in one direction', () => {\n    const max: Position = { x: 100, y: 200 };\n\n    const changes: Item[] = [\n      // Can move back in the y direction, but not back in the x direction\n      {\n        current: { x: 0, y: 1 },\n        change: { x: -1, y: -1 },\n      },\n      // Can move back in the x direction, but not back in the y direction\n      {\n        current: { x: 1, y: 0 },\n        change: { x: -1, y: -1 },\n      },\n      // Can move forward in the y direction, but not forward in the x direction\n      {\n        current: subtract(max, { x: 0, y: 1 }),\n        change: { x: 1, y: 1 },\n      },\n      // Can move forward in the x direction, but not forward in the y direction\n      {\n        current: subtract(max, { x: 1, y: 0 }),\n        change: { x: 1, y: 1 },\n      },\n    ];\n\n    changes.forEach((item: Item) => {\n      const result: boolean = canPartiallyScroll({\n        max,\n        current: item.current,\n        change: item.change,\n      });\n\n      expect(result).toBe(true);\n    });\n  });\n\n  it('should return false if on the min point and move backward in any direction', () => {\n    const current: Position = origin;\n    const max: Position = { x: 100, y: 200 };\n    const tooFarBack: Position[] = [\n      { x: 0, y: -1 },\n      { x: -1, y: 0 },\n    ];\n\n    tooFarBack.forEach((point: Position) => {\n      const result: boolean = canPartiallyScroll({\n        max,\n        current,\n        change: point,\n      });\n\n      expect(result).toBe(false);\n    });\n  });\n\n  it('should return false if on the max point and move forward in any direction', () => {\n    const max: Position = { x: 100, y: 200 };\n    const current: Position = max;\n    const tooFarForward: Position[] = [\n      add(max, { x: 0, y: 1 }),\n      add(max, { x: 1, y: 0 }),\n    ];\n\n    tooFarForward.forEach((point: Position) => {\n      const result: boolean = canPartiallyScroll({\n        max,\n        current,\n        change: point,\n      });\n\n      expect(result).toBe(false);\n    });\n  });\n\n  // It is possible in certain situations for the max scroll to exceed the current scroll.\n  // In this case we allow the movement backwards even though it is still above the max scroll point\n  it('should return true if moving backwards and the current scroll is greater than the max scroll', () => {\n    const max: Position = { x: 100, y: 200 };\n    const current: Position = { x: 110, y: 220 };\n    // Small changes that would still result in a current scroll greater than the max scroll\n    const backwards: Position[] = [\n      { x: -1, y: 0 },\n      { x: 0, y: -1 },\n    ];\n\n    backwards.forEach((change: Position) => {\n      const result: boolean = canPartiallyScroll({\n        current,\n        max,\n        change,\n      });\n\n      expect(result).toBe(true);\n    });\n  });\n\n  it('should return false if moving forwards and the current scroll is greater than the max scroll', () => {\n    const max: Position = { x: 100, y: 200 };\n    const current: Position = { x: 110, y: 220 };\n    const forwards: Position[] = [\n      { x: 1, y: 0 },\n      { x: 0, y: 1 },\n    ];\n\n    forwards.forEach((change: Position) => {\n      const result: boolean = canPartiallyScroll({\n        current,\n        max,\n        change,\n      });\n\n      expect(result).toBe(false);\n    });\n  });\n});\n\ndescribe('get overlap', () => {\n  describe('returning the remainder', () => {\n    const max: Position = { x: 100, y: 100 };\n    const current: Position = { x: 50, y: 50 };\n\n    type Item = {|\n      change: Position,\n      expected: Position,\n    |};\n\n    it('should return overlap on a single axis', () => {\n      const items: Item[] = [\n        // too far back: top\n        {\n          change: { x: 0, y: -70 },\n          expected: { x: 0, y: -20 },\n        },\n        // too far back: left\n        {\n          change: { x: -70, y: 0 },\n          expected: { x: -20, y: 0 },\n        },\n        // too far forward: right\n        {\n          change: { x: 70, y: 0 },\n          expected: { x: 20, y: 0 },\n        },\n        // too far forward: bottom\n        {\n          change: { x: 0, y: 70 },\n          expected: { x: 0, y: 20 },\n        },\n      ];\n\n      items.forEach((item: Item) => {\n        const result: ?Position = getOverlap({\n          current,\n          max,\n          change: item.change,\n        });\n\n        expect(result).toEqual(item.expected);\n      });\n    });\n\n    it('should return overlap on two axis in the same direction', () => {\n      const items: Item[] = [\n        // too far back: top\n        {\n          change: { x: -80, y: -70 },\n          expected: { x: -30, y: -20 },\n        },\n        // too far back: left\n        {\n          change: { x: -70, y: -80 },\n          expected: { x: -20, y: -30 },\n        },\n        // too far forward: right\n        {\n          change: { x: 70, y: 0 },\n          expected: { x: 20, y: 0 },\n        },\n        // too far forward: bottom\n        {\n          change: { x: 80, y: 70 },\n          expected: { x: 30, y: 20 },\n        },\n      ];\n\n      items.forEach((item: Item) => {\n        const result: ?Position = getOverlap({\n          current,\n          max,\n          change: item.change,\n        });\n\n        expect(result).toEqual(item.expected);\n      });\n    });\n\n    it('should return overlap on two axis in different directions', () => {\n      const items: Item[] = [\n        // too far back: vertical\n        // too far forward: horizontal\n        {\n          change: { x: 80, y: -70 },\n          expected: { x: 30, y: -20 },\n        },\n        // too far back: horizontal\n        // too far forward: vertical\n        {\n          change: { x: -70, y: 80 },\n          expected: { x: -20, y: 30 },\n        },\n      ];\n\n      items.forEach((item: Item) => {\n        const result: ?Position = getOverlap({\n          current,\n          max,\n          change: item.change,\n        });\n\n        expect(result).toEqual(item.expected);\n      });\n    });\n\n    it('should trim values that can be scrolled', () => {\n      const items: Item[] = [\n        // too far back: top\n        {\n          // x can be scrolled entirely\n          // y can be partially scrolled\n          change: { x: -20, y: -70 },\n          expected: { x: 0, y: -20 },\n        },\n        // too far back: left\n        {\n          // x can be partially scrolled\n          // y can be scrolled entirely\n          change: { x: -70, y: -40 },\n          expected: { x: -20, y: 0 },\n        },\n        // too far forward: right\n        {\n          // x can be partially scrolled\n          // y can be scrolled entirely\n          change: { x: 70, y: 40 },\n          expected: { x: 20, y: 0 },\n        },\n        // too far forward: bottom\n        {\n          // x can be scrolled entirely\n          // y can be partially scrolled\n          change: { x: 20, y: 70 },\n          expected: { x: 0, y: 20 },\n        },\n      ];\n\n      items.forEach((item: Item) => {\n        const result: ?Position = getOverlap({\n          current,\n          max,\n          change: item.change,\n        });\n\n        expect(result).toEqual(item.expected);\n      });\n    });\n  });\n});\n\ndescribe('can scroll droppable', () => {\n  it('should return false if the droppable is not scrollable', () => {\n    const result: boolean = canScrollDroppable(preset.home, { x: 1, y: 1 });\n\n    expect(result).toBe(false);\n  });\n\n  it('should return true if the droppable is able to be scrolled', () => {\n    const result: boolean = canScrollDroppable(scrollable, { x: 0, y: 20 });\n\n    expect(result).toBe(true);\n  });\n\n  it('should return false if the droppable is not able to be scrolled', () => {\n    const result: boolean = canScrollDroppable(scrollable, { x: -1, y: 0 });\n\n    expect(result).toBe(false);\n  });\n});\n\ndescribe('can scroll window', () => {\n  it('should return true if the window is able to be scrolled', () => {\n    const viewport: Viewport = createViewport({\n      frame: customViewport.frame,\n      scrollHeight: 200,\n      scrollWidth: 100,\n      scroll: origin,\n    });\n\n    const result: boolean = canScrollWindow(viewport, { x: 0, y: 50 });\n\n    expect(result).toBe(true);\n  });\n\n  it('should return false if the window is not able to be scrolled', () => {\n    const viewport: Viewport = createViewport({\n      frame: customViewport.frame,\n      scrollHeight: 200,\n      scrollWidth: 100,\n      // already at the max scroll\n      scroll: {\n        x: 0,\n        y: 200,\n      },\n    });\n\n    const result: boolean = canScrollWindow(viewport, { x: 0, y: 1 });\n\n    expect(result).toBe(false);\n  });\n});\n\ndescribe('get droppable overlap', () => {\n  it('should return null if there is no scroll container', () => {\n    const result: ?Position = getDroppableOverlap(preset.home, {\n      x: 1,\n      y: 1,\n    });\n\n    expect(result).toBe(null);\n  });\n\n  it('should return null if the droppable cannot be scrolled', () => {\n    // end of the scrollable area\n    const scroll: Position = {\n      x: 0,\n      y: 200,\n    };\n    const scrolled: DroppableDimension = scrollDroppable(scrollable, scroll);\n    const result: ?Position = getDroppableOverlap(scrolled, { x: 0, y: 1 });\n\n    expect(result).toBe(null);\n  });\n\n  // tested in get remainder\n  it('should return the overlap', () => {\n    // how far the droppable has already\n    const scroll: Position = {\n      x: 10,\n      y: 20,\n    };\n    const scrolled: DroppableDimension = scrollDroppable(scrollable, scroll);\n    const max: Position = getFrame(scrolled).scroll.max;\n    const totalSpace: Position = {\n      x: scrollableScrollSize.scrollWidth - max.x,\n      y: scrollableScrollSize.scrollHeight - max.y,\n    };\n    const remainingSpace = subtract(totalSpace, scroll);\n    const change: Position = { x: 300, y: 300 };\n    const expectedOverlap: Position = subtract(change, remainingSpace);\n\n    const result: ?Position = getDroppableOverlap(scrolled, change);\n\n    expect(result).toEqual(expectedOverlap);\n  });\n\n  it('should return null if there is no overlap', () => {\n    const change: Position = { x: 0, y: 1 };\n\n    const result: ?Position = getDroppableOverlap(scrollable, change);\n\n    expect(result).toEqual(null);\n\n    // verifying correctness of test\n    expect(canScrollDroppable(scrollable, change)).toBe(true);\n  });\n});\n\ndescribe('get window overlap', () => {\n  it('should return null if the window cannot be scrolled', () => {\n    const viewport: Viewport = createViewport({\n      frame: customViewport.frame,\n      scrollHeight: 200,\n      scrollWidth: 100,\n      // already at the max scroll\n      scroll: {\n        x: 0,\n        y: 200,\n      },\n    });\n\n    const result: ?Position = getWindowOverlap(viewport, { x: 0, y: 1 });\n\n    expect(result).toBe(null);\n  });\n\n  // tested in get remainder\n  it('should return the overlap', () => {\n    const viewport: Viewport = createViewport({\n      frame: customViewport.frame,\n      scrollHeight: 200,\n      scrollWidth: 200,\n      scroll: {\n        x: 50,\n        y: 50,\n      },\n    });\n\n    // little validation\n    const maxScroll: Position = getMaxScroll({\n      scrollHeight: 200,\n      scrollWidth: 200,\n      height: viewport.frame.height,\n      width: viewport.frame.width,\n    });\n    expect(maxScroll).toEqual({ x: 100, y: 100 });\n\n    const availableScrollSpace: Position = {\n      x: 50,\n      y: 50,\n    };\n    // cannot be absorbed in the current scroll plane\n    const bigChange: Position = { x: 300, y: 300 };\n    const expectedOverlap: Position = subtract(bigChange, availableScrollSpace);\n\n    const result: ?Position = getWindowOverlap(viewport, bigChange);\n\n    expect(result).toEqual(expectedOverlap);\n  });\n\n  it('should return null if there is no overlap', () => {\n    const viewport: Viewport = createViewport({\n      frame: customViewport.frame,\n      scrollHeight: 200,\n      scrollWidth: 200,\n      scroll: origin,\n    });\n\n    const result: ?Position = getWindowOverlap(viewport, { x: 10, y: 10 });\n\n    expect(result).toBe(null);\n  });\n});\n"
  },
  {
    "path": "test/unit/state/auto-scroll/choosing-the-right-scroller.spec.js",
    "content": "// @flow\nimport { getRect, type Position } from 'css-box-model';\nimport type {\n  DraggingState,\n  Viewport,\n  MovementMode,\n} from '../../../../src/types';\nimport { createViewport } from '../../../util/viewport';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport getScroller, { type Args } from '../../../../src/state/auto-scroller';\nimport type { AutoScroller } from '../../../../src/state/auto-scroller/auto-scroller-types';\nimport { origin } from '../../../../src/state/position';\n\nconst state = getStatePreset();\n\nconst getMocks = (): Args => ({\n  scrollDroppable: jest.fn(),\n  scrollWindow: jest.fn(),\n  move: jest.fn(),\n});\n\nconst windowScrollSize = {\n  scrollHeight: 2000,\n  scrollWidth: 1600,\n};\nconst scrollableViewport: Viewport = createViewport({\n  frame: getRect({\n    top: 0,\n    left: 0,\n    right: 800,\n    bottom: 1000,\n  }),\n  scrollHeight: windowScrollSize.scrollHeight,\n  scrollWidth: windowScrollSize.scrollWidth,\n  scroll: origin,\n});\n\nconst onCenter = (mode: MovementMode): DraggingState => ({\n  ...state.dragging(\n    state.preset.inHome1.descriptor.id,\n    scrollableViewport.frame.center,\n    scrollableViewport,\n  ),\n  movementMode: mode,\n});\n\nconst onEnd = (mode: MovementMode): DraggingState => ({\n  ...state.dragging(\n    state.preset.inHome1.descriptor.id,\n    {\n      x: scrollableViewport.frame.right,\n      y: scrollableViewport.frame.bottom,\n    },\n    scrollableViewport,\n  ),\n  movementMode: mode,\n});\n\nit('should use the fluid scroller when in fluid mode', () => {\n  const mocks: Args = getMocks();\n  const scroller: AutoScroller = getScroller(mocks);\n\n  // lift in center - should not cause an auto scroll\n  scroller.start(onCenter('FLUID'));\n  requestAnimationFrame.flush();\n  expect(mocks.scrollWindow).not.toHaveBeenCalled();\n\n  // now scrolling on visibile edge. Should cause a big auto scroll\n  // this will be done with the fluid scroller\n  scroller.scroll(onEnd('FLUID'));\n  requestAnimationFrame.step();\n  expect(mocks.scrollWindow).toHaveBeenCalled();\n});\n\nit('should use the jump scroller when in SNAP mode and there is a jumpScrollerRequest', () => {\n  const mocks: Args = getMocks();\n  const scroller: AutoScroller = getScroller(mocks);\n\n  // lift in center - should not cause an auto scroll\n  scroller.start(onCenter('SNAP'));\n  requestAnimationFrame.flush();\n  expect(mocks.scrollWindow).not.toHaveBeenCalled();\n\n  // now scrolling on visibile edge. Should not cause an auto scroll because we are in SNAP mode\n  scroller.scroll(onEnd('SNAP'));\n  requestAnimationFrame.step();\n  expect(mocks.scrollWindow).not.toHaveBeenCalled();\n\n  const request: Position = { x: 1, y: 1 };\n  const withRequest: DraggingState = state.scrollJumpRequest(\n    request,\n    scrollableViewport,\n  );\n  scroller.scroll(withRequest);\n  requestAnimationFrame.step();\n  expect(mocks.scrollWindow).toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/big-draggables.spec.js",
    "content": "// @flow\nimport type { Position, Spacing } from 'css-box-model';\nimport forEach, { type BlockFnArgs } from './util/for-each';\nimport type {\n  DraggableDimension,\n  DraggingState,\n} from '../../../../../src/types';\nimport { scrollableViewport, unscrollableViewport } from './util/viewport';\nimport getDroppable from './util/get-droppable';\nimport dragTo from './util/drag-to';\nimport getScroller, {\n  type PublicArgs,\n  type FluidScroller,\n} from '../../../../../src/state/auto-scroller/fluid-scroller';\nimport getDistanceThresholds, {\n  type DistanceThresholds,\n} from '../../../../../src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-distance-thresholds';\nimport { patch } from '../../../../../src/state/position';\nimport getArgsMock from './util/get-args-mock';\nimport { vertical, horizontal } from '../../../../../src/state/axis';\nimport { expandByPosition } from '../../../../../src/state/spacing';\nimport {\n  getDraggableDimension,\n  addDraggable,\n} from '../../../../util/dimension';\n\nforEach(({ axis, state, preset }: BlockFnArgs) => {\n  describe('window', () => {\n    const thresholds: DistanceThresholds = getDistanceThresholds(\n      scrollableViewport.frame,\n      axis,\n    );\n    const crossAxisThresholds: DistanceThresholds = getDistanceThresholds(\n      scrollableViewport.frame,\n      axis === vertical ? horizontal : vertical,\n    );\n    const onMaxBoundaryOfBoth: Position = patch(\n      axis.line,\n      scrollableViewport.frame[axis.size] - thresholds.maxScrollValueAt,\n      scrollableViewport.frame[axis.crossAxisSize] -\n        crossAxisThresholds.maxScrollValueAt,\n    );\n\n    it('should allow scrolling on the cross axis if too big on the main axis', () => {\n      const mocks: PublicArgs = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const biggerOnMainAxis: Spacing = expandByPosition(\n        scrollableViewport.frame,\n        patch(axis.line, 1),\n      );\n      const tooBigOnMainAxis: DraggableDimension = getDraggableDimension({\n        descriptor: preset.inHome1.descriptor,\n        borderBox: biggerOnMainAxis,\n      });\n      const first: DraggingState = addDraggable(\n        dragTo({\n          viewport: scrollableViewport,\n          selection: onMaxBoundaryOfBoth,\n          state,\n        }),\n        tooBigOnMainAxis,\n      );\n\n      scroller.start(first);\n      requestAnimationFrame.step();\n\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        // $FlowFixMe - using expect.any\n        patch(axis.crossAxisLine, expect.any(Number)),\n      );\n    });\n\n    it('should allow scrolling on the main axis if too big on the cross axis', () => {\n      const mocks: PublicArgs = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const biggerOnCrossAxis: Spacing = expandByPosition(\n        scrollableViewport.frame,\n        patch(axis.crossAxisLine, 1),\n      );\n      const tooBigOnCrossAxis: DraggableDimension = getDraggableDimension({\n        descriptor: preset.inHome1.descriptor,\n        borderBox: biggerOnCrossAxis,\n      });\n      const first: DraggingState = addDraggable(\n        dragTo({\n          viewport: scrollableViewport,\n          selection: onMaxBoundaryOfBoth,\n          state,\n        }),\n        tooBigOnCrossAxis,\n      );\n\n      scroller.start(first);\n      requestAnimationFrame.step();\n\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        // $FlowFixMe - using expect.any\n        patch(axis.line, expect.any(Number)),\n      );\n    });\n\n    it('should not allow scrolling on any axis if too big on both axis', () => {\n      const mocks: PublicArgs = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const biggerOnBothAxis: Spacing = expandByPosition(\n        scrollableViewport.frame,\n        patch(axis.line, 1, 1),\n      );\n      const tooBig: DraggableDimension = getDraggableDimension({\n        descriptor: preset.inHome1.descriptor,\n        borderBox: biggerOnBothAxis,\n      });\n      const first: DraggingState = addDraggable(\n        dragTo({\n          viewport: scrollableViewport,\n          selection: onMaxBoundaryOfBoth,\n          state,\n        }),\n        tooBig,\n      );\n\n      scroller.start(first);\n      requestAnimationFrame.flush();\n\n      expect(mocks.scrollWindow).not.toHaveBeenCalled();\n    });\n  });\n\n  describe('droppable', () => {\n    const { scrollable, frameClient } = getDroppable(preset);\n    const thresholds: DistanceThresholds = getDistanceThresholds(\n      frameClient.borderBox,\n      axis,\n    );\n    const crossAxisThresholds: DistanceThresholds = getDistanceThresholds(\n      frameClient.borderBox,\n      axis === vertical ? horizontal : vertical,\n    );\n    const onMaxBoundaryOfBoth: Position = patch(\n      axis.line,\n      frameClient.borderBox[axis.size] - thresholds.maxScrollValueAt,\n      frameClient.borderBox[axis.crossAxisSize] -\n        crossAxisThresholds.maxScrollValueAt,\n    );\n\n    it('should allow scrolling on the cross axis if too big on the main axis', () => {\n      const mocks: PublicArgs = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const biggerOnMainAxis: Spacing = expandByPosition(\n        frameClient.borderBox,\n        patch(axis.line, 1),\n      );\n      const tooBigOnMainAxis: DraggableDimension = getDraggableDimension({\n        descriptor: preset.inHome1.descriptor,\n        borderBox: biggerOnMainAxis,\n      });\n      const first: DraggingState = addDraggable(\n        dragTo({\n          viewport: unscrollableViewport,\n          selection: onMaxBoundaryOfBoth,\n          state,\n          droppable: scrollable,\n        }),\n        tooBigOnMainAxis,\n      );\n\n      scroller.start(first);\n      requestAnimationFrame.step();\n\n      expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n        scrollable.descriptor.id,\n        // $FlowFixMe - using expect.any\n        patch(axis.crossAxisLine, expect.any(Number)),\n      );\n    });\n\n    it('should allow scrolling on the main axis if too big on the cross axis', () => {\n      const mocks: PublicArgs = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const biggerOnCrossAxis: Spacing = expandByPosition(\n        frameClient.borderBox,\n        patch(axis.crossAxisLine, 1),\n      );\n      const tooBigOnCrossAxis: DraggableDimension = getDraggableDimension({\n        descriptor: preset.inHome1.descriptor,\n        borderBox: biggerOnCrossAxis,\n      });\n      const first: DraggingState = addDraggable(\n        dragTo({\n          viewport: unscrollableViewport,\n          selection: onMaxBoundaryOfBoth,\n          droppable: scrollable,\n          state,\n        }),\n        tooBigOnCrossAxis,\n      );\n\n      scroller.start(first);\n      requestAnimationFrame.step();\n\n      expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n        scrollable.descriptor.id,\n        // $FlowFixMe - using expect.any\n        patch(axis.line, expect.any(Number)),\n      );\n    });\n\n    it('should not allow scrolling on any axis if too big on both axis', () => {\n      const mocks: PublicArgs = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const biggerOnBothAxis: Spacing = expandByPosition(\n        frameClient.borderBox,\n        patch(axis.line, 1, 1),\n      );\n      const tooBig: DraggableDimension = getDraggableDimension({\n        descriptor: preset.inHome1.descriptor,\n        borderBox: biggerOnBothAxis,\n      });\n      const first: DraggingState = addDraggable(\n        dragTo({\n          viewport: unscrollableViewport,\n          selection: onMaxBoundaryOfBoth,\n          droppable: scrollable,\n          state,\n        }),\n        tooBig,\n      );\n\n      scroller.start(first);\n      requestAnimationFrame.flush();\n\n      expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/droppable-scrolling.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport forEach, { type BlockFnArgs } from './util/for-each';\nimport type { DroppableDimension, DroppableId } from '../../../../../src/types';\nimport { unscrollableViewport } from './util/viewport';\nimport getDroppable from './util/get-droppable';\nimport dragTo from './util/drag-to';\nimport getScroller, {\n  type FluidScroller,\n} from '../../../../../src/state/auto-scroller/fluid-scroller';\nimport getDistanceThresholds, {\n  type DistanceThresholds,\n} from '../../../../../src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-distance-thresholds';\nimport {\n  patch,\n  add,\n  subtract,\n  negate,\n} from '../../../../../src/state/position';\nimport getArgsMock from './util/get-args-mock';\nimport config from '../../../../../src/state/auto-scroller/fluid-scroller/config';\nimport scrollDroppable from '../../../../../src/state/droppable/scroll-droppable';\n\nforEach(({ axis, state, preset }: BlockFnArgs) => {\n  const { scrollable, frameClient } = getDroppable(preset);\n  const thresholds: DistanceThresholds = getDistanceThresholds(\n    frameClient.borderBox,\n    axis,\n  );\n\n  describe('moving forward to end of droppable', () => {\n    const onStartBoundary: Position = patch(\n      axis.line,\n      // to the boundary is not enough to start\n      frameClient.borderBox[axis.size] - thresholds.startScrollingFrom,\n      frameClient.borderBox.center[axis.crossAxisLine],\n    );\n    const onMaxBoundary: Position = patch(\n      axis.line,\n      frameClient.borderBox[axis.size] - thresholds.maxScrollValueAt,\n      frameClient.borderBox.center[axis.crossAxisLine],\n    );\n    const noScrollTarget: Position = subtract(\n      onStartBoundary,\n      patch(axis.line, 1),\n    );\n\n    const startWithNoScroll = (scroller: FluidScroller) => {\n      scroller.start(\n        dragTo({\n          selection: noScrollTarget,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n    };\n\n    it('should not scroll if before the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = subtract(onStartBoundary, patch(axis.line, 1));\n\n      scroller.start(\n        dragTo({\n          selection: target,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.flush();\n      expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n    });\n\n    it('should scroll if on the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      scroller.start(\n        dragTo({\n          selection: onStartBoundary,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n\n      expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalled();\n    });\n\n    it('should scroll if moving beyond the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = add(onStartBoundary, patch(axis.line, 1));\n\n      scroller.start(\n        dragTo({\n          selection: target,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n\n      expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n\n      // only called after a frame\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalled();\n      // moving forwards\n      const id: DroppableId = mocks.scrollDroppable.mock.calls[0][0];\n      const request: Position = mocks.scrollDroppable.mock.calls[0][1];\n      expect(id).toEqual(scrollable.descriptor.id);\n      expect(request[axis.line]).toBeGreaterThan(0);\n    });\n\n    it('should get faster the closer to the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const atStartOfRange: Position = onStartBoundary;\n      const atEndOfRange: Position = subtract(\n        onMaxBoundary,\n        patch(axis.line, 1),\n      );\n\n      // start the drag with no auto scrolling\n      // this will opt out of time dampening\n      startWithNoScroll(scroller);\n      expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n\n      scroller.scroll(\n        dragTo({\n          selection: atStartOfRange,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledTimes(1);\n      const scroll1: Position = (mocks.scrollDroppable.mock.calls[0][1]: any);\n\n      scroller.scroll(\n        dragTo({\n          selection: atEndOfRange,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledTimes(2);\n      const scroll2: Position = (mocks.scrollDroppable.mock.calls[1][1]: any);\n\n      expect(scroll1[axis.line]).toBeLessThan(scroll2[axis.line]);\n\n      // validation\n      expect(scroll1[axis.crossAxisLine]).toBe(0);\n      expect(scroll2[axis.crossAxisLine]).toBe(0);\n    });\n\n    it('should have the top speed at the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: onMaxBoundary,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n        scrollable.descriptor.id,\n        patch(axis.line, config.maxPixelScroll),\n      );\n    });\n\n    it('should have the top speed when moving beyond the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = add(onMaxBoundary, patch(axis.line, 1));\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: target,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n        scrollable.descriptor.id,\n        patch(axis.line, config.maxPixelScroll),\n      );\n    });\n\n    it('should throttle multiple scrolls into a single animation frame', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target1: Position = add(onStartBoundary, patch(axis.line, 1));\n      const target2: Position = subtract(onMaxBoundary, patch(axis.line, 1));\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: target1,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n      scroller.scroll(\n        dragTo({\n          selection: target2,\n          viewport: unscrollableViewport,\n          droppable: scrollable,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledTimes(1);\n      expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n        scrollable.descriptor.id,\n        patch(axis.line, config.maxPixelScroll),\n      );\n    });\n  });\n\n  describe('moving backward to start of droppable', () => {\n    const droppableScroll: Position = patch(axis.line, 10);\n    const scrolled: DroppableDimension = scrollDroppable(\n      scrollable,\n      droppableScroll,\n    );\n\n    const onStartBoundary: Position = patch(\n      axis.line,\n      // at the boundary is not enough to start\n      frameClient.borderBox[axis.start] + thresholds.startScrollingFrom,\n      frameClient.borderBox.center[axis.crossAxisLine],\n    );\n    const onMaxBoundary: Position = patch(\n      axis.line,\n      frameClient.borderBox[axis.start] + thresholds.maxScrollValueAt,\n      frameClient.borderBox.center[axis.crossAxisLine],\n    );\n    const noScrollTarget: Position = add(onStartBoundary, patch(axis.line, 1));\n\n    const startWithNoScroll = (scroller: FluidScroller) => {\n      scroller.start(\n        dragTo({\n          selection: noScrollTarget,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n    };\n\n    it('should not scroll if before the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = add(onStartBoundary, patch(axis.line, 1));\n\n      scroller.start(\n        dragTo({\n          selection: target,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.flush();\n      expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n    });\n\n    it('should scroll if on the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      scroller.start(\n        dragTo({\n          selection: onStartBoundary,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n\n      expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n      requestAnimationFrame.flush();\n      expect(mocks.scrollDroppable).toHaveBeenCalled();\n    });\n\n    it('should scroll if moving beyond the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = subtract(onStartBoundary, patch(axis.line, 1));\n\n      scroller.start(\n        dragTo({\n          selection: target,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n\n      expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n\n      // only called after a frame\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalled();\n      // moving forwards\n      const request: Position = mocks.scrollDroppable.mock.calls[0][1];\n      expect(request[axis.line]).toBeLessThan(0);\n    });\n\n    it('should get faster the closer to the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const atStartOfRange: Position = onStartBoundary;\n      const atEndOfRange: Position = add(onMaxBoundary, patch(axis.line, 1));\n\n      // start the drag with no auto scrolling\n      // this will opt out of time dampening\n      startWithNoScroll(scroller);\n      expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n\n      scroller.scroll(\n        dragTo({\n          selection: atStartOfRange,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledTimes(1);\n      const scroll1: Position = (mocks.scrollDroppable.mock.calls[0][1]: any);\n\n      scroller.scroll(\n        dragTo({\n          selection: atEndOfRange,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledTimes(2);\n      const scroll2: Position = (mocks.scrollDroppable.mock.calls[1][1]: any);\n\n      expect(scroll1[axis.line]).toBeGreaterThan(scroll2[axis.line]);\n\n      // validation\n      expect(scroll1[axis.crossAxisLine]).toBe(0);\n      expect(scroll2[axis.crossAxisLine]).toBe(0);\n    });\n\n    it('should have the top speed at the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: onMaxBoundary,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n        scrolled.descriptor.id,\n        negate(patch(axis.line, config.maxPixelScroll)),\n      );\n    });\n\n    it('should have the top speed when moving beyond the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = subtract(onMaxBoundary, patch(axis.line, 1));\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: target,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n        scrolled.descriptor.id,\n        negate(patch(axis.line, config.maxPixelScroll)),\n      );\n    });\n\n    it('should throttle multiple scrolls into a single animation frame', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target1: Position = subtract(onStartBoundary, patch(axis.line, 1));\n      const target2: Position = add(onMaxBoundary, patch(axis.line, 1));\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: target1,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n      scroller.scroll(\n        dragTo({\n          selection: target2,\n          viewport: unscrollableViewport,\n          droppable: scrolled,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.step();\n      expect(mocks.scrollDroppable).toHaveBeenCalledTimes(1);\n      expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n        scrolled.descriptor.id,\n        negate(patch(axis.line, config.maxPixelScroll)),\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/lifecycle.spec.js",
    "content": "// @flow\nimport forEach, { type BlockFnArgs } from './util/for-each';\nimport type { DraggingState } from '../../../../../src/types';\nimport getMocks from './util/get-args-mock';\nimport getScroller, {\n  type FluidScroller,\n} from '../../../../../src/state/auto-scroller/fluid-scroller';\n\nforEach(({ state }: BlockFnArgs) => {\n  const base: DraggingState = state.dragging();\n  it('should throw if a scroll occurs before a drag as started', () => {\n    const scroller: FluidScroller = getScroller(getMocks());\n    expect(() => scroller.scroll(base)).toThrow();\n\n    // after a drag\n    scroller.start(base);\n    scroller.stop();\n\n    expect(() => scroller.scroll(base)).toThrow();\n  });\n\n  it('should allow subsequent drags', () => {\n    const scroller: FluidScroller = getScroller(getMocks());\n    const run = () => {\n      scroller.start(base);\n      scroller.stop();\n    };\n\n    Array.from({ length: 1 }).forEach(() => {\n      expect(run).not.toThrow();\n    });\n  });\n\n  it('should allow defensive stop calls', () => {\n    const scroller: FluidScroller = getScroller(getMocks());\n    // newly created - not started\n    scroller.stop();\n\n    // started and then stopped multiple times\n    const run = () => {\n      scroller.start(base);\n      scroller.stop();\n      scroller.stop();\n      scroller.stop();\n    };\n    expect(run).not.toThrow();\n  });\n\n  it('should throw if started multiple times', () => {\n    const scroller: FluidScroller = getScroller(getMocks());\n    scroller.start(base);\n    expect(() => scroller.start(base)).toThrow();\n  });\n});\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/time-dampening.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport forEach, { type BlockFnArgs } from './util/for-each';\nimport { scrollableViewport } from './util/viewport';\nimport dragTo from './util/drag-to';\nimport getScroller, {\n  type FluidScroller,\n} from '../../../../../src/state/auto-scroller/fluid-scroller';\nimport getDistanceThresholds, {\n  type DistanceThresholds,\n} from '../../../../../src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-distance-thresholds';\nimport { patch } from '../../../../../src/state/position';\nimport getArgsMock from './util/get-args-mock';\nimport config from '../../../../../src/state/auto-scroller/fluid-scroller/config';\nimport minScroll from '../../../../../src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/min-scroll';\n\nconst stopAt: number = config.durationDampening.stopDampeningAt;\nconst startAcceleratingAt: number = config.durationDampening.accelerateAt;\nconst accelerationRange: number = stopAt - startAcceleratingAt;\n\nforEach(({ state, axis }: BlockFnArgs) => {\n  const thresholds: DistanceThresholds = getDistanceThresholds(\n    scrollableViewport.frame,\n    axis,\n  );\n  const onStartBoundary: Position = patch(\n    axis.line,\n    // to the boundary is not enough to start\n    scrollableViewport.frame[axis.size] - thresholds.startScrollingFrom,\n    scrollableViewport.frame.center[axis.crossAxisLine],\n  );\n  const onMaxBoundary: Position = patch(\n    axis.line,\n    scrollableViewport.frame[axis.size] - thresholds.maxScrollValueAt,\n    scrollableViewport.frame.center[axis.crossAxisLine],\n  );\n\n  const originalNow = Date.now;\n  let mockNow;\n\n  beforeEach(() => {\n    mockNow = jest.fn().mockReturnValue(0);\n    // $FlowFixMe - overriding global\n    Date.now = mockNow;\n  });\n\n  afterEach(() => {\n    mockNow.mockClear();\n    // $FlowFixMe - overriding global\n    Date.now = originalNow;\n  });\n\n  it('should not dampen scrolling if not starting in scrollable area', () => {\n    const mocks = getArgsMock();\n    const scroller: FluidScroller = getScroller(mocks);\n\n    // no scroll on initial lift\n    scroller.start(\n      dragTo({\n        selection: scrollableViewport.frame.center,\n        viewport: scrollableViewport,\n        state,\n      }),\n    );\n    requestAnimationFrame.flush();\n    expect(mocks.scrollWindow).not.toHaveBeenCalled();\n\n    // would be a max scroll\n    scroller.scroll(\n      dragTo({\n        selection: onMaxBoundary,\n        viewport: scrollableViewport,\n        state,\n      }),\n    );\n\n    requestAnimationFrame.step();\n    expect(mocks.scrollWindow).toHaveBeenCalledWith(\n      patch(axis.line, config.maxPixelScroll),\n    );\n  });\n\n  it('should dampen if lifted in a scrollable area', () => {\n    // on start of boundary: would have been a min scroll anyway\n    {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      // lifting in scrollable area\n      scroller.start(\n        dragTo({\n          selection: onStartBoundary,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        patch(axis.line, minScroll),\n      );\n    }\n    // would normally be max scroll speed\n    {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      // lifting in scrollable area\n      scroller.start(\n        dragTo({\n          selection: onMaxBoundary,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        patch(axis.line, minScroll),\n      );\n    }\n  });\n\n  it('should have the minimum scroll up to a small time threshold and then accelerate to the max speed as time continues', () => {\n    const mocks = getArgsMock();\n    const scroller: FluidScroller = getScroller(mocks);\n\n    // starting on the max boundary which normally\n    scroller.start(\n      dragTo({\n        selection: onMaxBoundary,\n        viewport: scrollableViewport,\n        state,\n      }),\n    );\n    requestAnimationFrame.step();\n    expect(mocks.scrollWindow).toHaveBeenCalledWith(\n      patch(axis.line, minScroll),\n    );\n    mocks.scrollWindow.mockClear();\n\n    // moving up to just before the acceleration point\n    mockNow.mockReturnValueOnce(startAcceleratingAt - 1);\n    scroller.scroll(\n      dragTo({\n        selection: onMaxBoundary,\n        viewport: scrollableViewport,\n        state,\n      }),\n    );\n\n    // still on the min scroll\n    requestAnimationFrame.step();\n    expect(mocks.scrollWindow).toHaveBeenCalledWith(\n      patch(axis.line, minScroll),\n    );\n    mocks.scrollWindow.mockClear();\n\n    // now on the acceleration start point\n    mockNow.mockReturnValueOnce(startAcceleratingAt);\n    scroller.scroll(\n      dragTo({\n        selection: onMaxBoundary,\n        viewport: scrollableViewport,\n        state,\n      }),\n    );\n    requestAnimationFrame.step();\n    // still on the min scroll as the % change will be quite low\n    expect(mocks.scrollWindow).toHaveBeenCalledWith(\n      patch(axis.line, minScroll),\n    );\n    mocks.scrollWindow.mockClear();\n\n    // Moving 30% of the way into the time dampening period\n    mockNow.mockReturnValueOnce(startAcceleratingAt + accelerationRange * 0.3);\n    scroller.scroll(\n      dragTo({\n        selection: onMaxBoundary,\n        viewport: scrollableViewport,\n        state,\n      }),\n    );\n    requestAnimationFrame.step();\n    const firstAcceleratedScroll: Position =\n      mocks.scrollWindow.mock.calls[0][0];\n    expect(firstAcceleratedScroll[axis.line]).toBeGreaterThan(minScroll);\n    expect(firstAcceleratedScroll[axis.line]).toBeLessThan(\n      config.maxPixelScroll,\n    );\n    mocks.scrollWindow.mockClear();\n\n    // Now passing event more time (60%)\n    mockNow.mockReturnValueOnce(startAcceleratingAt + accelerationRange * 0.6);\n    scroller.scroll(\n      dragTo({\n        selection: onMaxBoundary,\n        viewport: scrollableViewport,\n        state,\n      }),\n    );\n    requestAnimationFrame.step();\n    const secondAcceleratedScroll: Position =\n      mocks.scrollWindow.mock.calls[0][0];\n    // is greater in acceleration\n    expect(secondAcceleratedScroll[axis.line]).toBeGreaterThan(\n      firstAcceleratedScroll[axis.line],\n    );\n    expect(secondAcceleratedScroll[axis.line]).toBeGreaterThan(minScroll);\n    expect(secondAcceleratedScroll[axis.line]).toBeLessThan(\n      config.maxPixelScroll,\n    );\n    mocks.scrollWindow.mockClear();\n\n    // Moving to the end of the time dampening period\n    mockNow.mockReturnValueOnce(stopAt);\n    scroller.scroll(\n      dragTo({\n        selection: onMaxBoundary,\n        viewport: scrollableViewport,\n        state,\n      }),\n    );\n    requestAnimationFrame.step();\n    const lastAcceleratedScroll: Position = mocks.scrollWindow.mock.calls[0][0];\n    // is greater in acceleration\n    expect(lastAcceleratedScroll[axis.line]).toBeGreaterThan(\n      firstAcceleratedScroll[axis.line],\n    );\n    expect(lastAcceleratedScroll[axis.line]).toBeGreaterThan(minScroll);\n    expect(lastAcceleratedScroll[axis.line]).toEqual(config.maxPixelScroll);\n  });\n});\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/util/drag-to.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Viewport,\n  DragImpact,\n  DraggingState,\n  DroppableDimension,\n  DimensionMap,\n} from '../../../../../../src/types';\nimport patchDimensionMap from '../../../../../../src/state/patch-dimension-map';\n\ntype DragToArgs = {|\n  selection: Position,\n  viewport: Viewport,\n  state: Object,\n  impact?: DragImpact,\n  droppable?: DroppableDimension,\n|};\n\nexport default ({\n  selection,\n  viewport,\n  // seeding that we are over the home droppable\n  impact,\n  state,\n  droppable,\n}: DragToArgs): DraggingState => {\n  const base: DraggingState = state.dragging(\n    state.preset.inHome1.descriptor.id,\n    selection,\n    viewport,\n  );\n\n  const dimensions: DimensionMap = (() => {\n    if (!droppable) {\n      return base.dimensions;\n    }\n    return patchDimensionMap(base.dimensions, droppable);\n  })();\n\n  return {\n    ...base,\n    // add impact if needed\n    impact: impact || base.impact,\n    // add droppable if needed\n    dimensions,\n  };\n};\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/util/for-each.js",
    "content": "// @flow\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport type { Axis } from '../../../../../../src/types';\nimport { getPreset } from '../../../../../util/dimension';\nimport getSimpleStatePreset from '../../../../../util/get-simple-state-preset';\n\nexport type BlockFnArgs = {|\n  axis: Axis,\n  preset: Object,\n  state: Object,\n|};\n\ntype BlockFn = (args: BlockFnArgs) => void;\n\nexport default (block: BlockFn) => {\n  [vertical, horizontal].forEach((axis: Axis) => {\n    describe(`on the ${axis.direction} axis`, () => {\n      beforeEach(() => {\n        requestAnimationFrame.reset();\n        jest.useFakeTimers();\n      });\n      afterEach(() => {\n        jest.useRealTimers();\n      });\n\n      afterAll(() => {\n        requestAnimationFrame.reset();\n      });\n\n      const preset = getPreset(axis);\n      const state = getSimpleStatePreset(axis);\n\n      block({ axis, preset, state });\n    });\n  });\n};\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/util/get-args-mock.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { DroppableId } from '../../../../../../src/types';\n\n// Similiar to PublicArgs\ntype Result = {|\n  scrollWindow: JestMockFn<[Position], void>,\n  scrollDroppable: JestMockFn<[DroppableId, Position], void>,\n|};\n\nexport default (): Result => {\n  const scrollWindow: JestMockFn<[Position], void> = jest.fn();\n  const scrollDroppable: JestMockFn<[DroppableId, Position], void> = jest.fn();\n\n  return {\n    scrollWindow,\n    scrollDroppable,\n  };\n};\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/util/get-droppable.js",
    "content": "// @flow\nimport { createBox, type BoxModel } from 'css-box-model';\nimport type { DroppableDimension } from '../../../../../../src/types';\nimport { origin } from '../../../../../../src/state/position';\nimport { getDroppableDimension } from '../../../../../util/dimension';\n\nexport default (preset: Object) => {\n  const scrollableScrollSize = {\n    scrollWidth: 800,\n    scrollHeight: 800,\n  };\n  const frameClient: BoxModel = createBox({\n    borderBox: {\n      top: 0,\n      left: 0,\n      right: 600,\n      bottom: 600,\n    },\n  });\n\n  const scrollable: DroppableDimension = getDroppableDimension({\n    // stealing the home descriptor\n    descriptor: preset.home.descriptor,\n    direction: preset.home.axis.direction,\n    borderBox: {\n      top: 0,\n      left: 0,\n      // bigger than the frame\n      right: scrollableScrollSize.scrollWidth,\n      bottom: scrollableScrollSize.scrollHeight,\n    },\n    closest: {\n      borderBox: frameClient.borderBox,\n      scrollSize: {\n        scrollWidth: scrollableScrollSize.scrollWidth,\n        scrollHeight: scrollableScrollSize.scrollHeight,\n      },\n      scroll: origin,\n      shouldClipSubject: true,\n    },\n  });\n\n  return { scrollable, frameClient, scrollableScrollSize };\n};\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/util/viewport.js",
    "content": "// @flow\nimport { getRect } from 'css-box-model';\nimport type { Viewport } from '../../../../../../src/types';\nimport { origin } from '../../../../../../src/state/position';\nimport { createViewport } from '../../../../../util/viewport';\n\nexport const windowScrollSize = {\n  scrollHeight: 2000,\n  scrollWidth: 1600,\n};\nexport const scrollableViewport: Viewport = createViewport({\n  frame: getRect({\n    top: 0,\n    left: 0,\n    right: 800,\n    bottom: 1000,\n  }),\n  scrollHeight: windowScrollSize.scrollHeight,\n  scrollWidth: windowScrollSize.scrollWidth,\n  scroll: origin,\n});\n\nexport const unscrollableViewport: Viewport = createViewport({\n  frame: getRect({\n    top: 0,\n    left: 0,\n    right: 800,\n    bottom: 1000,\n  }),\n  scrollHeight: 1000,\n  scrollWidth: 800,\n  scroll: origin,\n});\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/window-before-droppable.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport forEach, { type BlockFnArgs } from './util/for-each';\nimport type { DroppableDimension } from '../../../../../src/types';\nimport { scrollableViewport, windowScrollSize } from './util/viewport';\nimport dragTo from './util/drag-to';\nimport getScroller, {\n  type PublicArgs,\n  type FluidScroller,\n} from '../../../../../src/state/auto-scroller/fluid-scroller';\nimport getDistanceThresholds, {\n  type DistanceThresholds,\n} from '../../../../../src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-distance-thresholds';\nimport { patch, origin } from '../../../../../src/state/position';\nimport getArgsMock from './util/get-args-mock';\nimport { getDroppableDimension } from '../../../../util/dimension';\n\nforEach(({ axis, state }: BlockFnArgs) => {\n  const custom: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'scrollable that is similiar to the viewport',\n      type: 'TYPE',\n      mode: 'standard',\n    },\n    direction: axis.direction,\n    borderBox: {\n      top: 0,\n      left: 0,\n      // bigger than the frame\n      right: windowScrollSize.scrollWidth,\n      bottom: windowScrollSize.scrollHeight,\n    },\n    closest: {\n      borderBox: scrollableViewport.frame,\n      scrollSize: {\n        scrollWidth: windowScrollSize.scrollWidth,\n        scrollHeight: windowScrollSize.scrollHeight,\n      },\n      scroll: origin,\n      shouldClipSubject: true,\n    },\n  });\n  const thresholds: DistanceThresholds = getDistanceThresholds(\n    scrollableViewport.frame,\n    axis,\n  );\n\n  it('should scroll the window only if both the window and droppable can be scrolled', () => {\n    const mocks: PublicArgs = getArgsMock();\n    const scroller: FluidScroller = getScroller(mocks);\n\n    const onMaxBoundary: Position = patch(\n      axis.line,\n      scrollableViewport.frame[axis.size] - thresholds.maxScrollValueAt,\n      scrollableViewport.frame.center[axis.crossAxisLine],\n    );\n\n    scroller.start(\n      dragTo({\n        selection: onMaxBoundary,\n        viewport: scrollableViewport,\n        state,\n        droppable: custom,\n      }),\n    );\n    requestAnimationFrame.step();\n\n    expect(mocks.scrollWindow).toHaveBeenCalled();\n    expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n  });\n});\n"
  },
  {
    "path": "test/unit/state/auto-scroll/fluid-scroller/window-scrolling.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport forEach, { type BlockFnArgs } from './util/for-each';\nimport type { Viewport } from '../../../../../src/types';\nimport { scrollableViewport } from './util/viewport';\nimport scrollViewport from '../../../../../src/state/scroll-viewport';\nimport dragTo from './util/drag-to';\nimport getScroller, {\n  type FluidScroller,\n} from '../../../../../src/state/auto-scroller/fluid-scroller';\nimport getDistanceThresholds, {\n  type DistanceThresholds,\n} from '../../../../../src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-distance-thresholds';\nimport {\n  patch,\n  add,\n  subtract,\n  negate,\n} from '../../../../../src/state/position';\nimport getArgsMock from './util/get-args-mock';\nimport config from '../../../../../src/state/auto-scroller/fluid-scroller/config';\n\nforEach(({ axis, state }: BlockFnArgs) => {\n  const thresholds: DistanceThresholds = getDistanceThresholds(\n    scrollableViewport.frame,\n    axis,\n  );\n\n  describe('moving forward to end of window', () => {\n    const onStartBoundary: Position = patch(\n      axis.line,\n      // to the boundary is not enough to start\n      scrollableViewport.frame[axis.size] - thresholds.startScrollingFrom,\n      scrollableViewport.frame.center[axis.crossAxisLine],\n    );\n    const onMaxBoundary: Position = patch(\n      axis.line,\n      scrollableViewport.frame[axis.size] - thresholds.maxScrollValueAt,\n      scrollableViewport.frame.center[axis.crossAxisLine],\n    );\n    const noScrollTarget: Position = subtract(\n      onStartBoundary,\n      patch(axis.line, 1),\n    );\n\n    const startWithNoScroll = (scroller: FluidScroller) => {\n      scroller.start(\n        dragTo({\n          selection: noScrollTarget,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n    };\n    it('should not scroll if before the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = subtract(onStartBoundary, patch(axis.line, 1));\n\n      scroller.start(\n        dragTo({\n          selection: target,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.flush();\n      expect(mocks.scrollWindow).not.toHaveBeenCalled();\n    });\n\n    it('should scroll if on the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      scroller.start(\n        dragTo({\n          selection: onStartBoundary,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n\n      expect(mocks.scrollWindow).not.toHaveBeenCalled();\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalled();\n    });\n\n    it('should scroll if moving beyond the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = add(onStartBoundary, patch(axis.line, 1));\n\n      scroller.start(\n        dragTo({\n          selection: target,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n\n      expect(mocks.scrollWindow).not.toHaveBeenCalled();\n\n      // only called after a frame\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalled();\n      // moving forwards\n      const request: Position = mocks.scrollWindow.mock.calls[0][0];\n      expect(request[axis.line]).toBeGreaterThan(0);\n    });\n\n    it('should get faster the closer to the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const atStartOfRange: Position = onStartBoundary;\n      const atEndOfRange: Position = subtract(\n        onMaxBoundary,\n        patch(axis.line, 1),\n      );\n\n      // start the drag with no auto scrolling\n      // this will opt out of time dampening\n      startWithNoScroll(scroller);\n      expect(mocks.scrollWindow).not.toHaveBeenCalled();\n\n      scroller.scroll(\n        dragTo({\n          selection: atStartOfRange,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledTimes(1);\n      const scroll1: Position = (mocks.scrollWindow.mock.calls[0][0]: any);\n\n      scroller.scroll(\n        dragTo({\n          selection: atEndOfRange,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledTimes(2);\n      const scroll2: Position = (mocks.scrollWindow.mock.calls[1][0]: any);\n\n      expect(scroll1[axis.line]).toBeLessThan(scroll2[axis.line]);\n\n      // validation\n      expect(scroll1[axis.crossAxisLine]).toBe(0);\n      expect(scroll2[axis.crossAxisLine]).toBe(0);\n    });\n\n    it('should have the top speed at the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: onMaxBoundary,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        patch(axis.line, config.maxPixelScroll),\n      );\n    });\n\n    it('should have the top speed when moving beyond the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = add(onMaxBoundary, patch(axis.line, 1));\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: target,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        patch(axis.line, config.maxPixelScroll),\n      );\n    });\n\n    it('should throttle multiple scrolls into a single animation frame', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target1: Position = add(onStartBoundary, patch(axis.line, 1));\n      const target2: Position = subtract(onMaxBoundary, patch(axis.line, 1));\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: target1,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n      scroller.scroll(\n        dragTo({\n          selection: target2,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledTimes(1);\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        patch(axis.line, config.maxPixelScroll),\n      );\n    });\n  });\n\n  describe('moving backward to start of window', () => {\n    const windowScroll: Position = patch(axis.line, 10);\n    const scrolledViewport: Viewport = scrollViewport(\n      scrollableViewport,\n      windowScroll,\n    );\n\n    const onStartBoundary: Position = patch(\n      axis.line,\n      // at the boundary is not enough to start\n      windowScroll[axis.line] + thresholds.startScrollingFrom,\n      scrolledViewport.frame.center[axis.crossAxisLine],\n    );\n    const onMaxBoundary: Position = patch(\n      axis.line,\n      windowScroll[axis.line] + thresholds.maxScrollValueAt,\n      scrolledViewport.frame.center[axis.crossAxisLine],\n    );\n    const noScrollTarget: Position = add(onStartBoundary, patch(axis.line, 1));\n\n    const startWithNoScroll = (scroller: FluidScroller) => {\n      scroller.start(\n        dragTo({\n          selection: noScrollTarget,\n          viewport: scrollableViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n    };\n\n    it('should not scroll if before the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = add(onStartBoundary, patch(axis.line, 1));\n\n      scroller.start(\n        dragTo({\n          selection: target,\n          viewport: scrolledViewport,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.flush();\n      expect(mocks.scrollWindow).not.toHaveBeenCalled();\n    });\n\n    it('should scroll if on the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      scroller.start(\n        dragTo({\n          selection: onStartBoundary,\n          viewport: scrolledViewport,\n          state,\n        }),\n      );\n\n      expect(mocks.scrollWindow).not.toHaveBeenCalled();\n      requestAnimationFrame.flush();\n      expect(mocks.scrollWindow).toHaveBeenCalled();\n    });\n\n    it('should scroll if moving beyond the start threshold', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = subtract(onStartBoundary, patch(axis.line, 1));\n\n      scroller.start(\n        dragTo({\n          selection: target,\n          viewport: scrolledViewport,\n          state,\n        }),\n      );\n\n      expect(mocks.scrollWindow).not.toHaveBeenCalled();\n\n      // only called after a frame\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalled();\n      // moving forwards\n      const request: Position = mocks.scrollWindow.mock.calls[0][0];\n      expect(request[axis.line]).toBeLessThan(0);\n    });\n\n    it('should get faster the closer to the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const atStartOfRange: Position = onStartBoundary;\n      const atEndOfRange: Position = add(onMaxBoundary, patch(axis.line, 1));\n\n      // start the drag with no auto scrolling\n      // this will opt out of time dampening\n      startWithNoScroll(scroller);\n      expect(mocks.scrollWindow).not.toHaveBeenCalled();\n\n      scroller.scroll(\n        dragTo({\n          selection: atStartOfRange,\n          viewport: scrolledViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledTimes(1);\n      const scroll1: Position = (mocks.scrollWindow.mock.calls[0][0]: any);\n\n      scroller.scroll(\n        dragTo({\n          selection: atEndOfRange,\n          viewport: scrolledViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledTimes(2);\n      const scroll2: Position = (mocks.scrollWindow.mock.calls[1][0]: any);\n\n      expect(scroll1[axis.line]).toBeGreaterThan(scroll2[axis.line]);\n\n      // validation\n      expect(scroll1[axis.crossAxisLine]).toBe(0);\n      expect(scroll2[axis.crossAxisLine]).toBe(0);\n    });\n\n    it('should have the top speed at the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: onMaxBoundary,\n          viewport: scrolledViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        negate(patch(axis.line, config.maxPixelScroll)),\n      );\n    });\n\n    it('should have the top speed when moving beyond the max speed point', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target: Position = subtract(onMaxBoundary, patch(axis.line, 1));\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: target,\n          viewport: scrolledViewport,\n          state,\n        }),\n      );\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        negate(patch(axis.line, config.maxPixelScroll)),\n      );\n    });\n\n    it('should throttle multiple scrolls into a single animation frame', () => {\n      const mocks = getArgsMock();\n      const scroller: FluidScroller = getScroller(mocks);\n      const target1: Position = subtract(onStartBoundary, patch(axis.line, 1));\n      const target2: Position = add(onMaxBoundary, patch(axis.line, 1));\n\n      startWithNoScroll(scroller);\n      scroller.scroll(\n        dragTo({\n          selection: target1,\n          viewport: scrolledViewport,\n          state,\n        }),\n      );\n      scroller.scroll(\n        dragTo({\n          selection: target2,\n          viewport: scrolledViewport,\n          state,\n        }),\n      );\n\n      requestAnimationFrame.step();\n      expect(mocks.scrollWindow).toHaveBeenCalledTimes(1);\n      expect(mocks.scrollWindow).toHaveBeenCalledWith(\n        negate(patch(axis.line, config.maxPixelScroll)),\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/auto-scroll/jump-scroller.spec.js",
    "content": "// @flow\nimport {\n  createBox,\n  getRect,\n  type BoxModel,\n  type Position,\n} from 'css-box-model';\nimport type {\n  Axis,\n  DraggingState,\n  DroppableDimension,\n  Viewport,\n} from '../../../../src/types';\nimport { add, patch, subtract, negate } from '../../../../src/state/position';\nimport { createViewport, withWindowScrollSize } from '../../../util/viewport';\nimport scrollViewport from '../../../../src/state/scroll-viewport';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport {\n  getPreset,\n  addDroppable,\n  getDroppableDimension,\n  getFrame,\n} from '../../../util/dimension';\nimport scrollDroppable from '../../../../src/state/droppable/scroll-droppable';\nimport getMaxScroll from '../../../../src/state/get-max-scroll';\nimport jumpScroller, {\n  type JumpScroller,\n} from '../../../../src/state/auto-scroller/jump-scroller';\n\nconst origin: Position = { x: 0, y: 0 };\n\nconst windowScrollSize = {\n  scrollHeight: 2000,\n  scrollWidth: 1600,\n};\nconst scrollableViewport: Viewport = createViewport({\n  frame: getRect({\n    top: 0,\n    left: 0,\n    right: 800,\n    bottom: 1000,\n  }),\n  scrollHeight: windowScrollSize.scrollHeight,\n  scrollWidth: windowScrollSize.scrollWidth,\n  scroll: origin,\n});\n\nconst unscrollableViewport: Viewport = createViewport({\n  frame: scrollableViewport.frame,\n  scrollHeight: scrollableViewport.frame.height,\n  scrollWidth: scrollableViewport.frame.width,\n  scroll: origin,\n});\n\nlet jumpScroll: JumpScroller;\nlet mocks;\n\nbeforeEach(() => {\n  mocks = {\n    scrollWindow: jest.fn(),\n    scrollDroppable: jest.fn(),\n    move: jest.fn(),\n  };\n  jumpScroll = jumpScroller(mocks);\n});\n\nafterEach(() => {\n  requestAnimationFrame.reset();\n});\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on the ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const state = getStatePreset(axis);\n\n    describe('window scrolling', () => {\n      describe('moving forwards', () => {\n        it('should manually move the item if the window is unable to scroll', () => {\n          const request: Position = patch(axis.line, 1);\n          const withRequest: DraggingState = state.scrollJumpRequest(\n            request,\n            unscrollableViewport,\n          );\n          const expected: Position = add(\n            withRequest.current.client.selection,\n            request,\n          );\n\n          jumpScroll(withRequest);\n\n          expect(mocks.move).toHaveBeenCalledWith({\n            client: expected,\n          });\n          expect(mocks.scrollWindow).not.toHaveBeenCalled();\n        });\n\n        it('should scroll the window if can absorb all of the movement', () => {\n          const request: Position = patch(axis.line, 1);\n\n          jumpScroll(state.scrollJumpRequest(request, scrollableViewport));\n\n          expect(mocks.scrollWindow).toHaveBeenCalledWith(request);\n          expect(mocks.move).not.toHaveBeenCalled();\n        });\n\n        it('should manually move the item any distance that the window is unable to scroll', () => {\n          // only allowing scrolling by 1 px\n          const restricted: Viewport = withWindowScrollSize({\n            viewport: scrollableViewport,\n            scrollHeight: scrollableViewport.frame.height + 1,\n            scrollWidth: scrollableViewport.frame.width + 1,\n          });\n          // more than the 1 pixel allowed\n          const request: Position = patch(axis.line, 3);\n          const existing: DraggingState = state.scrollJumpRequest(\n            request,\n            restricted,\n          );\n          const expected: Position = add(\n            existing.current.client.selection,\n            // the two pixels that could not be done by the window\n            patch(axis.line, 2),\n          );\n\n          jumpScroll(state.scrollJumpRequest(request, restricted));\n\n          // can scroll with what we have\n          expect(mocks.scrollWindow).toHaveBeenCalledWith(patch(axis.line, 1));\n          // remainder to be done by movement\n          expect(mocks.move).toHaveBeenCalledWith({\n            client: expected,\n          });\n        });\n      });\n\n      describe('moving backwards', () => {\n        it('should manually move the item if the window is unable to scroll', () => {\n          // unable to scroll backwards to start with\n          const request: Position = patch(axis.line, -1);\n          const existing: DraggingState = state.scrollJumpRequest(\n            request,\n            unscrollableViewport,\n          );\n          const expected: Position = add(\n            existing.current.client.selection,\n            request,\n          );\n\n          jumpScroll(existing);\n\n          expect(mocks.move).toHaveBeenCalledWith({\n            client: expected,\n          });\n          expect(mocks.scrollWindow).not.toHaveBeenCalled();\n        });\n\n        it('should scroll the window if can absorb all of the movement', () => {\n          const scrolled: Viewport = scrollViewport(\n            scrollableViewport,\n            patch(axis.line, 1),\n          );\n          const request: Position = patch(axis.line, -1);\n\n          jumpScroll(state.scrollJumpRequest(request, scrolled));\n\n          expect(mocks.scrollWindow).toHaveBeenCalledWith(request);\n          expect(mocks.move).not.toHaveBeenCalled();\n        });\n\n        it('should manually move the item any distance that the window is unable to scroll', () => {\n          // only allowing scrolling by 1 px\n          const windowScroll: Position = patch(axis.line, 1);\n          const scrolled: Viewport = scrollViewport(\n            scrollableViewport,\n            windowScroll,\n          );\n          // more than the 1 pixel allowed\n          const request: Position = patch(axis.line, -3);\n          const existing: DraggingState = state.scrollJumpRequest(\n            request,\n            scrolled,\n          );\n          const expected: Position = add(\n            existing.current.client.selection,\n            // the two pixels that could not be done by the window\n            patch(axis.line, -2),\n          );\n\n          jumpScroll(existing);\n\n          // can scroll with what we have\n          expect(mocks.scrollWindow).toHaveBeenCalledWith(patch(axis.line, -1));\n          // remainder to be done by movement\n          expect(mocks.move).toHaveBeenCalledWith({\n            client: expected,\n          });\n        });\n      });\n\n      it('should not scroll the window if window scrolling is disabled', () => {\n        const request: Position = patch(axis.line, 1);\n        const existing: DraggingState = {\n          ...state.scrollJumpRequest(request, scrollableViewport),\n          isWindowScrollAllowed: false,\n        };\n\n        jumpScroll(existing);\n\n        // window not scrolled\n        expect(mocks.scrollWindow).not.toHaveBeenCalledWith(request);\n        // manual move occurred\n        const expected: Position = add(\n          existing.current.client.selection,\n          // do all the movement with manual moving\n          request,\n        );\n        expect(mocks.move).toHaveBeenCalledWith({ client: expected });\n      });\n    });\n\n    describe('droppable scrolling (which can involve some window scrolling)', () => {\n      const scrollableScrollSize = {\n        scrollWidth: 800,\n        scrollHeight: 800,\n      };\n      const frameClient: BoxModel = createBox({\n        borderBox: {\n          top: 0,\n          left: 0,\n          right: 600,\n          bottom: 600,\n        },\n      });\n      const scrollable: DroppableDimension = getDroppableDimension({\n        // stealing the home descriptor so that the dragging item will\n        // be within in\n        descriptor: preset.home.descriptor,\n        borderBox: {\n          top: 0,\n          left: 0,\n          // bigger than the frame\n          right: scrollableScrollSize.scrollWidth,\n          bottom: scrollableScrollSize.scrollHeight,\n        },\n        closest: {\n          borderBox: frameClient.borderBox,\n          scrollSize: {\n            scrollWidth: scrollableScrollSize.scrollWidth,\n            scrollHeight: scrollableScrollSize.scrollHeight,\n          },\n          scroll: { x: 0, y: 0 },\n          shouldClipSubject: true,\n        },\n      });\n\n      const maxDroppableScroll: Position = getFrame(scrollable).scroll.max;\n\n      describe('moving forwards', () => {\n        describe('droppable is able to complete entire scroll', () => {\n          it('should only scroll the droppable', () => {\n            const request: Position = patch(axis.line, 1);\n\n            jumpScroll(\n              addDroppable(\n                state.scrollJumpRequest(request, unscrollableViewport),\n                scrollable,\n              ),\n            );\n\n            expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n              scrollable.descriptor.id,\n              request,\n            );\n            expect(mocks.scrollWindow).not.toHaveBeenCalled();\n            expect(mocks.move).not.toHaveBeenCalled();\n          });\n        });\n\n        describe('droppable is unable to complete the entire scroll', () => {\n          it('should manually move the entire request if it is unable to be partially completed by the window or the droppable', () => {\n            // droppable can no longer be scrolled\n            const scrolled: DroppableDimension = scrollDroppable(\n              scrollable,\n              maxDroppableScroll,\n            );\n            const request: Position = patch(axis.line, 1);\n            const existing: DraggingState = state.scrollJumpRequest(\n              request,\n              unscrollableViewport,\n            );\n            const expected: Position = add(\n              existing.current.client.selection,\n              request,\n            );\n\n            jumpScroll(addDroppable(existing, scrolled));\n\n            expect(mocks.scrollWindow).not.toHaveBeenCalled();\n            expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n            expect(mocks.move).toHaveBeenCalledWith({\n              client: expected,\n            });\n          });\n\n          describe('window is unable to absorb some of the scroll', () => {\n            it('should scroll the droppable what it can and move the rest', () => {\n              // able to scroll 1 pixel forward\n              const availableScroll: Position = patch(axis.line, 1);\n              const scroll: Position = subtract(\n                maxDroppableScroll,\n                availableScroll,\n              );\n              const scrolled: DroppableDimension = scrollDroppable(\n                scrollable,\n                scroll,\n              );\n              // want to move 3 pixels\n              const request: Position = patch(axis.line, 3);\n              const existing: DraggingState = state.scrollJumpRequest(\n                request,\n                unscrollableViewport,\n              );\n              const expectedManualMove: Position = add(\n                existing.current.client.selection,\n                patch(axis.line, 2),\n              );\n\n              jumpScroll(addDroppable(existing, scrolled));\n\n              expect(mocks.scrollWindow).not.toHaveBeenCalled();\n              expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n                preset.home.descriptor.id,\n                availableScroll,\n              );\n              expect(mocks.move).toHaveBeenCalledWith({\n                client: expectedManualMove,\n              });\n            });\n          });\n\n          describe('window can absorb some of the scroll', () => {\n            it('should scroll the entire overlap if it can', () => {\n              const availableScroll: Position = patch(axis.line, 1);\n              const scroll: Position = subtract(\n                maxDroppableScroll,\n                availableScroll,\n              );\n              const scrolled: DroppableDimension = scrollDroppable(\n                scrollable,\n                scroll,\n              );\n              // want to move 3 pixels\n              const request: Position = patch(axis.line, 3);\n\n              jumpScroll(\n                addDroppable(\n                  state.scrollJumpRequest(request, scrollableViewport),\n                  scrolled,\n                ),\n              );\n\n              expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n                scrolled.descriptor.id,\n                availableScroll,\n              );\n              expect(mocks.scrollWindow).toHaveBeenCalledWith(\n                patch(axis.line, 2),\n              );\n              expect(mocks.move).not.toHaveBeenCalled();\n            });\n\n            it('should scroll the droppable and window by what it can, and manually move the rest', () => {\n              // Setting the window scroll so it has a small amount of available space\n              const availableWindowScroll: Position = patch(axis.line, 2);\n              const maxWindowScroll: Position = getMaxScroll({\n                scrollHeight: windowScrollSize.scrollHeight,\n                scrollWidth: windowScrollSize.scrollWidth,\n                height: scrollableViewport.frame.height,\n                width: scrollableViewport.frame.width,\n              });\n              const windowScroll: Position = subtract(\n                maxWindowScroll,\n                availableWindowScroll,\n              );\n              // setWindowScroll(windowScroll);\n              const scrolledViewport: Viewport = scrollViewport(\n                scrollableViewport,\n                windowScroll,\n              );\n              // Setting the droppable scroll so it has a small amount of available space\n              const availableDroppableScroll: Position = patch(axis.line, 1);\n              const droppableScroll: Position = subtract(\n                maxDroppableScroll,\n                availableDroppableScroll,\n              );\n              const scrolled: DroppableDimension = scrollDroppable(\n                scrollable,\n                droppableScroll,\n              );\n              // How much we want to scroll\n              const request: Position = patch(axis.line, 5);\n              // How much we will not be able to absorb with droppable and window scroll\n              const remainder: Position = subtract(\n                subtract(request, availableDroppableScroll),\n                availableWindowScroll,\n              );\n              const existing: DraggingState = addDroppable(\n                state.scrollJumpRequest(request, scrolledViewport),\n                scrolled,\n              );\n              const expectedManualMove: Position = add(\n                existing.current.client.selection,\n                remainder,\n              );\n\n              jumpScroll(existing);\n\n              expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n                scrolled.descriptor.id,\n                availableDroppableScroll,\n              );\n              expect(mocks.scrollWindow).toHaveBeenCalledWith(\n                availableWindowScroll,\n              );\n              expect(mocks.move).toHaveBeenCalledWith({\n                client: expectedManualMove,\n              });\n            });\n          });\n        });\n      });\n\n      describe('moving backwards', () => {\n        describe('droppable is able to complete entire scroll', () => {\n          it('should only scroll the droppable', () => {\n            // move forward slightly to allow us to move forwards\n            const scrolled: DroppableDimension = scrollDroppable(\n              scrollable,\n              patch(axis.line, 1),\n            );\n            const request: Position = patch(axis.line, -1);\n\n            jumpScroll(\n              addDroppable(\n                state.scrollJumpRequest(request, scrollableViewport),\n                scrolled,\n              ),\n            );\n\n            expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n              scrolled.descriptor.id,\n              request,\n            );\n            expect(mocks.scrollWindow).not.toHaveBeenCalled();\n            expect(mocks.move).not.toHaveBeenCalled();\n          });\n        });\n\n        describe('droppable is unable to complete the entire scroll', () => {\n          it('should manually move the entire request if it is unable to be partially completed by the window or the droppable', () => {\n            const request: Position = patch(axis.line, -1);\n            const existing: DraggingState = state.scrollJumpRequest(\n              request,\n              unscrollableViewport,\n            );\n            const expected: Position = add(\n              existing.current.client.selection,\n              request,\n            );\n\n            jumpScroll(addDroppable(existing, scrollable));\n\n            expect(mocks.scrollWindow).not.toHaveBeenCalled();\n            expect(mocks.scrollDroppable).not.toHaveBeenCalled();\n            expect(mocks.move).toHaveBeenCalledWith({\n              client: expected,\n            });\n          });\n\n          describe('window is unable to absorb some of the scroll', () => {\n            it('should scroll the droppable what it can and move the rest', () => {\n              // able to scroll 1 pixel forward\n              const scrolled: DroppableDimension = scrollDroppable(\n                scrollable,\n                patch(axis.line, 1),\n              );\n              // want to move backwards 3 pixels\n              const request: Position = patch(axis.line, -3);\n              const existing: DraggingState = state.scrollJumpRequest(\n                request,\n                unscrollableViewport,\n              );\n              // manual move will take what the droppable cannot\n              const expectedManualMove: Position = add(\n                existing.current.client.selection,\n                patch(axis.line, -2),\n              );\n\n              jumpScroll(addDroppable(existing, scrolled));\n\n              expect(mocks.scrollWindow).not.toHaveBeenCalled();\n              expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n                preset.home.descriptor.id,\n                // can only scroll backwards what it has!\n                patch(axis.line, -1),\n              );\n              expect(mocks.move).toHaveBeenCalledWith({\n                client: expectedManualMove,\n              });\n            });\n          });\n\n          describe('window can absorb some of the scroll', () => {\n            it('should scroll the entire overlap if it can', () => {\n              // let the window scroll be enough to move back into\n              const scrolledViewport: Viewport = scrollViewport(\n                scrollableViewport,\n                patch(axis.line, 100),\n              );\n              const scrolledDroppable: DroppableDimension = scrollDroppable(\n                scrollable,\n                patch(axis.line, 1),\n              );\n              // want to move 3 pixels backwards\n              const request: Position = patch(axis.line, -3);\n\n              jumpScroll(\n                addDroppable(\n                  state.scrollJumpRequest(request, scrolledViewport),\n                  scrolledDroppable,\n                ),\n              );\n\n              expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n                scrolledDroppable.descriptor.id,\n                patch(axis.line, -1),\n              );\n              expect(mocks.scrollWindow).toHaveBeenCalledWith(\n                patch(axis.line, -2),\n              );\n              expect(mocks.move).not.toHaveBeenCalled();\n            });\n\n            it('should scroll the droppable and window by what it can, and manually move the rest', () => {\n              // Setting the window scroll so it has a small amount of available space\n              const windowScroll: Position = patch(axis.line, 2);\n              const scrolledViewport: Viewport = scrollViewport(\n                scrollableViewport,\n                windowScroll,\n              );\n              // Setting the droppable scroll so it has a small amount of available space\n              const droppableScroll: Position = patch(axis.line, 1);\n              const scrolled: DroppableDimension = scrollDroppable(\n                scrollable,\n                droppableScroll,\n              );\n              // How much we want to scroll\n              const request: Position = patch(axis.line, -5);\n              // How much we will not be able to absorb with droppable and window scroll\n              const remainder: Position = patch(axis.line, -2);\n              const existing: DraggingState = addDroppable(\n                state.scrollJumpRequest(request, scrolledViewport),\n                scrolled,\n              );\n              const expectedManualMove: Position = add(\n                existing.current.client.selection,\n                remainder,\n              );\n\n              jumpScroll(existing);\n\n              expect(mocks.scrollDroppable).toHaveBeenCalledWith(\n                scrolled.descriptor.id,\n                negate(droppableScroll),\n              );\n              expect(mocks.scrollWindow).toHaveBeenCalledWith(\n                negate(windowScroll),\n              );\n              expect(mocks.move).toHaveBeenCalledWith({\n                client: expectedManualMove,\n              });\n            });\n          });\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/can-start-drag.spec.js",
    "content": "// @flow\nimport canStartDrag from '../../../src/state/can-start-drag';\nimport getStatePreset from '../../util/get-simple-state-preset';\nimport { getPreset } from '../../util/dimension';\n\nconst preset = getPreset();\nconst state = getStatePreset();\n\ndescribe('can start drag', () => {\n  it('should allow lifting if in IDLE phase', () => {\n    expect(canStartDrag(state.idle, preset.inHome1.descriptor.id)).toBe(true);\n  });\n\n  it('should not allow lifting in the COLLECTING phase', () => {\n    expect(canStartDrag(state.collecting(), preset.inHome1.descriptor.id)).toBe(\n      false,\n    );\n  });\n\n  it('should not allow lifting in the DRAGGING phase', () => {\n    expect(canStartDrag(state.dragging(), preset.inHome1.descriptor.id)).toBe(\n      false,\n    );\n  });\n\n  it('should not allow lifting in the DROP_PENDING phase', () => {\n    expect(\n      canStartDrag(state.dropPending(), preset.inHome1.descriptor.id),\n    ).toBe(false);\n  });\n\n  describe('while animating drop', () => {\n    it('should allow lifting if dropping another item', () => {\n      expect(\n        canStartDrag(\n          state.dropAnimating(preset.inHome1.descriptor.id),\n          preset.inHome2.descriptor.id,\n        ),\n      ).toBe(true);\n    });\n\n    it('should disallow lifting if dropping the same item', () => {\n      expect(\n        canStartDrag(\n          state.dropAnimating(preset.inHome1.descriptor.id),\n          preset.inHome1.descriptor.id,\n        ),\n      ).toBe(false);\n    });\n\n    it('should disallow lifting while animating user cancel', () => {\n      expect(\n        canStartDrag(\n          state.userCancel(preset.inHome1.descriptor.id),\n          preset.inHome1.descriptor.id,\n        ),\n      ).toBe(false);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/dimension-structures.spec.js",
    "content": "// @flow\nimport {\n  toDraggableList,\n  toDraggableMap,\n  toDroppableMap,\n  toDroppableList,\n} from '../../../src/state/dimension-structures';\nimport { getPreset } from '../../util/dimension';\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n  DroppableDimensionMap,\n} from '../../../src/types';\n\nconst preset = getPreset();\n\nconst draggables: DraggableDimension[] = [preset.inHome1, preset.inHome2];\nconst droppables: DroppableDimension[] = [preset.home, preset.foreign];\n\nconst draggableMap: DraggableDimensionMap = {\n  [preset.inHome1.descriptor.id]: preset.inHome1,\n  [preset.inHome2.descriptor.id]: preset.inHome2,\n};\n\nconst droppableMap: DroppableDimensionMap = {\n  [preset.home.descriptor.id]: preset.home,\n  [preset.foreign.descriptor.id]: preset.foreign,\n};\n\nit('should convert a draggable list to a map', () => {\n  expect(toDraggableMap(draggables)).toEqual(draggableMap);\n});\n\nit('should convert a droppable list to a map', () => {\n  expect(toDroppableMap(droppables)).toEqual(droppableMap);\n});\n\nit('should convert a draggable map to a list', () => {\n  expect(toDraggableList(draggableMap)).toEqual(draggables);\n});\n\nit('should convert a droppable map to a list', () => {\n  expect(toDroppableList(droppableMap)).toEqual(droppables);\n});\n"
  },
  {
    "path": "test/unit/state/droppable/clip.spec.js",
    "content": "// @flow\nimport { getRect, type Spacing } from 'css-box-model';\nimport clip from '../../../../src/state/droppable/util/clip';\nimport { offsetByPosition } from '../../../../src/state/spacing';\n\nit('should select clip a subject in a frame', () => {\n  const subject: Spacing = {\n    top: 0,\n    left: 0,\n    right: 100,\n    bottom: 100,\n  };\n  const frame: Spacing = {\n    top: 20,\n    left: 20,\n    right: 50,\n    bottom: 50,\n  };\n\n  expect(clip(frame, subject)).toEqual(getRect(frame));\n});\n\nit('should return null when the subject it outside the frame on any side', () => {\n  const frame: Spacing = {\n    top: 0,\n    left: 0,\n    right: 100,\n    bottom: 100,\n  };\n  const outside: Spacing[] = [\n    // top\n    offsetByPosition(frame, { x: 0, y: -200 }),\n    // right\n    offsetByPosition(frame, { x: 200, y: 0 }),\n    // bottom\n    offsetByPosition(frame, { x: 0, y: 200 }),\n    // left\n    offsetByPosition(frame, { x: -200, y: 0 }),\n  ];\n\n  outside.forEach((subject: Spacing) => {\n    expect(clip(frame, subject)).toEqual(null);\n  });\n});\n"
  },
  {
    "path": "test/unit/state/droppable/get-droppable.spec.js",
    "content": "// @flow\nimport {\n  createBox,\n  withScroll,\n  type BoxModel,\n  type Spacing,\n  type Position,\n} from 'css-box-model';\nimport { invariant } from '../../../../src/invariant';\nimport getDroppableDimension from '../../../../src/state/droppable/get-droppable';\nimport { noSpacing } from '../../../../src/state/spacing';\nimport getMaxScroll from '../../../../src/state/get-max-scroll';\nimport { expandBySpacing } from '../../../util/spacing';\nimport type {\n  DroppableDescriptor,\n  DroppableDimension,\n  ScrollSize,\n  Scrollable,\n} from '../../../../src/types';\n\nconst descriptor: DroppableDescriptor = {\n  id: 'drop-1',\n  type: 'TYPE',\n  mode: 'standard',\n};\n\nconst margin: Spacing = {\n  top: 1,\n  right: 2,\n  bottom: 3,\n  left: 4,\n};\nconst padding: Spacing = {\n  top: 5,\n  right: 6,\n  bottom: 7,\n  left: 8,\n};\nconst border: Spacing = {\n  top: 9,\n  right: 10,\n  bottom: 11,\n  left: 12,\n};\nconst windowScroll: Position = {\n  x: 50,\n  y: 80,\n};\nconst origin: Position = { x: 0, y: 0 };\n\nconst client: BoxModel = createBox({\n  borderBox: {\n    top: 10,\n    right: 110,\n    bottom: 90,\n    left: 20,\n  },\n  margin,\n  padding,\n  border,\n});\nconst page: BoxModel = withScroll(client, windowScroll);\nconst ten: Spacing = {\n  top: 10,\n  right: 10,\n  bottom: 10,\n  left: 10,\n};\n\ndescribe('closest scrollable', () => {\n  describe('no closest scrollable', () => {\n    it('should not have a closest scrollable if there is no closest scrollable', () => {\n      const dimension: DroppableDimension = getDroppableDimension({\n        descriptor,\n        isEnabled: true,\n        isCombineEnabled: false,\n        isFixedOnPage: false,\n        client,\n        page,\n        direction: 'vertical',\n        closest: null,\n      });\n\n      expect(dimension.frame).toBe(null);\n    });\n  });\n\n  describe('with a closest scrollable', () => {\n    const dimension: DroppableDimension = getDroppableDimension({\n      descriptor,\n      isEnabled: true,\n      client,\n      page,\n      direction: 'vertical',\n      isCombineEnabled: false,\n      isFixedOnPage: false,\n      closest: {\n        client,\n        page,\n        scrollSize: {\n          scrollHeight: client.paddingBox.height,\n          scrollWidth: client.paddingBox.width,\n        },\n        scroll: { x: 10, y: 10 },\n        shouldClipSubject: true,\n      },\n    });\n\n    it('should offset the frame client by the window scroll', () => {\n      invariant(dimension.frame);\n      expect(dimension.frame.pageMarginBox).toEqual(page.marginBox);\n    });\n\n    it('should capture the frame information', () => {\n      const scrollSize: ScrollSize = {\n        scrollHeight: client.paddingBox.height,\n        scrollWidth: client.paddingBox.width,\n      };\n      const maxScroll: Position = getMaxScroll({\n        // scrollHeight and scrollWidth are based on the padding box\n        scrollHeight: scrollSize.scrollHeight,\n        scrollWidth: scrollSize.scrollWidth,\n        height: client.paddingBox.height,\n        width: client.paddingBox.width,\n      });\n      const expected: Scrollable = {\n        pageMarginBox: page.marginBox,\n        frameClient: client,\n        scrollSize,\n        shouldClipSubject: true,\n        scroll: {\n          initial: { x: 10, y: 10 },\n          current: { x: 10, y: 10 },\n          max: maxScroll,\n          diff: {\n            value: { x: 0, y: 0 },\n            displacement: { x: 0, y: 0 },\n          },\n        },\n      };\n\n      expect(dimension.frame).toEqual(expected);\n    });\n  });\n\n  describe('frame clipping', () => {\n    const frameClient: BoxModel = createBox({\n      // bigger on every side by 10px\n      borderBox: expandBySpacing(client.borderBox, ten),\n      margin,\n      border,\n      padding,\n    });\n    const framePage: BoxModel = withScroll(frameClient, windowScroll);\n\n    type Options = {|\n      shouldClipSubject: boolean,\n    |};\n\n    const defaultOptions: Options = { shouldClipSubject: true };\n\n    const getWithClient = (\n      customClient: BoxModel,\n      options?: Options = defaultOptions,\n    ): DroppableDimension =>\n      getDroppableDimension({\n        descriptor,\n        isEnabled: true,\n        client: customClient,\n        page: withScroll(customClient, windowScroll),\n        isCombineEnabled: false,\n        isFixedOnPage: false,\n        direction: 'vertical',\n        closest: {\n          client: frameClient,\n          page: framePage,\n          scrollSize: {\n            scrollHeight: client.paddingBox.height,\n            scrollWidth: client.paddingBox.width,\n          },\n          scroll: origin,\n          shouldClipSubject: options.shouldClipSubject,\n        },\n      });\n\n    it('should not clip the frame if requested not to', () => {\n      const expandedClient: BoxModel = createBox({\n        borderBox: expandBySpacing(frameClient.borderBox, ten),\n        margin,\n        padding,\n        border,\n      });\n      const expandedPage: BoxModel = withScroll(expandedClient, windowScroll);\n      const bigClient: BoxModel = createBox({\n        borderBox: expandedClient.borderBox,\n        margin,\n        padding,\n        border,\n      });\n\n      const droppable: DroppableDimension = getWithClient(bigClient, {\n        shouldClipSubject: false,\n      });\n\n      // Not clipped\n      expect(droppable.subject.active).toEqual(expandedPage.marginBox);\n      invariant(droppable.frame);\n      expect(droppable.frame.shouldClipSubject).toBe(false);\n    });\n\n    describe('frame is the same size as the subject', () => {\n      it('should not clip the subject', () => {\n        const droppable: DroppableDimension = getWithClient(frameClient);\n\n        expect(droppable.subject.active).toEqual(framePage.marginBox);\n      });\n    });\n\n    describe('frame is smaller than subject', () => {\n      it('should clip the subject to the size of the frame', () => {\n        const bigClient: BoxModel = createBox({\n          // expanding by 10px on each side\n          borderBox: expandBySpacing(frameClient.borderBox, ten),\n          margin,\n          padding,\n          border,\n        });\n\n        const droppable: DroppableDimension = getWithClient(bigClient);\n\n        expect(droppable.subject.active).toEqual(framePage.marginBox);\n      });\n    });\n\n    describe('frame is larger than subject', () => {\n      it('should return a clipped size that is equal to that of the subject', () => {\n        // client is already smaller than frame\n        const droppable: DroppableDimension = getWithClient(client);\n\n        expect(droppable.subject.active).toEqual(page.marginBox);\n      });\n    });\n\n    describe('subject clipped on one side by frame', () => {\n      it('should clip on all sides', () => {\n        // each of these subjects bleeds out past the frame in one direction\n        const changes: Spacing[] = [\n          { top: -10, ...noSpacing },\n          { left: -10, ...noSpacing },\n          { bottom: 10, ...noSpacing },\n          { right: 10, ...noSpacing },\n        ];\n\n        changes.forEach((expandBy: Spacing) => {\n          const custom: BoxModel = createBox({\n            borderBox: expandBySpacing(frameClient.borderBox, expandBy),\n            margin,\n            padding,\n            border,\n          });\n\n          const droppable: DroppableDimension = getWithClient(custom);\n\n          expect(droppable.subject.active).toEqual(framePage.marginBox);\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/droppable/get-subject.spec.js",
    "content": "// @flow\nimport {\n  type Spacing,\n  type Position,\n  type BoxModel,\n  type Rect,\n  getRect,\n  createBox,\n} from 'css-box-model';\nimport type {\n  Axis,\n  DroppableSubject,\n  Scrollable,\n  ScrollSize,\n} from '../../../../src/types';\nimport getSubject from '../../../../src/state/droppable/util/get-subject';\nimport { withAssortedSpacing } from '../../../util/dimension';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport { origin, negate, patch } from '../../../../src/state/position';\nimport { offsetByPosition } from '../../../../src/state/spacing';\nimport getMaxScroll from '../../../../src/state/get-max-scroll';\n\nconst borderBox: Spacing = {\n  top: 0,\n  left: 0,\n  right: 100,\n  bottom: 100,\n};\nconst page: BoxModel = createBox({ borderBox, ...withAssortedSpacing() });\n\nit('should displace by the droppable scroll', () => {\n  const scroll: Position = { x: 10, y: 20 };\n  const displacement: Position = negate(scroll);\n  const scrollSize: ScrollSize = {\n    scrollHeight: 100,\n    scrollWidth: 100,\n  };\n  const max: Position = getMaxScroll({\n    ...scrollSize,\n    height: page.marginBox.height,\n    width: page.marginBox.width,\n  });\n  const frame: Scrollable = {\n    // same as subject\n    pageMarginBox: page.marginBox,\n    // no window scroll\n    frameClient: page,\n    scrollSize,\n    // ignoring clipping for this test\n    shouldClipSubject: false,\n    scroll: {\n      initial: origin,\n      current: scroll,\n      max,\n      diff: {\n        value: scroll,\n        displacement,\n      },\n    },\n  };\n\n  const result: DroppableSubject = getSubject({\n    page,\n    withPlaceholder: null,\n    axis: vertical,\n    frame,\n  });\n\n  const expected: DroppableSubject = {\n    page,\n    withPlaceholder: null,\n    active: getRect(offsetByPosition(page.marginBox, displacement)),\n  };\n  expect(result).toEqual(expected);\n});\n\nit('should increase the subject by a placeholder', () => {\n  [vertical, horizontal].forEach((axis: Axis) => {\n    const increasedBy: Position = patch(axis.line, 100);\n\n    const result: DroppableSubject = getSubject({\n      page,\n      withPlaceholder: {\n        increasedBy,\n        placeholderSize: increasedBy,\n        oldFrameMaxScroll: null,\n      },\n      axis,\n      frame: null,\n    });\n\n    const expected: Rect = getRect({\n      ...page.marginBox,\n      [axis.end]: page.marginBox[axis.end] + increasedBy[axis.line],\n    });\n    expect(result.active).toEqual(expected);\n  });\n});\n\n// other clipping tests covered in 'clip.spec.js'\nit('should clip the subject by a frame', () => {\n  // frame is smaller than pageMarginBox by 10px on every side\n  const frameBorderBox: Rect = getRect({\n    top: 10,\n    left: 10,\n    right: 90,\n    bottom: 90,\n  });\n  const frame: Scrollable = {\n    pageMarginBox: frameBorderBox,\n    frameClient: createBox({\n      borderBox: frameBorderBox,\n    }),\n    scrollSize: {\n      scrollHeight: frameBorderBox.height,\n      scrollWidth: frameBorderBox.width,\n    },\n    shouldClipSubject: true,\n    scroll: {\n      initial: origin,\n      current: origin,\n      max: origin,\n      diff: {\n        value: origin,\n        displacement: origin,\n      },\n    },\n  };\n\n  const result: DroppableSubject = getSubject({\n    page,\n    withPlaceholder: null,\n    axis: vertical,\n    frame,\n  });\n\n  const expected: DroppableSubject = {\n    page,\n    withPlaceholder: null,\n    active: frameBorderBox,\n  };\n  expect(result).toEqual(expected);\n});\n\nit('should do nothing if there is no scroll, placeholder or frame', () => {\n  const result: DroppableSubject = getSubject({\n    page,\n    axis: vertical,\n    withPlaceholder: null,\n    frame: null,\n  });\n\n  const expected: DroppableSubject = {\n    page,\n    withPlaceholder: null,\n    active: page.marginBox,\n  };\n  expect(result).toEqual(expected);\n});\n"
  },
  {
    "path": "test/unit/state/droppable/is-home-of.spec.js",
    "content": "// @flow\nimport { getPreset } from '../../../util/dimension';\nimport isHomeOf from '../../../../src/state/droppable/is-home-of';\n\nconst preset = getPreset();\n\nit('should return true if destination is home of draggable', () => {\n  expect(isHomeOf(preset.inHome1, preset.home)).toBe(true);\n  expect(isHomeOf(preset.inHome2, preset.home)).toBe(true);\n  expect(isHomeOf(preset.inForeign1, preset.foreign)).toBe(true);\n});\n\nit('should return false if destination is not home of draggable', () => {\n  expect(isHomeOf(preset.inForeign1, preset.home)).toBe(false);\n  expect(isHomeOf(preset.inHome1, preset.foreign)).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/state/droppable/scroll-droppable.spec.js",
    "content": "// @flow\nimport {\n  type BoxModel,\n  type Position,\n  createBox,\n  getRect,\n} from 'css-box-model';\nimport { invariant } from '../../../../src/invariant';\nimport type {\n  ScrollSize,\n  DroppableDimension,\n  DroppableDescriptor,\n  Scrollable,\n  ScrollDetails,\n} from '../../../../src/types';\nimport getDroppable from '../../../../src/state/droppable/get-droppable';\nimport scrollDroppable from '../../../../src/state/droppable/scroll-droppable';\nimport { negate } from '../../../../src/state/position';\nimport getMaxScroll from '../../../../src/state/get-max-scroll';\n\nconst descriptor: DroppableDescriptor = {\n  id: 'drop-1',\n  type: 'TYPE',\n  mode: 'standard',\n};\n\nit('should update the frame scroll and the subject', () => {\n  const scrollSize: ScrollSize = {\n    scrollHeight: 500,\n    scrollWidth: 100,\n  };\n  const customClient: BoxModel = createBox({\n    borderBox: {\n      // 500 px high\n      top: 0,\n      left: 0,\n      bottom: scrollSize.scrollHeight,\n      right: scrollSize.scrollWidth,\n    },\n  });\n  const customPage: BoxModel = customClient;\n  const frameClient: BoxModel = createBox({\n    borderBox: {\n      // only viewing top 100px\n      bottom: 100,\n      // unchanged\n      top: 0,\n      right: scrollSize.scrollWidth,\n      left: 0,\n    },\n  });\n  const framePage: BoxModel = frameClient;\n  const originalFrameScroll: Position = { x: 0, y: 0 };\n  const droppable: DroppableDimension = getDroppable({\n    descriptor,\n    client: customClient,\n    page: customPage,\n    direction: 'vertical',\n    isEnabled: true,\n    isCombineEnabled: false,\n    isFixedOnPage: false,\n    closest: {\n      client: frameClient,\n      page: framePage,\n      scrollSize,\n      scroll: originalFrameScroll,\n      shouldClipSubject: true,\n    },\n  });\n\n  const originalFrame: ?Scrollable = droppable.frame;\n  invariant(originalFrame);\n  // original frame\n  expect(originalFrame.pageMarginBox).toEqual(framePage.marginBox);\n  // subject is currently clipped by the frame\n  expect(droppable.subject.active).toEqual(framePage.marginBox);\n\n  // scrolling down\n  const newScroll: Position = { x: 0, y: 100 };\n  const updated: DroppableDimension = scrollDroppable(droppable, newScroll);\n  const updatedFrame: ?Scrollable = updated.frame;\n  invariant(updatedFrame);\n\n  // unchanged frame client\n  expect(updatedFrame.frameClient).toEqual(originalFrame.frameClient);\n  expect(updatedFrame.pageMarginBox).toEqual(framePage.marginBox);\n\n  // updated scroll info\n  {\n    const expected: ScrollDetails = {\n      initial: originalFrameScroll,\n      current: newScroll,\n      diff: {\n        value: newScroll,\n        displacement: negate(newScroll),\n      },\n      max: getMaxScroll({\n        scrollWidth: scrollSize.scrollWidth,\n        scrollHeight: scrollSize.scrollHeight,\n        width: frameClient.paddingBox.width,\n        height: frameClient.paddingBox.height,\n      }),\n    };\n    expect(updatedFrame.scroll).toEqual(expected);\n  }\n\n  // updated clipped\n  // can now see the bottom half of the subject\n  expect(updated.subject.active).toEqual(\n    getRect({\n      top: 0,\n      bottom: 100,\n      // unchanged\n      right: 100,\n      left: 0,\n    }),\n  );\n});\n\nit('should allow scrolling beyond the max position', () => {\n  const customClient: BoxModel = createBox({\n    borderBox: {\n      top: 0,\n      left: 0,\n      right: 200,\n      bottom: 200,\n    },\n  });\n  const frameClient: BoxModel = createBox({\n    borderBox: {\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 100,\n    },\n  });\n  // this is to allow for scrolling into a foreign placeholder\n  const scrollable: DroppableDimension = getDroppable({\n    descriptor,\n    client: customClient,\n    page: customClient,\n    isEnabled: true,\n    direction: 'vertical',\n    isCombineEnabled: false,\n    isFixedOnPage: false,\n    closest: {\n      client: frameClient,\n      page: frameClient,\n      scrollSize: {\n        scrollWidth: 200,\n        scrollHeight: 200,\n      },\n      scroll: { x: 0, y: 0 },\n      shouldClipSubject: true,\n    },\n  });\n  const originalFrame: ?Scrollable = scrollable.frame;\n  invariant(originalFrame);\n\n  const scrolled: DroppableDimension = scrollDroppable(scrollable, {\n    x: 300,\n    y: 300,\n  });\n\n  // current is larger than max\n  const updatedFrame: ?Scrollable = scrolled.frame;\n  invariant(updatedFrame);\n  expect(updatedFrame.scroll.current).toEqual({\n    x: 300,\n    y: 300,\n  });\n  // current max is unchanged\n  expect(updatedFrame.scroll.max).toEqual(originalFrame.scroll.max);\n});\n"
  },
  {
    "path": "test/unit/state/droppable/what-is-dragged-over.spec.js",
    "content": "// @flow\nimport noImpact from '../../../../src/state/no-impact';\nimport whatIsDraggedOver from '../../../../src/state/droppable/what-is-dragged-over';\nimport type {\n  DraggableLocation,\n  DragImpact,\n  CombineImpact,\n} from '../../../../src/types';\n\nit('should return the droppableId of a reorder impact', () => {\n  const destination: DraggableLocation = {\n    droppableId: 'droppable',\n    index: 0,\n  };\n  const impact: DragImpact = {\n    ...noImpact,\n    at: {\n      type: 'REORDER',\n      destination,\n    },\n  };\n  expect(whatIsDraggedOver(impact)).toEqual(destination.droppableId);\n});\n\nit('should return the droppableId from a merge impact', () => {\n  const at: CombineImpact = {\n    type: 'COMBINE',\n    combine: {\n      draggableId: 'draggable',\n      droppableId: 'droppable',\n    },\n  };\n  const impact: DragImpact = {\n    ...noImpact,\n    at,\n  };\n  expect(whatIsDraggedOver(impact)).toEqual(at.combine.droppableId);\n});\n\nit('should return null when there is no destination or merge impact', () => {\n  expect(whatIsDraggedOver(noImpact)).toEqual(null);\n});\n"
  },
  {
    "path": "test/unit/state/droppable/with-placeholder.spec.js",
    "content": "// @flow\nimport { type Position, type Rect, getRect } from 'css-box-model';\nimport { invariant } from '../../../../src/invariant';\nimport type {\n  Axis,\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n  DroppableSubject,\n  DroppableDescriptor,\n  Scrollable,\n  DisplacedBy,\n} from '../../../../src/types';\nimport {\n  getDroppableDimension,\n  getDraggableDimension,\n} from '../../../util/dimension';\nimport {\n  addPlaceholder,\n  removePlaceholder,\n} from '../../../../src/state/droppable/with-placeholder';\nimport { toDraggableMap } from '../../../../src/state/dimension-structures';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport { add, patch, origin, isEqual } from '../../../../src/state/position';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\n\nconst crossAxisStart: number = 0;\nconst crossAxisEnd: number = 100;\nconst crossAxisSize: number = crossAxisEnd - crossAxisStart;\nconst droppableSize: number = 200;\nconst gap: number = 10;\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const descriptor: DroppableDescriptor = {\n      id: 'foo',\n      type: 'TYPE',\n      mode: 'standard',\n    };\n    const withoutFrame: DroppableDimension = getDroppableDimension({\n      descriptor,\n      direction: axis.direction,\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: 0,\n        [axis.end]: droppableSize,\n      },\n    });\n    const inForeign1: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'in-foreign-1',\n        index: 0,\n        droppableId: descriptor.id,\n        type: descriptor.type,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: 0,\n        [axis.end]: droppableSize / 2,\n      },\n    });\n\n    const inForeign2: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'in-foreign-2',\n        index: 1,\n        droppableId: descriptor.id,\n        type: descriptor.type,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: droppableSize / 2,\n        // leave a little gap before the end\n        [axis.end]: droppableSize - gap,\n      },\n    });\n\n    const getHomeDraggable = (borderBoxSize: number): DraggableDimension =>\n      getDraggableDimension({\n        descriptor: {\n          id: 'in-foreign-3',\n          index: 2,\n          droppableId: 'home',\n          type: descriptor.type,\n        },\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          [axis.start]: inForeign2.client.borderBox[axis.end],\n          [axis.end]: inForeign2.client.borderBox[axis.end] + borderBoxSize,\n        },\n      });\n\n    const withHomeDraggable = (\n      inHome1: DraggableDimension,\n    ): DraggableDimensionMap =>\n      toDraggableMap([inHome1, inForeign1, inForeign2]);\n\n    const getPlaceholderSize = (draggable: DraggableDimension): Position =>\n      patch(axis.line, draggable.displaceBy[axis.line]);\n\n    it('should throw an error if trying to add a placeholder to a home list', () => {\n      expect(() =>\n        addPlaceholder(\n          withoutFrame,\n          inForeign1,\n          toDraggableMap([inForeign1, inForeign2]),\n        ),\n      ).toThrow();\n    });\n\n    describe('without frame', () => {\n      describe('adding placeholder', () => {\n        it('should not grow the subject if not required', () => {\n          const inHome: DraggableDimension = getHomeDraggable(gap - 5);\n\n          const result: DroppableDimension = addPlaceholder(\n            withoutFrame,\n            inHome,\n            withHomeDraggable(inHome),\n          );\n\n          const expected: DroppableSubject = {\n            // unchanged\n            page: withoutFrame.subject.page,\n            active: withoutFrame.subject.active,\n            // added\n            withPlaceholder: {\n              increasedBy: null,\n              oldFrameMaxScroll: null,\n              placeholderSize: getPlaceholderSize(inHome),\n            },\n          };\n          expect(result.subject).toEqual(expected);\n        });\n\n        it('should grow the subject if required', () => {\n          const excess: number = 20;\n          const inHome: DraggableDimension = getHomeDraggable(gap + excess);\n\n          const result: DroppableDimension = addPlaceholder(\n            withoutFrame,\n            inHome,\n            withHomeDraggable(inHome),\n          );\n\n          const active: ?Rect = withoutFrame.subject.active;\n          invariant(active);\n          const expected: DroppableSubject = {\n            // unchanged\n            page: withoutFrame.subject.page,\n            // increased\n            active: getRect({\n              ...active,\n              [axis.end]: active[axis.end] + excess,\n            }),\n            // added\n            withPlaceholder: {\n              increasedBy: patch(axis.line, excess),\n              oldFrameMaxScroll: null,\n              placeholderSize: getPlaceholderSize(inHome),\n            },\n          };\n          expect(result.subject).toEqual(expected);\n        });\n      });\n\n      it('should restore the subject to its original size when placeholder is no longer needed', () => {\n        const excess: number = 20;\n        const inHome: DraggableDimension = getHomeDraggable(gap + excess);\n\n        const added: DroppableDimension = addPlaceholder(\n          withoutFrame,\n          inHome,\n          withHomeDraggable(inHome),\n        );\n        const removed: DroppableDimension = removePlaceholder(added);\n\n        expect(removed).toEqual(withoutFrame);\n      });\n    });\n\n    describe('with frame', () => {\n      const withFrame: DroppableDimension = getDroppableDimension({\n        descriptor,\n        direction: axis.direction,\n        borderBox: withoutFrame.client.borderBox,\n        closest: {\n          borderBox: withoutFrame.client.borderBox,\n          scrollSize: {\n            scrollWidth: axis === vertical ? crossAxisSize : droppableSize,\n            scrollHeight: axis === vertical ? droppableSize : crossAxisSize,\n          },\n          scroll: origin,\n          shouldClipSubject: false,\n        },\n      });\n      const originalFrame: ?Scrollable = withFrame.frame;\n      invariant(\n        originalFrame && isEqual(originalFrame.scroll.max, origin),\n        'expecting no max scroll',\n      );\n\n      it('should not grow the subject if not required', () => {\n        const inHome: DraggableDimension = getHomeDraggable(gap - 5);\n\n        const result: DroppableDimension = addPlaceholder(\n          withFrame,\n          inHome,\n          withHomeDraggable(inHome),\n        );\n\n        const expected: DroppableSubject = {\n          // unchanged\n          page: withFrame.subject.page,\n          active: withFrame.subject.active,\n          // added\n          withPlaceholder: {\n            increasedBy: null,\n            // holding onto old max regardless\n            oldFrameMaxScroll: originalFrame.scroll.max,\n            placeholderSize: getPlaceholderSize(inHome),\n          },\n        };\n        expect(result.subject).toEqual(expected);\n        // no change in frame or scroll\n        const newFrame: ?Scrollable = result.frame;\n        invariant(newFrame);\n        expect(originalFrame.scroll.max).toEqual(newFrame.scroll.max);\n        expect(originalFrame).toEqual(newFrame);\n      });\n\n      it('should grow the subject if required', () => {\n        const excess: number = 20;\n        const inHome: DraggableDimension = getHomeDraggable(gap + excess);\n\n        const result: DroppableDimension = addPlaceholder(\n          withFrame,\n          inHome,\n          withHomeDraggable(inHome),\n        );\n\n        const increasedBy: Position = patch(axis.line, excess);\n        const active: ?Rect = withFrame.subject.active;\n        invariant(active);\n        const expected: DroppableSubject = {\n          // unchanged\n          page: withFrame.subject.page,\n          // increased\n          active: getRect({\n            ...active,\n            [axis.end]: active[axis.end] + excess,\n          }),\n          // added\n          withPlaceholder: {\n            increasedBy,\n            oldFrameMaxScroll: originalFrame.scroll.max,\n            placeholderSize: getPlaceholderSize(inHome),\n          },\n        };\n        expect(result.subject).toEqual(expected);\n        // max scroll change\n        const newFrame: ?Scrollable = result.frame;\n        invariant(newFrame);\n        expect(originalFrame.scroll.max).not.toEqual(newFrame.scroll.max);\n        expect(newFrame.scroll.max).toEqual(\n          add(originalFrame.scroll.max, increasedBy),\n        );\n        // no client change\n        expect(newFrame.frameClient).toEqual(newFrame.frameClient);\n      });\n\n      it('should restore the original frame when placeholder is no longer needed', () => {\n        const excess: number = 20;\n        const inHome: DraggableDimension = getHomeDraggable(gap + excess);\n\n        const added: DroppableDimension = addPlaceholder(\n          withFrame,\n          inHome,\n          withHomeDraggable(inHome),\n        );\n        const removed: DroppableDimension = removePlaceholder(added);\n\n        expect(removed).toEqual(withFrame);\n      });\n    });\n\n    describe('virtual list', () => {\n      const virtual: DroppableDimension = getDroppableDimension({\n        descriptor: {\n          ...descriptor,\n          mode: 'virtual',\n        },\n        direction: axis.direction,\n        borderBox: withoutFrame.client.borderBox,\n        closest: {\n          borderBox: withoutFrame.client.borderBox,\n          scrollSize: {\n            scrollWidth: axis === vertical ? crossAxisSize : droppableSize,\n            scrollHeight: axis === vertical ? droppableSize : crossAxisSize,\n          },\n          scroll: origin,\n          shouldClipSubject: false,\n        },\n      });\n      const originalFrame: ?Scrollable = virtual.frame;\n      invariant(\n        originalFrame && isEqual(originalFrame.scroll.max, origin),\n        'expecting no max scroll',\n      );\n\n      it('should always grow the subject required', () => {\n        const inHome: DraggableDimension = getHomeDraggable(gap - 5);\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          inHome.displaceBy,\n        );\n        // increasing by the whole amount, not just the gap\n        // for virtual lists we cannot count the size of existing items\n        // as they all might not be there\n        const increasedBy: Position = patch(axis.line, displacedBy.value);\n\n        const result: DroppableDimension = addPlaceholder(\n          virtual,\n          inHome,\n          withHomeDraggable(inHome),\n        );\n\n        const active: ?Rect = virtual.subject.active;\n        invariant(active);\n        const expected: DroppableSubject = {\n          // unchanged\n          page: virtual.subject.page,\n          // increased\n          active: getRect({\n            ...active,\n            [axis.end]: active[axis.end] + displacedBy.value,\n          }),\n          // added\n          withPlaceholder: {\n            increasedBy,\n            oldFrameMaxScroll: originalFrame.scroll.max,\n            placeholderSize: getPlaceholderSize(inHome),\n          },\n        };\n        expect(result.subject).toEqual(expected);\n        // max scroll change\n        const newFrame: ?Scrollable = result.frame;\n        invariant(newFrame);\n        expect(originalFrame.scroll.max).not.toEqual(newFrame.scroll.max);\n        expect(newFrame.scroll.max).toEqual(\n          add(originalFrame.scroll.max, increasedBy),\n        );\n        // no client change\n        expect(newFrame.frameClient).toEqual(newFrame.frameClient);\n      });\n\n      it('should restore the original frame when placeholder is no longer needed', () => {\n        const excess: number = 20;\n        const inHome: DraggableDimension = getHomeDraggable(gap + excess);\n\n        const added: DroppableDimension = addPlaceholder(\n          virtual,\n          inHome,\n          withHomeDraggable(inHome),\n        );\n        const removed: DroppableDimension = removePlaceholder(added);\n\n        expect(removed).toEqual(virtual);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-client-border-box-center.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DroppableDimension,\n  Viewport,\n  Axis,\n  DragImpact,\n  DisplacedBy,\n} from '../../../../src/types';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport { add, negate, subtract } from '../../../../src/state/position';\nimport scrollDroppable from '../../../../src/state/droppable/scroll-droppable';\nimport { getPreset, makeScrollable } from '../../../util/dimension';\nimport getClientBorderBoxCenter from '../../../../src/state/get-center-from-impact/get-client-border-box-center';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport noImpact from '../../../../src/state/no-impact';\nimport scrollViewport from '../../../../src/state/scroll-viewport';\nimport getLiftEffect from '../../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../../util/impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const preset = getPreset();\n  const { afterCritical, impact: homeImpact } = getLiftEffect({\n    draggable: preset.inHome1,\n    draggables: preset.draggables,\n    home: preset.home,\n    viewport: preset.viewport,\n  });\n\n  it('should account for the scroll of the droppable you are over when reordering', () => {\n    const scrollableHome: DroppableDimension = makeScrollable(preset.home);\n    const scroll: Position = { x: 10, y: 15 };\n    const displacement: Position = negate(scroll);\n    const scrolled: DroppableDimension = scrollDroppable(\n      scrollableHome,\n      scroll,\n    );\n\n    const newClientCenter: Position = getClientBorderBoxCenter({\n      impact: homeImpact,\n      draggable: preset.inHome1,\n      droppable: scrolled,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n      afterCritical,\n    });\n\n    const offset: Position = subtract(\n      newClientCenter,\n      preset.inHome1.client.borderBox.center,\n    );\n    expect(offset).toEqual(displacement);\n  });\n\n  it('should account for the scroll of the droppable you are over when combining', () => {\n    const scrollableHome: DroppableDimension = makeScrollable(preset.home);\n    const scroll: Position = { x: 10, y: 15 };\n    const displacement: Position = negate(scroll);\n    const scrolled: DroppableDimension = scrollDroppable(\n      scrollableHome,\n      scroll,\n    );\n    // inHome1 combining with inHome2\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome1.displaceBy,\n    );\n    const impact: DragImpact = {\n      displaced: getForcedDisplacement({\n        visible: [\n          {\n            dimension: preset.inHome2,\n            shouldAnimate: false,\n          },\n          {\n            dimension: preset.inHome3,\n            shouldAnimate: false,\n          },\n          {\n            dimension: preset.inHome4,\n            shouldAnimate: false,\n          },\n        ],\n      }),\n      displacedBy,\n      at: {\n        type: 'COMBINE',\n        combine: {\n          draggableId: preset.inHome2.descriptor.id,\n          droppableId: preset.home.descriptor.id,\n        },\n      },\n    };\n\n    const newClientCenter: Position = getClientBorderBoxCenter({\n      impact,\n      draggable: preset.inHome1,\n      draggables: preset.draggables,\n      droppable: scrolled,\n      viewport: preset.viewport,\n      afterCritical,\n    });\n    const offset: Position = subtract(\n      newClientCenter,\n      preset.inHome1.client.borderBox.center,\n    );\n\n    const expectedCenter: Position = preset.inHome2.client.borderBox.center;\n    const original: Position = preset.inHome1.client.borderBox.center;\n    const centerDiff: Position = subtract(expectedCenter, original);\n    const expectedOffset: Position = add(centerDiff, displacement);\n    expect(offset).toEqual(expectedOffset);\n  });\n\n  it('should account for any changes in the window scroll', () => {\n    const scroll: Position = { x: 10, y: 15 };\n    const displacement: Position = negate(scroll);\n    const scrolled: Viewport = scrollViewport(\n      preset.viewport,\n      // adding to the existing scroll\n      add(preset.windowScroll, scroll),\n    );\n\n    const newClientCenter: Position = getClientBorderBoxCenter({\n      impact: noImpact,\n      draggable: preset.inHome1,\n      draggables: preset.draggables,\n      droppable: preset.home,\n      viewport: scrolled,\n      afterCritical,\n    });\n    const offset: Position = subtract(\n      newClientCenter,\n      preset.inHome1.client.borderBox.center,\n    );\n\n    expect(offset).toEqual(displacement);\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-client-from-page-border-box-center.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { DraggableDimension, Viewport } from '../../../../src/types';\nimport { add } from '../../../../src/state/position';\nimport { getPreset } from '../../../util/dimension';\nimport scrollViewport from '../../../../src/state/scroll-viewport';\nimport getClientFromPageBorderBoxCenter from '../../../../src/state/get-center-from-impact/get-client-border-box-center/get-client-from-page-border-box-center';\n\nconst preset = getPreset();\nconst draggable: DraggableDimension = preset.inHome1;\nconst originalPageCenter: Position = preset.inHome1.page.borderBox.center;\nconst originalClientCenter: Position = preset.inHome1.client.borderBox.center;\n\nit('should unwind window scroll changes', () => {\n  const scroll: Position = { x: 10, y: 20 };\n  const newScroll: Position = add(preset.windowScroll, scroll);\n  const scrolled: Viewport = scrollViewport(preset.viewport, newScroll);\n  const pageBorderBoxCenter: Position = add(originalPageCenter, scroll);\n\n  const result: Position = getClientFromPageBorderBoxCenter({\n    pageBorderBoxCenter,\n    draggable,\n    viewport: scrolled,\n  });\n\n  expect(result).toEqual(originalClientCenter);\n});\n\nit('should account for manual offsets', () => {\n  const offset: Position = { x: 10, y: 25 };\n  const pageBorderBoxCenter: Position = add(originalPageCenter, offset);\n\n  const result: Position = getClientFromPageBorderBoxCenter({\n    pageBorderBoxCenter,\n    draggable,\n    viewport: preset.viewport,\n  });\n\n  expect(result).toEqual(add(originalClientCenter, offset));\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-page-border-box-center/combine/when-combining.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DroppableDimension,\n  DisplacedBy,\n  DragImpact,\n} from '../../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport getPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../../util/dimension';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport { subtract, add } from '../../../../../../src/state/position';\nimport { getForcedDisplacement } from '../../../../../util/impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const withCombineEnabled: DroppableDimension = {\n      ...preset.home,\n      isCombineEnabled: true,\n    };\n    const { afterCritical } = getLiftEffect({\n      draggable: preset.inHome2,\n      home: withCombineEnabled,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome2.displaceBy,\n    );\n\n    describe('item started displaced', () => {\n      it('should move onto a displaced center - the initial visible center', () => {\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              {\n                dimension: preset.inHome3,\n                shouldAnimate: false,\n              },\n              {\n                dimension: preset.inHome4,\n                shouldAnimate: false,\n              },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'COMBINE',\n            // combining with inHome3\n            combine: {\n              draggableId: preset.inHome3.descriptor.id,\n              droppableId: preset.inHome3.descriptor.droppableId,\n            },\n          },\n        };\n\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          afterCritical,\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          droppable: withCombineEnabled,\n        });\n\n        expect(result).toEqual(preset.inHome3.page.borderBox.center);\n      });\n\n      it('should move onto a non-displaced center', () => {\n        // combining with inHome3 which is no longer displaced\n        // inHome2 would have moved forward and is now moving backwards\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n          }),\n          displacedBy,\n          at: {\n            type: 'COMBINE',\n            // combining with not displaced inHome1\n            combine: {\n              draggableId: preset.inHome3.descriptor.id,\n              droppableId: preset.inHome3.descriptor.droppableId,\n            },\n          },\n        };\n\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          afterCritical,\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          droppable: withCombineEnabled,\n        });\n\n        const expected: Position = subtract(\n          preset.inHome3.page.borderBox.center,\n          displacedBy.point,\n        );\n        expect(result).toEqual(expected);\n      });\n    });\n\n    describe('item did not start displaced', () => {\n      it('should move onto a displaced center', () => {\n        // moving inHome2 backwards past inHome1 (pushing it forward)\n        // and then moving onto inHome1\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            // inHome2 not displaced as it is the dragging item\n            visible: [\n              {\n                dimension: preset.inHome1,\n                shouldAnimate: true,\n              },\n              {\n                dimension: preset.inHome3,\n                shouldAnimate: false,\n              },\n              {\n                dimension: preset.inHome4,\n                shouldAnimate: false,\n              },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'COMBINE',\n            // combining with not displaced inHome1\n            combine: {\n              draggableId: preset.inHome1.descriptor.id,\n              droppableId: preset.inHome1.descriptor.droppableId,\n            },\n          },\n        };\n\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          afterCritical,\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          droppable: withCombineEnabled,\n        });\n\n        const expected: Position = add(\n          preset.inHome1.page.borderBox.center,\n          displacedBy.point,\n        );\n        expect(result).toEqual(expected);\n      });\n\n      it('should move onto a non-displaced center', () => {\n        // moving inHome2 backwards onto inHome1\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            // inHome2 not displaced as it is the dragging item\n            visible: [\n              {\n                dimension: preset.inHome3,\n                shouldAnimate: false,\n              },\n              {\n                dimension: preset.inHome4,\n                shouldAnimate: false,\n              },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'COMBINE',\n            // combining with not displaced inHome1\n            combine: {\n              draggableId: preset.inHome1.descriptor.id,\n              droppableId: preset.inHome1.descriptor.droppableId,\n            },\n          },\n        };\n\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          afterCritical,\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          droppable: withCombineEnabled,\n        });\n\n        expect(result).toEqual(preset.inHome1.page.borderBox.center);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-page-border-box-center/combine/with-droppable-scroll.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DisplacedBy,\n  DroppableDimension,\n} from '../../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport getPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getPreset, makeScrollable } from '../../../../../util/dimension';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport { negate, add } from '../../../../../../src/state/position';\nimport scrollDroppable from '../../../../../../src/state/droppable/scroll-droppable';\nimport { getForcedDisplacement } from '../../../../../util/impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const withCombineEnabled: DroppableDimension = {\n      ...preset.home,\n      isCombineEnabled: true,\n    };\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome1.displaceBy,\n    );\n    const { afterCritical } = getLiftEffect({\n      draggable: preset.inHome1,\n      home: withCombineEnabled,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n\n    it('should account for any scroll in the droppable being dropped into (into foreign list)', () => {\n      // combining with inHome2\n      const impact: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            {\n              dimension: preset.inHome2,\n              shouldAnimate: false,\n            },\n            {\n              dimension: preset.inHome3,\n              shouldAnimate: false,\n            },\n            {\n              dimension: preset.inHome4,\n              shouldAnimate: false,\n            },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'COMBINE',\n          // combining with inHome2\n          combine: {\n            draggableId: preset.inHome2.descriptor.id,\n            droppableId: preset.inHome2.descriptor.droppableId,\n          },\n        },\n      };\n\n      const inHome2Center: Position = preset.inHome2.page.borderBox.center;\n      // without any scroll\n      {\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          afterCritical,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppable: withCombineEnabled,\n        });\n\n        expect(result).toEqual(inHome2Center);\n      }\n      // into start of empty foreign list (with scroll)\n      {\n        const scroll: Position = { x: 10, y: 20 };\n        const displacement: Position = negate(scroll);\n        const scrollable: DroppableDimension = makeScrollable(\n          withCombineEnabled,\n        );\n        const scrolled: DroppableDimension = scrollDroppable(\n          scrollable,\n          scroll,\n        );\n\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          draggable: preset.inHome1,\n          draggables: preset.dimensions.draggables,\n          droppable: scrolled,\n          afterCritical,\n        });\n\n        expect(result).toEqual(add(inHome2Center, displacement));\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-page-border-box-center/in-home-location.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { vertical, horizontal } from '../../../../../src/state/axis';\nimport getPageBorderBoxCenter from '../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../util/dimension';\nimport type { Axis } from '../../../../../src/types';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const original: Position = preset.inHome1.page.borderBox.center;\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome1,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n\n    it('should return original center when not over anything', () => {\n      const result: Position = getPageBorderBoxCenter({\n        impact: homeImpact,\n        draggable: preset.inHome1,\n        droppable: preset.home,\n        draggables: preset.dimensions.draggables,\n        afterCritical,\n      });\n\n      expect(result).toEqual(original);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-page-border-box-center/over-nothing.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { horizontal, vertical } from '../../../../../src/state/axis';\nimport getPageBorderBoxCenter from '../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../util/dimension';\nimport type { Axis } from '../../../../../src/types';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const original: Position = preset.inHome1.page.borderBox.center;\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome1,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n\n    it('should return original center when not over anything', () => {\n      const result: Position = getPageBorderBoxCenter({\n        impact: homeImpact,\n        draggable: preset.inHome1,\n        droppable: null,\n        draggables: preset.dimensions.draggables,\n        afterCritical,\n      });\n\n      expect(result).toEqual(original);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-page-border-box-center/reorder/in-empty-list.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { Axis } from '../../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport getPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../../util/dimension';\nimport { goIntoStart } from '../../../../../../src/state/get-center-from-impact/move-relative-to';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome1,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n\n    it('should move into the start of the list', () => {\n      const result: Position = getPageBorderBoxCenter({\n        impact: homeImpact,\n        afterCritical,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppable: preset.emptyForeign,\n      });\n\n      const expected: Position = goIntoStart({\n        axis,\n        moveInto: preset.emptyForeign.page,\n        isMoving: preset.inHome1.page,\n      });\n      expect(result).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-page-border-box-center/reorder/nothing-displaced.spec.js",
    "content": "// @flow\nimport { offset, type Position } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport getPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../../util/dimension';\nimport { goAfter } from '../../../../../../src/state/get-center-from-impact/move-relative-to';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport { negate } from '../../../../../../src/state/position';\nimport { emptyGroups } from '../../../../../../src/state/no-impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n\n    describe('last item is the dragging item', () => {\n      it('should return to the original center', () => {\n        const { afterCritical, impact: homeImpact } = getLiftEffect({\n          draggable: preset.inHome4,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const result: Position = getPageBorderBoxCenter({\n          impact: homeImpact,\n          afterCritical,\n          draggable: preset.inHome4,\n          draggables: preset.draggables,\n          droppable: preset.home,\n        });\n\n        expect(result).toEqual(preset.inHome4.page.borderBox.center);\n      });\n    });\n\n    describe('last item started displaced', () => {\n      it('should go after the item in its current non-displaced location', () => {\n        const { afterCritical } = getLiftEffect({\n          draggable: preset.inHome1,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome1.displaceBy,\n        );\n\n        const impact: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              index: preset.inHome4.descriptor.index,\n              droppableId: preset.inHome4.descriptor.id,\n            },\n          },\n        };\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          afterCritical,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppable: preset.home,\n        });\n\n        const expected: Position = goAfter({\n          axis,\n          moveRelativeTo: offset(\n            preset.inHome4.page,\n            negate(displacedBy.point),\n          ),\n          isMoving: preset.inHome1.page,\n        });\n        expect(result).toEqual(expected);\n      });\n    });\n\n    describe('last item did not start displaced', () => {\n      it('should go after the item in its current non-displaced location', () => {\n        const { afterCritical } = getLiftEffect({\n          draggable: preset.inHome1,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome1.displaceBy,\n        );\n        const impact: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            // currently after inForeign4\n            destination: {\n              index: preset.inForeign4.descriptor.index + 1,\n              droppableId: preset.inForeign4.descriptor.id,\n            },\n          },\n        };\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          afterCritical,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppable: preset.foreign,\n        });\n\n        const expected: Position = goAfter({\n          axis,\n          moveRelativeTo: preset.inForeign4.page,\n          isMoving: preset.inHome1.page,\n        });\n        expect(result).toEqual(expected);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-page-border-box-center/reorder/there-is-displacement.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { offset } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport getPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../../util/dimension';\nimport { goBefore } from '../../../../../../src/state/get-center-from-impact/move-relative-to';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport { getForcedDisplacement } from '../../../../../util/impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n\n    describe('closest displaced started displaced', () => {\n      it('should go before the visible (displaced) position of the item', () => {\n        const { afterCritical } = getLiftEffect({\n          draggable: preset.inHome1,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome1.displaceBy,\n        );\n\n        const impact: DragImpact = {\n          // moved forward over inHome2\n          displaced: getForcedDisplacement({\n            visible: [\n              {\n                dimension: preset.inHome3,\n                shouldAnimate: false,\n              },\n              {\n                dimension: preset.inHome4,\n                shouldAnimate: false,\n              },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              index: preset.inHome3.descriptor.index,\n              droppableId: preset.inHome3.descriptor.id,\n            },\n          },\n        };\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          afterCritical,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppable: preset.home,\n        });\n\n        const expected: Position = goBefore({\n          axis,\n          moveRelativeTo: preset.inHome3.page,\n          isMoving: preset.inHome1.page,\n        });\n        expect(result).toEqual(expected);\n      });\n    });\n\n    describe('closest displaced did not start displaced', () => {\n      it('should go before the displaced position of the item', () => {\n        const { afterCritical } = getLiftEffect({\n          draggable: preset.inHome1,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome1.displaceBy,\n        );\n        // moved into foreign\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              {\n                dimension: preset.inForeign2,\n                shouldAnimate: false,\n              },\n              {\n                dimension: preset.inForeign3,\n                shouldAnimate: false,\n              },\n              {\n                dimension: preset.inForeign4,\n                shouldAnimate: false,\n              },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            // currently in position of inForeign2\n            destination: {\n              index: preset.inForeign2.descriptor.index,\n              droppableId: preset.inForeign2.descriptor.id,\n            },\n          },\n        };\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          afterCritical,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppable: preset.foreign,\n        });\n\n        const expected: Position = goBefore({\n          axis,\n          moveRelativeTo: offset(preset.inForeign2.page, displacedBy.point),\n          isMoving: preset.inHome1.page,\n        });\n        expect(result).toEqual(expected);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/get-page-border-box-center/reorder/with-droppable-scroll.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DisplacedBy,\n  DroppableDimension,\n} from '../../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport getPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getPreset, makeScrollable } from '../../../../../util/dimension';\nimport { goIntoStart } from '../../../../../../src/state/get-center-from-impact/move-relative-to';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport { negate, add } from '../../../../../../src/state/position';\nimport scrollDroppable from '../../../../../../src/state/droppable/scroll-droppable';\nimport { emptyGroups } from '../../../../../../src/state/no-impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    it('should account for any scroll in the droppable being dropped into (into foreign list)', () => {\n      // inHome1 over the end of empty\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        preset.inHome1.displaceBy,\n      );\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const impact: DragImpact = {\n        displaced: emptyGroups,\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: 0,\n            droppableId: preset.emptyForeign.descriptor.id,\n          },\n        },\n      };\n      const expectedCenter: Position = goIntoStart({\n        axis,\n        moveInto: preset.emptyForeign.page,\n        isMoving: preset.inHome1.page,\n      });\n      // into start of empty foreign list (without scroll)\n      {\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          draggable: preset.inHome1,\n          draggables: preset.dimensions.draggables,\n          droppable: preset.emptyForeign,\n          afterCritical,\n        });\n\n        expect(result).toEqual(expectedCenter);\n      }\n      // into start of empty foreign list (with scroll)\n      {\n        const scroll: Position = { x: 10, y: 20 };\n        const displacement: Position = negate(scroll);\n        const scrollable: DroppableDimension = makeScrollable(\n          preset.emptyForeign,\n        );\n        const scrolled: DroppableDimension = scrollDroppable(\n          scrollable,\n          scroll,\n        );\n\n        const result: Position = getPageBorderBoxCenter({\n          impact,\n          draggable: preset.inHome1,\n          draggables: preset.dimensions.draggables,\n          droppable: scrolled,\n          afterCritical,\n        });\n\n        expect(result).toEqual(add(expectedCenter, displacement));\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-center-from-impact/move-relative-to.spec.js",
    "content": "// @flow\nimport {\n  createBox,\n  type BoxModel,\n  type Spacing,\n  type Position,\n} from 'css-box-model';\nimport type { Axis } from '../../../../src/types';\nimport {\n  goBefore,\n  goAfter,\n  goIntoStart,\n} from '../../../../src/state/get-center-from-impact/move-relative-to';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport { patch } from '../../../../src/state/position';\n\nlet spacing: number = 1;\n\nconst getAssortedSpacing = (): Spacing => ({\n  top: spacing++,\n  right: spacing++,\n  bottom: spacing++,\n  left: spacing++,\n});\n\nconst moveRelativeTo: BoxModel = createBox({\n  borderBox: {\n    top: 0,\n    left: 0,\n    right: 100,\n    bottom: 100,\n  },\n  margin: getAssortedSpacing(),\n  border: getAssortedSpacing(),\n  padding: getAssortedSpacing(),\n});\n\nconst isMoving: BoxModel = createBox({\n  borderBox: {\n    top: 400,\n    left: 400,\n    right: 500,\n    bottom: 500,\n  },\n  margin: getAssortedSpacing(),\n  border: getAssortedSpacing(),\n  padding: getAssortedSpacing(),\n});\n\nconst distanceFromStartToCenter = (axis: Axis, box: BoxModel): number =>\n  box.margin[axis.start] + box.borderBox[axis.size] / 2;\n\nconst distanceFromEndToCenter = (axis: Axis, box: BoxModel): number =>\n  box.margin[axis.end] + box.borderBox[axis.size] / 2;\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    it('should align before the target', () => {\n      const newCenter: Position = goBefore({\n        axis,\n        moveRelativeTo,\n        isMoving,\n      });\n\n      const expected: Position = patch(\n        axis.line,\n        // start at the start of the item we are moving relative to\n        moveRelativeTo.marginBox[axis.start] -\n          // add the space from the end of the dragging item to its center\n          distanceFromEndToCenter(axis, isMoving),\n        // start at the cross axis start of the item we are moving relative to\n        moveRelativeTo.marginBox[axis.crossAxisStart] +\n          isMoving.margin[axis.crossAxisStart] +\n          isMoving.borderBox[axis.crossAxisSize] / 2,\n      );\n\n      expect(newCenter).toEqual(expected);\n    });\n\n    it('should align after the target', () => {\n      const newCenter: Position = goAfter({\n        axis,\n        moveRelativeTo,\n        isMoving,\n      });\n\n      const expected: Position = patch(\n        axis.line,\n        // start at the end of the margin box\n        moveRelativeTo.marginBox[axis.end] +\n          // add the distance to the start of the target center\n          distanceFromStartToCenter(axis, isMoving),\n        // start at the cross axis start of the item we are moving relative to\n        moveRelativeTo.marginBox[axis.crossAxisStart] +\n          isMoving.margin[axis.crossAxisStart] +\n          isMoving.borderBox[axis.crossAxisSize] / 2,\n      );\n\n      expect(newCenter).toEqual(expected);\n    });\n\n    it('should move into the start of the context box of the target', () => {\n      const newCenter: Position = goIntoStart({\n        axis,\n        moveInto: moveRelativeTo,\n        isMoving,\n      });\n\n      const expected: Position = patch(\n        axis.line,\n        // start from the start of the context box of the target\n        moveRelativeTo.contentBox[axis.start] +\n          // add the distance from the start to the center of the moving item\n          distanceFromStartToCenter(axis, isMoving),\n        // start at the cross axis start of the item we are moving relative to\n        moveRelativeTo.contentBox[axis.crossAxisStart] +\n          isMoving.margin[axis.crossAxisStart] +\n          isMoving.borderBox[axis.crossAxisSize] / 2,\n      );\n\n      expect(newCenter).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-displacement-groups/get-displacement-groups.spec.js",
    "content": "// @flow\nimport { getRect } from 'css-box-model';\nimport type {\n  Axis,\n  Viewport,\n  DisplacedBy,\n  DisplacementGroups,\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n} from '../../../../src/types';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport { createViewport } from '../../../util/viewport';\nimport { origin, patch } from '../../../../src/state/position';\nimport {\n  getDroppableDimension,\n  getDraggableDimension,\n} from '../../../util/dimension';\nimport { emptyGroups } from '../../../../src/state/no-impact';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport { toDraggableMap } from '../../../../src/state/dimension-structures';\nimport getLiftEffect from '../../../../src/state/get-lift-effect';\nimport getDisplacementGroups from '../../../../src/state/get-displacement-groups';\nimport { getForcedDisplacement } from '../../../util/impact';\nimport scrollViewport from '../../../../src/state/scroll-viewport';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on the ${axis.direction} axis`, () => {\n    const viewport: Viewport = createViewport({\n      frame: getRect({\n        top: 0,\n        right: 1000,\n        left: 0,\n        bottom: 1000,\n      }),\n      scroll: origin,\n      scrollHeight: 1000,\n      scrollWidth: 1000,\n    });\n\n    const homeCrossAxisEnd: number =\n      viewport.frame[axis.crossAxisStart] +\n      viewport.frame[axis.crossAxisSize] / 2;\n\n    const home: DroppableDimension = getDroppableDimension({\n      descriptor: {\n        id: 'home',\n        type: 'TYPE',\n        mode: 'standard',\n      },\n      direction: axis.direction,\n      borderBox: {\n        [axis.start]: viewport.frame[axis.start],\n        [axis.end]: viewport.frame[axis.end] + 2000,\n        [axis.crossAxisStart]: viewport.frame[axis.crossAxisStart],\n        [axis.crossAxisEnd]: homeCrossAxisEnd,\n      },\n    });\n\n    const foreign: DroppableDimension = getDroppableDimension({\n      descriptor: {\n        id: 'foreign',\n        type: 'TYPE',\n        mode: 'standard',\n      },\n      direction: axis.direction,\n      borderBox: {\n        [axis.start]: viewport.frame[axis.start],\n        [axis.end]: viewport.frame[axis.end] + 2000,\n        [axis.crossAxisStart]: homeCrossAxisEnd + 1,\n        [axis.crossAxisEnd]: viewport.frame[axis.crossAxisEnd],\n      },\n    });\n\n    const dragging: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'in-viewport',\n        droppableId: home.descriptor.id,\n        type: home.descriptor.type,\n        index: 0,\n      },\n      borderBox: {\n        top: 0,\n        left: 0,\n        right: 200,\n        bottom: 200,\n      },\n    });\n\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      home.axis,\n      dragging.displaceBy,\n    );\n\n    const isVisible: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'is-visible',\n        droppableId: foreign.descriptor.id,\n        type: foreign.descriptor.type,\n        index: 0,\n      },\n      // outside of viewport but within droppable\n      borderBox: viewport.frame,\n    });\n\n    const isVisibleDueToOverScanning: DraggableDimension = getDraggableDimension(\n      {\n        descriptor: {\n          id: 'is-visible-due-to-overscanning',\n          droppableId: foreign.descriptor.id,\n          type: foreign.descriptor.type,\n          index: 1,\n        },\n        // outside of viewport but within droppable\n        borderBox: {\n          ...foreign.client.borderBox,\n          [axis.start]: viewport.frame[axis.end] + 1,\n          [axis.end]: viewport.frame[axis.end] + 100,\n        },\n      },\n    );\n\n    const isNotVisible: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'is-not-visible',\n        droppableId: foreign.descriptor.id,\n        type: foreign.descriptor.type,\n        index: 2,\n      },\n      // outside of viewport but within droppable\n      borderBox: {\n        ...viewport.frame,\n        [axis.start]:\n          viewport.frame[axis.end] + dragging.client.marginBox[axis.size] + 1,\n        [axis.end]:\n          viewport.frame[axis.end] + dragging.client.marginBox[axis.size] + 10,\n      },\n    });\n\n    const draggables: DraggableDimensionMap = toDraggableMap([\n      dragging,\n      isVisible,\n      isVisibleDueToOverScanning,\n      isNotVisible,\n    ]);\n\n    const { impact: homeImpact } = getLiftEffect({\n      draggable: dragging,\n      home,\n      draggables,\n      viewport,\n    });\n\n    const afterDragging: DraggableDimension[] = [\n      isVisible,\n      isVisibleDueToOverScanning,\n      isNotVisible,\n    ];\n\n    it('should return nothing when nothing is after the dragging item', () => {\n      const result: DisplacementGroups = getDisplacementGroups({\n        afterDragging: [],\n        destination: home,\n        displacedBy,\n        last: homeImpact.displaced,\n        viewport: viewport.frame,\n      });\n\n      expect(result).toEqual(emptyGroups);\n    });\n\n    it('should correctly mark item visibility', () => {\n      const result: DisplacementGroups = getDisplacementGroups({\n        afterDragging,\n        destination: foreign,\n        displacedBy,\n        last: homeImpact.displaced,\n        viewport: viewport.frame,\n      });\n\n      const expected: DisplacementGroups = getForcedDisplacement({\n        visible: [\n          { dimension: isVisible },\n          // overscanning\n          { dimension: isVisibleDueToOverScanning },\n        ],\n        invisible: [isNotVisible],\n      });\n\n      expect(result).toEqual(expected);\n    });\n\n    it('should keep displacement animation consistent between calls', () => {\n      const last: DisplacementGroups = getForcedDisplacement({\n        visible: [\n          // forcing this to be difference so we know this is working\n          { dimension: isVisible, shouldAnimate: false },\n          { dimension: isVisibleDueToOverScanning },\n        ],\n        invisible: [isNotVisible],\n      });\n\n      const result: DisplacementGroups = getDisplacementGroups({\n        afterDragging,\n        destination: foreign,\n        displacedBy,\n        last,\n        viewport: viewport.frame,\n      });\n\n      expect(result).toEqual(last);\n    });\n\n    it('should mark an item as not animated when moving from invisible to visible', () => {\n      const last: DisplacementGroups = getForcedDisplacement({\n        visible: [\n          { dimension: isVisible },\n          { dimension: isVisibleDueToOverScanning },\n        ],\n        invisible: [isNotVisible],\n      });\n      // scrolling enough for isNotVisible to be visible\n      const scrolled: Viewport = scrollViewport(viewport, patch(axis.line, 1));\n\n      const result: DisplacementGroups = getDisplacementGroups({\n        afterDragging,\n        destination: foreign,\n        displacedBy,\n        last,\n        viewport: scrolled.frame,\n      });\n\n      const expected: DisplacementGroups = getForcedDisplacement({\n        visible: [\n          { dimension: isVisible },\n          { dimension: isVisibleDueToOverScanning },\n          { dimension: isNotVisible, shouldAnimate: false },\n        ],\n      });\n\n      expect(result).toEqual(expected);\n    });\n\n    it('should make displacement animated if being displaced for the first time', () => {\n      const result: DisplacementGroups = getDisplacementGroups({\n        afterDragging,\n        destination: foreign,\n        displacedBy,\n        last: emptyGroups,\n        viewport: viewport.frame,\n      });\n\n      const expected: DisplacementGroups = getForcedDisplacement({\n        // both are animated\n        visible: [\n          { dimension: isVisible },\n          // overscanning\n          { dimension: isVisibleDueToOverScanning },\n        ],\n        invisible: [isNotVisible],\n      });\n\n      expect(result).toEqual(expected);\n    });\n\n    it('should force the animation value when requested', () => {\n      const result: DisplacementGroups = getDisplacementGroups({\n        afterDragging,\n        destination: foreign,\n        displacedBy,\n        last: emptyGroups,\n        viewport: viewport.frame,\n        forceShouldAnimate: false,\n      });\n\n      const expected: DisplacementGroups = getForcedDisplacement({\n        visible: [\n          { dimension: isVisible, shouldAnimate: false },\n          { dimension: isVisibleDueToOverScanning, shouldAnimate: false },\n        ],\n\n        invisible: [isNotVisible],\n      });\n\n      expect(result).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-displacement-groups/use-initial-position-not-displaced.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DisplacementGroups,\n  DisplacedBy,\n  Viewport,\n} from '../../../../src/types';\nimport { horizontal, vertical } from '../../../../src/state/axis';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport { add, negate, patch, subtract } from '../../../../src/state/position';\nimport scrollViewport from '../../../../src/state/scroll-viewport';\nimport { isPartiallyVisible } from '../../../../src/state/visibility/is-visible';\nimport { getPreset } from '../../../util/dimension';\nimport { offsetByPosition } from '../../../../src/state/spacing';\nimport { getForcedDisplacement } from '../../../util/impact';\nimport getDisplacementGroups from '../../../../src/state/get-displacement-groups';\nimport { emptyGroups } from '../../../../src/state/no-impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const viewport: Viewport = preset.viewport;\n\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome1.displaceBy,\n    );\n\n    it('should calculate visibility as if in original location', () => {\n      const onEndOfInHome2: Position = patch(\n        axis.line,\n        preset.inHome2.page.marginBox[axis.end],\n        preset.inHome2.page.marginBox.center[axis.crossAxisLine],\n      );\n      const endOfInHome2MovedBackwards: Position = subtract(\n        onEndOfInHome2,\n        displacedBy.point,\n      );\n\n      const newScroll: Position = add(\n        endOfInHome2MovedBackwards,\n        patch(axis.line, 1),\n      );\n\n      const scrolled: Viewport = scrollViewport(viewport, newScroll);\n\n      // Displaced location is currently not visible\n      expect(\n        isPartiallyVisible({\n          target: offsetByPosition(\n            preset.inHome2.page.marginBox,\n            negate(displacedBy.point),\n          ),\n          destination: preset.home,\n          viewport: scrolled.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(false);\n\n      // Displacement states that inHome2 is visible despite currently being invisible due to displacement\n      const result: DisplacementGroups = getForcedDisplacement({\n        visible: [\n          { dimension: preset.inHome2 },\n          { dimension: preset.inHome3 },\n          { dimension: preset.inHome4 },\n        ],\n      });\n\n      const expected: DisplacementGroups = getDisplacementGroups({\n        afterDragging: [preset.inHome2, preset.inHome3, preset.inHome4],\n        destination: preset.home,\n        displacedBy: getDisplacedBy(axis, preset.inHome1.displaceBy),\n        last: emptyGroups,\n        viewport: scrolled.frame,\n      });\n      expect(result).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/combine/is-combine-disabled.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DroppableDimensionMap,\n} from '../../../../../src/types';\nimport { horizontal, vertical } from '../../../../../src/state/axis';\nimport getDisplacedBy from '../../../../../src/state/get-displaced-by';\nimport getDragImpact from '../../../../../src/state/get-drag-impact';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\nimport { patch, add } from '../../../../../src/state/position';\nimport afterPoint from '../../../../util/after-point';\nimport { enableCombining, getPreset } from '../../../../util/dimension';\nimport { getForcedDisplacement } from '../../../../util/impact';\nimport { getThreshold } from '../util/get-combine-threshold';\nimport { getOffsetForEndEdge } from '../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome2,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n    const withCombineEnabled: DroppableDimensionMap = enableCombining(\n      preset.droppables,\n    );\n    const startOfInHome3: Position = patch(\n      axis.line,\n      preset.inHome3.page.borderBox[axis.start],\n      preset.inHome3.page.borderBox.center[axis.crossAxisLine],\n    );\n    const threshold: Position = getThreshold(axis, preset.inHome3);\n    const combineStart: Position = getOffsetForEndEdge({\n      endEdgeOn: add(startOfInHome3, threshold),\n      dragging: preset.inHome2.page.borderBox,\n      axis,\n    });\n\n    it('should not create a combine impact when combining is disabled', () => {\n      // does not combine when combine is disabled\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: afterPoint(axis, combineStart),\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: homeImpact,\n          viewport: preset.viewport,\n          afterCritical,\n        });\n\n        expect(impact).toEqual(homeImpact);\n      }\n      // would have combined if was enabled (validation)\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: afterPoint(axis, combineStart),\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          droppables: withCombineEnabled,\n          previousImpact: homeImpact,\n          viewport: preset.viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              // displaced is not animated as it was the starting displacement\n              { dimension: preset.inHome3, shouldAnimate: false },\n              { dimension: preset.inHome4, shouldAnimate: false },\n            ],\n          }),\n          displacedBy: getDisplacedBy(axis, preset.inHome2.displaceBy),\n          at: {\n            type: 'COMBINE',\n            combine: {\n              draggableId: preset.inHome3.descriptor.id,\n              droppableId: preset.inHome3.descriptor.droppableId,\n            },\n          },\n        };\n        expect(impact).toEqual(expected);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/combine/should-not-combine-with-home-draggable.spec.js",
    "content": "// @flow\nimport type {\n  Axis,\n  DragImpact,\n  DroppableDimensionMap,\n} from '../../../../../src/types';\nimport { horizontal, vertical } from '../../../../../src/state/axis';\nimport getDragImpact from '../../../../../src/state/get-drag-impact';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\nimport { enableCombining, getPreset } from '../../../../util/dimension';\nimport { origin } from '../../../../../src/state/position';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n\n    it('should not allow combining with the dragging item', () => {\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const withCombineEnabled: DroppableDimensionMap = enableCombining(\n        preset.droppables,\n      );\n\n      // from the home impact\n\n      const impact: DragImpact = getDragImpact({\n        pageOffset: origin,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: withCombineEnabled,\n        previousImpact: homeImpact,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n      expect(impact).toEqual(homeImpact);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/combine/started-after-critical.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DisplacedBy,\n  DroppableDimensionMap,\n} from '../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../src/state/axis';\nimport { getPreset, enableCombining } from '../../../../util/dimension';\nimport getDragImpact from '../../../../../src/state/get-drag-impact';\nimport getDisplacedBy from '../../../../../src/state/get-displaced-by';\nimport { patch, subtract, add } from '../../../../../src/state/position';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\nimport afterPoint from '../../../../util/after-point';\nimport beforePoint from '../../../../util/before-point';\nimport { getForcedDisplacement } from '../../../../util/impact';\nimport noImpact, { emptyGroups } from '../../../../../src/state/no-impact';\nimport { getThreshold } from '../util/get-combine-threshold';\nimport {\n  getOffsetForEndEdge,\n  getOffsetForStartEdge,\n} from '../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome2,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n    const withCombineEnabled: DroppableDimensionMap = enableCombining(\n      preset.droppables,\n    );\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome2.displaceBy,\n    );\n    const combineWithInHome3Impact: DragImpact = {\n      displaced: getForcedDisplacement({\n        // ordered by closest to current location\n        // displaced is not animated as it was the starting displacement\n        visible: [\n          { dimension: preset.inHome3, shouldAnimate: false },\n          { dimension: preset.inHome4, shouldAnimate: false },\n        ],\n      }),\n      displacedBy,\n      at: {\n        type: 'COMBINE',\n        combine: {\n          draggableId: preset.inHome3.descriptor.id,\n          droppableId: preset.inHome3.descriptor.droppableId,\n        },\n      },\n    };\n\n    const startOfInHome3: Position = patch(\n      axis.line,\n      preset.inHome3.page.borderBox[axis.start],\n      preset.inHome3.page.borderBox.center[axis.crossAxisLine],\n    );\n    const endOfInHome3: Position = patch(\n      axis.line,\n      preset.inHome3.page.borderBox[axis.end],\n      preset.inHome3.page.borderBox.center[axis.crossAxisLine],\n    );\n    const inHome3Threshold: Position = getThreshold(axis, preset.inHome3);\n\n    describe('moving onto displaced item', () => {\n      const combineStart: Position = add(startOfInHome3, inHome3Threshold);\n      const combineEnd: Position = subtract(endOfInHome3, inHome3Threshold);\n\n      it('should move onto a target once it hits (1/5) of the targets size ', () => {\n        const offset: Position = getOffsetForEndEdge({\n          endEdgeOn: combineStart,\n          dragging: preset.inHome2.page.borderBox,\n          axis,\n        });\n\n        // sitting on combine point\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: offset,\n            draggable: preset.inHome2,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: homeImpact,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n\n          expect(impact).toEqual(homeImpact);\n        }\n        // gone past combine point\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: afterPoint(axis, offset),\n            draggable: preset.inHome2,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: homeImpact,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n\n          expect(impact).toEqual(combineWithInHome3Impact);\n        }\n      });\n\n      it('should remain displaced until the bottom of the dragging item goes onto the (4/5) mark', () => {\n        const offset: Position = getOffsetForEndEdge({\n          endEdgeOn: combineEnd,\n          dragging: preset.inHome2.page.borderBox,\n          axis,\n        });\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: beforePoint(axis, offset),\n            draggable: preset.inHome2,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: homeImpact,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n\n          expect(impact).toEqual(combineWithInHome3Impact);\n        }\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: offset,\n            draggable: preset.inHome2,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: homeImpact,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n\n          const expected: DragImpact = {\n            displaced: getForcedDisplacement({\n              visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n            }),\n            displacedBy,\n            at: {\n              type: 'REORDER',\n              // now in position of inHome3\n              destination: {\n                index: preset.inHome3.descriptor.index,\n                droppableId: preset.inHome3.descriptor.droppableId,\n              },\n            },\n          };\n          expect(impact).toEqual(expected);\n        }\n      });\n    });\n\n    describe('moving backwards onto un displaced item', () => {\n      const displacedStartOfInHome3: Position = subtract(\n        startOfInHome3,\n        displacedBy.point,\n      );\n      const displacedEndOfInHome3: Position = subtract(\n        endOfInHome3,\n        displacedBy.point,\n      );\n      const combineStart: Position = add(\n        displacedStartOfInHome3,\n        inHome3Threshold,\n      );\n      const combineEnd: Position = subtract(\n        displacedEndOfInHome3,\n        inHome3Threshold,\n      );\n\n      const combineWithDisplacedInHome3Impact: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            // inHome3 is not displaced. It is visibly displaced as the initial displacement has been removed\n            { dimension: preset.inHome4, shouldAnimate: false },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome3.descriptor.id,\n            droppableId: preset.inHome3.descriptor.droppableId,\n          },\n        },\n      };\n\n      // have moved past merging with inHome3\n      const first: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          // now in position of inHome3\n          destination: {\n            index: preset.inHome3.descriptor.index,\n            droppableId: preset.inHome3.descriptor.droppableId,\n          },\n        },\n      };\n\n      it('should move backwards onto an item that has shifted backwards', () => {\n        const offset: Position = getOffsetForStartEdge({\n          startEdgeOn: combineEnd,\n          dragging: preset.inHome2.page.borderBox,\n          axis,\n        });\n\n        // have not moved far enough backwards yet\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: offset,\n            draggable: preset.inHome2,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: first,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n          expect(impact.at).toHaveProperty('type', 'REORDER');\n        }\n        // moved back enough\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: beforePoint(axis, offset),\n            draggable: preset.inHome2,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: first,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n\n          expect(impact).toEqual(combineWithDisplacedInHome3Impact);\n        }\n      });\n\n      it('should no longer combine with an item once it hits the top threshold', () => {\n        const offset: Position = getOffsetForStartEdge({\n          startEdgeOn: combineStart,\n          dragging: preset.inHome2.page.borderBox,\n          axis,\n        });\n\n        // have not moved far enough backwards yet\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: afterPoint(axis, offset),\n            draggable: preset.inHome2,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: first,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n          expect(impact).toEqual(combineWithDisplacedInHome3Impact);\n        }\n        // moved back enough\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: offset,\n            draggable: preset.inHome2,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: first,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n\n          expect(impact.at).toHaveProperty('type', 'REORDER');\n        }\n      });\n    });\n\n    // - dragging inHome3 out of home\n    // - inHome4 will have shifted backwards\n    // - re-enter home list\n    // TODO: I am not sure this test is asserting the right thing\n    it('should understand that when re-entering a list, items that started displaced no longer are', () => {\n      const inHome4Threshold: Position = getThreshold(axis, preset.inHome4);\n      const endOfInHome4: Position = patch(\n        axis.line,\n        preset.inHome4.page.borderBox[axis.end],\n        preset.inHome4.page.borderBox.center[axis.crossAxisLine],\n      );\n      const displacedEndOfInHome4: Position = subtract(\n        endOfInHome4,\n        displacedBy.point,\n      );\n      const combineEnd: Position = subtract(\n        displacedEndOfInHome4,\n        inHome4Threshold,\n      );\n\n      const offset: Position = getOffsetForStartEdge({\n        startEdgeOn: combineEnd,\n        dragging: preset.inHome3.page.borderBox,\n        axis,\n      });\n\n      const impact: DragImpact = getDragImpact({\n        pageOffset: beforePoint(axis, offset),\n        draggable: preset.inHome3,\n        draggables: preset.draggables,\n        droppables: withCombineEnabled,\n        // out of the list\n        previousImpact: noImpact,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n      const expected: DragImpact = {\n        displaced: emptyGroups,\n        displacedBy: getDisplacedBy(axis, preset.inHome3.displaceBy),\n        // below inHome4\n        at: {\n          type: 'REORDER',\n          destination: {\n            droppableId: preset.inHome3.descriptor.droppableId,\n            index: preset.inHome4.descriptor.index,\n          },\n        },\n      };\n      expect(impact).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/combine/started-before-critical.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DisplacedBy,\n  DroppableDimensionMap,\n} from '../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../src/state/axis';\nimport { getPreset, enableCombining } from '../../../../util/dimension';\nimport getDragImpact from '../../../../../src/state/get-drag-impact';\nimport getDisplacedBy from '../../../../../src/state/get-displaced-by';\nimport { patch, subtract, add } from '../../../../../src/state/position';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\nimport afterPoint from '../../../../util/after-point';\nimport beforePoint from '../../../../util/before-point';\nimport { getForcedDisplacement } from '../../../../util/impact';\nimport { getThreshold } from '../util/get-combine-threshold';\nimport {\n  getOffsetForEndEdge,\n  getOffsetForStartEdge,\n} from '../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const { afterCritical } = getLiftEffect({\n      draggable: preset.inHome1,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n    const withCombineEnabled: DroppableDimensionMap = enableCombining(\n      preset.droppables,\n    );\n    // will be over a foreign list for these tests\n    const crossAxisCenter: number =\n      preset.foreign.page.borderBox.center[axis.crossAxisLine];\n\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome1.displaceBy,\n    );\n\n    const whenEnteredForeign: DragImpact = {\n      displaced: getForcedDisplacement({\n        visible: [\n          { dimension: preset.inForeign3, shouldAnimate: true },\n          { dimension: preset.inForeign4, shouldAnimate: true },\n        ],\n      }),\n      displacedBy,\n      at: {\n        type: 'REORDER',\n        // in position of inForeign3\n        destination: {\n          index: preset.inForeign3.descriptor.index,\n          droppableId: preset.inForeign3.descriptor.droppableId,\n        },\n      },\n    };\n\n    // moving onto a displaced inForeign3\n    describe('combining with displaced item', () => {\n      const combineWithDisplacedInForeign3: DragImpact = {\n        displaced: getForcedDisplacement({\n          // inForeign3 is still displaced - we are just merging with it\n          visible: [\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'COMBINE',\n          // now merging with inForeign3\n          combine: {\n            draggableId: preset.inForeign3.descriptor.id,\n            droppableId: preset.inForeign3.descriptor.droppableId,\n          },\n        },\n      };\n\n      describe('item is displaced forward', () => {\n        const threshold: Position = getThreshold(axis, preset.inHome3);\n        const startOfInForeign3: Position = patch(\n          axis.line,\n          preset.inForeign3.page.borderBox[axis.start],\n          crossAxisCenter,\n        );\n        const endOfInForeign3: Position = patch(\n          axis.line,\n          preset.inForeign3.page.borderBox[axis.end],\n          crossAxisCenter,\n        );\n        const displacedStartOfInForeign3: Position = add(\n          startOfInForeign3,\n          displacedBy.point,\n        );\n        const displacedEndOfInForeign3: Position = add(\n          endOfInForeign3,\n          displacedBy.point,\n        );\n        const combineStart: Position = add(\n          displacedStartOfInForeign3,\n          threshold,\n        );\n        const combineEnd: Position = subtract(\n          displacedEndOfInForeign3,\n          threshold,\n        );\n\n        it('should combine when moving forward past the displaced start threshold', () => {\n          const endOnCombineStart: Position = getOffsetForEndEdge({\n            endEdgeOn: combineStart,\n            dragging: preset.inHome1.page.borderBox,\n            axis,\n          });\n\n          // it should not merge on the threshold\n          {\n            const impact: DragImpact = getDragImpact({\n              pageOffset: endOnCombineStart,\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              droppables: withCombineEnabled,\n              previousImpact: whenEnteredForeign,\n              viewport: preset.viewport,\n              afterCritical,\n            });\n            expect(impact).toEqual(whenEnteredForeign);\n          }\n          // it should merge with the item when it goes onto the displaced start\n          {\n            const impact: DragImpact = getDragImpact({\n              pageOffset: afterPoint(axis, endOnCombineStart),\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              droppables: withCombineEnabled,\n              previousImpact: whenEnteredForeign,\n              viewport: preset.viewport,\n              afterCritical,\n            });\n            expect(impact).toEqual(combineWithDisplacedInForeign3);\n          }\n        });\n\n        it('should no longer merge when moving onto 4/5 of the target', () => {\n          const endOnCombineEnd: Position = getOffsetForEndEdge({\n            endEdgeOn: combineEnd,\n            dragging: preset.inHome1.page.borderBox,\n            axis,\n          });\n\n          // merge when still in on two thirds\n          {\n            const impact: DragImpact = getDragImpact({\n              pageOffset: beforePoint(axis, endOnCombineEnd),\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              droppables: withCombineEnabled,\n              previousImpact: whenEnteredForeign,\n              viewport: preset.viewport,\n              afterCritical,\n            });\n            expect(impact).toEqual(combineWithDisplacedInForeign3);\n          }\n          {\n            const impact: DragImpact = getDragImpact({\n              pageOffset: endOnCombineEnd,\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              droppables: withCombineEnabled,\n              previousImpact: whenEnteredForeign,\n              viewport: preset.viewport,\n              afterCritical,\n            });\n\n            const expected: DragImpact = {\n              displaced: getForcedDisplacement({\n                visible: [{ dimension: preset.inForeign4 }],\n              }),\n              displacedBy,\n              at: {\n                type: 'REORDER',\n                // now in spot of inForeign4\n                destination: {\n                  index: preset.inForeign4.descriptor.index,\n                  droppableId: preset.inForeign4.descriptor.droppableId,\n                },\n              },\n            };\n            expect(impact).toEqual(expected);\n          }\n        });\n      });\n    });\n\n    // moving onto a non-displaced inForeign2\n    describe('combining with non-displaced item', () => {\n      const threshold: Position = getThreshold(axis, preset.inForeign2);\n      const startOfInForeign2: Position = patch(\n        axis.line,\n        preset.inForeign2.page.borderBox[axis.start],\n        crossAxisCenter,\n      );\n      const endOfInForeign2: Position = patch(\n        axis.line,\n        preset.inForeign2.page.borderBox[axis.end],\n        crossAxisCenter,\n      );\n      const combineStart: Position = add(startOfInForeign2, threshold);\n      const combineEnd: Position = subtract(endOfInForeign2, threshold);\n      const combineWithInForeign2: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        // now merging with inForeign2\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inForeign2.descriptor.id,\n            droppableId: preset.inForeign2.descriptor.droppableId,\n          },\n        },\n      };\n\n      it('should combine with an item when moving backwards past 1 / 5 of the items size', () => {\n        const startOnCombineEnd: Position = getOffsetForStartEdge({\n          startEdgeOn: combineEnd,\n          dragging: preset.inHome1.page.borderBox,\n          axis,\n        });\n        // on edge is not far enough\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: startOnCombineEnd,\n            draggable: preset.inHome1,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: whenEnteredForeign,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n          expect(impact).toEqual(whenEnteredForeign);\n        }\n        // over edge is enough\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: beforePoint(axis, startOnCombineEnd),\n            draggable: preset.inHome1,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: whenEnteredForeign,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n          expect(impact).toEqual(combineWithInForeign2);\n        }\n      });\n\n      it('should stop combining when going back onto 2/3 of the size', () => {\n        const startOnCombineStart: Position = getOffsetForStartEdge({\n          startEdgeOn: combineStart,\n          dragging: preset.inHome1.page.borderBox,\n          axis,\n        });\n        // after start is all good\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: afterPoint(axis, startOnCombineStart),\n            draggable: preset.inHome1,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: whenEnteredForeign,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n          expect(impact).toEqual(combineWithInForeign2);\n        }\n        // on combine start = stop combining\n        {\n          const impact: DragImpact = getDragImpact({\n            pageOffset: startOnCombineStart,\n            draggable: preset.inHome1,\n            draggables: preset.draggables,\n            droppables: withCombineEnabled,\n            previousImpact: whenEnteredForeign,\n            viewport: preset.viewport,\n            afterCritical,\n          });\n\n          const expected: DragImpact = {\n            displaced: getForcedDisplacement({\n              visible: [\n                { dimension: preset.inForeign2 },\n                { dimension: preset.inForeign3 },\n                { dimension: preset.inForeign4 },\n              ],\n            }),\n            displacedBy,\n            at: {\n              type: 'REORDER',\n              destination: {\n                index: preset.inForeign2.descriptor.index,\n                droppableId: preset.inForeign2.descriptor.droppableId,\n              },\n            },\n          };\n          expect(impact).toEqual(expected);\n        }\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/combine/with-droppable-scroll.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DroppableDimension,\n  DroppableDimensionMap,\n} from '../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../src/state/axis';\nimport scrollDroppable from '../../../../../src/state/droppable/scroll-droppable';\nimport getDragImpact from '../../../../../src/state/get-drag-impact';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\nimport { patch, add } from '../../../../../src/state/position';\nimport { getPreset, makeScrollable } from '../../../../util/dimension';\nimport { getThreshold } from '../util/get-combine-threshold';\nimport { getOffsetForEndEdge } from '../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n\n    const withCombineEnabled: DroppableDimension = {\n      ...preset.home,\n      isCombineEnabled: true,\n    };\n    const scrollableHome: DroppableDimension = makeScrollable(\n      withCombineEnabled,\n    );\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome1,\n      home: scrollableHome,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n    const scroll: Position = patch(axis.line, 1);\n    const scrolled: DroppableDimension = scrollDroppable(\n      scrollableHome,\n      scroll,\n    );\n    const withoutScrolled: DroppableDimensionMap = {\n      ...preset.droppables,\n      [preset.home.descriptor.id]: scrollableHome,\n    };\n    const withScrolled: DroppableDimensionMap = {\n      ...preset.droppables,\n      [preset.home.descriptor.id]: scrolled,\n    };\n    const startOfInHome2: Position = patch(\n      axis.line,\n      preset.inHome2.page.borderBox[axis.start],\n      preset.inHome2.page.borderBox.center[axis.crossAxisLine],\n    );\n    const threshold: Position = getThreshold(axis, preset.inHome2);\n    const combineStart: Position = add(startOfInHome2, threshold);\n    const offsetForOnCombineStart: Position = getOffsetForEndEdge({\n      endEdgeOn: combineStart,\n      dragging: preset.inHome1.page.borderBox,\n      axis,\n    });\n\n    it('should take into account droppable scroll', () => {\n      // no combine without droppable scroll\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: offsetForOnCombineStart,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppables: withoutScrolled,\n          previousImpact: homeImpact,\n          viewport: preset.viewport,\n          afterCritical,\n        });\n\n        expect(impact.at).toHaveProperty('type', 'REORDER');\n      }\n      // combine now due to do droppable scroll\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: offsetForOnCombineStart,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppables: withScrolled,\n          previousImpact: homeImpact,\n          viewport: preset.viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: homeImpact.displaced,\n          displacedBy: homeImpact.displacedBy,\n          at: {\n            type: 'COMBINE',\n            combine: {\n              draggableId: preset.inHome2.descriptor.id,\n              droppableId: preset.home.descriptor.id,\n            },\n          },\n        };\n        expect(impact).toEqual(expected);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/is-disabled.spec.js",
    "content": "// @flow\nimport type {\n  Axis,\n  DroppableDimension,\n  DroppableDimensionMap,\n  DragImpact,\n} from '../../../../src/types';\nimport { horizontal, vertical } from '../../../../src/state/axis';\nimport getDragImpact from '../../../../src/state/get-drag-impact';\nimport noImpact from '../../../../src/state/no-impact';\nimport { disableDroppable, getPreset } from '../../../util/dimension';\nimport getLiftEffect from '../../../../src/state/get-lift-effect';\nimport { origin } from '../../../../src/state/position';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome1,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n\n    it('should return no impact when home is disabled', () => {\n      const disabled: DroppableDimension = disableDroppable(preset.home);\n      const withDisabled: DroppableDimensionMap = {\n        ...preset.droppables,\n        [disabled.descriptor.id]: disabled,\n      };\n\n      const impact: DragImpact = getDragImpact({\n        // no change - should still be in same spot\n        pageOffset: origin,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: withDisabled,\n        previousImpact: homeImpact,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n\n      expect(impact).toEqual(noImpact);\n    });\n\n    it('should return no impact when foreign is disabled', () => {\n      const disabled: DroppableDimension = disableDroppable(preset.foreign);\n      const withDisabled: DroppableDimensionMap = {\n        ...preset.droppables,\n        [disabled.descriptor.id]: disabled,\n      };\n\n      const impact: DragImpact = getDragImpact({\n        pageOffset: origin,\n        draggable: preset.inForeign1,\n        draggables: preset.draggables,\n        droppables: withDisabled,\n        previousImpact: homeImpact,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n\n      expect(impact).toEqual(noImpact);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/over-nothing.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { horizontal, vertical } from '../../../../src/state/axis';\nimport getDragImpact from '../../../../src/state/get-drag-impact';\nimport noImpact from '../../../../src/state/no-impact';\nimport { getPreset } from '../../../util/dimension';\nimport type { Axis, DragImpact } from '../../../../src/types';\nimport getLiftEffect from '../../../../src/state/get-lift-effect';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n\n    it('should return no impact when not dragging over anything', () => {\n      // dragging up above the list\n      const farAway: Position = {\n        x: 10000,\n        y: 10000,\n      };\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n\n      const impact: DragImpact = getDragImpact({\n        pageOffset: farAway,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: preset.droppables,\n        previousImpact: homeImpact,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n\n      expect(impact).toEqual(noImpact);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/reorder/over-foreign-list/did-not-start-displaced.spec.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport getDragImpact from '../../../../../../src/state/get-drag-impact';\nimport { add } from '../../../../../../src/state/position';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport { getPreset } from '../../../../../util/dimension';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport type {\n  Axis,\n  DragImpact,\n  Viewport,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport afterPoint from '../../../../../util/after-point';\nimport beforePoint from '../../../../../util/before-point';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport {\n  getOffsetForStartEdge,\n  getOffsetForEndEdge,\n} from '../../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const viewport: Viewport = preset.viewport;\n\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome1.displaceBy,\n    );\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome1,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n\n    const offsetForStartOnInForeign2Center: Position = getOffsetForStartEdge({\n      startEdgeOn: preset.inForeign2.page.borderBox.center,\n      dragging: preset.inHome1.page.borderBox,\n      axis,\n    });\n\n    const goingBackwards: DragImpact = getDragImpact({\n      pageOffset: beforePoint(axis, offsetForStartOnInForeign2Center),\n      draggable: preset.inHome1,\n      draggables: preset.draggables,\n      droppables: preset.droppables,\n      previousImpact: homeImpact,\n      viewport,\n      afterCritical,\n    });\n\n    it('should displace items when moving backwards past their bottom edge', () => {\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: offsetForStartOnInForeign2Center,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: homeImpact,\n          viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              // ordered by closest to current location\n              // animated and visible as it is a foreign list\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              // is now in position of inForeign3\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign3.descriptor.index,\n            },\n          },\n        };\n\n        expect(impact).toEqual(expected);\n      }\n\n      const expected: DragImpact = {\n        displaced: getForcedDisplacement({\n          // ordered by closest to current location\n          visible: [\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            // is now in position of inForeign2\n            droppableId: preset.inForeign2.descriptor.droppableId,\n            index: preset.inForeign2.descriptor.index,\n          },\n        },\n      };\n      expect(goingBackwards).toEqual(expected);\n    });\n\n    it('should end displacement if moving forward over the displaced center', () => {\n      const offsetForEndOnInForeign2Center: Position = getOffsetForEndEdge({\n        endEdgeOn: preset.inForeign2.page.borderBox.center,\n        dragging: preset.inHome1.page.borderBox,\n        axis,\n      });\n      const displaced: Position = add(\n        offsetForEndOnInForeign2Center,\n        displacedBy.point,\n      );\n\n      // still not far enough\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: displaced,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: goingBackwards,\n          viewport,\n          afterCritical,\n        });\n        expect(impact).toEqual(goingBackwards);\n      }\n      // no longer displace as we have moved forwards past the displaced center\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: afterPoint(axis, displaced),\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: goingBackwards,\n          viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // ordered by closest impacted\n            visible: [\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              // is now in position of inForeign3\n              droppableId: preset.inForeign3.descriptor.droppableId,\n              index: preset.inForeign3.descriptor.index,\n            },\n          },\n        };\n        expect(impact).toEqual(expected);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/reorder/over-foreign-list/move-backward-from-last-item.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  Viewport,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport { horizontal, vertical } from '../../../../../../src/state/axis';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport getDragImpact from '../../../../../../src/state/get-drag-impact';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../../util/dimension';\nimport { emptyGroups } from '../../../../../../src/state/no-impact';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport beforePoint from '../../../../../util/before-point';\nimport { getOffsetForStartEdge } from '../../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    it('should allow movement past from last item', () => {\n      const preset = getPreset(axis);\n      const viewport: Viewport = preset.viewport;\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        preset.inHome1.displaceBy,\n      );\n\n      const inLastSpot: DragImpact = {\n        displaced: emptyGroups,\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          // after last item\n          destination: {\n            index: preset.inForeign4.descriptor.index + 1,\n            droppableId: preset.inForeign4.descriptor.droppableId,\n          },\n        },\n      };\n\n      const offsetForEndOnInForeign4Center: Position = getOffsetForStartEdge({\n        startEdgeOn: preset.inForeign4.page.borderBox.center,\n        dragging: preset.inHome1.page.borderBox,\n        axis,\n      });\n\n      const goingBackwards: DragImpact = getDragImpact({\n        pageOffset: beforePoint(axis, offsetForEndOnInForeign4Center),\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: preset.droppables,\n        previousImpact: inLastSpot,\n        viewport,\n        afterCritical,\n      });\n\n      const expected: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [{ dimension: preset.inForeign4 }],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          // now in visual spot of inForeign4\n          destination: {\n            index: preset.inForeign4.descriptor.index,\n            droppableId: preset.inForeign4.descriptor.droppableId,\n          },\n        },\n      };\n      expect(goingBackwards).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/reorder/over-foreign-list/move-past-last-item.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  Viewport,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport { horizontal, vertical } from '../../../../../../src/state/axis';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport getDragImpact from '../../../../../../src/state/get-drag-impact';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../../util/dimension';\nimport { emptyGroups } from '../../../../../../src/state/no-impact';\nimport { getOffsetForStartEdge } from '../../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    it('should allow movement past the last item', () => {\n      const preset = getPreset(axis);\n      const viewport: Viewport = preset.viewport;\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        preset.inHome1.displaceBy,\n      );\n\n      const offsetForStartOnInForeign4Center: Position = getOffsetForStartEdge({\n        startEdgeOn: preset.inForeign4.page.borderBox.center,\n        dragging: preset.inHome1.page.borderBox,\n        axis,\n      });\n\n      const goingForwards: DragImpact = getDragImpact({\n        // because this is a new impact - nothing is previously displaced\n        // targetStart < childCenter;\n        pageOffset: offsetForStartOnInForeign4Center,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: preset.droppables,\n        previousImpact: homeImpact,\n        viewport,\n        afterCritical,\n      });\n\n      const expected: DragImpact = {\n        displaced: emptyGroups,\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          // after last item\n          destination: {\n            index: preset.inForeign4.descriptor.index + 1,\n            droppableId: preset.inForeign4.descriptor.droppableId,\n          },\n        },\n      };\n      expect(goingForwards).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/reorder/over-home-list/displacement-visibility.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport getDragImpact from '../../../../../../src/state/get-drag-impact';\nimport noImpact from '../../../../../../src/state/no-impact';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport type {\n  Axis,\n  DragImpact,\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n  DroppableDimensionMap,\n  Viewport,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport {\n  getDroppableDimension,\n  getDraggableDimension,\n} from '../../../../../util/dimension';\nimport getViewport from '../../../../../../src/view/window/get-viewport';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport noAfterCritical from '../../../../../util/no-after-critical';\nimport { origin, subtract } from '../../../../../../src/state/position';\n\nconst viewport: Viewport = getViewport();\n\n// this is just an application of get-displacement.spec\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const crossAxisStart: number = 0;\n    const crossAxisEnd: number = 100;\n\n    it('should indicate when a displacement is not visible due to being outside of the droppable frame', () => {\n      const droppable: DroppableDimension = getDroppableDimension({\n        descriptor: {\n          id: 'my-custom-droppable',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          [axis.start]: 0,\n          // will be cut by the frame\n          [axis.end]: 200,\n        },\n        closest: {\n          borderBox: {\n            [axis.crossAxisStart]: crossAxisStart,\n            [axis.crossAxisEnd]: crossAxisEnd,\n            [axis.start]: 0,\n            // will cut the subject,\n            [axis.end]: 100,\n          },\n          scrollSize: {\n            scrollWidth: 100,\n            scrollHeight: 100,\n          },\n          scroll: { x: 0, y: 0 },\n          shouldClipSubject: true,\n        },\n      });\n      const visible: DraggableDimension = getDraggableDimension({\n        descriptor: {\n          id: 'visible',\n          droppableId: droppable.descriptor.id,\n          type: droppable.descriptor.type,\n          index: 0,\n        },\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          [axis.start]: 0,\n          [axis.end]: 90,\n        },\n      });\n      const partialVisible: DraggableDimension = getDraggableDimension({\n        descriptor: {\n          id: 'partial-visible',\n          droppableId: droppable.descriptor.id,\n          type: droppable.descriptor.type,\n          index: 1,\n        },\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          // partially in frame\n          [axis.start]: 90,\n          [axis.end]: 120,\n        },\n      });\n      const notVisible1: DraggableDimension = getDraggableDimension({\n        descriptor: {\n          id: 'not-visible-1',\n          droppableId: droppable.descriptor.id,\n          type: droppable.descriptor.type,\n          index: 2,\n        },\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          // inside the frame, but not in the visible area\n          [axis.start]: 130,\n          [axis.end]: 140,\n        },\n      });\n      const notVisible2: DraggableDimension = getDraggableDimension({\n        descriptor: {\n          id: 'not-visible-2',\n          droppableId: droppable.descriptor.id,\n          type: droppable.descriptor.type,\n          index: 3,\n        },\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          // inside the frame, but not in the visible area\n          [axis.start]: 150,\n          [axis.end]: 170,\n        },\n      });\n      const customDraggables: DraggableDimensionMap = {\n        [visible.descriptor.id]: visible,\n        [partialVisible.descriptor.id]: partialVisible,\n        [notVisible1.descriptor.id]: notVisible1,\n        [notVisible2.descriptor.id]: notVisible2,\n      };\n      const customDroppables: DroppableDimensionMap = {\n        [droppable.descriptor.id]: droppable,\n      };\n      // dragging notVisible2 backwards into first position\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        notVisible2.displaceBy,\n      );\n      const expected: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            {\n              dimension: visible,\n              shouldAnimate: true,\n            },\n            {\n              dimension: partialVisible,\n              shouldAnimate: true,\n            },\n          ],\n          invisible: [notVisible1],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            droppableId: droppable.descriptor.id,\n            index: 0,\n          },\n        },\n      };\n\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: notVisible2,\n        home: droppable,\n        draggables: customDraggables,\n        viewport,\n      });\n      // moving backwards to near the start of the droppable\n      const destination: Position = { x: 1, y: 1 };\n      const offset: Position = subtract(\n        destination,\n        notVisible2.page.borderBox.center,\n      );\n      const impact: DragImpact = getDragImpact({\n        pageOffset: offset,\n        draggable: notVisible2,\n        draggables: customDraggables,\n        droppables: customDroppables,\n        previousImpact: homeImpact,\n        viewport,\n        afterCritical,\n      });\n\n      expect(impact).toEqual(expected);\n    });\n\n    it('should indicate when a displacement is not visible due to being outside of the viewport', () => {\n      const droppable: DroppableDimension = getDroppableDimension({\n        descriptor: {\n          id: 'my-custom-droppable',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          [axis.start]: 0,\n          [axis.end]: viewport.frame[axis.end] + 100,\n        },\n      });\n      const visible: DraggableDimension = getDraggableDimension({\n        descriptor: {\n          id: 'visible',\n          droppableId: droppable.descriptor.id,\n          type: droppable.descriptor.type,\n          index: 0,\n        },\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          [axis.start]: 0,\n          [axis.end]: viewport.frame[axis.end] - 20,\n        },\n      });\n      const partialVisible: DraggableDimension = getDraggableDimension({\n        descriptor: {\n          id: 'partial-visible',\n          droppableId: droppable.descriptor.id,\n          type: droppable.descriptor.type,\n          index: 1,\n        },\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          [axis.start]: viewport.frame[axis.end] - 20,\n          [axis.end]: viewport.frame[axis.end] + 10,\n        },\n      });\n      const notVisible1: DraggableDimension = getDraggableDimension({\n        descriptor: {\n          id: 'not-visible-1',\n          droppableId: droppable.descriptor.id,\n          type: droppable.descriptor.type,\n          index: 2,\n        },\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          [axis.start]:\n            viewport.frame[axis.end] + visible.page.marginBox[axis.size],\n          [axis.end]:\n            viewport.frame[axis.end] +\n            visible.page.marginBox[axis.crossAxisSize],\n        },\n      });\n      const notVisible2: DraggableDimension = getDraggableDimension({\n        descriptor: {\n          id: 'not-visible-2',\n          droppableId: droppable.descriptor.id,\n          type: droppable.descriptor.type,\n          index: 3,\n        },\n        borderBox: {\n          [axis.crossAxisStart]: crossAxisStart,\n          [axis.crossAxisEnd]: crossAxisEnd,\n          // inside the droppable, but not in the visible area\n          [axis.start]:\n            viewport.frame[axis.end] + visible.page.marginBox[axis.size] + 1,\n          [axis.end]:\n            viewport.frame[axis.end] +\n            visible.page.marginBox[axis.crossAxisSize] +\n            1,\n        },\n      });\n      const customDraggables: DraggableDimensionMap = {\n        [visible.descriptor.id]: visible,\n        [partialVisible.descriptor.id]: partialVisible,\n        [notVisible1.descriptor.id]: notVisible1,\n        [notVisible2.descriptor.id]: notVisible2,\n      };\n      const customDroppables: DroppableDimensionMap = {\n        [droppable.descriptor.id]: droppable,\n      };\n      const displacedBy: DisplacedBy = getDisplacedBy(axis, visible.displaceBy);\n      const expected: DragImpact = {\n        // no longer the same due to visibility overscanning\n        displaced: getForcedDisplacement({\n          visible: [\n            {\n              dimension: partialVisible,\n              shouldAnimate: true,\n            },\n            {\n              dimension: notVisible1,\n              shouldAnimate: true,\n            },\n          ],\n          invisible: [notVisible2],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            droppableId: droppable.descriptor.id,\n            index: 0,\n          },\n        },\n      };\n\n      const impact: DragImpact = getDragImpact({\n        pageOffset: origin,\n        draggable: visible,\n        draggables: customDraggables,\n        droppables: customDroppables,\n        previousImpact: noImpact,\n        viewport,\n        afterCritical: noAfterCritical,\n      });\n\n      expect(impact).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/reorder/over-home-list/move-past-last-item.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { Axis, DragImpact, Viewport } from '../../../../../../src/types';\nimport { horizontal, vertical } from '../../../../../../src/state/axis';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport getDragImpact from '../../../../../../src/state/get-drag-impact';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../../util/dimension';\nimport { emptyGroups } from '../../../../../../src/state/no-impact';\nimport afterPoint from '../../../../../util/after-point';\nimport { getOffsetForEndEdge } from '../../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    it('should allow movement past the last item', () => {\n      const preset = getPreset(axis);\n      const viewport: Viewport = preset.viewport;\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const offsetForEndOnInHome4Center: Position = getOffsetForEndEdge({\n        endEdgeOn: preset.inHome4.page.borderBox.center,\n        dragging: preset.inHome1.page.borderBox,\n        axis,\n      });\n\n      const goingForwards: DragImpact = getDragImpact({\n        pageOffset: afterPoint(axis, offsetForEndOnInHome4Center),\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: preset.droppables,\n        previousImpact: homeImpact,\n        viewport,\n        afterCritical,\n      });\n\n      const expected: DragImpact = {\n        displaced: emptyGroups,\n        displacedBy: getDisplacedBy(axis, preset.inHome1.displaceBy),\n        at: {\n          type: 'REORDER',\n          // in the visual position of the last itme\n          destination: {\n            index: preset.inHome4.descriptor.index,\n            droppableId: preset.inHome4.descriptor.droppableId,\n          },\n        },\n      };\n      expect(goingForwards).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/reorder/over-home-list/started-after-critical.spec.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport getDragImpact from '../../../../../../src/state/get-drag-impact';\nimport { subtract } from '../../../../../../src/state/position';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport { getPreset } from '../../../../../util/dimension';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport type {\n  Axis,\n  DragImpact,\n  Viewport,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport beforePoint from '../../../../../util/before-point';\nimport afterPoint from '../../../../../util/after-point';\nimport getHomeLocation from '../../../../../../src/state/get-home-location';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport {\n  getOffsetForEndEdge,\n  getOffsetForStartEdge,\n} from '../../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const viewport: Viewport = preset.viewport;\n\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome2.displaceBy,\n    );\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome2,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n\n    const offsetForEndOnInHome3Center: Position = getOffsetForEndEdge({\n      endEdgeOn: preset.inHome3.page.borderBox.center,\n      dragging: preset.inHome2.page.borderBox,\n      axis,\n    });\n\n    const endPastInHome3Center: DragImpact = getDragImpact({\n      pageOffset: afterPoint(axis, offsetForEndOnInHome3Center),\n      draggable: preset.inHome2,\n      draggables: preset.draggables,\n      droppables: preset.droppables,\n      previousImpact: homeImpact,\n      viewport,\n      afterCritical,\n    });\n\n    it('should displace items backwards when end of dragging item goes past the target center', () => {\n      {\n        const endOnInHome3Center: DragImpact = getDragImpact({\n          pageOffset: offsetForEndOnInHome3Center,\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: homeImpact,\n          viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // inHome4 would have been displaced on lift so it won't be animated\n            visible: [\n              {\n                dimension: preset.inHome3,\n                shouldAnimate: false,\n              },\n              {\n                dimension: preset.inHome4,\n                shouldAnimate: false,\n              },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: getHomeLocation(preset.inHome2.descriptor),\n          },\n        };\n\n        expect(endOnInHome3Center).toEqual(expected);\n      }\n\n      const expected: DragImpact = {\n        displaced: getForcedDisplacement({\n          // inHome4 would have been displaced on lift so it won't be animated\n          visible: [\n            {\n              dimension: preset.inHome4,\n              shouldAnimate: false,\n            },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            // is now in position of inHome3\n            droppableId: preset.home.descriptor.id,\n            index: preset.inHome3.descriptor.index,\n          },\n        },\n      };\n\n      expect(endPastInHome3Center).toEqual(expected);\n    });\n\n    // Even though inHome3 is not 'displaced'\n    // it is visibly displaced from the start of the drag\n    it('should end displacement if the start of the dragging item is less than the displaced target center', () => {\n      const displacedInHome3Center: Position = subtract(\n        preset.inHome3.page.borderBox.center,\n        displacedBy.point,\n      );\n\n      const offsetForStartOnDisplacedInHome2Center: Position = getOffsetForStartEdge(\n        {\n          startEdgeOn: displacedInHome3Center,\n          dragging: preset.inHome2.page.borderBox,\n          axis,\n        },\n      );\n\n      // still not far enough\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: offsetForStartOnDisplacedInHome2Center,\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: endPastInHome3Center,\n          viewport,\n          afterCritical,\n        });\n        expect(impact).toEqual(endPastInHome3Center);\n      }\n      // no longer displace as we move backwards past the displaced center\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: beforePoint(axis, offsetForStartOnDisplacedInHome2Center),\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: endPastInHome3Center,\n          viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // inHome4 would have been displaced on lift so it won't be animated\n            visible: [\n              // inHome3 is now animated\n              {\n                dimension: preset.inHome3,\n                shouldAnimate: true,\n              },\n              // inHome4 displacement stays not displaced\n              {\n                dimension: preset.inHome4,\n                shouldAnimate: false,\n              },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome2.descriptor.index,\n            },\n          },\n        };\n\n        expect(impact).toEqual(expected);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/reorder/over-home-list/started-before-critical.spec.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport getDragImpact from '../../../../../../src/state/get-drag-impact';\nimport { add } from '../../../../../../src/state/position';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport { getPreset } from '../../../../../util/dimension';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport type {\n  Axis,\n  DragImpact,\n  Viewport,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport beforePoint from '../../../../../util/before-point';\nimport afterPoint from '../../../../../util/after-point';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport {\n  getOffsetForStartEdge,\n  getOffsetForEndEdge,\n} from '../../util/get-offset-for-edge';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const viewport: Viewport = preset.viewport;\n\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome3.displaceBy,\n    );\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome3,\n      home: preset.home,\n      draggables: preset.draggables,\n      viewport: preset.viewport,\n    });\n\n    const offsetForStartOnInHome1Center: Position = getOffsetForStartEdge({\n      startEdgeOn: preset.inHome1.page.borderBox.center,\n      dragging: preset.inHome3.page.borderBox,\n      axis,\n    });\n\n    const startBeforeInHome1Center: DragImpact = getDragImpact({\n      pageOffset: beforePoint(axis, offsetForStartOnInHome1Center),\n      draggable: preset.inHome3,\n      draggables: preset.draggables,\n      droppables: preset.droppables,\n      previousImpact: homeImpact,\n      viewport,\n      afterCritical,\n    });\n\n    it('should displace items forward when the start edge of the dragging item goes backwards past the items center', () => {\n      // after center of inHome1\n      {\n        const startOnInHome1Center: DragImpact = getDragImpact({\n          pageOffset: offsetForStartOnInHome1Center,\n          draggable: preset.inHome3,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: homeImpact,\n          viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // ordered by closest to current location\n            visible: [\n              { dimension: preset.inHome2, shouldAnimate: true },\n              // inHome3 is not displaced as it is the dragging item\n              // inHome4 would have been displaced on lift so it won't be animated\n              { dimension: preset.inHome4, shouldAnimate: false },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              // is now in position of inHome2\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome2.descriptor.index,\n            },\n          },\n        };\n        expect(startOnInHome1Center).toEqual(expected);\n      }\n      // on center of inHome1\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // ordered by closest to current location\n            visible: [\n              { dimension: preset.inHome1 },\n              { dimension: preset.inHome2 },\n              // inHome3 is not displaced as it is the dragging item\n              // inHome4 would have been displaced on lift so it won't be animated\n              { dimension: preset.inHome4, shouldAnimate: false },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              // is now in position of inHome1\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome1.descriptor.index,\n            },\n          },\n        };\n        expect(startBeforeInHome1Center).toEqual(expected);\n      }\n    });\n\n    it('should end displacement if the dragging item bottom edge goes forward past the displaced center', () => {\n      const displacedInHome1Center: Position = add(\n        preset.inHome1.page.borderBox.center,\n        displacedBy.point,\n      );\n\n      const offsetForEndOnDisplacedInHome1Center: Position = getOffsetForEndEdge(\n        {\n          endEdgeOn: displacedInHome1Center,\n          dragging: preset.inHome3.page.borderBox,\n          axis,\n        },\n      );\n\n      // still not far enough\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: offsetForEndOnDisplacedInHome1Center,\n          draggable: preset.inHome3,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: startBeforeInHome1Center,\n          viewport,\n          afterCritical,\n        });\n        expect(impact).toEqual(startBeforeInHome1Center);\n      }\n      // no longer displace as we have moved onto the displaced top edge\n      {\n        const impact: DragImpact = getDragImpact({\n          pageOffset: afterPoint(axis, offsetForEndOnDisplacedInHome1Center),\n          draggable: preset.inHome3,\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: startBeforeInHome1Center,\n          viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inHome2 },\n              // not displacing inHome3 as it is the dragging item\n              { dimension: preset.inHome4, shouldAnimate: false },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              // is now in position of inHome2\n              index: preset.inHome2.descriptor.index,\n            },\n          },\n        };\n        expect(impact).toEqual(expected);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/reorder/over-home-list/with-droppable-scroll.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Axis,\n  DisplacedBy,\n  DroppableDimension,\n  DroppableDimensionMap,\n  DragImpact,\n  Viewport,\n} from '../../../../../../src/types';\nimport { horizontal, vertical } from '../../../../../../src/state/axis';\nimport scrollDroppable from '../../../../../../src/state/droppable/scroll-droppable';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport getDragImpact from '../../../../../../src/state/get-drag-impact';\nimport { patch, origin } from '../../../../../../src/state/position';\nimport getViewport from '../../../../../../src/view/window/get-viewport';\nimport { getPreset, makeScrollable } from '../../../../../util/dimension';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../../../../util/impact';\n\nconst viewport: Viewport = getViewport();\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n\n    const scrollableHome: DroppableDimension = makeScrollable(preset.home);\n    const withScrollableHome = {\n      ...preset.droppables,\n      [preset.home.descriptor.id]: scrollableHome,\n    };\n\n    // moving inHome1 past inHome2 by scrolling the dimension\n    describe('moving beyond start position with own scroll', () => {\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: scrollableHome,\n        draggables: preset.draggables,\n        viewport,\n      });\n\n      it('should move past other draggables', () => {\n        const centerOfInHome2: number =\n          preset.inHome2.page.borderBox.center[axis.line];\n        const distanceNeeded: Position = patch(\n          axis.line,\n          centerOfInHome2 - preset.inHome1.page.borderBox[axis.end] + 1,\n        );\n\n        const scrolledHome: DroppableDimension = scrollDroppable(\n          scrollableHome,\n          distanceNeeded,\n        );\n        const updatedDroppables: DroppableDimensionMap = {\n          ...withScrollableHome,\n          [preset.home.descriptor.id]: scrolledHome,\n        };\n        // moving forward over inHome2\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome1.displaceBy,\n        );\n        const impact: DragImpact = getDragImpact({\n          pageOffset: origin,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          droppables: updatedDroppables,\n          previousImpact: homeImpact,\n          viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // inHome2 no longer displaced\n            // originally displaced so not animated\n            visible: [\n              { dimension: preset.inHome3, shouldAnimate: false },\n              { dimension: preset.inHome4, shouldAnimate: false },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              // now in position of inHome2 as it has moved backwards (it started displaced)\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome2.descriptor.index,\n            },\n          },\n        };\n        expect(impact).toEqual(expected);\n      });\n    });\n\n    // moving inHome4 back past inHome2\n    describe('moving back past start position with own scroll', () => {\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome4,\n        home: scrollableHome,\n        draggables: preset.draggables,\n        viewport,\n      });\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        preset.inHome4.displaceBy,\n      );\n\n      it('should move back past inHome2', () => {\n        const centerOfInHome2: number =\n          preset.inHome2.page.borderBox.center[axis.line];\n\n        // Displacement will end when start goes past the displaced center of inHome2\n        const distanceNeeded: Position = patch(\n          axis.line,\n          centerOfInHome2 - preset.inHome4.page.borderBox[axis.start] - 1,\n        );\n        const scrolledHome: DroppableDimension = scrollDroppable(\n          scrollableHome,\n          distanceNeeded,\n        );\n        const updatedDroppables: DroppableDimensionMap = {\n          ...withScrollableHome,\n          [preset.home.descriptor.id]: scrolledHome,\n        };\n\n        const impact: DragImpact = getDragImpact({\n          // no changes in current page center from original\n          pageOffset: origin,\n          draggable: preset.inHome4,\n          draggables: preset.draggables,\n          droppables: updatedDroppables,\n          previousImpact: homeImpact,\n          viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              // ordered by closest to current location\n              { dimension: preset.inHome2 },\n              { dimension: preset.inHome3 },\n              // inHome4 not displaced as it is the dragging item\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              // is now in place of inHome2\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome2.descriptor.index,\n            },\n          },\n        };\n        expect(impact).toEqual(expected);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/util/get-combine-threshold.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { Axis, DraggableDimension } from '../../../../../src/types';\nimport { patch } from '../../../../../src/state/position';\nimport { combineThresholdDivisor } from '../../../../../src/state/get-drag-impact/get-combine-impact';\n\nexport function getThreshold(\n  axis: Axis,\n  draggable: DraggableDimension,\n): Position {\n  return patch(\n    axis.line,\n    draggable.page.borderBox[axis.size] / combineThresholdDivisor,\n  );\n}\n"
  },
  {
    "path": "test/unit/state/get-drag-impact/util/get-offset-for-edge.js",
    "content": "// @flow\nimport type { Position, Rect } from 'css-box-model';\nimport type { Axis } from '../../../../../src/types';\nimport { patch, subtract } from '../../../../../src/state/position';\n\ntype ForStart = {|\n  startEdgeOn: Position,\n  dragging: Rect,\n  axis: Axis,\n|};\n\nexport function getOffsetForStartEdge({\n  startEdgeOn,\n  dragging,\n  axis,\n}: ForStart): Position {\n  const offset: Position = subtract(\n    startEdgeOn,\n    patch(axis.line, dragging[axis.start], dragging.center[axis.crossAxisLine]),\n  );\n  return offset;\n}\n\ntype ForCrossAxisStart = {|\n  crossAxisStartEdgeOn: Position,\n  dragging: Rect,\n  axis: Axis,\n|};\n\nexport function getOffsetForCrossAxisStartEdge({\n  crossAxisStartEdgeOn,\n  dragging,\n  axis,\n}: ForCrossAxisStart): Position {\n  const offset: Position = subtract(\n    crossAxisStartEdgeOn,\n    patch(axis.line, dragging.center[axis.line], dragging[axis.crossAxisStart]),\n  );\n  return offset;\n}\n\ntype ForEnd = {|\n  endEdgeOn: Position,\n  dragging: Rect,\n  axis: Axis,\n|};\n\nexport function getOffsetForEndEdge({\n  endEdgeOn,\n  dragging,\n  axis,\n}: ForEnd): Position {\n  const offset: Position = subtract(\n    endEdgeOn,\n    patch(axis.line, dragging[axis.end], dragging.center[axis.crossAxisLine]),\n  );\n  return offset;\n}\n\ntype ForCrossAxisEnd = {|\n  crossAxisEndEdgeOn: Position,\n  dragging: Rect,\n  axis: Axis,\n|};\n\nexport function getOffsetForCrossAxisEndEdge({\n  crossAxisEndEdgeOn,\n  dragging,\n  axis,\n}: ForCrossAxisEnd): Position {\n  const offset: Position = subtract(\n    crossAxisEndEdgeOn,\n    patch(axis.line, dragging.center[axis.line], dragging[axis.crossAxisEnd]),\n  );\n  return offset;\n}\n"
  },
  {
    "path": "test/unit/state/get-draggables-inside-droppable.spec.js",
    "content": "// @flow\nimport getDraggablesInsideDroppable from '../../../src/state/get-draggables-inside-droppable';\nimport scrollDroppable from '../../../src/state/droppable/scroll-droppable';\nimport { getPreset, makeScrollable } from '../../util/dimension';\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n} from '../../../src/types';\n\nconst preset = getPreset();\n\ndescribe('get draggables inside a droppable', () => {\n  it('should only return dimensions that are inside a droppable', () => {\n    const result: DraggableDimension[] = getDraggablesInsideDroppable(\n      preset.home.descriptor.id,\n      preset.draggables,\n    );\n\n    expect(result).toEqual(preset.inHomeList);\n  });\n\n  it('should order the dimensions by index', () => {\n    const result: DraggableDimension[] = getDraggablesInsideDroppable(\n      preset.home.descriptor.id,\n      preset.draggables,\n    );\n\n    expect(result).toEqual([\n      preset.inHome1,\n      preset.inHome2,\n      preset.inHome3,\n      preset.inHome4,\n    ]);\n  });\n\n  it('should memoize by the id and not the object reference', () => {\n    const first: DraggableDimension[] = getDraggablesInsideDroppable(\n      preset.home.descriptor.id,\n      preset.draggables,\n    );\n    // even though we are scrolling the droppable (new reference) we are maintaining memoization\n    const scrolledHome: DroppableDimension = scrollDroppable(\n      makeScrollable(preset.home),\n      { x: 10, y: 20 },\n    );\n    const second: DraggableDimension[] = getDraggablesInsideDroppable(\n      scrolledHome.descriptor.id,\n      preset.draggables,\n    );\n\n    expect(first).toBe(second);\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-droppable-over/center-is-over.spec.js",
    "content": "// @flow\nimport type { Position, Rect } from 'css-box-model';\nimport type {\n  Axis,\n  DroppableId,\n  DraggableDimension,\n} from '../../../../src/types';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport { getPreset } from '../../../util/dimension';\nimport { getCorners, expandByPosition } from '../../../../src/state/spacing';\nimport getDroppableOver from '../../../../src/state/get-droppable-over';\nimport { invariant } from '../../../../src/invariant';\nimport { subtract, patch } from '../../../../src/state/position';\nimport { offsetRectByPosition } from '../../../../src/state/rect';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const active: ?Rect = preset.home.subject.active;\n    invariant(active, 'expected active');\n    const draggable: DraggableDimension = preset.inHome1;\n\n    it('should return a list when the center is over the list', () => {\n      const corners: Position[] = getCorners(active);\n\n      corners.forEach((corner: Position) => {\n        const pageOffset: Position = subtract(\n          corner,\n          draggable.page.borderBox.center,\n        );\n        const pageBorderBox: Rect = offsetRectByPosition(\n          draggable.page.borderBox,\n          pageOffset,\n        );\n\n        const result: ?DroppableId = getDroppableOver({\n          pageBorderBox,\n          draggable,\n          droppables: preset.droppables,\n        });\n\n        expect(result).toBe(preset.home.descriptor.id);\n      });\n    });\n\n    it('should not return a match when the center is not over a list (and no other candidate conditions are met)', () => {\n      const outside: Position[] = getCorners(\n        // getting corners of a slightly bigger active\n        // which would be outside the current active\n        expandByPosition(active, patch(axis.line, 1)),\n      );\n\n      outside.forEach((corner: Position) => {\n        const pageOffset: Position = subtract(\n          corner,\n          draggable.page.borderBox.center,\n        );\n        const pageBorderBox: Rect = offsetRectByPosition(\n          draggable.page.borderBox,\n          pageOffset,\n        );\n        const result: ?DroppableId = getDroppableOver({\n          pageBorderBox,\n          draggable,\n          droppables: preset.droppables,\n        });\n\n        expect(result).toBe(null);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/get-droppable-over/is-disabled.spec.js",
    "content": "// @flow\nimport type { DroppableDimensionMap, DroppableId } from '../../../../src/types';\nimport getDroppableOver from '../../../../src/state/get-droppable-over';\nimport { disableDroppable, getPreset } from '../../../util/dimension';\n\nconst preset = getPreset();\n\nit('should not consider lists that are disabled', () => {\n  const withDisabled: DroppableDimensionMap = {\n    ...preset.droppables,\n    [preset.home.descriptor.id]: disableDroppable(preset.home),\n  };\n\n  const whileEnabled: ?DroppableId = getDroppableOver({\n    pageBorderBox: preset.inHome1.page.borderBox,\n    draggable: preset.inHome1,\n    droppables: preset.droppables,\n  });\n  const whileDisabled: ?DroppableId = getDroppableOver({\n    pageBorderBox: preset.inHome1.page.borderBox,\n    draggable: preset.inHome1,\n    droppables: withDisabled,\n  });\n\n  expect(whileEnabled).toBe(preset.home.descriptor.id);\n  expect(whileDisabled).toBe(null);\n});\n"
  },
  {
    "path": "test/unit/state/get-droppable-over/is-not-visible.spec.js",
    "content": "// @flow\nimport { type Position, type Rect } from 'css-box-model';\nimport {\n  getDroppableDimension,\n  getDraggableDimension,\n} from '../../../util/dimension';\nimport { subtract } from '../../../../src/state/position';\nimport getDroppableOver from '../../../../src/state/get-droppable-over';\nimport { offsetRectByPosition } from '../../../../src/state/rect';\nimport type {\n  TypeId,\n  DraggableDimension,\n  DroppableDimension,\n  DroppableId,\n} from '../../../../src/types';\n\nconst type: TypeId = 'standard';\nconst droppableId: DroppableId = 'list';\n\nconst dragging: DraggableDimension = getDraggableDimension({\n  descriptor: {\n    id: 'dragging',\n    index: 0,\n    type,\n    droppableId,\n  },\n  borderBox: {\n    top: 20,\n    left: 20,\n    right: 60,\n    bottom: 60,\n  },\n});\n\nit('should hit when inside subject, but outside the frame', () => {\n  const droppable: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: droppableId,\n      type,\n      mode: 'standard',\n    },\n    borderBox: {\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 100,\n    },\n    closest: {\n      borderBox: {\n        top: 0,\n        left: 0,\n        right: 50,\n        bottom: 50,\n      },\n      scrollSize: {\n        scrollHeight: 100,\n        scrollWidth: 100,\n      },\n      scroll: { x: 0, y: 0 },\n      shouldClipSubject: true,\n    },\n  });\n  const target: Position = { x: 20, y: 20 };\n  const distance: Position = subtract(target, dragging.page.borderBox.center);\n\n  const pageBorderBox: Rect = offsetRectByPosition(\n    dragging.page.borderBox,\n    distance,\n  );\n\n  const result: ?DroppableId = getDroppableOver({\n    pageBorderBox,\n    draggable: dragging,\n    droppables: { [droppableId]: droppable },\n  });\n\n  expect(result).toBe(droppableId);\n});\n\nit('should not hit when inside subject, but outside the frame', () => {\n  const droppable: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: droppableId,\n      type,\n      mode: 'standard',\n    },\n    borderBox: {\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 100,\n    },\n    closest: {\n      borderBox: {\n        top: 0,\n        left: 0,\n        right: 50,\n        bottom: 50,\n      },\n      scrollSize: {\n        scrollHeight: 100,\n        scrollWidth: 100,\n      },\n      scroll: { x: 0, y: 0 },\n      shouldClipSubject: true,\n    },\n  });\n  const target: Position = { x: 60, y: 60 };\n  const distance: Position = subtract(target, dragging.page.borderBox.center);\n\n  const pageBorderBox: Rect = offsetRectByPosition(\n    dragging.page.borderBox,\n    distance,\n  );\n\n  const result: ?DroppableId = getDroppableOver({\n    pageBorderBox,\n    draggable: dragging,\n    droppables: { [droppableId]: droppable },\n  });\n\n  expect(result).toBe(null);\n});\n\nit('should not hit when outside subject and inside the frame (partially visible subject)', () => {\n  const droppable: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: droppableId,\n      type,\n      mode: 'standard',\n    },\n    borderBox: {\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 100,\n    },\n    closest: {\n      borderBox: {\n        top: 0,\n        left: 0,\n        right: 200,\n        bottom: 200,\n      },\n      scrollSize: {\n        scrollHeight: 200,\n        scrollWidth: 200,\n      },\n      scroll: { x: 0, y: 0 },\n      shouldClipSubject: true,\n    },\n  });\n  const target: Position = { x: 120, y: 120 };\n  const distance: Position = subtract(target, dragging.page.borderBox.center);\n\n  const pageBorderBox: Rect = offsetRectByPosition(\n    dragging.page.borderBox,\n    distance,\n  );\n\n  const result: ?DroppableId = getDroppableOver({\n    pageBorderBox,\n    draggable: dragging,\n    droppables: { [droppableId]: droppable },\n  });\n\n  expect(result).toBe(null);\n});\n\nit('should not hit when outside subject and inside the frame (invisible subject)', () => {\n  const droppable: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: droppableId,\n      type,\n      mode: 'standard',\n    },\n    borderBox: {\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 100,\n    },\n    closest: {\n      borderBox: {\n        top: 0,\n        left: 0,\n        right: 200,\n        bottom: 200,\n      },\n      scrollSize: {\n        scrollHeight: 250,\n        scrollWidth: 250,\n      },\n      scroll: { x: 200, y: 200 },\n      shouldClipSubject: true,\n    },\n  });\n  const target: Position = { x: 250, y: 250 };\n  const distance: Position = subtract(target, dragging.page.borderBox.center);\n\n  const pageBorderBox: Rect = offsetRectByPosition(\n    dragging.page.borderBox,\n    distance,\n  );\n\n  const result: ?DroppableId = getDroppableOver({\n    pageBorderBox,\n    draggable: dragging,\n    droppables: { [droppableId]: droppable },\n  });\n\n  expect(result).toBe(null);\n});\n"
  },
  {
    "path": "test/unit/state/get-droppable-over/is-over-nothing.spec.js",
    "content": "// @flow\nimport type { DroppableId } from '../../../../src/types';\nimport getDroppableOver from '../../../../src/state/get-droppable-over';\nimport { getPreset } from '../../../util/dimension';\nimport { offsetRectByPosition } from '../../../../src/state/rect';\n\nconst preset = getPreset();\n\nit('should return null when over nothing', () => {\n  const result: ?DroppableId = getDroppableOver({\n    pageBorderBox: offsetRectByPosition(preset.inHome1.page.borderBox, {\n      x: 10000,\n      y: 10000,\n    }),\n    draggable: preset.inHome1,\n    droppables: preset.droppables,\n  });\n\n  expect(result).toBe(null);\n});\n"
  },
  {
    "path": "test/unit/state/get-droppable-over/item-edge-is-over-list-center.spec.js",
    "content": "// @flow\nimport { type Rect } from 'css-box-model';\nimport {\n  getDroppableDimension,\n  getDraggableDimension,\n} from '../../../util/dimension';\nimport { offsetRectByPosition } from '../../../../src/state/rect';\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n} from '../../../../src/types';\n\nimport getDroppableOver from '../../../../src/state/get-droppable-over';\nimport {\n  getOffsetForCrossAxisEndEdge,\n  getOffsetForCrossAxisStartEdge,\n} from '../get-drag-impact/util/get-offset-for-edge';\nimport { toDroppableMap } from '../../../../src/state/dimension-structures';\nimport { beforeCrossAxisPoint } from '../../../util/before-point';\nimport { afterCrossAxisPoint } from '../../../util/after-point';\n\nconst droppableLarge: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'large',\n    type: 'standard',\n    mode: 'standard',\n  },\n  borderBox: {\n    top: 0,\n    left: 0,\n    right: 400,\n    bottom: 400,\n  },\n});\n\nconst droppableSmall: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'small',\n    type: 'standard',\n    mode: 'standard',\n  },\n  borderBox: {\n    top: 1000,\n    left: 1000,\n    right: 1100,\n    bottom: 1100,\n  },\n});\n\nconst draggable: DraggableDimension = getDraggableDimension({\n  descriptor: {\n    id: 'my draggable',\n    index: 0,\n    type: droppableLarge.descriptor.type,\n    droppableId: droppableLarge.descriptor.id,\n  },\n  borderBox: droppableLarge.client.borderBox,\n});\n\nit('should hit when dragging cross axis end edge is over the list center', () => {\n  const offset = getOffsetForCrossAxisEndEdge({\n    crossAxisEndEdgeOn: droppableSmall.page.borderBox.center,\n    dragging: draggable.page.borderBox,\n    axis: droppableSmall.axis,\n  });\n\n  {\n    const pageBorderBox: Rect = offsetRectByPosition(\n      draggable.page.borderBox,\n      offset,\n    );\n\n    const result = getDroppableOver({\n      pageBorderBox,\n      draggable,\n      droppables: toDroppableMap([droppableLarge, droppableSmall]),\n    });\n\n    expect(result).toEqual(null);\n  }\n\n  {\n    const pageBorderBox: Rect = offsetRectByPosition(\n      draggable.page.borderBox,\n      afterCrossAxisPoint(droppableSmall.axis, offset),\n    );\n\n    const result = getDroppableOver({\n      pageBorderBox,\n      draggable,\n      droppables: toDroppableMap([droppableLarge, droppableSmall]),\n    });\n\n    expect(result).toEqual(droppableSmall.descriptor.id);\n  }\n});\n\n// For this test we are hitting draggableSmall from the (right side) cross axis side\nit('should hit when dragging cross axis start edge is over the list center', () => {\n  const offset = getOffsetForCrossAxisStartEdge({\n    crossAxisStartEdgeOn: droppableSmall.page.borderBox.center,\n    dragging: draggable.page.borderBox,\n    axis: droppableSmall.axis,\n  });\n\n  {\n    const pageBorderBox: Rect = offsetRectByPosition(\n      draggable.page.borderBox,\n      offset,\n    );\n\n    const result = getDroppableOver({\n      pageBorderBox,\n      draggable,\n      droppables: toDroppableMap([droppableLarge, droppableSmall]),\n    });\n\n    expect(result).toEqual(null);\n  }\n\n  {\n    const pageBorderBox: Rect = offsetRectByPosition(\n      draggable.page.borderBox,\n      beforeCrossAxisPoint(droppableSmall.axis, offset),\n    );\n\n    const result = getDroppableOver({\n      pageBorderBox,\n      draggable,\n      droppables: toDroppableMap([droppableLarge, droppableSmall]),\n    });\n\n    expect(result).toEqual(droppableSmall.descriptor.id);\n  }\n});\n"
  },
  {
    "path": "test/unit/state/get-droppable-over/item-is-totally-over.spec.js",
    "content": "// @flow\nimport { type Position, type Rect } from 'css-box-model';\nimport {\n  getDroppableDimension,\n  getDraggableDimension,\n} from '../../../util/dimension';\nimport { patch } from '../../../../src/state/position';\nimport { offsetRectByPosition } from '../../../../src/state/rect';\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n} from '../../../../src/types';\nimport getDroppableOver from '../../../../src/state/get-droppable-over';\nimport {\n  getOffsetForCrossAxisEndEdge,\n  getOffsetForCrossAxisStartEdge,\n} from '../get-drag-impact/util/get-offset-for-edge';\nimport { toDroppableMap } from '../../../../src/state/dimension-structures';\nimport { beforeCrossAxisPoint } from '../../../util/before-point';\nimport { afterCrossAxisPoint } from '../../../util/after-point';\n\nconst droppableLarge: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'large',\n    type: 'standard',\n    mode: 'standard',\n  },\n  borderBox: {\n    top: 0,\n    left: 0,\n    right: 600,\n    bottom: 600,\n  },\n});\n\nconst droppableSmall: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'small',\n    type: 'standard',\n    mode: 'standard',\n  },\n  borderBox: {\n    top: 1000,\n    left: 1000,\n    right: 1100,\n    bottom: 1100,\n  },\n});\n\nconst axis = droppableSmall.axis;\n\nconst draggable: DraggableDimension = getDraggableDimension({\n  descriptor: {\n    id: 'my draggable',\n    index: 0,\n    type: droppableLarge.descriptor.type,\n    droppableId: droppableLarge.descriptor.id,\n  },\n  borderBox: droppableLarge.client.borderBox,\n});\n\nit('should hit when dragging element completely covers the list (end edge +1)', () => {\n  const endEdge: Position = patch(\n    axis.line,\n    droppableSmall.page.borderBox[axis.crossAxisEnd],\n    droppableSmall.page.borderBox.center[axis.line],\n  );\n\n  const offset = getOffsetForCrossAxisEndEdge({\n    crossAxisEndEdgeOn: endEdge,\n    dragging: draggable.page.borderBox,\n    axis: droppableSmall.axis,\n  });\n\n  // we do not have overlap yet\n  {\n    const pageBorderBox: Rect = offsetRectByPosition(\n      draggable.page.borderBox,\n      offset,\n    );\n\n    const result = getDroppableOver({\n      pageBorderBox,\n      draggable,\n      droppables: toDroppableMap([droppableLarge, droppableSmall]),\n    });\n\n    expect(result).toEqual(null);\n  }\n\n  // we have overlap\n  {\n    const pageBorderBox: Rect = offsetRectByPosition(\n      draggable.page.borderBox,\n      afterCrossAxisPoint(droppableSmall.axis, offset),\n    );\n\n    const result = getDroppableOver({\n      pageBorderBox,\n      draggable,\n      droppables: toDroppableMap([droppableLarge, droppableSmall]),\n    });\n\n    expect(result).toEqual(droppableSmall.descriptor.id);\n  }\n});\n\nit('should hit when dragging element completely covers the list (start edge -1)', () => {\n  const startEdge: Position = patch(\n    axis.line,\n    droppableSmall.page.borderBox[axis.crossAxisStart],\n    droppableSmall.page.borderBox.center[axis.line],\n  );\n\n  const offset = getOffsetForCrossAxisStartEdge({\n    crossAxisStartEdgeOn: startEdge,\n    dragging: draggable.page.borderBox,\n    axis: droppableSmall.axis,\n  });\n\n  // we do not have overlap yet\n  {\n    const pageBorderBox: Rect = offsetRectByPosition(\n      draggable.page.borderBox,\n      offset,\n    );\n\n    const result = getDroppableOver({\n      pageBorderBox,\n      draggable,\n      droppables: toDroppableMap([droppableLarge, droppableSmall]),\n    });\n\n    expect(result).toEqual(null);\n  }\n\n  // we have overlap\n  {\n    const pageBorderBox: Rect = offsetRectByPosition(\n      draggable.page.borderBox,\n      beforeCrossAxisPoint(droppableSmall.axis, offset),\n    );\n\n    const result = getDroppableOver({\n      pageBorderBox,\n      draggable,\n      droppables: toDroppableMap([droppableLarge, droppableSmall]),\n    });\n\n    expect(result).toEqual(droppableSmall.descriptor.id);\n  }\n});\n"
  },
  {
    "path": "test/unit/state/get-droppable-over/preferencing.spec.js",
    "content": "// @flow\nimport { type Rect } from 'css-box-model';\nimport {\n  getDroppableDimension,\n  getDraggableDimension,\n} from '../../../util/dimension';\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n} from '../../../../src/types';\nimport { getOffsetForCrossAxisEndEdge } from '../get-drag-impact/util/get-offset-for-edge';\nimport { offsetRectByPosition } from '../../../../src/state/rect';\nimport getDroppableOver from '../../../../src/state/get-droppable-over';\nimport { toDroppableMap } from '../../../../src/state/dimension-structures';\nimport { afterCrossAxisPoint } from '../../../util/after-point';\n\nconst droppableOrigin: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'large',\n    type: 'standard',\n    mode: 'standard',\n  },\n  borderBox: {\n    top: 0,\n    left: 0,\n    right: 600,\n    bottom: 600,\n  },\n});\n\nconst droppableFirst: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'small',\n    type: 'standard',\n    mode: 'standard',\n  },\n  borderBox: {\n    top: 1000,\n    left: 1000,\n    right: 1100,\n    bottom: 1100,\n  },\n});\n\nconst droppableSecond: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'secondary',\n    type: 'standard',\n    mode: 'standard',\n  },\n  borderBox: {\n    top: 1000,\n    left: 1200,\n    right: 1300,\n    // This is really tall to test the distance calculation against varied lists\n    bottom: 8000,\n  },\n});\n\nconst droppableThird: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'tertiary',\n    type: 'standard',\n    mode: 'standard',\n  },\n  borderBox: {\n    top: 1000,\n    left: 1400,\n    right: 1500,\n    bottom: 1100,\n  },\n});\n\nconst draggable: DraggableDimension = getDraggableDimension({\n  descriptor: {\n    id: 'my draggable',\n    index: 0,\n    type: droppableOrigin.descriptor.type,\n    droppableId: droppableOrigin.descriptor.id,\n  },\n  borderBox: droppableOrigin.client.borderBox,\n});\n\n/**\n * In this case we're hovering over all three lists.\n * We expect that the furthest away active element is returned.\n */\nit('should prefer the furthest away droppable when multiple lists are hit', () => {\n  const offset = getOffsetForCrossAxisEndEdge({\n    crossAxisEndEdgeOn: droppableThird.page.borderBox.center,\n    dragging: draggable.page.borderBox,\n    axis: droppableThird.axis,\n  });\n\n  const pageBorderBox: Rect = offsetRectByPosition(\n    draggable.page.borderBox,\n    afterCrossAxisPoint(droppableThird.axis, offset),\n  );\n\n  const result = getDroppableOver({\n    pageBorderBox,\n    draggable,\n    droppables: toDroppableMap([\n      droppableOrigin,\n      droppableFirst,\n      droppableSecond,\n      droppableThird,\n    ]),\n  });\n\n  expect(result).toEqual(droppableThird.descriptor.id);\n});\n\n/**\n * In this case we're hovering over the primary and secondary and lists.\n * We expect that the furthest away active element is returned (not including the tertiary list).\n */\nit('should prefer the second furthest away droppable when multiple lists are hit', () => {\n  const offset = getOffsetForCrossAxisEndEdge({\n    crossAxisEndEdgeOn: droppableSecond.page.borderBox.center,\n    dragging: draggable.page.borderBox,\n    axis: droppableSecond.axis,\n  });\n\n  const pageBorderBox: Rect = offsetRectByPosition(\n    draggable.page.borderBox,\n    afterCrossAxisPoint(droppableSecond.axis, offset),\n  );\n\n  const result = getDroppableOver({\n    pageBorderBox,\n    draggable,\n    droppables: toDroppableMap([\n      droppableOrigin,\n      droppableFirst,\n      droppableSecond,\n      droppableThird,\n    ]),\n  });\n\n  expect(result).toEqual(droppableSecond.descriptor.id);\n});\n"
  },
  {
    "path": "test/unit/state/get-lift-effect/get-lift-effect.spec.js",
    "content": "// @flow\nimport type {\n  DisplacedBy,\n  DraggableDimension,\n  DragImpact,\n  LiftEffect,\n} from '../../../../src/types';\nimport getLiftEffect from '../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../util/dimension';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport getHomeLocation from '../../../../src/state/get-home-location';\nimport {\n  getForcedDisplacement,\n  getDraggableIdMap,\n  getDraggableIds,\n} from '../../../util/impact';\n\nconst preset = getPreset();\n\nit('should mark everything after the critical ', () => {\n  const { impact, afterCritical } = getLiftEffect({\n    draggable: preset.inHome2,\n    home: preset.home,\n    draggables: preset.draggables,\n    viewport: preset.viewport,\n  });\n\n  // originally displacement\n  const displacedBy: DisplacedBy = getDisplacedBy(\n    preset.home.axis,\n    preset.inHome2.displaceBy,\n  );\n\n  // ordered by closest impacted\n  const all: DraggableDimension[] = [preset.inHome3, preset.inHome4];\n\n  {\n    const expected: LiftEffect = {\n      inVirtualList: false,\n      effected: getDraggableIdMap(getDraggableIds(all)),\n      displacedBy,\n    };\n    expect(afterCritical).toEqual(expected);\n  }\n  {\n    const expected: DragImpact = {\n      displaced: getForcedDisplacement({\n        visible: all.map((dimension) => ({ dimension, shouldAnimate: false })),\n      }),\n      displacedBy,\n      at: {\n        type: 'REORDER',\n        destination: getHomeLocation(preset.inHome2.descriptor),\n      },\n    };\n    expect(impact).toEqual(expected);\n  }\n});\n"
  },
  {
    "path": "test/unit/state/is-within.spec.js",
    "content": "// @flow\nimport isWithin from '../../../src/state/is-within';\n\ndescribe('is within', () => {\n  const lowerBound: number = 5;\n  const upperBound: number = 10;\n  const execute = isWithin(5, 10);\n\n  it('should return true when the value is between the bounds', () => {\n    expect(execute(lowerBound + 1)).toBe(true);\n  });\n\n  it('should return true when the value is equal to the lower bound', () => {\n    expect(execute(lowerBound)).toBe(true);\n  });\n\n  it('should return true when the value is equal to the upper bound', () => {\n    expect(execute(upperBound)).toBe(true);\n  });\n\n  it('should return false when the value is less then the lower bound', () => {\n    expect(execute(lowerBound - 1)).toBe(false);\n  });\n\n  it('should return false when the value is greater than the upper bound', () => {\n    expect(execute(upperBound + 1)).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/unit/state/middleware/auto-scroll.spec.js",
    "content": "// @flow\nimport type { Action, Store } from '../../../../src/state/store-types';\nimport type { AutoScroller } from '../../../../src/state/auto-scroller/auto-scroller-types';\nimport createStore from './util/create-store';\nimport middleware from '../../../../src/state/middleware/auto-scroll';\nimport {\n  animateDropArgs,\n  userCancelArgs,\n  initialPublishArgs,\n  getCompletedArgs,\n} from '../../../util/preset-action-args';\nimport {\n  animateDrop,\n  completeDrop,\n  initialPublish,\n  moveDown,\n  flush,\n} from '../../../../src/state/action-creators';\n\nconst shouldStop: Action[] = [\n  animateDrop(animateDropArgs),\n  animateDrop(userCancelArgs),\n  completeDrop(getCompletedArgs('CANCEL')),\n  completeDrop(getCompletedArgs('DROP')),\n  flush(),\n];\n\nconst getScrollerStub = (): AutoScroller => ({\n  start: jest.fn(),\n  stop: jest.fn(),\n  scroll: jest.fn(),\n});\n\nshouldStop.forEach((action: Action) => {\n  it(`should stop the auto scroller when a ${action.type} is fired`, () => {\n    const scroller: AutoScroller = getScrollerStub();\n    const store: Store = createStore(middleware(scroller));\n\n    store.dispatch(initialPublish(initialPublishArgs));\n    expect(store.getState().phase).toBe('DRAGGING');\n    expect(scroller.start).toHaveBeenCalled();\n\n    store.dispatch(action);\n    expect(scroller.stop).toHaveBeenCalled();\n  });\n});\n\nit('should fire a scroll when there is an update', () => {\n  const scroller: AutoScroller = getScrollerStub();\n  const store: Store = createStore(middleware(scroller));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(scroller.start).toHaveBeenCalledWith(store.getState());\n\n  expect(scroller.scroll).not.toHaveBeenCalled();\n  store.dispatch(moveDown());\n  expect(scroller.scroll).toHaveBeenCalledWith(store.getState());\n});\n"
  },
  {
    "path": "test/unit/state/middleware/dimension-marshal-stopper.spec.js",
    "content": "// @flow\nimport type { Store } from '../../../../src/state/store-types';\nimport type { DimensionMarshal } from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport middleware from '../../../../src/state/middleware/dimension-marshal-stopper';\nimport dropMiddleware from '../../../../src/state/middleware/drop/drop-middleware';\nimport createStore from './util/create-store';\nimport {\n  flush,\n  initialPublish,\n  drop,\n  completeDrop,\n  animateDrop,\n  collectionStarting,\n} from '../../../../src/state/action-creators';\nimport {\n  initialPublishArgs,\n  getCompletedArgs,\n  userCancelArgs,\n} from '../../../util/preset-action-args';\n\nconst getMarshal = (stopPublishing: Function): DimensionMarshal => {\n  const fake: DimensionMarshal = ({\n    stopPublishing,\n  }: any);\n\n  return fake;\n};\n\nit('should stop a collection if a drag is aborted', () => {\n  const stopPublishing = jest.fn();\n  const store: Store = createStore(middleware(getMarshal(stopPublishing)));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n\n  expect(stopPublishing).not.toHaveBeenCalled();\n  store.dispatch(flush());\n  expect(stopPublishing).toHaveBeenCalledTimes(1);\n});\n\nit('should not stop a collection if a drop is pending', () => {\n  const stopPublishing = jest.fn();\n  const store: Store = createStore(\n    middleware(getMarshal(stopPublishing)),\n    // will convert the drop into a drop pending\n    dropMiddleware,\n  );\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(store.getState().phase).toBe('DRAGGING');\n  store.dispatch(collectionStarting());\n  expect(store.getState().phase).toBe('COLLECTING');\n  expect(stopPublishing).not.toHaveBeenCalled();\n\n  // dropping\n  store.dispatch(drop({ reason: 'DROP' }));\n  expect(store.getState().phase).toBe('DROP_PENDING');\n  expect(stopPublishing).not.toHaveBeenCalled();\n});\n\nit('should stop a collection if a drag is complete', () => {\n  const stopPublishing = jest.fn();\n  const store: Store = createStore(\n    middleware(getMarshal(stopPublishing)),\n    // will convert the drop into a drop pending\n    dropMiddleware,\n  );\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(store.getState().phase).toBe('DRAGGING');\n  expect(stopPublishing).not.toHaveBeenCalled();\n\n  // complete drop\n  store.dispatch(completeDrop(getCompletedArgs('DROP')));\n\n  expect(stopPublishing).toHaveBeenCalled();\n});\n\nit('should stop a collection if a drop animation starts', () => {\n  const stopPublishing = jest.fn();\n  const store: Store = createStore(\n    middleware(getMarshal(stopPublishing)),\n    // will convert the drop into a drop pending\n    dropMiddleware,\n  );\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(store.getState().phase).toBe('DRAGGING');\n  expect(stopPublishing).not.toHaveBeenCalled();\n\n  store.dispatch(animateDrop(userCancelArgs));\n\n  expect(stopPublishing).toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/state/middleware/drop/conditionally-animate-drop.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { invariant } from '../../../../../src/invariant';\nimport {\n  animateDrop,\n  flush,\n  completeDrop,\n  drop,\n  initialPublish,\n  move,\n  moveDown,\n  updateDroppableIsCombineEnabled,\n  moveUp,\n  type InitialPublishArgs,\n  type AnimateDropArgs,\n} from '../../../../../src/state/action-creators';\nimport type { Store } from '../../../../../src/state/store-types';\nimport middleware from '../../../../../src/state/middleware/drop';\nimport getDropDuration from '../../../../../src/state/middleware/drop/get-drop-duration';\nimport { add, origin } from '../../../../../src/state/position';\nimport {\n  preset,\n  getDragStart,\n  initialPublishArgs,\n  homeImpact,\n  afterCritical,\n  critical,\n  getCompletedArgs,\n  getDropImpactForReason,\n} from '../../../../util/preset-action-args';\nimport createStore from '../util/create-store';\nimport passThrough from '../util/pass-through-middleware';\nimport type {\n  DropResult,\n  CompletedDrag,\n  DraggableLocation,\n  DropReason,\n  DragImpact,\n  State,\n  Combine,\n} from '../../../../../src/types';\nimport getDropImpact from '../../../../../src/state/middleware/drop/get-drop-impact';\nimport getNewHomeClientOffset from '../../../../../src/state/middleware/drop/get-new-home-client-offset';\nimport { tryGetCombine } from '../../../../../src/state/get-impact-location';\n\n['DROP', 'CANCEL'].forEach((reason: DropReason) => {\n  describe(`with drop reason: ${reason}`, () => {\n    it('should fire a complete drop action is no drop animation is required', () => {\n      const mock = jest.fn();\n      const store: Store = createStore(passThrough(mock), middleware);\n\n      store.dispatch(flush());\n      store.dispatch(initialPublish(initialPublishArgs));\n      expect(store.getState().phase).toBe('DRAGGING');\n\n      // no movement yet\n      mock.mockReset();\n      store.dispatch(drop({ reason }));\n\n      expect(mock).toHaveBeenCalledWith(drop({ reason }));\n      expect(mock).toHaveBeenCalledWith(completeDrop(getCompletedArgs(reason)));\n      expect(mock).toHaveBeenCalledTimes(2);\n\n      // reset to initial phase\n      expect(store.getState().phase).toBe('IDLE');\n    });\n\n    it('should fire an animate drop action if a drop animation movement is required', () => {\n      const mock = jest.fn();\n      const store: Store = createStore(passThrough(mock), middleware);\n\n      store.dispatch(initialPublish(initialPublishArgs));\n      expect(store.getState().phase).toBe('DRAGGING');\n\n      // moving a little bit so that a drop animation will be needed\n      const shift: Position = { x: 1, y: 1 };\n      store.dispatch(\n        move({\n          client: add(initialPublishArgs.clientSelection, shift),\n        }),\n      );\n      const current: State = store.getState();\n      invariant(current.isDragging);\n      // impact is cleared when cancelling\n      const destination: ?DraggableLocation =\n        reason === 'DROP' ? getDragStart().source : null;\n\n      mock.mockReset();\n      store.dispatch(drop({ reason }));\n\n      const result: DropResult = {\n        ...getDragStart(),\n        destination,\n        reason,\n        combine: null,\n      };\n      const completed: CompletedDrag = {\n        result,\n        impact: getDropImpactForReason(reason),\n        critical,\n        afterCritical,\n      };\n      const args: AnimateDropArgs = {\n        completed,\n        newHomeClientOffset: origin,\n        dropDuration: getDropDuration({\n          current: shift,\n          destination: origin,\n          reason,\n        }),\n      };\n      expect(mock).toHaveBeenCalledWith(drop({ reason }));\n      expect(mock).toHaveBeenCalledWith(animateDrop(args));\n      expect(mock).toHaveBeenCalledTimes(2);\n      expect(store.getState().phase).toBe('DROP_ANIMATING');\n    });\n\n    it('should fire an animate drop action if combining', () => {\n      const mock = jest.fn();\n      const store: Store = createStore(passThrough(mock), middleware);\n\n      const inSnapMode: InitialPublishArgs = {\n        ...initialPublishArgs,\n        movementMode: 'SNAP',\n      };\n      store.dispatch(initialPublish(inSnapMode));\n      store.dispatch(\n        updateDroppableIsCombineEnabled({\n          id: inSnapMode.critical.droppable.id,\n          isCombineEnabled: true,\n        }),\n      );\n      {\n        const current: State = store.getState();\n        invariant(current.phase === 'DRAGGING');\n        invariant(current.movementMode === 'SNAP');\n        invariant(\n          current.dimensions.droppables[inSnapMode.critical.droppable.id]\n            .isCombineEnabled,\n        );\n      }\n      // combine\n      store.dispatch(moveDown());\n      // move past and shift item up\n      store.dispatch(moveDown());\n      // move backwards onto the displaced item\n      store.dispatch(moveUp());\n      mock.mockReset();\n\n      const current: State = store.getState();\n      invariant(current.isDragging);\n\n      // if (reason === 'DROP') {\n      const combine: ?Combine = tryGetCombine(current.impact);\n      invariant(combine);\n      // moved forwards past in home2, and then backwards onto it\n      expect(combine).toEqual({\n        draggableId: preset.inHome2.descriptor.id,\n        droppableId: preset.home.descriptor.id,\n      });\n\n      store.dispatch(drop({ reason }));\n\n      const combineDropImpact: DragImpact = getDropImpact({\n        reason,\n        draggables: preset.draggables,\n        lastImpact: current.impact,\n        home: preset.home,\n        viewport: preset.viewport,\n        onLiftImpact: homeImpact,\n        afterCritical,\n      }).impact;\n\n      const completed: CompletedDrag = {\n        critical,\n        impact: combineDropImpact,\n        afterCritical,\n        result: {\n          ...getDragStart(),\n          // we are using snap movements\n          mode: 'SNAP',\n          destination: null,\n          combine: reason === 'DROP' ? combine : null,\n          reason,\n        },\n      };\n      const args: AnimateDropArgs = {\n        completed,\n        newHomeClientOffset: getNewHomeClientOffset({\n          impact: combineDropImpact,\n          draggable: preset.inHome1,\n          dimensions: preset.dimensions,\n          viewport: preset.viewport,\n          afterCritical,\n        }),\n        // $ExpectError - wrong type\n        dropDuration: expect.any(Number),\n      };\n      expect(mock).toHaveBeenCalledWith(drop({ reason }));\n      expect(mock).toHaveBeenCalledWith(animateDrop(args));\n      expect(mock).toHaveBeenCalledTimes(2);\n      expect(store.getState().phase).toBe('DROP_ANIMATING');\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/middleware/drop/drop-animation-finish-middleware.spec.js",
    "content": "// @flow\nimport type { State } from '../../../../../src/types';\nimport type { Store } from '../../../../../src/state/store-types';\nimport { invariant } from '../../../../../src/invariant';\nimport middleware from '../../../../../src/state/middleware/drop/drop-animation-finish-middleware';\nimport dropMiddleware from '../../../../../src/state/middleware/drop/drop-middleware';\nimport createStore from '../util/create-store';\nimport passThrough from '../util/pass-through-middleware';\nimport { add } from '../../../../../src/state/position';\nimport {\n  initialPublish,\n  completeDrop,\n  move,\n  dropAnimationFinished,\n  drop,\n} from '../../../../../src/state/action-creators';\nimport {\n  initialPublishArgs,\n  getCompletedArgs,\n} from '../../../../util/preset-action-args';\n\nit('should fire a complete drop action when a drop animation finish action is fired', () => {\n  const mock = jest.fn();\n\n  const store: Store = createStore(\n    passThrough(mock),\n    // will convert the drop into a drop animate\n    dropMiddleware,\n    middleware,\n  );\n\n  store.dispatch(initialPublish(initialPublishArgs));\n\n  expect(store.getState().phase).toBe('DRAGGING');\n\n  // A small movement so a drop animation will be needed\n  store.dispatch(\n    move({\n      client: add(initialPublishArgs.clientSelection, { x: 1, y: 1 }),\n    }),\n  );\n  store.dispatch(drop({ reason: 'DROP' }));\n\n  const state: State = store.getState();\n  invariant(\n    state.phase === 'DROP_ANIMATING',\n    `Incorrect phase: ${state.phase}`,\n  );\n\n  mock.mockReset();\n  store.dispatch(dropAnimationFinished());\n  expect(mock).toHaveBeenCalledWith(dropAnimationFinished());\n\n  expect(mock).toHaveBeenCalledWith(completeDrop(getCompletedArgs('DROP')));\n  expect(mock).toHaveBeenCalledTimes(2);\n});\n\nit('should throw if a drop animation finished action occurs while not in the drop animating phase', () => {\n  const store: Store = createStore(middleware);\n\n  expect(() => store.dispatch(dropAnimationFinished())).toThrow();\n});\n"
  },
  {
    "path": "test/unit/state/middleware/drop/drop-animation-flush-on-scroll-middleware.spec.js",
    "content": "// @flow\nimport type { State } from '../../../../../src/types';\nimport type { Store } from '../../../../../src/state/store-types';\nimport { invariant } from '../../../../../src/invariant';\nimport middleware from '../../../../../src/state/middleware/drop/drop-animation-flush-on-scroll-middleware';\nimport dropMiddleware from '../../../../../src/state/middleware/drop/drop-middleware';\nimport createStore from '../util/create-store';\nimport passThrough from '../util/pass-through-middleware';\nimport { add } from '../../../../../src/state/position';\nimport {\n  initialPublish,\n  completeDrop,\n  move,\n  dropAnimationFinished,\n  drop,\n  flush,\n  type Action,\n} from '../../../../../src/state/action-creators';\nimport {\n  initialPublishArgs,\n  getCompletedArgs,\n} from '../../../../util/preset-action-args';\n\nfunction getToDropAnimation(mock: JestMockFn<*, *>): Store {\n  const store: Store = createStore(\n    passThrough(mock),\n    // will convert the drop into a drop animate\n    dropMiddleware,\n    middleware,\n  );\n\n  store.dispatch(initialPublish(initialPublishArgs));\n\n  expect(store.getState().phase).toBe('DRAGGING');\n\n  // A small movement so a drop animation will be needed\n  store.dispatch(\n    move({\n      client: add(initialPublishArgs.clientSelection, { x: 1, y: 1 }),\n    }),\n  );\n  store.dispatch(drop({ reason: 'DROP' }));\n\n  const state: State = store.getState();\n  invariant(\n    state.phase === 'DROP_ANIMATING',\n    `Incorrect phase: ${state.phase}`,\n  );\n\n  return store;\n}\n\nit('should clear any running drop is a scroll event occurs', () => {\n  const mock = jest.fn();\n  getToDropAnimation(mock);\n\n  mock.mockReset();\n  // waiting for an animation frame before any scroll events would cancel a drag\n  window.dispatchEvent(new Event('scroll'));\n  expect(mock).not.toHaveBeenCalled();\n\n  // after an animation frame, we should be in business\n  requestAnimationFrame.step();\n  window.dispatchEvent(new Event('scroll'));\n\n  expect(mock).toHaveBeenCalledWith(dropAnimationFinished());\n  expect(mock).toHaveBeenCalledTimes(1);\n});\n\nit('should only try to clear once', () => {\n  const mock = jest.fn();\n  getToDropAnimation(mock);\n\n  mock.mockReset();\n\n  // after an animation frame, we should be in business\n  requestAnimationFrame.step();\n  window.dispatchEvent(new Event('scroll'));\n  window.dispatchEvent(new Event('scroll'));\n\n  expect(mock).toHaveBeenCalledWith(dropAnimationFinished());\n  expect(mock).toHaveBeenCalledTimes(1);\n});\n\nit('should not try to cancel a drop animation if the drop finished', () => {\n  [\n    flush(),\n    completeDrop(getCompletedArgs('DROP')),\n    dropAnimationFinished(),\n  ].forEach((action: Action) => {\n    const mock = jest.fn();\n    const store: Store = getToDropAnimation(mock);\n\n    store.dispatch(action);\n    mock.mockClear();\n\n    // would normally trigger a dropAnimationFinished\n    requestAnimationFrame.step();\n    window.dispatchEvent(new Event('scroll'));\n\n    expect(mock).not.toHaveBeenCalled();\n  });\n});\n"
  },
  {
    "path": "test/unit/state/middleware/drop/drop-impact.spec.js",
    "content": "// @flow\nimport type { DisplacedBy, DragImpact } from '../../../../../src/types';\nimport getDropImpact, {\n  type Result,\n} from '../../../../../src/state/middleware/drop/get-drop-impact';\nimport noImpact, { emptyGroups } from '../../../../../src/state/no-impact';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\nimport { getPreset } from '../../../../util/dimension';\nimport getDisplacedBy from '../../../../../src/state/get-displaced-by';\nimport { vertical } from '../../../../../src/state/axis';\nimport { getForcedDisplacement } from '../../../../util/impact';\n\nconst preset = getPreset();\n\nconst { afterCritical, impact: homeImpact } = getLiftEffect({\n  draggable: preset.inHome1,\n  draggables: preset.draggables,\n  home: preset.home,\n  viewport: preset.viewport,\n});\nconst displacedBy: DisplacedBy = getDisplacedBy(\n  vertical,\n  preset.inHome1.displaceBy,\n);\n\nconst recomputedHomeImpact: DragImpact = {\n  displaced: getForcedDisplacement({\n    visible: [\n      // when recomputed the displaced will be animated\n      // originally it was not\n      { dimension: preset.inHome2 },\n      { dimension: preset.inHome3 },\n      { dimension: preset.inHome4 },\n    ],\n  }),\n  displacedBy,\n  at: homeImpact.at,\n};\n\nit('should recompute the home impact when not dropped in a list', () => {\n  const result: Result = getDropImpact({\n    reason: 'DROP',\n    lastImpact: noImpact,\n    home: preset.home,\n    viewport: preset.viewport,\n    draggables: preset.draggables,\n    onLiftImpact: homeImpact,\n    afterCritical,\n  });\n\n  const expected: Result = {\n    impact: recomputedHomeImpact,\n    didDropInsideDroppable: false,\n  };\n  expect(result).toEqual(expected);\n});\n\nit('should recompute the home impact when the drag is cancelled', () => {\n  const result: Result = getDropImpact({\n    reason: 'CANCEL',\n    // was over home\n    lastImpact: homeImpact,\n    home: preset.home,\n    viewport: preset.viewport,\n    draggables: preset.draggables,\n    onLiftImpact: homeImpact,\n    afterCritical,\n  });\n\n  const expected: Result = {\n    impact: recomputedHomeImpact,\n    didDropInsideDroppable: false,\n  };\n  expect(result).toEqual(expected);\n});\n\nit('should use the existing impact when reordering', () => {\n  // inHome1 moved into position of inHome2\n  const lastImpact: DragImpact = {\n    displaced: getForcedDisplacement({\n      // initial displacement is not animated\n      visible: [\n        { dimension: preset.inHome3, shouldAnimate: false },\n        { dimension: preset.inHome4, shouldAnimate: false },\n      ],\n    }),\n    displacedBy,\n    at: {\n      type: 'REORDER',\n      destination: {\n        index: preset.inHome2.descriptor.index,\n        droppableId: preset.home.descriptor.id,\n      },\n    },\n  };\n\n  const result: Result = getDropImpact({\n    reason: 'DROP',\n    lastImpact,\n    home: preset.home,\n    viewport: preset.viewport,\n    draggables: preset.draggables,\n    onLiftImpact: homeImpact,\n    afterCritical,\n  });\n\n  const expected: Result = {\n    impact: lastImpact,\n    didDropInsideDroppable: true,\n  };\n  expect(result).toEqual(expected);\n});\n\nit('should remove any movement when merging so items will collapse', () => {\n  // inHome1 moved forward and merged with inHome3\n  // inHome2 has been moved past\n  const lastImpact: DragImpact = {\n    displaced: getForcedDisplacement({\n      visible: [\n        // initial displacement is not animated\n        { dimension: preset.inHome3, shouldAnimate: false },\n        { dimension: preset.inHome4, shouldAnimate: false },\n      ],\n    }),\n    displacedBy,\n    at: {\n      type: 'COMBINE',\n      combine: {\n        droppableId: preset.home.descriptor.id,\n        draggableId: preset.inHome3.descriptor.id,\n      },\n    },\n  };\n\n  const result: Result = getDropImpact({\n    reason: 'DROP',\n    lastImpact,\n    home: preset.home,\n    viewport: preset.viewport,\n    draggables: preset.draggables,\n    onLiftImpact: homeImpact,\n    afterCritical,\n  });\n\n  const newImpact: DragImpact = {\n    ...lastImpact,\n    displaced: emptyGroups,\n  };\n  const expected: Result = {\n    impact: newImpact,\n    didDropInsideDroppable: true,\n  };\n  expect(result).toEqual(expected);\n});\n"
  },
  {
    "path": "test/unit/state/middleware/drop/drop-position.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  DroppableDimension,\n  Axis,\n  DragImpact,\n  DisplacedBy,\n  DimensionMap,\n} from '../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../src/state/axis';\nimport { negate, subtract, origin } from '../../../../../src/state/position';\nimport scrollDroppable from '../../../../../src/state/droppable/scroll-droppable';\nimport { getPreset, makeScrollable } from '../../../../util/dimension';\nimport getClientBorderBoxCenter from '../../../../../src/state/get-center-from-impact/get-client-border-box-center';\nimport getDisplacedBy from '../../../../../src/state/get-displaced-by';\nimport noImpact from '../../../../../src/state/no-impact';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\nimport getNewHomeClientOffset from '../../../../../src/state/middleware/drop/get-new-home-client-offset';\nimport patchDimensionMap from '../../../../../src/state/patch-dimension-map';\nimport { getForcedDisplacement } from '../../../../util/impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const { afterCritical, impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome1,\n      draggables: preset.draggables,\n      home: preset.home,\n      viewport: preset.viewport,\n    });\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome1.displaceBy,\n    );\n\n    it('should return nothing if already over the home', () => {\n      const offset: Position = getNewHomeClientOffset({\n        impact: homeImpact,\n        draggable: preset.inHome1,\n        dimensions: preset.dimensions,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n\n      expect(offset).toEqual(origin);\n    });\n\n    it('should return the difference between the current client position and where it needs to be', () => {\n      // inHome1 in inHome2 position\n      const pastInHome2: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inHome3, shouldAnimate: false },\n            { dimension: preset.inHome4, shouldAnimate: false },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inHome2.descriptor.index,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n\n      const currentClientCenter: Position = getClientBorderBoxCenter({\n        impact: pastInHome2,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        afterCritical,\n        droppable: preset.home,\n        viewport: preset.viewport,\n      });\n      const offsetFromHome: Position = getNewHomeClientOffset({\n        impact: pastInHome2,\n        draggable: preset.inHome1,\n        dimensions: preset.dimensions,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n\n      const diff: Position = subtract(\n        currentClientCenter,\n        preset.inHome1.client.borderBox.center,\n      );\n      expect(offsetFromHome).toEqual(diff);\n    });\n\n    it('should account for a collapsing home draggable when merging', () => {\n      // inHome1 merging with inHome3\n      // inHome1 will collapse on drop and this needs to be accounted for\n      const mergingWithInHome3: DragImpact = {\n        displacedBy,\n        displaced: getForcedDisplacement({\n          // inHome2 is no longer displaced\n          visible: [\n            { dimension: preset.inHome3, shouldAnimate: false },\n            { dimension: preset.inHome4, shouldAnimate: false },\n          ],\n        }),\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome3.descriptor.id,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n\n      const currentClientCenter: Position = getClientBorderBoxCenter({\n        impact: mergingWithInHome3,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        afterCritical,\n        droppable: preset.home,\n        viewport: preset.viewport,\n      });\n      const offsetFromHome: Position = getNewHomeClientOffset({\n        impact: mergingWithInHome3,\n        draggable: preset.inHome1,\n        dimensions: preset.dimensions,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n      const offset: Position = subtract(\n        currentClientCenter,\n        preset.inHome1.client.borderBox.center,\n      );\n\n      expect(offsetFromHome).toEqual(offset);\n    });\n\n    it('should account for the scroll of your home list if you are not over any list', () => {\n      const scrollableHome: DroppableDimension = makeScrollable(preset.home);\n      const scroll: Position = { x: 10, y: 15 };\n      const displacement: Position = negate(scroll);\n      const scrolled: DroppableDimension = scrollDroppable(\n        scrollableHome,\n        scroll,\n      );\n      const withScrolledHome: DimensionMap = patchDimensionMap(\n        preset.dimensions,\n        scrolled,\n      );\n\n      const withScroll: Position = getNewHomeClientOffset({\n        impact: noImpact,\n        draggable: preset.inHome1,\n        dimensions: withScrolledHome,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n      const withoutScroll: Position = getNewHomeClientOffset({\n        impact: noImpact,\n        draggable: preset.inHome1,\n        // no droppable scroll\n        dimensions: preset.dimensions,\n        viewport: preset.viewport,\n        afterCritical,\n      });\n\n      const diff: Position = subtract(withScroll, withoutScroll);\n\n      expect(diff).toEqual(displacement);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/middleware/drop/get-drop-duration.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport getDropDuration from '../../../../../src/state/middleware/drop/get-drop-duration';\n\nit('should return the a small amount if not moving anywhere', () => {\n  const noWhere: number = getDropDuration({\n    current: { x: 10, y: 10 },\n    destination: { x: 10, y: 10 },\n    reason: 'DROP',\n  });\n  const further: number = getDropDuration({\n    current: { x: 1, y: 1 },\n    destination: { x: 100, y: 100 },\n    reason: 'DROP',\n  });\n\n  expect(noWhere).toEqual(expect.any(Number));\n  expect(noWhere).toBeLessThan(further);\n});\n\nit('should return higher drop times the further away you are', () => {\n  const closer: number = getDropDuration({\n    current: { x: 1, y: 1 },\n    destination: { x: 5, y: 5 },\n    reason: 'DROP',\n  });\n  const further: number = getDropDuration({\n    current: { x: 1, y: 1 },\n    destination: { x: 100, y: 100 },\n    reason: 'DROP',\n  });\n\n  expect(closer).toBeLessThan(further);\n});\n\nit('should return faster drop times if cancelling', () => {\n  const current: Position = { x: 1, y: 1 };\n  const destination: Position = { x: 1, y: 10 };\n  const cancel: number = getDropDuration({\n    current,\n    destination,\n    reason: 'CANCEL',\n  });\n  const drop: number = getDropDuration({\n    current,\n    destination,\n    reason: 'DROP',\n  });\n\n  expect(cancel).toBeLessThan(drop);\n});\n"
  },
  {
    "path": "test/unit/state/middleware/drop/result-impact-mismatch.spec.js",
    "content": "// @flow\nimport {\n  type AnimateDropArgs,\n  drop,\n  initialPublish,\n  move,\n  moveDown,\n} from '../../../../../src/state/action-creators';\nimport { invariant } from '../../../../../src/invariant';\nimport middleware from '../../../../../src/state/middleware/drop';\nimport { enableCombining } from '../../../../util/dimension';\nimport { initialPublishArgs } from '../../../../util/preset-action-args';\nimport createStore from '../util/create-store';\nimport passThrough from '../util/pass-through-middleware';\nimport type { State, CompletedDrag } from '../../../../../src/types';\nimport type { Store } from '../../../../../src/state/store-types';\nimport {\n  tryGetDestination,\n  tryGetCombine,\n} from '../../../../../src/state/get-impact-location';\n\nit('should clear any destination from a final impact if not dropping on a droppable', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(passThrough(mock), middleware);\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(store.getState().phase).toBe('DRAGGING');\n  const initial: State = store.getState();\n  invariant(initial.phase === 'DRAGGING');\n  invariant(tryGetDestination !== null);\n\n  // no destination\n  store.dispatch(move({ client: { x: 10000, y: 10000 } }));\n  {\n    const current: State = store.getState();\n    invariant(current.phase === 'DRAGGING');\n    expect(tryGetDestination(current.impact)).toBe(null);\n  }\n\n  // drop\n  store.dispatch(drop({ reason: 'DROP' }));\n\n  const args: AnimateDropArgs =\n    mock.mock.calls[mock.mock.calls.length - 1][0].payload;\n  const completed: CompletedDrag = args.completed;\n\n  // the impact has the home destination for animation\n  expect(tryGetDestination(completed.impact)).toBe(\n    tryGetDestination(initial.impact),\n  );\n  // but the consumer will be told that there was no destination\n  expect(completed.result.destination).toBe(null);\n});\n\nit('should clear any destination from a final impact canceling', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(passThrough(mock), middleware);\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(store.getState().phase).toBe('DRAGGING');\n  const initial: State = store.getState();\n  invariant(initial.phase === 'DRAGGING');\n  invariant(tryGetDestination(initial.impact) !== null);\n\n  // cancel\n  store.dispatch(drop({ reason: 'CANCEL' }));\n\n  const args: AnimateDropArgs =\n    mock.mock.calls[mock.mock.calls.length - 1][0].payload;\n  const completed: CompletedDrag = args.completed;\n\n  // the impact has the home destination for animation\n  expect(tryGetDestination(completed.impact)).toBe(\n    tryGetDestination(initial.impact),\n  );\n  // but the consumer will be told that there was no destination\n  expect(completed.result.destination).toBe(null);\n});\n\nit('should clear any combine from a final impact if cancelling', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(passThrough(mock), middleware);\n\n  store.dispatch(\n    initialPublish({\n      ...initialPublishArgs,\n      dimensions: {\n        draggables: initialPublishArgs.dimensions.draggables,\n        droppables: enableCombining(initialPublishArgs.dimensions.droppables),\n      },\n      movementMode: 'SNAP',\n    }),\n  );\n  expect(store.getState().phase).toBe('DRAGGING');\n  const initial: State = store.getState();\n  invariant(initial.phase === 'DRAGGING');\n  invariant(tryGetDestination(initial.impact) !== null);\n\n  // moving onto a combine\n  store.dispatch(moveDown());\n  {\n    const current: State = store.getState();\n    invariant(current.phase === 'DRAGGING');\n    expect(tryGetDestination(current.impact)).toBe(null);\n    expect(tryGetCombine(current.impact)).toBeTruthy();\n  }\n\n  // drop\n  store.dispatch(drop({ reason: 'CANCEL' }));\n\n  const args: AnimateDropArgs =\n    mock.mock.calls[mock.mock.calls.length - 1][0].payload;\n  const completed: CompletedDrag = args.completed;\n\n  // the combine has been removed\n  expect(tryGetCombine(completed.impact)).toBe(null);\n  // for animation purposes it has a final impact of moving back to the starting position\n  expect(tryGetDestination(completed.impact)).toBe(\n    tryGetDestination(initial.impact),\n  );\n  // the consumer will be told that there was no combine\n  expect(completed.result.combine).toBe(null);\n});\n"
  },
  {
    "path": "test/unit/state/middleware/drop/timing.spec.js",
    "content": "// @flow\nimport { invariant } from '../../../../../src/invariant';\nimport {\n  flush,\n  collectionStarting,\n  drop,\n  dropPending,\n  initialPublish,\n  move,\n} from '../../../../../src/state/action-creators';\nimport middleware from '../../../../../src/state/middleware/drop';\nimport { add } from '../../../../../src/state/position';\nimport { initialPublishArgs } from '../../../../util/preset-action-args';\nimport createStore from '../util/create-store';\nimport passThrough from '../util/pass-through-middleware';\nimport type { State } from '../../../../../src/types';\nimport type { Store } from '../../../../../src/state/store-types';\n\nit('should throw an error if a drop action occurs while not in a phase where you can drop', () => {\n  const store: Store = createStore(middleware);\n\n  // idle (it is okay to perform a defensive drop here)\n  // this can happen during an exception flow\n  expect(() => {\n    store.dispatch(drop({ reason: 'DROP' }));\n  }).not.toThrow();\n\n  // drop animating\n  store.dispatch(flush());\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(store.getState().phase).toBe('DRAGGING');\n\n  // moving a little bit so that a drop animation will be needed\n  store.dispatch(\n    move({\n      client: add(initialPublishArgs.clientSelection, { x: 1, y: 1 }),\n    }),\n  );\n\n  store.dispatch(drop({ reason: 'DROP' }));\n  expect(store.getState().phase).toBe('DROP_ANIMATING');\n\n  expect(() => store.dispatch(drop({ reason: 'DROP' }))).toThrow();\n});\n\nit('should dispatch a DROP_PENDING action if COLLECTING', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(passThrough(mock), middleware);\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(store.getState().phase).toBe('DRAGGING');\n  store.dispatch(collectionStarting());\n\n  // now in the bulk collecting phase\n  expect(store.getState().phase).toBe('COLLECTING');\n  mock.mockReset();\n\n  // drop\n  store.dispatch(drop({ reason: 'DROP' }));\n\n  expect(mock).toHaveBeenCalledWith(drop({ reason: 'DROP' }));\n  expect(mock).toHaveBeenCalledWith(dropPending({ reason: 'DROP' }));\n  expect(mock).toHaveBeenCalledTimes(2);\n  expect(store.getState().phase).toBe('DROP_PENDING');\n});\n\nit('should throw if a drop action is fired and there is DROP_PENDING and it is waiting for a publish', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(passThrough(mock), middleware);\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  store.dispatch(collectionStarting());\n\n  // now in the bulk collecting phase\n  expect(store.getState().phase).toBe('COLLECTING');\n  mock.mockReset();\n\n  // drop moving to drop pending\n  store.dispatch(drop({ reason: 'DROP' }));\n  expect(mock).toHaveBeenCalledWith(dropPending({ reason: 'DROP' }));\n\n  const state: State = store.getState();\n  invariant(state.phase === 'DROP_PENDING', 'invalid phase');\n\n  expect(state.isWaiting).toBe(true);\n\n  // Drop action being fired (should not happen?)\n\n  expect(() => store.dispatch(drop({ reason: 'DROP' }))).toThrow(\n    'A DROP action occurred while DROP_PENDING and still waiting',\n  );\n});\n"
  },
  {
    "path": "test/unit/state/middleware/lift.spec.js",
    "content": "// @flow\nimport type { CompletedDrag, DimensionMap } from '../../../../src/types';\nimport type { Action, Store } from '../../../../src/state/store-types';\nimport type { DimensionMarshal } from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport middleware from '../../../../src/state/middleware/lift';\nimport createStore from './util/create-store';\nimport passThrough from './util/pass-through-middleware';\nimport { setViewport, resetViewport } from '../../../util/viewport';\nimport {\n  lift,\n  initialPublish,\n  animateDrop,\n  completeDrop,\n  type AnimateDropArgs,\n  flush,\n  beforeInitialCapture,\n} from '../../../../src/state/action-creators';\nimport { createMarshal } from '../../../util/dimension-marshal';\nimport {\n  preset,\n  liftArgs,\n  initialPublishArgs,\n  beforeCaptureArgs,\n  getCompletedArgs,\n} from '../../../util/preset-action-args';\nimport { populate } from '../../../util/registry';\nimport type { Registry } from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\n\nconst getPopulatedRegistry = (dimensions?: DimensionMap): Registry => {\n  const registry: Registry = createRegistry();\n  populate(registry, dimensions);\n  return registry;\n};\n\nconst getBasicMarshal = (dispatch: (Action) => void): DimensionMarshal => {\n  return createMarshal(getPopulatedRegistry(), dispatch);\n};\n\nbeforeEach(() => {\n  setViewport(preset.viewport);\n  jest.useFakeTimers();\n});\n\nafterEach(() => {\n  resetViewport();\n  jest.clearAllTimers();\n  jest.useRealTimers();\n});\n\nit('should throw if a drag cannot be started when a lift action occurs', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(\n    passThrough(mock),\n    middleware(\n      getBasicMarshal((action: Action) => {\n        store.dispatch(action);\n      }),\n    ),\n  );\n\n  // first lift is all good\n  store.dispatch(lift(liftArgs));\n  expect(mock).toHaveBeenCalledWith(lift(liftArgs));\n  expect(store.getState().phase).toBe('DRAGGING');\n\n  // a lift is not permitted in the DRAGGING phase\n  expect(() => store.dispatch(lift(liftArgs))).toThrow();\n});\n\nit('should flush any animating drops', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(\n    passThrough(mock),\n    middleware(\n      getBasicMarshal((action: Action) => {\n        store.dispatch(action);\n      }),\n    ),\n  );\n\n  // start a drag\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(store.getState().phase).toBe('DRAGGING');\n\n  const completed: CompletedDrag = getCompletedArgs('DROP').completed;\n\n  // start a drop\n  const args: AnimateDropArgs = {\n    newHomeClientOffset: { x: -1, y: -1 },\n    dropDuration: 1,\n    completed,\n  };\n  store.dispatch(animateDrop(args));\n  expect(store.getState().phase).toBe('DROP_ANIMATING');\n\n  // while drop animating a lift occurs\n  mock.mockReset();\n  store.dispatch(lift(liftArgs));\n  expect(mock).toHaveBeenCalledWith(lift(liftArgs));\n  // the previous drag is flushed\n  expect(mock).toHaveBeenCalledWith(completeDrop({ completed }));\n  // any animations are flushed\n  expect(mock).toHaveBeenCalledWith(flush());\n  // a before capture is fired\n  expect(mock).toHaveBeenCalledWith(beforeInitialCapture(beforeCaptureArgs));\n  // the new lift continues\n  expect(mock).toHaveBeenCalledTimes(5);\n});\n\nit('should publish the initial dimensions when lifting', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(\n    passThrough(mock),\n    middleware(\n      getBasicMarshal((action: Action) => {\n        store.dispatch(action);\n      }),\n    ),\n  );\n\n  // first lift is preparing\n  store.dispatch(lift(liftArgs));\n  expect(mock).toHaveBeenCalledWith(lift(liftArgs));\n  // last drag flushed\n  expect(mock).toHaveBeenCalledWith(flush());\n  expect(mock).toHaveBeenCalledWith(initialPublish(initialPublishArgs));\n  expect(mock).toHaveBeenCalledWith(beforeInitialCapture(beforeCaptureArgs));\n  expect(mock).toHaveBeenCalledTimes(4);\n  expect(store.getState().phase).toBe('DRAGGING');\n});\n"
  },
  {
    "path": "test/unit/state/middleware/pending-drop.spec.js",
    "content": "// @flow\nimport type { State } from '../../../../src/types';\nimport type { Store } from '../../../../src/state/store-types';\nimport { invariant } from '../../../../src/invariant';\nimport {\n  collectionStarting,\n  completeDrop,\n  drop,\n  initialPublish,\n  publishWhileDragging,\n} from '../../../../src/state/action-creators';\nimport dropMiddleware from '../../../../src/state/middleware/drop/drop-middleware';\nimport middleware from '../../../../src/state/middleware/pending-drop';\nimport {\n  initialPublishWithScrollables,\n  publishAdditionArgs,\n} from '../../../util/preset-action-args';\nimport createStore from './util/create-store';\nimport passThrough from './util/pass-through-middleware';\n\nit('should trigger a drop on a dynamic publish if a drop pending is waiting', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(\n    passThrough(mock),\n    // will fire the pending drop action\n    dropMiddleware,\n    middleware,\n  );\n\n  store.dispatch(initialPublish(initialPublishWithScrollables));\n  store.dispatch(collectionStarting());\n  store.dispatch(drop({ reason: 'DROP' }));\n\n  const postDrop: State = store.getState();\n  invariant(\n    postDrop.phase === 'DROP_PENDING',\n    `Incorrect phase : ${postDrop.phase}`,\n  );\n  expect(postDrop.isWaiting).toBe(true);\n\n  // This will finish the drag\n  mock.mockReset();\n  store.dispatch(publishWhileDragging(publishAdditionArgs));\n\n  expect(mock).toHaveBeenCalledWith(drop({ reason: 'DROP' }));\n\n  expect(mock).toHaveBeenCalledWith(\n    // $ExpectError - this calculation is not completed by this module and it is non trival\n    completeDrop({\n      completed: expect.any(Object),\n    }),\n  );\n  expect(mock).toHaveBeenCalledTimes(3);\n  expect(store.getState().phase).toBe('IDLE');\n});\n\nit('should not trigger a drop on a publish if a drop is not pending', () => {\n  const mock = jest.fn();\n  const store: Store = createStore(\n    passThrough(mock),\n    // will fire the pending drop action\n    dropMiddleware,\n    middleware,\n  );\n\n  store.dispatch(initialPublish(initialPublishWithScrollables));\n  store.dispatch(collectionStarting());\n\n  mock.mockReset();\n  store.dispatch(publishWhileDragging(publishAdditionArgs));\n\n  expect(mock).toHaveBeenCalledWith(publishWhileDragging(publishAdditionArgs));\n  expect(mock).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "test/unit/state/middleware/responders/abort.spec.js",
    "content": "// @flow\nimport type {\n  DraggableLocation,\n  Responders,\n  State,\n  DropResult,\n} from '../../../../../src/types';\nimport { invariant } from '../../../../../src/invariant';\nimport type { Store } from '../../../../../src/state/store-types';\nimport {\n  flush,\n  completeDrop,\n  initialPublish,\n} from '../../../../../src/state/action-creators';\nimport middleware from '../../../../../src/state/middleware/responders';\nimport {\n  getDragStart,\n  initialPublishArgs,\n} from '../../../../util/preset-action-args';\nimport createStore from '../util/create-store';\nimport getAnnounce from './util/get-announce-stub';\nimport createResponders from './util/get-responders-stub';\nimport getCompletedWithResult from './util/get-completed-with-result';\nimport { tryGetDestination } from '../../../../../src/state/get-impact-location';\n\njest.useFakeTimers();\n\nit('should call onDragEnd with the last published critical descriptor', () => {\n  const responders: Responders = createResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  store.dispatch(flush());\n  store.dispatch(initialPublish(initialPublishArgs));\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n\n  store.dispatch(flush());\n  const expected: DropResult = {\n    ...getDragStart(),\n    destination: null,\n    combine: null,\n    reason: 'CANCEL',\n  };\n  expect(responders.onDragEnd).toHaveBeenCalledWith(\n    expected,\n    expect.any(Object),\n  );\n});\n\nit('should publish an onDragEnd with no destination even if there is a current destination', () => {\n  const responders: Responders = createResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  store.dispatch(flush());\n  store.dispatch(initialPublish(initialPublishArgs));\n  jest.runOnlyPendingTimers();\n\n  const state: State = store.getState();\n  invariant(state.phase === 'DRAGGING');\n  // in home location\n  const home: DraggableLocation = {\n    droppableId: initialPublishArgs.critical.droppable.id,\n    index: initialPublishArgs.critical.draggable.index,\n  };\n  expect(tryGetDestination(state.impact)).toEqual(home);\n\n  store.dispatch(flush());\n  const expected: DropResult = {\n    ...getDragStart(),\n    // destination has been cleared\n    destination: null,\n    combine: null,\n    reason: 'CANCEL',\n  };\n  expect(responders.onDragEnd).toHaveBeenCalledWith(\n    expected,\n    expect.any(Object),\n  );\n});\n\nit('should not publish an onDragEnd if aborted after a drop', () => {\n  const responders: Responders = createResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  // lift\n  store.dispatch(flush());\n  store.dispatch(initialPublish(initialPublishArgs));\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragStart).toHaveBeenCalled();\n\n  // drop\n  const result: DropResult = {\n    ...getDragStart(),\n    destination: null,\n    combine: null,\n    reason: 'CANCEL',\n  };\n  store.dispatch(\n    completeDrop({\n      completed: getCompletedWithResult(result, store.getState()),\n    }),\n  );\n  expect(responders.onDragEnd).toHaveBeenCalledTimes(1);\n  // $ExpectError - mock\n  responders.onDragEnd.mockReset();\n\n  // abort\n  store.dispatch(flush());\n  expect(responders.onDragEnd).not.toHaveBeenCalled();\n});\n\nit('should publish an on drag end if aborted before the publish of an onDragStart', () => {\n  const responders: Responders = createResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  // lift\n  store.dispatch(flush());\n  store.dispatch(initialPublish(initialPublishArgs));\n  // onDragStart not flushed yet\n  expect(responders.onDragStart).not.toHaveBeenCalled();\n\n  // drop\n  const result: DropResult = {\n    ...getDragStart(),\n    destination: null,\n    combine: null,\n    reason: 'CANCEL',\n  };\n  store.dispatch(\n    completeDrop({\n      completed: getCompletedWithResult(result, store.getState()),\n    }),\n  );\n  expect(responders.onDragEnd).toHaveBeenCalledTimes(1);\n\n  // validation - onDragStart has been flushed\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "test/unit/state/middleware/responders/announcements.spec.js",
    "content": "// @flow\nimport { invariant } from '../../../../../src/invariant';\nimport {\n  completeDrop,\n  initialPublish,\n  moveDown,\n  updateDroppableIsCombineEnabled,\n} from '../../../../../src/state/action-creators';\nimport middleware from '../../../../../src/state/middleware/responders';\nimport messagePreset from '../../../../../src/screen-reader-message-preset';\nimport {\n  preset,\n  getDragStart,\n  initialPublishArgs,\n} from '../../../../util/preset-action-args';\nimport createStore from '../util/create-store';\nimport type {\n  Responders,\n  DragUpdate,\n  DropResult,\n  ResponderProvided,\n} from '../../../../../src/types';\nimport type { Store, Dispatch } from '../../../../../src/state/store-types';\nimport createResponders from './util/get-responders-stub';\nimport getAnnounce from './util/get-announce-stub';\nimport getCompletedWithResult from './util/get-completed-with-result';\n\njest.useFakeTimers();\n\ntype Case = {|\n  responder: 'onDragStart' | 'onDragUpdate' | 'onDragEnd',\n  description?: string,\n  execute: (store: Store) => void,\n  defaultMessage: string,\n|};\n\nconst moveForwardUpdate: DragUpdate = {\n  ...getDragStart(),\n  destination: {\n    droppableId: initialPublishArgs.critical.droppable.id,\n    index: initialPublishArgs.critical.draggable.index + 1,\n  },\n  combine: null,\n};\n\nconst combineUpdate: DragUpdate = {\n  ...getDragStart(),\n  destination: null,\n  combine: {\n    draggableId: preset.inHome2.descriptor.id,\n    droppableId: initialPublishArgs.critical.droppable.id,\n  },\n};\n\nconst start = (dispatch: Dispatch) => {\n  dispatch(initialPublish(initialPublishArgs));\n  // release async responder\n  jest.runOnlyPendingTimers();\n};\n\nconst update = (dispatch: Dispatch) => {\n  dispatch(moveDown());\n  // release async responder\n  jest.runOnlyPendingTimers();\n};\n\nconst end = (store: Store) => {\n  const result: DropResult = {\n    ...moveForwardUpdate,\n    reason: 'DROP',\n  };\n  store.dispatch(\n    completeDrop({\n      completed: getCompletedWithResult(result, store.getState()),\n    }),\n  );\n};\n\nconst cases: Case[] = [\n  {\n    responder: 'onDragStart',\n    execute: (store: Store) => {\n      start(store.dispatch);\n    },\n    defaultMessage: messagePreset.onDragStart(getDragStart()),\n  },\n  {\n    // a reorder upate\n    responder: 'onDragUpdate',\n    description: 'a reorder update',\n    execute: (store: Store) => {\n      start(store.dispatch);\n      update(store.dispatch);\n    },\n    defaultMessage: messagePreset.onDragUpdate(moveForwardUpdate),\n  },\n  {\n    // a combine update\n    responder: 'onDragUpdate',\n    description: 'a combine update',\n    execute: (store: Store) => {\n      start(store.dispatch);\n      store.dispatch(\n        updateDroppableIsCombineEnabled({\n          id: initialPublishArgs.critical.droppable.id,\n          isCombineEnabled: true,\n        }),\n      );\n      update(store.dispatch);\n    },\n    defaultMessage: messagePreset.onDragUpdate(combineUpdate),\n  },\n  {\n    responder: 'onDragEnd',\n    execute: (store: Store) => {\n      start(store.dispatch);\n      update(store.dispatch);\n      end(store);\n    },\n    defaultMessage: messagePreset.onDragEnd({\n      ...moveForwardUpdate,\n      reason: 'DROP',\n    }),\n  },\n];\n\ncases.forEach((current: Case) => {\n  describe(`for responder: ${current.responder}${\n    current.description ? `: ${current.description}` : ''\n  }`, () => {\n    let responders: Responders;\n    let announce: JestMockFn<string[], void>;\n    let store: Store;\n\n    beforeEach(() => {\n      responders = createResponders();\n      announce = getAnnounce();\n      store = createStore(middleware(() => responders, announce));\n    });\n\n    it('should announce with the default message if no responder is provided', () => {\n      // This test is not relevant for onDragEnd as it must always be provided\n      if (current.responder === 'onDragEnd') {\n        expect(true).toBe(true);\n        return;\n      }\n      // unsetting responder\n      responders[current.responder] = undefined;\n      current.execute(store);\n      expect(announce).toHaveBeenCalledWith(current.defaultMessage);\n    });\n\n    it('should announce with the default message if the responder does not announce', () => {\n      current.execute(store);\n      expect(announce).toHaveBeenCalledWith(current.defaultMessage);\n    });\n\n    it('should not announce twice if the responder makes an announcement', () => {\n      responders[current.responder] = jest.fn(\n        (data: any, provided: ResponderProvided) => {\n          announce.mockReset();\n          provided.announce('hello');\n          expect(announce).toHaveBeenCalledWith('hello');\n          // asserting there was no double call\n          expect(announce).toHaveBeenCalledTimes(1);\n        },\n      );\n\n      current.execute(store);\n    });\n\n    it('should prevent async announcements', () => {\n      const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});\n\n      let provided: ResponderProvided;\n      responders[current.responder] = jest.fn(\n        (data: any, supplied: ResponderProvided) => {\n          announce.mockReset();\n          provided = supplied;\n        },\n      );\n\n      current.execute(store);\n\n      // We did not announce so it would have been called with the default message\n      expect(announce).toHaveBeenCalledWith(current.defaultMessage);\n      expect(announce).toHaveBeenCalledTimes(1);\n      expect(warn).not.toHaveBeenCalled();\n      announce.mockReset();\n\n      // perform an async message\n      setTimeout(() => provided.announce('async message'));\n      jest.runOnlyPendingTimers();\n\n      expect(announce).not.toHaveBeenCalled();\n      expect(warn).toHaveBeenCalled();\n\n      // cleanup\n      warn.mockRestore();\n    });\n\n    it('should prevent multiple announcement calls from a consumer', () => {\n      const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});\n\n      let provided: ResponderProvided;\n      responders[current.responder] = jest.fn(\n        (data: any, supplied: ResponderProvided) => {\n          announce.mockReset();\n          provided = supplied;\n          provided.announce('hello');\n        },\n      );\n\n      current.execute(store);\n\n      expect(announce).toHaveBeenCalledWith('hello');\n      expect(announce).toHaveBeenCalledTimes(1);\n      expect(warn).not.toHaveBeenCalled();\n      announce.mockReset();\n\n      // perform another announcement\n      invariant(provided, 'provided is not set');\n      provided.announce('another one');\n\n      expect(announce).not.toHaveBeenCalled();\n      expect(warn).toHaveBeenCalled();\n\n      warn.mockRestore();\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/middleware/responders/drop.spec.js",
    "content": "// @flow\nimport type {\n  Responders,\n  DropResult,\n  CompletedDrag,\n  State,\n  DraggableLocation,\n} from '../../../../../src/types';\nimport { invariant } from '../../../../../src/invariant';\nimport type { Store } from '../../../../../src/state/store-types';\nimport middleware from '../../../../../src/state/middleware/responders';\nimport createStore from '../util/create-store';\nimport {\n  initialPublishArgs,\n  getDragStart,\n} from '../../../../util/preset-action-args';\nimport {\n  initialPublish,\n  completeDrop,\n} from '../../../../../src/state/action-creators';\nimport getResponders from './util/get-responders-stub';\nimport getAnnounce from './util/get-announce-stub';\nimport getCompletedWithResult from './util/get-completed-with-result';\nimport getSimpleStatePreset from '../../../../util/get-simple-state-preset';\nimport { tryGetDestination } from '../../../../../src/state/get-impact-location';\n\nconst result: DropResult = {\n  ...getDragStart(),\n  destination: {\n    droppableId: initialPublishArgs.critical.droppable.id,\n    index: 2,\n  },\n  combine: null,\n  reason: 'DROP',\n};\n\njest.useFakeTimers();\n\nit('should call the onDragEnd responder when a DROP_COMPLETE action occurs', () => {\n  const responders: Responders = getResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n\n  store.dispatch(\n    completeDrop({\n      completed: getCompletedWithResult(result, store.getState()),\n    }),\n  );\n  expect(responders.onDragEnd).toHaveBeenCalledWith(result, expect.any(Object));\n});\n\nit('should throw an exception if there was no drag start published', () => {\n  const responders: Responders = getResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  const borrowed: CompletedDrag = getSimpleStatePreset().dropAnimating()\n    .completed;\n\n  // throws when in idle\n  expect(() =>\n    store.dispatch(\n      completeDrop({\n        completed: borrowed,\n      }),\n    ),\n  ).toThrow('Can only flush responders while dragging');\n});\n\nit('should use the drop result and not the final impact', () => {\n  const responders: Responders = getResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n\n  const state: State = store.getState();\n  invariant(state.phase === 'DRAGGING');\n  const destination: ?DraggableLocation = tryGetDestination(state.impact);\n  invariant(destination);\n  const fakeResult: DropResult = {\n    ...getDragStart(),\n    // ensuring the destination is different to the current impact to ensure\n    // that the result is used for responders and not the last impact\n    destination: {\n      droppableId: destination.droppableId,\n      index: destination.index + 1,\n    },\n    combine: null,\n    reason: 'DROP',\n  };\n\n  store.dispatch(\n    completeDrop({\n      completed: getCompletedWithResult(fakeResult, store.getState()),\n    }),\n  );\n  expect(responders.onDragEnd).toHaveBeenCalledWith(\n    fakeResult,\n    expect.any(Object),\n  );\n});\n"
  },
  {
    "path": "test/unit/state/middleware/responders/flushing.spec.js",
    "content": "// @flow\nimport middleware from '../../../../../src/state/middleware/responders';\nimport createStore from '../util/create-store';\nimport type { Responders, DropResult } from '../../../../../src/types';\nimport {\n  initialPublishArgs,\n  getDragStart,\n} from '../../../../util/preset-action-args';\nimport {\n  initialPublish,\n  completeDrop,\n  moveDown,\n  moveUp,\n} from '../../../../../src/state/action-creators';\nimport type { Store } from '../../../../../src/state/store-types';\nimport getResponders from './util/get-responders-stub';\nimport getAnnounce from './util/get-announce-stub';\nimport getCompletedWithResult from './util/get-completed-with-result';\n\nconst result: DropResult = {\n  ...getDragStart(),\n  destination: {\n    droppableId: initialPublishArgs.critical.droppable.id,\n    index: 2,\n  },\n  combine: null,\n  reason: 'DROP',\n};\n\njest.useFakeTimers();\n\nit('should trigger an on drag start after in the next cycle', () => {\n  const responders: Responders = getResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(responders.onDragStart).not.toHaveBeenCalled();\n\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n});\n\nit('should queue a drag start if an action comes in while the timeout is pending', () => {\n  const responders: Responders = getResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(responders.onDragStart).not.toHaveBeenCalled();\n\n  store.dispatch(moveDown());\n  expect(responders.onDragStart).not.toHaveBeenCalled();\n\n  jest.runOnlyPendingTimers();\n\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n  expect(responders.onDragUpdate).toHaveBeenCalledTimes(1);\n});\n\nit('should flush any pending responders if a drop occurs', () => {\n  const responders: Responders = getResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(responders.onDragStart).not.toHaveBeenCalled();\n  expect(responders.onDragUpdate).not.toHaveBeenCalled();\n\n  store.dispatch(moveDown());\n  expect(responders.onDragStart).not.toHaveBeenCalled();\n  expect(responders.onDragUpdate).not.toHaveBeenCalled();\n\n  store.dispatch(moveUp());\n  expect(responders.onDragStart).not.toHaveBeenCalled();\n  expect(responders.onDragUpdate).not.toHaveBeenCalled();\n\n  store.dispatch(\n    completeDrop({\n      completed: getCompletedWithResult(result, store.getState()),\n    }),\n  );\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n  expect(responders.onDragUpdate).toHaveBeenCalledTimes(2);\n  expect(responders.onDragEnd).toHaveBeenCalledWith(result, expect.any(Object));\n});\n\nit('should work across multiple drags', () => {\n  const responders: Responders = getResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n  Array.from({ length: 4 }).forEach(() => {\n    store.dispatch(initialPublish(initialPublishArgs));\n    expect(responders.onBeforeDragStart).toHaveBeenCalled();\n    expect(responders.onDragStart).not.toHaveBeenCalled();\n\n    store.dispatch(moveDown());\n    expect(responders.onDragStart).not.toHaveBeenCalled();\n    expect(responders.onDragUpdate).not.toHaveBeenCalled();\n\n    store.dispatch(\n      completeDrop({\n        completed: getCompletedWithResult(result, store.getState()),\n      }),\n    );\n    expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n    expect(responders.onDragUpdate).toHaveBeenCalledTimes(1);\n    expect(responders.onDragEnd).toHaveBeenCalledWith(\n      result,\n      expect.any(Object),\n    );\n\n    // $FlowFixMe - responder does not have mockReset property\n    responders.onDragStart.mockReset();\n    // $FlowFixMe - responder does not have mockReset property\n    responders.onDragUpdate.mockReset();\n    // $FlowFixMe - responder does not have mockReset property\n    responders.onDragEnd.mockReset();\n  });\n});\n"
  },
  {
    "path": "test/unit/state/middleware/responders/repeated-use.spec.js",
    "content": "// @flow\nimport {\n  flush,\n  completeDrop,\n  initialPublish,\n  moveDown,\n} from '../../../../../src/state/action-creators';\nimport middleware from '../../../../../src/state/middleware/responders';\nimport {\n  getDragStart,\n  initialPublishArgs,\n} from '../../../../util/preset-action-args';\nimport createStore from '../util/create-store';\nimport type {\n  Responders,\n  DragUpdate,\n  DropResult,\n} from '../../../../../src/types';\nimport createResponders from './util/get-responders-stub';\nimport getAnnounce from './util/get-announce-stub';\nimport getCompletedWithResult from './util/get-completed-with-result';\n\njest.useFakeTimers();\n\nit('should behave correctly across multiple drags', () => {\n  const responders: Responders = createResponders();\n  const store = createStore(middleware(() => responders, getAnnounce()));\n  Array.from({ length: 4 }).forEach(() => {\n    // start\n    store.dispatch(initialPublish(initialPublishArgs));\n    jest.runOnlyPendingTimers();\n    expect(responders.onDragStart).toHaveBeenCalledWith(\n      getDragStart(),\n      expect.any(Object),\n    );\n    expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n\n    // update\n    const update: DragUpdate = {\n      ...getDragStart(),\n      destination: {\n        droppableId: initialPublishArgs.critical.droppable.id,\n        index: initialPublishArgs.critical.draggable.index + 1,\n      },\n      combine: null,\n    };\n    store.dispatch(moveDown());\n    // flush responder call\n    jest.runOnlyPendingTimers();\n    expect(responders.onDragUpdate).toHaveBeenCalledWith(\n      update,\n      expect.any(Object),\n    );\n    expect(responders.onDragUpdate).toHaveBeenCalledTimes(1);\n\n    // drop\n    const result: DropResult = {\n      ...update,\n      reason: 'DROP',\n    };\n    store.dispatch(\n      completeDrop({\n        completed: getCompletedWithResult(result, store.getState()),\n      }),\n    );\n    expect(responders.onDragEnd).toHaveBeenCalledWith(\n      result,\n      expect.any(Object),\n    );\n    expect(responders.onDragEnd).toHaveBeenCalledTimes(1);\n\n    // cleanup\n    store.dispatch(flush());\n    // $ExpectError - unknown mock reset property\n    responders.onDragStart.mockReset();\n    // $ExpectError - unknown mock reset property\n    responders.onDragUpdate.mockReset();\n    // $ExpectError - unknown mock reset property\n    responders.onDragEnd.mockReset();\n  });\n});\n"
  },
  {
    "path": "test/unit/state/middleware/responders/start.spec.js",
    "content": "// @flow\nimport { invariant } from '../../../../../src/invariant';\nimport { initialPublish } from '../../../../../src/state/action-creators';\nimport middleware from '../../../../../src/state/middleware/responders';\nimport {\n  getDragStart,\n  initialPublishArgs,\n} from '../../../../util/preset-action-args';\nimport createStore from '../util/create-store';\nimport passThrough from '../util/pass-through-middleware';\nimport type { Responders } from '../../../../../src/types';\nimport type { Store } from '../../../../../src/state/store-types';\nimport getRespondersStub from './util/get-responders-stub';\nimport getAnnounce from './util/get-announce-stub';\n\njest.useFakeTimers();\n\nit('should call the onDragStart responder when a initial publish occurs', () => {\n  const responders: Responders = getRespondersStub();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  // prepare step should not trigger responder\n  expect(responders.onDragStart).not.toHaveBeenCalled();\n\n  // first initial publish\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(responders.onDragStart).not.toHaveBeenCalled();\n\n  // flushing onDragStart\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragStart).toHaveBeenCalledWith(\n    getDragStart(),\n    expect.any(Object),\n  );\n});\n\nit('should call the onBeforeDragState and onDragStart in the correct order', () => {\n  let mockCalled: ?number = null;\n  let onBeforeDragStartCalled: ?number = null;\n  let onDragStartCalled: ?number = null;\n  const mock = jest.fn().mockImplementation(() => {\n    mockCalled = performance.now();\n  });\n  const responders: Responders = getRespondersStub();\n  // $FlowFixMe - no property mockImplementation\n  responders.onBeforeDragStart.mockImplementation(() => {\n    onBeforeDragStartCalled = performance.now();\n  });\n  // $FlowFixMe - no property mockImplementation\n  responders.onDragStart.mockImplementation(() => {\n    onDragStartCalled = performance.now();\n  });\n  const store: Store = createStore(\n    middleware(() => responders, getAnnounce()),\n    passThrough(mock),\n  );\n\n  // first initial publish\n  store.dispatch(initialPublish(initialPublishArgs));\n  expect(responders.onBeforeDragStart).toHaveBeenCalledWith(getDragStart());\n  // flushing onDragStart\n  jest.runOnlyPendingTimers();\n\n  // checking the order\n  invariant(onBeforeDragStartCalled);\n  invariant(mockCalled);\n  invariant(onDragStartCalled);\n  expect(mock).toHaveBeenCalledTimes(1);\n  expect(onBeforeDragStartCalled).toBeLessThan(mockCalled);\n  expect(mockCalled).toBeLessThan(onDragStartCalled);\n});\n\nit('should throw an exception if an initial publish is called before a drag ends', () => {\n  const responders: Responders = getRespondersStub();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  const start = () => {\n    store.dispatch(initialPublish(initialPublishArgs));\n    jest.runOnlyPendingTimers();\n  };\n  // first execution is all good\n  start();\n  expect(responders.onDragStart).toHaveBeenCalled();\n\n  // should not happen\n  expect(start).toThrow();\n});\n"
  },
  {
    "path": "test/unit/state/middleware/responders/update.spec.js",
    "content": "// @flow\nimport { invariant } from '../../../../../src/invariant';\nimport {\n  initialPublish,\n  move,\n  moveDown,\n  type MoveArgs,\n} from '../../../../../src/state/action-creators';\nimport middleware from '../../../../../src/state/middleware/responders';\nimport { add } from '../../../../../src/state/position';\nimport {\n  getDragStart,\n  initialPublishArgs,\n} from '../../../../util/preset-action-args';\nimport createStore from '../util/create-store';\nimport getAnnounce from './util/get-announce-stub';\nimport createResponders from './util/get-responders-stub';\nimport type { Responders, State, DragUpdate } from '../../../../../src/types';\nimport type { Store, Dispatch } from '../../../../../src/state/store-types';\n\njest.useFakeTimers();\n\nconst start = (dispatch: Dispatch) => {\n  dispatch(initialPublish(initialPublishArgs));\n  jest.runOnlyPendingTimers();\n};\n\nit('should call onDragUpdate if the position has changed on move', () => {\n  const responders: Responders = createResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  start(store.dispatch);\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n  expect(responders.onDragUpdate).not.toHaveBeenCalled();\n\n  // Okay let's move it\n  store.dispatch(moveDown());\n  // not called until next cycle\n  expect(responders.onDragUpdate).not.toHaveBeenCalled();\n\n  jest.runOnlyPendingTimers();\n  const update: DragUpdate = {\n    ...getDragStart(),\n    combine: null,\n    destination: {\n      droppableId: initialPublishArgs.critical.droppable.id,\n      index: initialPublishArgs.critical.draggable.index + 1,\n    },\n  };\n  expect(responders.onDragUpdate).toHaveBeenCalledWith(\n    update,\n    expect.any(Object),\n  );\n});\n\nit('should not call onDragUpdate if there is no movement from the last update', () => {\n  const responders: Responders = createResponders();\n  const store: Store = createStore(middleware(() => responders, getAnnounce()));\n\n  start(store.dispatch);\n  expect(responders.onDragStart).toHaveBeenCalledTimes(1);\n\n  // onDragUpdate not called yet\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragUpdate).not.toHaveBeenCalled();\n\n  // A movement to the same index is not causing an update\n  const moveArgs: MoveArgs = {\n    // tiny change\n    client: add(initialPublishArgs.clientSelection, { x: 1, y: 1 }),\n  };\n  store.dispatch(move(moveArgs));\n\n  // update not called after flushing\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragUpdate).not.toHaveBeenCalled();\n\n  // Triggering an actual movement\n  store.dispatch(moveDown());\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragUpdate).toHaveBeenCalledTimes(1);\n\n  const state: State = store.getState();\n  invariant(\n    state.phase === 'DRAGGING',\n    'Expecting state to be in dragging phase',\n  );\n\n  // A small movement that should not trigger any index changes\n  store.dispatch(\n    move({\n      client: add(state.current.client.selection, { x: -1, y: -1 }),\n    }),\n  );\n\n  jest.runOnlyPendingTimers();\n  expect(responders.onDragUpdate).toHaveBeenCalledTimes(1);\n});\n"
  },
  {
    "path": "test/unit/state/middleware/responders/util/get-announce-stub.js",
    "content": "// @flow\nimport type { Announce } from '../../../../../../src/types';\n\nexport default (): Announce => jest.fn();\n"
  },
  {
    "path": "test/unit/state/middleware/responders/util/get-completed-with-result.js",
    "content": "// @flow\nimport type {\n  DropResult,\n  State,\n  CompletedDrag,\n} from '../../../../../../src/types';\nimport { invariant } from '../../../../../../src/invariant';\n\nexport default (result: DropResult, state: State): CompletedDrag => {\n  invariant(\n    state.phase === 'DRAGGING',\n    `This is just a simple helper.\n    Unsupported phase: ${state.phase}`,\n  );\n\n  return {\n    afterCritical: state.afterCritical,\n    critical: state.critical,\n    result,\n    impact: state.impact,\n  };\n};\n"
  },
  {
    "path": "test/unit/state/middleware/responders/util/get-responders-stub.js",
    "content": "// @flow\nimport type { Responders } from '../../../../../../src/types';\n\nexport default (): Responders => ({\n  onBeforeDragStart: jest.fn(),\n  onDragStart: jest.fn(),\n  onDragUpdate: jest.fn(),\n  onDragEnd: jest.fn(),\n});\n"
  },
  {
    "path": "test/unit/state/middleware/style.spec.js",
    "content": "// @flow\nimport middleware from '../../../../src/state/middleware/style';\nimport type { StyleMarshal } from '../../../../src/view/use-style-marshal/style-marshal-types';\nimport type { DropReason } from '../../../../src/types';\nimport type { Store } from '../../../../src/state/store-types';\nimport createStore from './util/create-store';\nimport {\n  initialPublish,\n  animateDrop,\n  completeDrop,\n  flush,\n} from '../../../../src/state/action-creators';\nimport {\n  initialPublishArgs,\n  animateDropArgs,\n  getCompletedArgs,\n} from '../../../util/preset-action-args';\n\nconst getMarshalStub = (): StyleMarshal => ({\n  dragging: jest.fn(),\n  dropping: jest.fn(),\n  resting: jest.fn(),\n});\n\nit('should use the dragging styles on an initial publish', () => {\n  const marshal: StyleMarshal = getMarshalStub();\n  const store: Store = createStore(middleware(marshal));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n\n  expect(marshal.dragging).toHaveBeenCalled();\n});\n\nit('should use the dropping styles when drop animating', () => {\n  const marshal: StyleMarshal = getMarshalStub();\n  const store: Store = createStore(middleware(marshal));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n  store.dispatch(animateDrop(animateDropArgs));\n\n  expect(marshal.dropping).toHaveBeenCalledWith(\n    animateDropArgs.completed.result.reason,\n  );\n});\n\nit('should use the resting styles when a drop completes', () => {\n  ['DROP', 'CANCEL'].forEach((reason: DropReason) => {\n    const marshal: StyleMarshal = getMarshalStub();\n    const store: Store = createStore(middleware(marshal));\n\n    store.dispatch(initialPublish(initialPublishArgs));\n\n    expect(marshal.resting).not.toHaveBeenCalled();\n    store.dispatch(completeDrop(getCompletedArgs(reason)));\n\n    expect(marshal.resting).toHaveBeenCalled();\n  });\n});\n\nit('should use the resting styles when aborting', () => {\n  const marshal: StyleMarshal = getMarshalStub();\n  const store: Store = createStore(middleware(marshal));\n\n  store.dispatch(initialPublish(initialPublishArgs));\n\n  expect(marshal.resting).not.toHaveBeenCalled();\n  store.dispatch(flush());\n\n  expect(marshal.resting).toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/state/middleware/util/create-store.js",
    "content": "// @flow\nimport { createStore, applyMiddleware } from 'redux';\nimport reducer from '../../../../../src/state/reducer';\nimport type { Store, Middleware } from '../../../../../src/state/store-types';\n\nexport default (...middleware: Middleware[]): Store =>\n  createStore(reducer, applyMiddleware(...middleware));\n"
  },
  {
    "path": "test/unit/state/middleware/util/pass-through-middleware.js",
    "content": "// @flow\nimport type { Action, Middleware } from '../../../../../src/state/store-types';\n\nconst passThrough = (mock: Function): Middleware => {\n  const result: Middleware = () => (next: Function) => (\n    action: Action,\n  ): any => {\n    mock(action);\n    next(action);\n  };\n\n  return result;\n};\n\nexport default passThrough;\n"
  },
  {
    "path": "test/unit/state/middleware/validate-indexes.spec.js",
    "content": "// @flow\nimport type { DraggableDimension, DimensionMap } from '../../../../src/types';\nimport type { Store } from '../../../../src/state/store-types';\nimport type { DimensionMarshal } from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport {\n  flush,\n  initialPublish,\n  type InitialPublishArgs,\n  lift,\n  beforeInitialCapture,\n} from '../../../../src/state/action-creators';\nimport middleware from '../../../../src/state/middleware/lift';\nimport createRegistry from '../../../../src/state/registry/create-registry';\nimport { createMarshal } from '../../../util/dimension-marshal';\nimport {\n  copy,\n  initialPublishArgs,\n  beforeCaptureArgs,\n  liftArgs,\n  preset,\n} from '../../../util/preset-action-args';\nimport { populate } from '../../../util/registry';\nimport { resetViewport, setViewport } from '../../../util/viewport';\nimport createStore from './util/create-store';\nimport passThrough from './util/pass-through-middleware';\nimport type { Registry } from '../../../../src/state/registry/registry-types';\n\nconst getPopulatedRegistry = (dimensions?: DimensionMap): Registry => {\n  const registry: Registry = createRegistry();\n  populate(registry, dimensions);\n  return registry;\n};\n\nbeforeEach(() => {\n  setViewport(preset.viewport);\n  jest.useFakeTimers();\n});\n\nafterEach(() => {\n  resetViewport();\n  jest.clearAllTimers();\n  jest.useRealTimers();\n});\n\nit('should log a warning if items are added that do not have consecutive indexes', () => {\n  const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});\n\n  const mock = jest.fn();\n  const customInHome2: DraggableDimension = {\n    ...preset.inHome2,\n    descriptor: {\n      ...preset.inHome2.descriptor,\n      index: preset.inHome2.descriptor.index + 5,\n    },\n  };\n  const copied: DimensionMap = copy(preset.dimensions);\n  copied.draggables[preset.inHome2.descriptor.id] = customInHome2;\n\n  const marshal: DimensionMarshal = createMarshal(\n    getPopulatedRegistry(copied),\n    // lazy use of store.dispatch\n    (action) =>\n      // eslint-disable-next-line no-use-before-define\n      store.dispatch(action),\n  );\n  const store: Store = createStore(passThrough(mock), middleware(marshal));\n  const initial: InitialPublishArgs = {\n    ...initialPublishArgs,\n    dimensions: copied,\n  };\n\n  // first lift is preparing\n  store.dispatch(lift(liftArgs));\n  expect(mock).toHaveBeenCalledWith(lift(liftArgs));\n  expect(mock).toHaveBeenCalledWith(flush());\n  expect(mock).toHaveBeenCalledWith(beforeInitialCapture(beforeCaptureArgs));\n  expect(mock).toHaveBeenCalledWith(initialPublish(initial));\n  expect(mock).toHaveBeenCalledTimes(4);\n  expect(store.getState().phase).toBe('DRAGGING');\n\n  // a warning is logged\n  expect(warn).toHaveBeenCalled();\n  expect(warn.mock.calls[0][0]).toEqual(\n    // dimensions will be ordered by index\n    // inHome1: index 0: all good\n    // inHome3: index 2: boom\n    // inHome4: index 3: all good (2 + 1)\n    // inHome2: index 6: boom\n    expect.stringContaining(`0, [🔥2], 3, [🔥6]`),\n  );\n\n  warn.mockRestore();\n});\n\nit('should log a warning if items are added have duplicate indexes', () => {\n  const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});\n\n  const mock = jest.fn();\n  const customInHome4: DraggableDimension = {\n    ...preset.inHome4,\n    descriptor: {\n      ...preset.inHome4.descriptor,\n      // duplicate index\n      index: preset.inHome3.descriptor.index,\n    },\n  };\n  const dimensions: DimensionMap = copy(preset.dimensions);\n  dimensions.draggables[preset.inHome4.descriptor.id] = customInHome4;\n\n  const marshal: DimensionMarshal = createMarshal(\n    getPopulatedRegistry(dimensions),\n    // lazy use of store.dispatch\n    (action) =>\n      // eslint-disable-next-line no-use-before-define\n      store.dispatch(action),\n  );\n  const store: Store = createStore(passThrough(mock), middleware(marshal));\n  const initial: InitialPublishArgs = {\n    ...initialPublishArgs,\n    dimensions,\n  };\n\n  // first lift is preparing\n  store.dispatch(lift(liftArgs));\n  expect(mock).toHaveBeenCalledWith(lift(liftArgs));\n  expect(mock).toHaveBeenCalledWith(flush());\n  expect(mock).toHaveBeenCalledWith(beforeInitialCapture(beforeCaptureArgs));\n  expect(mock).toHaveBeenCalledWith(initialPublish(initial));\n  expect(mock).toHaveBeenCalledTimes(4);\n  expect(store.getState().phase).toBe('DRAGGING');\n\n  // a warning is logged\n  expect(warn).toHaveBeenCalled();\n  expect(warn.mock.calls[0][0]).toEqual(\n    expect.stringContaining('0, 1, [🔥2], [🔥2]'),\n  );\n\n  warn.mockRestore();\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-cross-axis/get-best-cross-axis-droppable.spec.js",
    "content": "// @flow\nimport { type Position, type Spacing } from 'css-box-model';\nimport getBestCrossAxisDroppable from '../../../../../src/state/move-in-direction/move-cross-axis/get-best-cross-axis-droppable';\nimport { getDroppableDimension } from '../../../../util/dimension';\nimport { add } from '../../../../../src/state/position';\nimport { horizontal, vertical } from '../../../../../src/state/axis';\nimport getViewport from '../../../../../src/view/window/get-viewport';\nimport type {\n  Viewport,\n  Axis,\n  DroppableDimension,\n  DroppableDimensionMap,\n} from '../../../../../src/types';\n\nconst viewport: Viewport = getViewport();\n\ndescribe('get best cross axis droppable', () => {\n  describe('on the vertical axis', () => {\n    const axis: Axis = vertical;\n\n    it('should return the first droppable on the cross axis when moving forward', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        },\n      });\n      const forward = getDroppableDimension({\n        descriptor: {\n          id: 'forward',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 30,\n          right: 40,\n          bottom: 10,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [forward.descriptor.id]: forward,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n\n      expect(result).toBe(forward);\n    });\n\n    it('should return the first droppable on the cross axis when moving backward', () => {\n      const behind = getDroppableDimension({\n        descriptor: {\n          id: 'behind',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        },\n      });\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 30,\n          right: 40,\n          bottom: 10,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [behind.descriptor.id]: behind,\n        [source.descriptor.id]: source,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        // moving backwards\n        isMovingForward: false,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        viewport,\n        droppables,\n      });\n\n      expect(result).toBe(behind);\n    });\n\n    it('should exclude options that are not in the desired direction', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        },\n      });\n      const behind = getDroppableDimension({\n        descriptor: {\n          id: 'behind',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 0,\n          right: 10,\n          bottom: 10,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [behind.descriptor.id]: behind,\n        [source.descriptor.id]: source,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n      expect(result).toBe(null);\n\n      // checking that it would have been returned if was moving in the other direction\n      const result2: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: false,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n      expect(result2).toBe(behind);\n    });\n\n    it('should exclude options that are not enabled', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        },\n      });\n      const disabled = getDroppableDimension({\n        descriptor: {\n          id: 'disabled',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        isEnabled: false,\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 30,\n          right: 40,\n          bottom: 10,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [disabled.descriptor.id]: disabled,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n\n      expect(result).toBe(null);\n    });\n\n    it('should exclude options that are not in the viewport', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        },\n      });\n      const outsideViewport = getDroppableDimension({\n        descriptor: {\n          id: 'outsideViewport',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          left: 30,\n          right: 40,\n          top: viewport.frame.bottom + 1,\n          bottom: viewport.frame.bottom + 10,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [outsideViewport.descriptor.id]: outsideViewport,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n\n      expect(result).toBe(null);\n    });\n\n    it('should exclude options that do not overlap on the main axis', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        },\n      });\n      const noOverlap = getDroppableDimension({\n        descriptor: {\n          id: 'noOverlap',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          // top is below where the source ended\n          top: 11,\n          left: 30,\n          right: 40,\n          bottom: 20,\n        },\n      });\n\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [noOverlap.descriptor.id]: noOverlap,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n\n      expect(result).toBe(null);\n    });\n\n    describe('more than one option share the same crossAxisStart value', () => {\n      // this happens when two lists sit on top of one another\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 0,\n          right: 20,\n          bottom: 100,\n        },\n      });\n      const sibling1 = getDroppableDimension({\n        descriptor: {\n          id: 'sibling1',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 20,\n          left: 20,\n          right: 40,\n          // long droppable inside a shorter container - this should be clipped\n          bottom: 80,\n        },\n        closest: {\n          borderBox: {\n            // not the same top value as source\n            top: 20,\n            // shares the left edge with the source\n            left: 20,\n            right: 40,\n            bottom: 40,\n          },\n          scrollSize: {\n            scrollWidth: 20,\n            scrollHeight: 80,\n          },\n          scroll: { x: 0, y: 0 },\n          shouldClipSubject: true,\n        },\n      });\n      const sibling2 = getDroppableDimension({\n        descriptor: {\n          id: 'sibling2',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          // shares the bottom edge with sibling1\n          top: 40,\n          // shares the left edge with the source\n          left: 20,\n          right: 40,\n          bottom: 60,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [sibling1.descriptor.id]: sibling1,\n        [sibling2.descriptor.id]: sibling2,\n      };\n\n      it('should return a droppable where the center position (axis.line) of the draggable draggable sits within the size of a droppable', () => {\n        // sitting inside source - but within the size of sibling2 on the main axis\n        const center: Position = {\n          y: 50,\n          x: 10,\n        };\n\n        const result: ?DroppableDimension = getBestCrossAxisDroppable({\n          isMovingForward: true,\n          pageBorderBoxCenter: center,\n          source,\n          droppables,\n          viewport,\n        });\n\n        expect(result).toBe(sibling2);\n      });\n\n      it('should account for container clipping', () => {\n        // inside sibling1's droppable bounds, but outside its clipped bounds\n        const center: Position = {\n          y: 50,\n          x: 10,\n        };\n\n        // if we're clipping dimensions correctly we should land in sibling2\n        // if not, we'll land in sibling1\n        const result: ?DroppableDimension = getBestCrossAxisDroppable({\n          isMovingForward: true,\n          pageBorderBoxCenter: center,\n          source,\n          droppables,\n          viewport,\n        });\n\n        expect(result).toBe(sibling2);\n      });\n\n      describe('center point is not contained within a droppable', () => {\n        it('should return the droppable that has the closest corner', () => {\n          // Choosing a point that is above the first sibling\n          const center: Position = {\n            // above sibling 1\n            y: 10,\n            x: 10,\n          };\n\n          const result: ?DroppableDimension = getBestCrossAxisDroppable({\n            isMovingForward: true,\n            pageBorderBoxCenter: center,\n            source,\n            droppables,\n            viewport,\n          });\n\n          expect(result).toBe(sibling1);\n        });\n\n        it('should choose the droppable that is furthest back (closest to {x: 0, y: 0} on the screen) in the event of a tie', () => {\n          // Choosing a point that is above the first sibling\n          const center: Position = {\n            // this line is shared between sibling1 and sibling2\n            y: 40,\n            x: 10,\n          };\n\n          const result: ?DroppableDimension = getBestCrossAxisDroppable({\n            isMovingForward: true,\n            pageBorderBoxCenter: center,\n            source,\n            droppables,\n            viewport,\n          });\n\n          expect(result).toBe(sibling1);\n\n          // checking that center position was selected correctly\n          const center2: Position = add(center, { x: 0, y: 1 });\n          const result2: ?DroppableDimension = getBestCrossAxisDroppable({\n            isMovingForward: true,\n            pageBorderBoxCenter: center2,\n            source,\n            droppables,\n            viewport,\n          });\n          expect(result2).toBe(sibling2);\n        });\n      });\n    });\n  });\n\n  describe('on the horizontal axis', () => {\n    const axis: Axis = horizontal;\n\n    it('should return the first droppable on the cross axis when moving forward', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 0,\n          right: 20,\n          bottom: 20,\n        },\n      });\n      const forward = getDroppableDimension({\n        descriptor: {\n          id: 'forward',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 20,\n          left: 0,\n          right: 20,\n          bottom: 30,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [forward.descriptor.id]: forward,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n\n      expect(result).toBe(forward);\n    });\n\n    it('should return the first droppable on the cross axis when moving backward', () => {\n      const behind = getDroppableDimension({\n        descriptor: {\n          id: 'behind',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 0,\n          right: 20,\n          bottom: 10,\n        },\n      });\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 10,\n          left: 0,\n          right: 20,\n          bottom: 20,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [behind.descriptor.id]: behind,\n        [source.descriptor.id]: source,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        // moving backwards\n        isMovingForward: false,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        viewport,\n        droppables,\n      });\n\n      expect(result).toBe(behind);\n    });\n\n    it('should exclude options that are not in the desired direction', () => {\n      const behind = getDroppableDimension({\n        descriptor: {\n          id: 'behind',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 0,\n          right: 20,\n          bottom: 10,\n        },\n      });\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 10,\n          left: 0,\n          right: 20,\n          bottom: 20,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [behind.descriptor.id]: behind,\n        [source.descriptor.id]: source,\n      };\n\n      // now moving in the other direction\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n      expect(result).toBe(null);\n\n      // Ensuring that normally it would be returned if moving in the right direction\n      const result2: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: false,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n      expect(result2).toBe(behind);\n    });\n\n    it('should exclude options that are not enabled', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        },\n      });\n      const disabled = getDroppableDimension({\n        descriptor: {\n          id: 'disabled',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        isEnabled: false,\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 30,\n          right: 40,\n          bottom: 10,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [disabled.descriptor.id]: disabled,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n\n      expect(result).toBe(null);\n    });\n\n    it('should exclude options that are not visible in their frame', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          [axis.start]: 0,\n          [axis.end]: 100,\n          [axis.crossAxisStart]: 0,\n          [axis.crossAxisEnd]: 100,\n        },\n      });\n      const subjectNotVisibleThroughFrame = getDroppableDimension({\n        descriptor: {\n          id: 'notInViewport',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        // totally hidden by frame\n        borderBox: {\n          [axis.start]: 0,\n          [axis.end]: 100,\n          // would normally be a good candidate\n          [axis.crossAxisStart]: 200,\n          [axis.crossAxisEnd]: 300,\n        },\n        closest: {\n          borderBox: {\n            [axis.start]: 0,\n            [axis.end]: 100,\n            // frame hides subject\n            [axis.crossAxisStart]: 400,\n            [axis.crossAxisEnd]: 500,\n          },\n          scroll: { x: 0, y: 0 },\n          scrollSize: {\n            scrollWidth: 100,\n            scrollHeight: 100,\n          },\n          shouldClipSubject: true,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [subjectNotVisibleThroughFrame.descriptor\n          .id]: subjectNotVisibleThroughFrame,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n\n      expect(result).toBe(null);\n    });\n\n    it('should exclude options that are not in the viewport', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          bottom: 10,\n          left: 20,\n          right: 30,\n        },\n      });\n      const notInViewport = getDroppableDimension({\n        descriptor: {\n          id: 'notInViewport',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          bottom: 10,\n          left: viewport.frame.right + 1,\n          right: viewport.frame.right + 10,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [notInViewport.descriptor.id]: notInViewport,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n\n      expect(result).toBe(null);\n    });\n\n    it('should exclude options that do not overlap on the main axis', () => {\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 0,\n          right: 20,\n          bottom: 10,\n        },\n      });\n      const noOverlap = getDroppableDimension({\n        descriptor: {\n          id: 'noOverlap',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          // comes after the source\n          top: 10,\n          // but its left value is > the rigt of the source\n          left: 30,\n          right: 40,\n          bottom: 20,\n        },\n      });\n\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [noOverlap.descriptor.id]: noOverlap,\n      };\n\n      const result: ?DroppableDimension = getBestCrossAxisDroppable({\n        isMovingForward: true,\n        pageBorderBoxCenter: source.page.borderBox.center,\n        source,\n        droppables,\n        viewport,\n      });\n\n      expect(result).toBe(null);\n    });\n\n    describe('more than one option share the same crossAxisStart value', () => {\n      // this happens when two lists sit side by side\n      const source = getDroppableDimension({\n        descriptor: {\n          id: 'source',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          top: 0,\n          left: 0,\n          right: 100,\n          bottom: 10,\n        },\n      });\n      const sibling1 = getDroppableDimension({\n        descriptor: {\n          id: 'sibling1',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          // shares an edge with the source\n          top: 10,\n          // shares the left edge with the source\n          left: 20,\n          right: 40,\n          bottom: 20,\n        },\n      });\n      const sibling2 = getDroppableDimension({\n        descriptor: {\n          id: 'sibling2',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          // shares an edge with the source\n          top: 10,\n          // shares the left edge with the source\n          left: 40,\n          right: 60,\n          bottom: 20,\n        },\n      });\n      const droppables: DroppableDimensionMap = {\n        [source.descriptor.id]: source,\n        [sibling1.descriptor.id]: sibling1,\n        [sibling2.descriptor.id]: sibling2,\n      };\n\n      it('should return a droppable where the center position (axis.line) of the draggable draggable sits within the size of a droppable', () => {\n        // sitting inside source - but within the size of sibling2 on the main axis\n        const center: Position = {\n          y: 5,\n          x: 50,\n        };\n\n        const result: ?DroppableDimension = getBestCrossAxisDroppable({\n          isMovingForward: true,\n          pageBorderBoxCenter: center,\n          source,\n          droppables,\n          viewport,\n        });\n\n        expect(result).toBe(sibling2);\n      });\n\n      describe('center point is not contained within a droppable', () => {\n        it('should return the droppable that has the closest corner', () => {\n          // Choosing a point that is before the first sibling\n          const center: Position = {\n            // above sibling 1\n            y: 5,\n            // before the left value of sibling 1\n            x: 10,\n          };\n\n          const result: ?DroppableDimension = getBestCrossAxisDroppable({\n            isMovingForward: true,\n            pageBorderBoxCenter: center,\n            source,\n            droppables,\n            viewport,\n          });\n\n          expect(result).toBe(sibling1);\n        });\n\n        it('should choose the droppable that is furthest back (closest to {x: 0, y: 0} on the screen) in the event of a tie', () => {\n          // Choosing a point that is above the first sibling\n          const center: Position = {\n            y: 5,\n            // this line is shared between sibling1 and sibling2\n            x: 40,\n          };\n\n          const result: ?DroppableDimension = getBestCrossAxisDroppable({\n            isMovingForward: true,\n            pageBorderBoxCenter: center,\n            source,\n            droppables,\n            viewport,\n          });\n\n          expect(result).toBe(sibling1);\n\n          // checking that center point is correct\n\n          const center2: Position = add(center, { y: 0, x: 1 });\n          const result2: ?DroppableDimension = getBestCrossAxisDroppable({\n            isMovingForward: true,\n            pageBorderBoxCenter: center2,\n            source,\n            droppables,\n            viewport,\n          });\n\n          expect(result2).toBe(sibling2);\n        });\n      });\n    });\n  });\n\n  describe('overlap', () => {\n    const axis: Axis = vertical;\n\n    describe('moving forward', () => {\n      it('allow overlap as long as the end of the target is after the end of the source', () => {\n        const box: Spacing = {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        };\n        const source = getDroppableDimension({\n          descriptor: {\n            id: 'source',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: box,\n        });\n        const forward = getDroppableDimension({\n          descriptor: {\n            id: 'forward',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: {\n            ...box,\n            right: box.right + 1,\n          },\n        });\n        const droppables: DroppableDimensionMap = {\n          [source.descriptor.id]: source,\n          [forward.descriptor.id]: forward,\n        };\n\n        const result: ?DroppableDimension = getBestCrossAxisDroppable({\n          isMovingForward: true,\n          pageBorderBoxCenter: source.page.borderBox.center,\n          source,\n          droppables,\n          viewport,\n        });\n\n        expect(result).toBe(forward);\n      });\n\n      it('should not allow movement when the droppables are on top of each other', () => {\n        const box: Spacing = {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        };\n        const source = getDroppableDimension({\n          descriptor: {\n            id: 'source',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: box,\n        });\n        const forward = getDroppableDimension({\n          descriptor: {\n            id: 'forward',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: box,\n        });\n        const droppables: DroppableDimensionMap = {\n          [source.descriptor.id]: source,\n          [forward.descriptor.id]: forward,\n        };\n\n        const result: ?DroppableDimension = getBestCrossAxisDroppable({\n          isMovingForward: true,\n          pageBorderBoxCenter: source.page.borderBox.center,\n          source,\n          droppables,\n          viewport,\n        });\n\n        expect(result).toBe(null);\n      });\n\n      it('should not allow movement the right edge of the source is not greater than the right edge of the target', () => {\n        const box: Spacing = {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        };\n        const source = getDroppableDimension({\n          descriptor: {\n            id: 'source',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: box,\n        });\n        const forward = getDroppableDimension({\n          descriptor: {\n            id: 'forward',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: {\n            ...box,\n            // forward a little bit\n            left: box.left + 1,\n            // not far enough\n            right: box.right - 1,\n          },\n        });\n        const droppables: DroppableDimensionMap = {\n          [source.descriptor.id]: source,\n          [forward.descriptor.id]: forward,\n        };\n\n        const result: ?DroppableDimension = getBestCrossAxisDroppable({\n          isMovingForward: true,\n          pageBorderBoxCenter: source.page.borderBox.center,\n          source,\n          droppables,\n          viewport,\n        });\n\n        expect(result).toBe(null);\n      });\n    });\n\n    describe('moving backwards', () => {\n      it('should allow overlap as long as the start of the target is before the start of the source', () => {\n        const box: Spacing = {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        };\n        const source = getDroppableDimension({\n          descriptor: {\n            id: 'source',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: box,\n        });\n        const backwards = getDroppableDimension({\n          descriptor: {\n            id: 'forward',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: {\n            ...box,\n            left: box.left - 1,\n          },\n        });\n        const droppables: DroppableDimensionMap = {\n          [source.descriptor.id]: source,\n          [backwards.descriptor.id]: backwards,\n        };\n\n        const result: ?DroppableDimension = getBestCrossAxisDroppable({\n          isMovingForward: false,\n          pageBorderBoxCenter: source.page.borderBox.center,\n          source,\n          droppables,\n          viewport,\n        });\n\n        expect(result).toBe(backwards);\n      });\n\n      it('should not allow movement when the droppables are on top of each other', () => {\n        const box: Spacing = {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        };\n        const source = getDroppableDimension({\n          descriptor: {\n            id: 'source',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: box,\n        });\n        const backward = getDroppableDimension({\n          descriptor: {\n            id: 'forward',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: box,\n        });\n        const droppables: DroppableDimensionMap = {\n          [source.descriptor.id]: source,\n          [backward.descriptor.id]: backward,\n        };\n\n        const result: ?DroppableDimension = getBestCrossAxisDroppable({\n          isMovingForward: false,\n          pageBorderBoxCenter: source.page.borderBox.center,\n          source,\n          droppables,\n          viewport,\n        });\n\n        expect(result).toBe(null);\n      });\n\n      it('should not allow movement left edge of the source is not greater than the left edge of the target', () => {\n        const box: Spacing = {\n          top: 0,\n          left: 20,\n          right: 30,\n          bottom: 10,\n        };\n        const source = getDroppableDimension({\n          descriptor: {\n            id: 'source',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: box,\n        });\n        const backward = getDroppableDimension({\n          descriptor: {\n            id: 'forward',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          direction: axis.direction,\n          borderBox: {\n            ...box,\n            // backward a little bit\n            right: box.right - 1,\n            // not far enough\n            left: box.left,\n          },\n        });\n        const droppables: DroppableDimensionMap = {\n          [source.descriptor.id]: source,\n          [backward.descriptor.id]: backward,\n        };\n\n        const result: ?DroppableDimension = getBestCrossAxisDroppable({\n          isMovingForward: true,\n          pageBorderBoxCenter: source.page.borderBox.center,\n          source,\n          droppables,\n          viewport,\n        });\n\n        expect(result).toBe(null);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-cross-axis/get-closest-draggable/with-starting-displacement.spec.js",
    "content": "// @flow\nimport { getRect, type Position, type Rect, type Spacing } from 'css-box-model';\nimport type {\n  Axis,\n  DraggableDimension,\n  DroppableDimension,\n  Viewport,\n} from '../../../../../../src/types';\nimport { horizontal, vertical } from '../../../../../../src/state/axis';\nimport { toDraggableMap } from '../../../../../../src/state/dimension-structures';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport getClosestDraggable from '../../../../../../src/state/move-in-direction/move-cross-axis/get-closest-draggable';\nimport { negate, patch } from '../../../../../../src/state/position';\nimport scrollViewport from '../../../../../../src/state/scroll-viewport';\nimport { offsetByPosition } from '../../../../../../src/state/spacing';\nimport { isTotallyVisible } from '../../../../../../src/state/visibility/is-visible';\nimport getViewport from '../../../../../../src/view/window/get-viewport';\nimport {\n  getDraggableDimension,\n  getDroppableDimension,\n} from '../../../../../util/dimension';\nimport { noAfterCritical } from '../../../../../../src/state/no-impact';\n\nconst viewport: Viewport = getViewport();\n\n// Not covering all cases. Full coverage in without-starting-displacement.spec\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on the ${axis.direction} axis`, () => {\n    const start: number = 0;\n    const end: number = 100;\n    const crossAxisStart: number = 0;\n    const crossAxisEnd: number = 20;\n\n    const borderBox: Rect = getRect({\n      [axis.start]: start,\n      [axis.end]: end,\n      [axis.crossAxisStart]: crossAxisStart,\n      [axis.crossAxisEnd]: crossAxisEnd,\n    });\n\n    const home: DroppableDimension = getDroppableDimension({\n      descriptor: {\n        id: 'home',\n        type: 'TYPE',\n        mode: 'standard',\n      },\n      direction: axis.direction,\n      borderBox,\n    });\n\n    // dragging item\n    const inHome1: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'inHome1',\n        droppableId: home.descriptor.id,\n        type: home.descriptor.type,\n        index: 2,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: 0,\n        [axis.end]: 20,\n      },\n    });\n\n    const inHome2: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'inHome2',\n        droppableId: home.descriptor.id,\n        type: home.descriptor.type,\n        index: 2,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: 20,\n        [axis.end]: 40,\n      },\n    });\n\n    const inHome3: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'inHome3',\n        droppableId: home.descriptor.id,\n        type: home.descriptor.type,\n        index: 2,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: 40,\n        [axis.end]: 60,\n      },\n    });\n\n    const insideDestination: DraggableDimension[] = [inHome1, inHome2, inHome3];\n    const { afterCritical } = getLiftEffect({\n      draggable: inHome1,\n      home,\n      viewport,\n      draggables: toDraggableMap(insideDestination),\n    });\n\n    it('should find the closest draggable based on the items visible position (without initial displacement)', () => {\n      const center: Position = patch(\n        axis.line,\n        inHome2.page.borderBox.center[axis.line],\n        100,\n      );\n\n      {\n        const result: ?DraggableDimension = getClosestDraggable({\n          pageBorderBoxCenter: center,\n          destination: home,\n          insideDestination,\n          viewport,\n          afterCritical,\n        });\n        expect(result).toEqual(inHome3);\n      }\n      // validation: without initial displacement it would have been inHome2\n      {\n        const result: ?DraggableDimension = getClosestDraggable({\n          pageBorderBoxCenter: center,\n          destination: home,\n          insideDestination,\n          viewport,\n          afterCritical: noAfterCritical,\n        });\n        expect(result).toEqual(inHome2);\n      }\n    });\n\n    it('should ignore draggables backward that have no total visibility', () => {\n      const center: Position = patch(\n        axis.line,\n        inHome1.page.borderBox.center[axis.line],\n        100,\n      );\n      const scrolled: Viewport = scrollViewport(viewport, patch(axis.line, 1));\n\n      const result: ?DraggableDimension = getClosestDraggable({\n        pageBorderBoxCenter: center,\n        destination: home,\n        insideDestination,\n        viewport: scrolled,\n        afterCritical: noAfterCritical,\n      });\n      expect(result).toEqual(inHome2);\n\n      // validate visibility\n      {\n        // visible when not displaced\n        expect(\n          isTotallyVisible({\n            target: inHome2.page.borderBox,\n            destination: home,\n            viewport: scrolled.frame,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(true);\n\n        const inVisibleLocation: Spacing = offsetByPosition(\n          inHome2.page.borderBox,\n          negate(afterCritical.displacedBy.point),\n        );\n        // visible when not scrolled\n        expect(\n          isTotallyVisible({\n            target: inVisibleLocation,\n            destination: home,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(true);\n        // not visible when scrolled\n        expect(\n          isTotallyVisible({\n            target: inVisibleLocation,\n            destination: home,\n            viewport: scrolled.frame,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(false);\n      }\n\n      // validate inHome2 would have been the target expect for displacement\n      {\n        const validate: ?DraggableDimension = getClosestDraggable({\n          pageBorderBoxCenter: center,\n          destination: home,\n          insideDestination,\n          viewport: scrolled,\n          afterCritical: noAfterCritical,\n        });\n        expect(validate).toEqual(inHome2);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-cross-axis/get-closest-draggable/without-starting-displacement.spec.js",
    "content": "// @flow\nimport { getRect, type Rect, type Position } from 'css-box-model';\nimport type {\n  Axis,\n  DraggableDimension,\n  DroppableDimension,\n  Viewport,\n} from '../../../../../../src/types';\nimport getClosestDraggable from '../../../../../../src/state/move-in-direction/move-cross-axis/get-closest-draggable';\nimport scrollDroppable from '../../../../../../src/state/droppable/scroll-droppable';\nimport { add, distance, patch } from '../../../../../../src/state/position';\nimport {\n  getDroppableDimension,\n  getDraggableDimension,\n  withAssortedSpacing,\n} from '../../../../../util/dimension';\nimport { expandByPosition } from '../../../../../../src/state/spacing';\nimport { horizontal, vertical } from '../../../../../../src/state/axis';\nimport getViewport from '../../../../../../src/view/window/get-viewport';\nimport { noAfterCritical } from '../../../../../../src/state/no-impact';\n\nconst viewport: Viewport = getViewport();\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on the ${axis.direction} axis`, () => {\n    const start: number = 0;\n    const end: number = 100;\n    const crossAxisStart: number = 0;\n    const crossAxisEnd: number = 20;\n\n    const borderBox: Rect = getRect({\n      [axis.start]: start,\n      [axis.end]: end,\n      [axis.crossAxisStart]: crossAxisStart,\n      [axis.crossAxisEnd]: crossAxisEnd,\n    });\n\n    const droppable: DroppableDimension = getDroppableDimension({\n      descriptor: {\n        id: 'droppable',\n        type: 'TYPE',\n        mode: 'standard',\n      },\n      direction: axis.direction,\n      borderBox,\n      ...withAssortedSpacing(),\n    });\n\n    const hiddenBackwards: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'hiddenBackwards',\n        droppableId: droppable.descriptor.id,\n        type: droppable.descriptor.type,\n        index: 0,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: -30, // -10\n        [axis.end]: -10,\n      },\n      ...withAssortedSpacing(),\n    });\n\n    // item bleeds backwards past the start of the droppable\n    const partiallyHiddenBackwards: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'partialHiddenBackwards',\n        droppableId: droppable.descriptor.id,\n        type: droppable.descriptor.type,\n        index: 1,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: -10, // -10\n        [axis.end]: 20,\n      },\n      ...withAssortedSpacing(),\n    });\n\n    const visible1: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'visible1',\n        droppableId: droppable.descriptor.id,\n        type: droppable.descriptor.type,\n        index: 2,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: 20,\n        [axis.end]: 40,\n      },\n      ...withAssortedSpacing(),\n    });\n\n    const visible2: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'visible2',\n        droppableId: droppable.descriptor.id,\n        type: droppable.descriptor.type,\n        index: 3,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: 40,\n        [axis.end]: 60,\n      },\n      ...withAssortedSpacing(),\n    });\n\n    // bleeds over the end of the visible boundary\n    const partiallyHiddenForwards: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'partiallyHiddenForwards',\n        droppableId: droppable.descriptor.id,\n        type: droppable.descriptor.type,\n        index: 4,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: 60,\n        [axis.end]: 120,\n      },\n      ...withAssortedSpacing(),\n    });\n\n    // totally invisible\n    const hiddenForwards: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'hiddenForwards',\n        droppableId: droppable.descriptor.id,\n        type: droppable.descriptor.type,\n        index: 5,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: 120,\n        [axis.end]: 140,\n      },\n      ...withAssortedSpacing(),\n    });\n\n    const outOfViewport: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'hidden',\n        droppableId: droppable.descriptor.id,\n        type: droppable.descriptor.type,\n        index: 6,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: crossAxisStart,\n        [axis.crossAxisEnd]: crossAxisEnd,\n        [axis.start]: viewport.frame[axis.end] + 1,\n        [axis.end]: viewport.frame[axis.end] + 10,\n      },\n      ...withAssortedSpacing(),\n    });\n\n    const insideDestination: DraggableDimension[] = [\n      hiddenBackwards,\n      partiallyHiddenBackwards,\n      visible1,\n      visible2,\n      partiallyHiddenForwards,\n      hiddenForwards,\n      outOfViewport,\n    ];\n\n    it('should return the closest draggable', () => {\n      // closet to visible1\n      const center1: Position = patch(\n        axis.line,\n        visible1.page.borderBox.center[axis.line],\n        100,\n      );\n      const result1: ?DraggableDimension = getClosestDraggable({\n        pageBorderBoxCenter: center1,\n        destination: droppable,\n        insideDestination,\n        viewport,\n        afterCritical: noAfterCritical,\n      });\n      expect(result1).toBe(visible1);\n\n      // closest to visible2\n      const center2: Position = patch(\n        axis.line,\n        visible2.page.borderBox.center[axis.line],\n        100,\n      );\n      const result2: ?DraggableDimension = getClosestDraggable({\n        pageBorderBoxCenter: center2,\n        destination: droppable,\n        insideDestination,\n        viewport,\n        afterCritical: noAfterCritical,\n      });\n      expect(result2).toBe(visible2);\n    });\n\n    it('should return null if there are no draggables in the droppable', () => {\n      const center: Position = {\n        x: 100,\n        y: 100,\n      };\n\n      const result: ?DraggableDimension = getClosestDraggable({\n        pageBorderBoxCenter: center,\n        destination: droppable,\n        insideDestination: [],\n        viewport,\n        afterCritical: noAfterCritical,\n      });\n\n      expect(result).toBe(null);\n    });\n\n    it('should take into account the change in droppable scroll', () => {\n      const scrollable: DroppableDimension = getDroppableDimension({\n        descriptor: droppable.descriptor,\n        direction: axis.direction,\n        borderBox,\n        closest: {\n          borderBox: expandByPosition(borderBox, patch(axis.line, 100)),\n          scrollSize: {\n            scrollHeight: borderBox.width + 100,\n            scrollWidth: borderBox.height + 100,\n          },\n          scroll: { x: 0, y: 0 },\n          shouldClipSubject: true,\n        },\n      });\n      const scrolled: DroppableDimension = scrollDroppable(\n        scrollable,\n        patch(axis.line, 20),\n      );\n      const center: Position = patch(\n        axis.line,\n        visible1.page.borderBox.center[axis.line],\n        100,\n      );\n\n      const result: ?DraggableDimension = getClosestDraggable({\n        pageBorderBoxCenter: center,\n        destination: scrolled,\n        insideDestination,\n        viewport,\n        afterCritical: noAfterCritical,\n      });\n\n      expect(result).toBe(visible2);\n\n      // validation - with no scroll applied we are normally closer to visible1\n      const result1: ?DraggableDimension = getClosestDraggable({\n        pageBorderBoxCenter: center,\n        destination: droppable,\n        insideDestination,\n        viewport,\n        afterCritical: noAfterCritical,\n      });\n      expect(result1).toBe(visible1);\n    });\n\n    describe('removal of draggables that are visible', () => {\n      it('should ignore draggables backward that have no total visiblity', () => {\n        const center: Position = patch(\n          axis.line,\n          hiddenBackwards.page.borderBox.center[axis.line],\n          100,\n        );\n\n        const result: ?DraggableDimension = getClosestDraggable({\n          pageBorderBoxCenter: center,\n          destination: droppable,\n          insideDestination,\n          viewport,\n          afterCritical: noAfterCritical,\n        });\n\n        expect(result).toBe(visible1);\n      });\n\n      it('should ignore draggables that have backwards partial visiblility', () => {\n        const center: Position = patch(\n          axis.line,\n          partiallyHiddenBackwards.page.borderBox.center[axis.line],\n          100,\n        );\n\n        const result: ?DraggableDimension = getClosestDraggable({\n          pageBorderBoxCenter: center,\n          destination: droppable,\n          insideDestination,\n          viewport,\n          afterCritical: noAfterCritical,\n        });\n\n        expect(result).toBe(visible1);\n      });\n\n      it('should ignore draggables that have forward partial visiblility', () => {\n        const center: Position = patch(\n          axis.line,\n          partiallyHiddenForwards.page.borderBox.center[axis.line],\n          100,\n        );\n\n        const result: ?DraggableDimension = getClosestDraggable({\n          pageBorderBoxCenter: center,\n          destination: droppable,\n          insideDestination,\n          viewport,\n          afterCritical: noAfterCritical,\n        });\n\n        expect(result).toBe(visible2);\n      });\n\n      it('should ignore draggables forward that have no visiblity', () => {\n        const center: Position = patch(\n          axis.line,\n          hiddenForwards.page.borderBox.center[axis.line],\n          100,\n        );\n\n        const result: ?DraggableDimension = getClosestDraggable({\n          pageBorderBoxCenter: center,\n          destination: droppable,\n          insideDestination,\n          viewport,\n          afterCritical: noAfterCritical,\n        });\n\n        expect(result).toBe(visible2);\n      });\n\n      it('should ignore draggables that are outside of the viewport', () => {\n        const center: Position = patch(\n          axis.line,\n          outOfViewport.page.borderBox.center[axis.line],\n          100,\n        );\n\n        const result: ?DraggableDimension = getClosestDraggable({\n          pageBorderBoxCenter: center,\n          destination: droppable,\n          insideDestination,\n          viewport,\n          afterCritical: noAfterCritical,\n        });\n\n        expect(result).toBe(visible2);\n      });\n\n      it('should return null if there are no visible targets', () => {\n        const notVisible: DraggableDimension[] = [\n          hiddenBackwards,\n          hiddenForwards,\n          outOfViewport,\n        ];\n        const center: Position = {\n          x: 0,\n          y: 0,\n        };\n\n        const result: ?DraggableDimension = getClosestDraggable({\n          pageBorderBoxCenter: center,\n          destination: droppable,\n          insideDestination: notVisible,\n          viewport,\n          afterCritical: noAfterCritical,\n        });\n\n        expect(result).toBe(null);\n      });\n    });\n\n    it('should return the draggable that is first on the main axis in the event of a tie', () => {\n      // in this case the distance between visible1 and visible2 is the same\n      const center: Position = patch(\n        axis.line,\n        // this is shared edge\n        visible2.page.borderBox[axis.start],\n        100,\n      );\n\n      const result: ?DraggableDimension = getClosestDraggable({\n        pageBorderBoxCenter: center,\n        destination: droppable,\n        insideDestination,\n        viewport,\n        afterCritical: noAfterCritical,\n      });\n\n      expect(result).toBe(visible1);\n\n      // validating test assumptions\n\n      // 1. that they have equal distances\n      expect(distance(center, visible1.page.borderBox.center)).toEqual(\n        distance(center, visible2.page.borderBox.center),\n      );\n\n      // 2. if we move beyond the edge visible2 will be selected\n      const result2: ?DraggableDimension = getClosestDraggable({\n        pageBorderBoxCenter: add(center, patch(axis.line, 1)),\n        destination: droppable,\n        insideDestination,\n        viewport,\n        afterCritical: noAfterCritical,\n      });\n      expect(result2).toBe(visible2);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-cross-axis/move-to-new-droppable/to-foreign-list.spec.js",
    "content": "// @flow\nimport type { BoxModel, Position, Spacing } from 'css-box-model';\nimport type {\n  Viewport,\n  Axis,\n  DragImpact,\n  DroppableDimension,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport { invariant } from '../../../../../../src/invariant';\nimport { horizontal, vertical } from '../../../../../../src/state/axis';\nimport scrollDroppable from '../../../../../../src/state/droppable/scroll-droppable';\nimport { goIntoStart } from '../../../../../../src/state/get-center-from-impact/move-relative-to';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport moveToNewDroppable from '../../../../../../src/state/move-in-direction/move-cross-axis/move-to-new-droppable';\nimport {\n  add,\n  negate,\n  patch,\n  subtract,\n} from '../../../../../../src/state/position';\nimport scrollViewport from '../../../../../../src/state/scroll-viewport';\nimport { offsetByPosition } from '../../../../../../src/state/spacing';\nimport {\n  getDroppableDimension,\n  getPreset,\n  makeScrollable,\n} from '../../../../../util/dimension';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport {\n  emptyGroups,\n  noDisplacedBy,\n} from '../../../../../../src/state/no-impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const viewport: Viewport = preset.viewport;\n\n    describe('moving into an unpopulated list', () => {\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n\n      it('should move into the first position of the list', () => {\n        const result: ?DragImpact = moveToNewDroppable({\n          previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          moveRelativeTo: null,\n          destination: preset.emptyForeign,\n          insideDestination: [],\n          viewport,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expected: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy: noDisplacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.emptyForeign.descriptor.id,\n              index: 0,\n            },\n          },\n        };\n\n        expect(result).toEqual(expected);\n      });\n\n      describe('only move into first position if it is visible', () => {\n        const distanceToContentBoxStart = (box: BoxModel): number =>\n          box.margin[axis.start] +\n          box.border[axis.start] +\n          box.padding[axis.start];\n\n        it('should not move into the start of list if the position is not visible due to droppable scroll', () => {\n          const whatNewCenterWouldBeWithoutScroll: Position = goIntoStart({\n            axis,\n            moveInto: preset.emptyForeign.page,\n            isMoving: preset.inHome1.page,\n          });\n          const totalShift: Position = subtract(\n            whatNewCenterWouldBeWithoutScroll,\n            preset.inHome1.page.borderBox.center,\n          );\n          const shiftedInHome1Page: Spacing = offsetByPosition(\n            preset.inHome1.page.borderBox,\n            totalShift,\n          );\n          invariant(preset.emptyForeign.subject.active);\n          const maxAllowableScroll: Position = negate(\n            subtract(\n              patch(axis.line, preset.emptyForeign.subject.active[axis.start]),\n              patch(axis.line, shiftedInHome1Page[axis.start]),\n            ),\n          );\n          const pastMaxAllowableScroll: Position = add(\n            maxAllowableScroll,\n            patch(axis.line, 1),\n          );\n\n          // validation: no scrolled droppable\n          {\n            const result: ?DragImpact = moveToNewDroppable({\n              previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              moveRelativeTo: null,\n              destination: preset.emptyForeign,\n              insideDestination: [],\n              viewport,\n              afterCritical,\n            });\n            expect(result).toBeTruthy();\n          }\n\n          // center on visible edge = can move\n          {\n            const scrollable: DroppableDimension = makeScrollable(\n              preset.foreign,\n              maxAllowableScroll[axis.line],\n            );\n            const scrolled: DroppableDimension = scrollDroppable(\n              scrollable,\n              maxAllowableScroll,\n            );\n\n            const result: ?DragImpact = moveToNewDroppable({\n              previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              moveRelativeTo: null,\n              destination: scrolled,\n              insideDestination: [],\n              viewport,\n              afterCritical,\n            });\n            expect(result).toBeTruthy();\n          }\n          // center past visible edge = cannot move\n          {\n            const scrollable: DroppableDimension = makeScrollable(\n              preset.emptyForeign,\n              pastMaxAllowableScroll[axis.line],\n            );\n            const scrolled: DroppableDimension = scrollDroppable(\n              scrollable,\n              pastMaxAllowableScroll,\n            );\n            const result: ?DragImpact = moveToNewDroppable({\n              previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              moveRelativeTo: null,\n              destination: scrolled,\n              insideDestination: [],\n              viewport,\n              afterCritical,\n            });\n\n            expect(result).toBe(null);\n          }\n        });\n\n        it('should not move into the start of list if the position is not visible due to page scroll', () => {\n          const emptyForeignPageBox: BoxModel = preset.emptyForeign.page;\n\n          // How far to the start of the droppable content box?\n          const distanceToStartOfDroppableContextBox: number =\n            emptyForeignPageBox.marginBox[axis.start] +\n            distanceToContentBoxStart(emptyForeignPageBox);\n\n          const onVisibleStartEdge: Position = patch(\n            axis.line,\n            distanceToStartOfDroppableContextBox +\n              preset.inHome1.page.margin[axis.start],\n          );\n          const pastVisibleStartEdge: Position = add(\n            onVisibleStartEdge,\n            patch(axis.line, 1),\n          );\n          // validate with no scroll\n          {\n            const result: ?DragImpact = moveToNewDroppable({\n              previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              destination: preset.emptyForeign,\n              moveRelativeTo: null,\n              insideDestination: [],\n              viewport,\n              afterCritical,\n            });\n\n            expect(result).toBeTruthy();\n          }\n          // center on visible edge = can move\n          {\n            const scrolled: Viewport = scrollViewport(\n              viewport,\n              onVisibleStartEdge,\n            );\n\n            const result: ?DragImpact = moveToNewDroppable({\n              previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              destination: preset.emptyForeign,\n              moveRelativeTo: null,\n              insideDestination: [],\n              viewport: scrolled,\n              afterCritical,\n            });\n\n            expect(result).toBeTruthy();\n          }\n          // start is no longer visible = cannot move\n          {\n            const scrolled: Viewport = scrollViewport(\n              viewport,\n              pastVisibleStartEdge,\n            );\n\n            const result: ?DragImpact = moveToNewDroppable({\n              previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n              draggable: preset.inHome1,\n              draggables: preset.draggables,\n              moveRelativeTo: null,\n              destination: preset.emptyForeign,\n              insideDestination: [],\n              viewport: scrolled,\n              afterCritical,\n            });\n\n            expect(result).toBe(null);\n          }\n        });\n\n        it('should allow a big item to move into a smaller list', () => {\n          const crossAxisStart: number =\n            preset.home.client.marginBox[axis.crossAxisEnd] + 1;\n          const smallDroppable: DroppableDimension = getDroppableDimension({\n            descriptor: {\n              id: 'small',\n              type: preset.home.descriptor.type,\n              mode: 'standard',\n            },\n            // currently no room in the box\n            borderBox: {\n              [axis.crossAxisStart]: crossAxisStart,\n              [axis.crossAxisEnd]: crossAxisStart,\n              [axis.start]: 0,\n              [axis.end]: 0,\n            },\n            direction: axis.direction,\n            windowScroll: preset.windowScroll,\n          });\n\n          const result: ?DragImpact = moveToNewDroppable({\n            previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n            draggable: preset.inHome1,\n            draggables: preset.draggables,\n            moveRelativeTo: null,\n            destination: smallDroppable,\n            insideDestination: [],\n            viewport,\n            afterCritical,\n          });\n\n          expect(result).toBeTruthy();\n        });\n      });\n    });\n\n    describe('is going before a target', () => {\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        preset.inHome1.displaceBy,\n      );\n\n      it('should move the target and everything below it forward', () => {\n        // moving home1 into the second position of the list\n\n        const result: ?DragImpact = moveToNewDroppable({\n          previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          // moving before target\n          moveRelativeTo: preset.inForeign2,\n          destination: preset.foreign,\n          insideDestination: preset.inForeignList,\n          viewport,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // ordered by closest impacted\n            visible: [\n              { dimension: preset.inForeign2 },\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign2.descriptor.index,\n            },\n          },\n        };\n\n        expect(result).toEqual(expected);\n      });\n    });\n\n    describe('is going after a target', () => {\n      it('should move the target and everything below it forward', () => {\n        // moving inHome3 relative to inForeign1 (will go after inForeign1)\n        const { afterCritical } = getLiftEffect({\n          draggable: preset.inHome1,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome3.displaceBy,\n        );\n        const result: ?DragImpact = moveToNewDroppable({\n          previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n          draggable: preset.inHome3,\n          draggables: preset.draggables,\n          // moving relative to inForeign1\n          // will actually go after it\n          moveRelativeTo: preset.inForeign1,\n          destination: preset.foreign,\n          insideDestination: preset.inForeignList,\n          viewport,\n          afterCritical,\n        });\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // everything after inForeign1\n            // ordered by closest impacted\n            visible: [\n              { dimension: preset.inForeign2 },\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign2.descriptor.index,\n            },\n          },\n        };\n        expect(result).toEqual(expected);\n      });\n    });\n\n    describe('is moving after the last position of a list', () => {\n      it('should go after the non-displaced last item in the list', () => {\n        // Moving inHome4 relative to inForeign1\n        // Stripping out all the other items in the foreign so that we\n        // are sure to move after the last item (inForeign1)\n        const { afterCritical } = getLiftEffect({\n          draggable: preset.inHome4,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome4.displaceBy,\n        );\n\n        const result: ?DragImpact = moveToNewDroppable({\n          previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n          draggable: preset.inHome4,\n          draggables: preset.draggables,\n          moveRelativeTo: preset.inForeign1,\n          destination: preset.foreign,\n          insideDestination: [preset.inForeign1],\n          viewport,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expected: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign1.descriptor.index + 1,\n            },\n          },\n        };\n        expect(result).toEqual(expected);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-cross-axis/move-to-new-droppable/to-home-list.spec.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport type {\n  Viewport,\n  Axis,\n  DragImpact,\n  DisplacedBy,\n} from '../../../../../../src/types';\nimport { invariant } from '../../../../../../src/invariant';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport moveToNewDroppable from '../../../../../../src/state/move-in-direction/move-cross-axis/move-to-new-droppable';\nimport { getPreset } from '../../../../../util/dimension';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport { emptyGroups } from '../../../../../../src/state/no-impact';\n\nconst dontCare: Position = { x: 0, y: 0 };\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const viewport: Viewport = preset.viewport;\n\n    it('should not to anything if there is not target (can happen if invisible)', () => {\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome2,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n\n      expect(\n        moveToNewDroppable({\n          previousPageBorderBoxCenter: dontCare,\n          destination: preset.home,\n          insideDestination: preset.inHomeList,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          moveRelativeTo: null,\n          viewport,\n          afterCritical,\n        }),\n      ).toBe(null);\n    });\n\n    describe('moving back into original index', () => {\n      it('should return a home impact with the original location', () => {\n        // the second draggable is moving back into its preset.home\n        const { afterCritical } = getLiftEffect({\n          draggable: preset.inHome2,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome2.displaceBy,\n        );\n\n        const result: ?DragImpact = moveToNewDroppable({\n          previousPageBorderBoxCenter: dontCare,\n          draggable: preset.inHome2,\n          draggables: preset.draggables,\n          moveRelativeTo: preset.inHome2,\n          destination: preset.home,\n          insideDestination: preset.inHomeList,\n          viewport,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // unlike the original displacement, this will be animated\n            visible: [\n              { dimension: preset.inHome3 },\n              { dimension: preset.inHome4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome2.descriptor.index,\n            },\n          },\n        };\n        expect(result).toEqual(expected);\n      });\n    });\n\n    describe('moving before the original index', () => {\n      it('should move the everything after the target index forward', () => {\n        // moving preset.inHome4 into the preset.inHome2 position\n        const { afterCritical } = getLiftEffect({\n          draggable: preset.inHome4,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome4.displaceBy,\n        );\n\n        const result: ?DragImpact = moveToNewDroppable({\n          previousPageBorderBoxCenter: dontCare,\n          draggable: preset.inHome4,\n          draggables: preset.draggables,\n          moveRelativeTo: preset.inHome2,\n          destination: preset.home,\n          insideDestination: preset.inHomeList,\n          viewport,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inHome2 },\n              { dimension: preset.inHome3 },\n              // inHome4 not displaced!\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome2.descriptor.index,\n            },\n          },\n        };\n        expect(result).toEqual(expected);\n      });\n    });\n\n    describe('moving after the original index', () => {\n      it('should move the everything from the target index to the original index forward', () => {\n        // moving inHome1 after inHome4\n        const { afterCritical } = getLiftEffect({\n          draggable: preset.inHome1,\n          home: preset.home,\n          draggables: preset.draggables,\n          viewport: preset.viewport,\n        });\n        const displacedBy: DisplacedBy = getDisplacedBy(\n          axis,\n          preset.inHome1.displaceBy,\n        );\n        const result: ?DragImpact = moveToNewDroppable({\n          previousPageBorderBoxCenter: dontCare,\n          draggable: preset.inHome1,\n          draggables: preset.draggables,\n          moveRelativeTo: preset.inHome4,\n          destination: preset.home,\n          insideDestination: preset.inHomeList,\n          viewport,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expected: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome4.descriptor.index,\n            },\n          },\n        };\n        expect(result).toEqual(expected);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-cross-axis/no-visible-targets-in-list.spec.js",
    "content": "// @flow\nimport type { PublicResult } from '../../../../../src/state/move-in-direction/move-in-direction-types';\nimport type {\n  Viewport,\n  DraggableDimension,\n  DroppableDimension,\n  DraggableDimensionMap,\n  DroppableDimensionMap,\n} from '../../../../../src/types';\nimport moveCrossAxis from '../../../../../src/state/move-in-direction/move-cross-axis';\nimport getViewport from '../../../../../src/view/window/get-viewport';\nimport {\n  getPreset,\n  getDroppableDimension,\n  getDraggableDimension,\n} from '../../../../util/dimension';\nimport getLiftEffect from '../../../../../src/state/get-lift-effect';\n\nconst preset = getPreset();\nconst viewport: Viewport = getViewport();\n\n// The functionality of move-cross-axis is covered by other files in this folder.\n// This spec file is directed any any logic in move-cross-axis/index.js\n\nit('should return null if there are draggables in a destination list but none are visible', () => {\n  const custom: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'custom',\n      type: 'TYPE',\n      mode: 'standard',\n    },\n    borderBox: {\n      left: preset.home.client.borderBox.left + 1,\n      right: preset.home.client.borderBox.left + 10,\n      top: 0,\n      bottom: viewport.frame.bottom + 200,\n    },\n  });\n  const notVisible: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'not-visible',\n      droppableId: custom.descriptor.id,\n      type: custom.descriptor.type,\n      index: 0,\n    },\n    borderBox: {\n      left: preset.home.client.borderBox.left + 1,\n      right: preset.home.client.borderBox.left + 10,\n      // outside of the viewport\n      top: viewport.frame.bottom + 1,\n      bottom: viewport.frame.bottom + 10,\n    },\n  });\n  const draggables: DraggableDimensionMap = {\n    ...preset.draggables,\n    [notVisible.descriptor.id]: notVisible,\n  };\n  const droppables: DroppableDimensionMap = {\n    [preset.home.descriptor.id]: preset.home,\n    [custom.descriptor.id]: custom,\n  };\n  const { afterCritical } = getLiftEffect({\n    draggable: preset.inHome1,\n    draggables,\n    home: preset.home,\n    viewport: preset.viewport,\n  });\n\n  const result: ?PublicResult = moveCrossAxis({\n    isMovingForward: true,\n    previousPageBorderBoxCenter: preset.inHome1.page.borderBox.center,\n    draggable: preset.inHome1,\n    isOver: preset.home,\n    draggables,\n    droppables,\n    viewport,\n    afterCritical,\n  });\n\n  expect(result).toBe(null);\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-in-direction.spec.js",
    "content": "// @flow\nimport type {\n  DraggableLocation,\n  DraggingState,\n  DroppableDimension,\n  Axis,\n} from '../../../../src/types';\nimport { invariant } from '../../../../src/invariant';\nimport type { PublicResult } from '../../../../src/state/move-in-direction/move-in-direction-types';\nimport moveInDirection from '../../../../src/state/move-in-direction';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport { getPreset, disableDroppable } from '../../../util/dimension';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport { tryGetDestination } from '../../../../src/state/get-impact-location';\n\ndescribe('on the vertical axis', () => {\n  const preset = getPreset(vertical);\n  const state = getStatePreset(vertical);\n\n  it('should move forward on a MOVE_DOWN', () => {\n    const result: ?PublicResult = moveInDirection({\n      state: state.dragging(),\n      type: 'MOVE_DOWN',\n    });\n\n    invariant(result, 'expected a result');\n    const expected: DraggableLocation = {\n      droppableId: preset.home.descriptor.id,\n      index: 1,\n    };\n    expect(tryGetDestination(result.impact)).toEqual(expected);\n  });\n\n  it('should move backwards on a MOVE_UP', () => {\n    const result: ?PublicResult = moveInDirection({\n      state: state.dragging(preset.inHome2.descriptor.id),\n      type: 'MOVE_UP',\n    });\n\n    invariant(result, 'expected a result');\n    const expected: DraggableLocation = {\n      droppableId: preset.home.descriptor.id,\n      index: 0,\n    };\n    expect(tryGetDestination(result.impact)).toEqual(expected);\n  });\n\n  it('should move cross axis forwards on a MOVE_RIGHT', () => {\n    const result: ?PublicResult = moveInDirection({\n      state: state.dragging(),\n      type: 'MOVE_RIGHT',\n    });\n\n    invariant(result, 'expected a result');\n    const expected: DraggableLocation = {\n      droppableId: preset.foreign.descriptor.id,\n      index: 1,\n    };\n    expect(tryGetDestination(result.impact)).toEqual(expected);\n  });\n\n  it('should move cross axis backwards on a MOVE_LEFT', () => {\n    const result: ?PublicResult = moveInDirection({\n      state: state.dragging(preset.inForeign1.descriptor.id),\n      type: 'MOVE_LEFT',\n    });\n\n    invariant(result, 'expected a result');\n    const expected: DraggableLocation = {\n      droppableId: preset.home.descriptor.id,\n      index: 0,\n    };\n    expect(tryGetDestination(result.impact)).toEqual(expected);\n  });\n});\n\ndescribe('on the horizontal axis', () => {\n  const preset = getPreset(horizontal);\n  const state = getStatePreset(horizontal);\n\n  it('should move forward on a MOVE_RIGHT', () => {\n    const result: ?PublicResult = moveInDirection({\n      state: state.dragging(),\n      type: 'MOVE_RIGHT',\n    });\n\n    invariant(result, 'expected a result');\n    const expected: DraggableLocation = {\n      droppableId: preset.home.descriptor.id,\n      index: 1,\n    };\n    expect(tryGetDestination(result.impact)).toEqual(expected);\n  });\n\n  it('should move backwards on a MOVE_LEFT', () => {\n    const result: ?PublicResult = moveInDirection({\n      state: state.dragging(preset.inHome2.descriptor.id),\n      type: 'MOVE_LEFT',\n    });\n\n    invariant(result, 'expected a result');\n    const expected: DraggableLocation = {\n      droppableId: preset.home.descriptor.id,\n      index: 0,\n    };\n    expect(tryGetDestination(result.impact)).toEqual(expected);\n  });\n\n  it('should move cross axis forwards on a MOVE_DOWN', () => {\n    const result: ?PublicResult = moveInDirection({\n      state: state.dragging(),\n      type: 'MOVE_DOWN',\n    });\n\n    invariant(result, 'expected a result');\n    const expected: DraggableLocation = {\n      droppableId: preset.foreign.descriptor.id,\n      index: 1,\n    };\n    expect(tryGetDestination(result.impact)).toEqual(expected);\n  });\n\n  it('should move cross axis backwards on a MOVE_UP', () => {\n    const result: ?PublicResult = moveInDirection({\n      state: state.dragging(preset.inForeign1.descriptor.id),\n      type: 'MOVE_UP',\n    });\n\n    invariant(result, 'expected a result');\n    const expected: DraggableLocation = {\n      droppableId: preset.home.descriptor.id,\n      index: 0,\n    };\n    expect(tryGetDestination(result.impact)).toEqual(expected);\n  });\n});\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const state = getStatePreset(axis);\n  const preset = getPreset(axis);\n\n  describe(`main axis blocking in the ${axis.direction} direction`, () => {\n    it('should not allow movement on the main axis if lifting in a disabled droppable', () => {\n      const custom: DraggingState = state.dragging();\n\n      // no destination when lifting in disabled droppable\n      custom.impact.at = null;\n      // disabling the droppable for good measure\n      const critical: DroppableDimension =\n        custom.dimensions.droppables[custom.critical.droppable.id];\n      custom.dimensions.droppables[\n        custom.critical.droppable.id\n      ] = disableDroppable(critical);\n\n      // Main axis movement not allowed\n      const forward = axis.direction === 'vertical' ? 'MOVE_DOWN' : 'MOVE_LEFT';\n      const backward = axis.direction === 'vertical' ? 'MOVE_UP' : 'MOVE_RIGHT';\n      expect(\n        moveInDirection({\n          state: custom,\n          type: forward,\n        }),\n      ).toBe(null);\n      expect(\n        moveInDirection({\n          state: custom,\n          type: backward,\n        }),\n      ).toBe(null);\n\n      // cross axis movement allowed\n      const crossAxisForward =\n        axis.direction === 'vertical' ? 'MOVE_RIGHT' : 'MOVE_DOWN';\n\n      const result: ?PublicResult = moveInDirection({\n        state: state.dragging(),\n        type: crossAxisForward,\n      });\n\n      invariant(result, 'expected a result');\n      const expected: DraggableLocation = {\n        droppableId: preset.foreign.descriptor.id,\n        index: 1,\n      };\n      expect(tryGetDestination(result.impact)).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-to-next-place/move-to-next-combine/in-foreign-list.legacy.spec.js",
    "content": "// @flow\nimport type {\n  Axis,\n  DragImpact,\n  DisplacedBy,\n  DroppableDimension,\n} from '../../../../../../src/types';\nimport { invariant } from '../../../../../../src/invariant';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport { getPreset } from '../../../../../util/dimension';\nimport moveToNextCombine from '../../../../../../src/state/move-in-direction/move-to-next-place/move-to-next-combine/index';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport { emptyGroups } from '../../../../../../src/state/no-impact';\n\nconst enableCombine = (droppable: DroppableDimension): DroppableDimension => ({\n  ...droppable,\n  isCombineEnabled: true,\n});\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const preset = getPreset(axis);\n\n  // always displace forward in foreign list\n  const displacedBy: DisplacedBy = getDisplacedBy(\n    axis,\n    preset.inHome1.displaceBy,\n  );\n\n  describe(`on ${axis.direction} axis`, () => {\n    it('should move onto a displaced item when moving forwards', () => {\n      // inHome1 cross axis moved after inForeign1,\n      // now moving forward onto inForeign2\n      const current: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inForeign2.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextCombine({\n        isMovingForward: true,\n        draggable: preset.inHome1,\n        destination: enableCombine(preset.foreign),\n        insideDestination: preset.inForeignList,\n        previousImpact: current,\n      });\n      invariant(result);\n\n      const expected: DragImpact = {\n        ...current,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inForeign2.descriptor.id,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should move onto a non-displaced item when moving backwards', () => {\n      // inHome1 in foreign list after inForeign2\n      // moving backwards will move it onto the non-displaced inForeign2\n      // ordered by closest impacted\n      const current: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inForeign3.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextCombine({\n        isMovingForward: false,\n        draggable: preset.inHome1,\n        destination: enableCombine(preset.foreign),\n        insideDestination: preset.inForeignList,\n        previousImpact: current,\n      });\n      invariant(result);\n\n      // no change to displacement\n      const expected: DragImpact = {\n        ...current,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inForeign2.descriptor.id,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should not allow combining with anything before the first item', () => {\n      const current: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign1 },\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          // in first position\n          destination: {\n            index: preset.inForeign1.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextCombine({\n        isMovingForward: false,\n        draggable: preset.inHome1,\n        destination: enableCombine(preset.foreign),\n        insideDestination: preset.inForeignList,\n        previousImpact: current,\n      });\n\n      expect(result).toEqual(null);\n    });\n\n    it('should not allow combining with anything after the last item', () => {\n      // in last position\n      const current: DragImpact = {\n        displaced: emptyGroups,\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          // in last position\n          destination: {\n            index: preset.inForeign4.descriptor.index + 1,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextCombine({\n        isMovingForward: true,\n        draggable: preset.inHome1,\n        destination: enableCombine(preset.foreign),\n        insideDestination: preset.inForeignList,\n        previousImpact: current,\n      });\n\n      expect(result).toEqual(null);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-to-next-place/move-to-next-combine/in-home-list.legacy.spec.js",
    "content": "// @flow\nimport type {\n  Axis,\n  DragImpact,\n  DroppableDimension,\n} from '../../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport { invariant } from '../../../../../../src/invariant';\nimport { getPreset } from '../../../../../util/dimension';\nimport moveToNextCombine from '../../../../../../src/state/move-in-direction/move-to-next-place/move-to-next-combine/index';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../../../../util/impact';\n\nconst enableCombine = (droppable: DroppableDimension): DroppableDimension => ({\n  ...droppable,\n  isCombineEnabled: true,\n});\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const preset = getPreset(axis);\n  describe(`on ${axis.direction} axis`, () => {\n    it('should move onto an item that started displaced', () => {\n      const { impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        home: preset.home,\n        viewport: preset.viewport,\n      });\n\n      const result: ?DragImpact = moveToNextCombine({\n        isMovingForward: true,\n        draggable: preset.inHome2,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: homeImpact,\n      });\n      invariant(result);\n\n      const expected: DragImpact = {\n        ...homeImpact,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome3.descriptor.id,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should move onto an item that started displaced - but now is not', () => {\n      // inHome2 moved forward past inHome3 and now moving back onto inHome3\n\n      const pastInHome3: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome2.displaceBy),\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inHome3.descriptor.index,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n      const moveBackwardsOntoInHome3: ?DragImpact = moveToNextCombine({\n        isMovingForward: false,\n        draggable: preset.inHome2,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: pastInHome3,\n      });\n      invariant(moveBackwardsOntoInHome3);\n\n      const expected: DragImpact = {\n        ...pastInHome3,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome3.descriptor.id,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n      expect(moveBackwardsOntoInHome3).toEqual(expected);\n    });\n\n    it('should move onto an item that did not start displaced', () => {\n      // moving inHome3 backwards onto inHome2\n      const { impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome3,\n        draggables: preset.draggables,\n        home: preset.home,\n        viewport: preset.viewport,\n      });\n\n      const result: ?DragImpact = moveToNextCombine({\n        isMovingForward: false,\n        draggable: preset.inHome3,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: homeImpact,\n      });\n      invariant(result);\n\n      const expected: DragImpact = {\n        ...homeImpact,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome2.descriptor.id,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should move onto an item that did not start displaced but now is', () => {\n      // inHome3 moved backward before inHome2 and now moving back onto inHome2\n\n      const beforeInHome2: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inHome2 },\n            // originally displaced\n            { dimension: preset.inHome4, shouldAnimate: false },\n          ],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome3.displaceBy),\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inHome2.descriptor.index,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n\n      const moveForwardsOntoInHome2: ?DragImpact = moveToNextCombine({\n        isMovingForward: true,\n        draggable: preset.inHome3,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: beforeInHome2,\n      });\n      invariant(moveForwardsOntoInHome2);\n\n      const expected: DragImpact = {\n        ...beforeInHome2,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome2.descriptor.id,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n      expect(moveForwardsOntoInHome2).toEqual(expected);\n    });\n\n    it('should not allow combining with anything before the first item', () => {\n      const { impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n\n      const result: ?DragImpact = moveToNextCombine({\n        isMovingForward: false,\n        draggable: preset.inHome1,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: homeImpact,\n      });\n\n      expect(result).toBe(null);\n    });\n\n    it('should not allow combining with anything after the last item', () => {\n      const { impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome4,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n\n      const result: ?DragImpact = moveToNextCombine({\n        isMovingForward: true,\n        draggable: preset.inHome1,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: homeImpact,\n      });\n\n      expect(result).toBe(null);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-to-next-place/move-to-next-index/from-combine/did-not-start-after-critical.spec.js",
    "content": "// @flow\nimport type {\n  Axis,\n  DragImpact,\n  DroppableDimension,\n} from '../../../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../../../src/state/axis';\nimport { getPreset } from '../../../../../../util/dimension';\nimport moveToNextIndex from '../../../../../../../src/state/move-in-direction/move-to-next-place/move-to-next-index/index';\nimport getDisplacedBy from '../../../../../../../src/state/get-displaced-by';\nimport getLiftEffect from '../../../../../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../../../../../util/impact';\n\nconst enableCombine = (droppable: DroppableDimension): DroppableDimension => ({\n  ...droppable,\n  isCombineEnabled: true,\n});\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const preset = getPreset(axis);\n  describe(`on ${axis.direction} axis`, () => {\n    it('should move forward off combining with is displaced', () => {\n      // Setup: inHome1 combining with inForeign1 and then moving forward past it\n      // Expected: inHome1 moves after inForeign1 and inForeign1 is no longer displaced\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const combining: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign1 },\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome1.displaceBy),\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inForeign1.descriptor.id,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextIndex({\n        isMovingForward: true,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: enableCombine(preset.foreign),\n        insideDestination: preset.inForeignList,\n        previousImpact: combining,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n\n      const expected: DragImpact = {\n        // inForeign1 no longer displaced\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome1.displaceBy),\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inForeign2.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should move backward off combining with is displaced', () => {\n      // Setup: inHome1 combining with inForeign1 and then moving backward before it\n      // Expected: inHome1 goes before inForeign1 and displacement is not changed\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const combining: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign1 },\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome1.displaceBy),\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inForeign1.descriptor.id,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextIndex({\n        isMovingForward: false,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: enableCombine(preset.foreign),\n        insideDestination: preset.inForeignList,\n        previousImpact: combining,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n\n      const expected: DragImpact = {\n        ...combining,\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inForeign1.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should move forward off combining with a non-displaced item', () => {\n      // Setup\n      // - inHome1 past inForeign1\n      // - inHome1 moves backwards onto inForeign1\n      // - inHome1 moves forwards off inForeign1\n      // Expected\n      // - inHome1 moves before inForeign1\n      // - inForeign1 becomes displaced\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const combining: DragImpact = {\n        displaced: getForcedDisplacement({\n          // inForeign1 is not displaced\n          visible: [\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome1.displaceBy),\n        // moved backward onto inForeign1\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inForeign1.descriptor.id,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextIndex({\n        isMovingForward: true,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: enableCombine(preset.foreign),\n        insideDestination: preset.inForeignList,\n        previousImpact: combining,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n\n      const expected: DragImpact = {\n        displaced: getForcedDisplacement({\n          // inForeign1 still not displaced\n          visible: [\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome1.displaceBy),\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inForeign2.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      expect(result).toEqual(expected);\n    });\n\n    it('should move backward off combining with a non-displaced item', () => {\n      // Setup\n      // - inHome1 past inForeign1\n      // - inHome1 moves backwards onto inForeign1\n      // - inHome1 moves backwards off inForeign1\n      // Expected\n      // - inHome1 moves forward off inForeign1\n      // - no displacement changes\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome1,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const combining: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            // inForeign1 not displaced\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome1.displaceBy),\n        at: {\n          // moved backward onto inForeign1\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inForeign1.descriptor.id,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextIndex({\n        isMovingForward: false,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: enableCombine(preset.foreign),\n        insideDestination: preset.inForeignList,\n        previousImpact: combining,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n\n      const expected: DragImpact = {\n        displaced: getForcedDisplacement({\n          // inForeign1 now displaced\n          visible: [\n            { dimension: preset.inForeign1 },\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome1.displaceBy),\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inForeign1.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-to-next-place/move-to-next-index/from-combine/started-after-critical.spec.js",
    "content": "// @flow\nimport type {\n  Axis,\n  DragImpact,\n  DroppableDimension,\n} from '../../../../../../../src/types';\nimport { vertical, horizontal } from '../../../../../../../src/state/axis';\nimport { getPreset } from '../../../../../../util/dimension';\nimport moveToNextIndex from '../../../../../../../src/state/move-in-direction/move-to-next-place/move-to-next-index/index';\nimport getDisplacedBy from '../../../../../../../src/state/get-displaced-by';\nimport getLiftEffect from '../../../../../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../../../../../util/impact';\n\nconst enableCombine = (droppable: DroppableDimension): DroppableDimension => ({\n  ...droppable,\n  isCombineEnabled: true,\n});\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const preset = getPreset(axis);\n  describe(`on ${axis.direction} axis`, () => {\n    it('should move backward off combining with an item that is displaced', () => {\n      // inHome2 combining with inHome3\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome2,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const combining: DragImpact = {\n        ...homeImpact,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome3.descriptor.id,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: false,\n        isInHomeList: true,\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: combining,\n        afterCritical,\n      });\n\n      expect(result).toEqual(homeImpact);\n    });\n\n    it('should move forward past a combining an item that is displaced', () => {\n      // inHome2 combining with inHome3\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome2,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const combining: DragImpact = {\n        ...homeImpact,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome3.descriptor.id,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: true,\n        isInHomeList: true,\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: combining,\n        afterCritical,\n      });\n\n      const expected: DragImpact = {\n        displaced: getForcedDisplacement({\n          // inHome3 now displaced\n          visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome2.displaceBy),\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inHome3.descriptor.index,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should move backwards past combining with an item that started displaced - but now is not', () => {\n      // inHome2 moved past inHome3 and then backwards onto it\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome2,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n      const combining: DragImpact = {\n        displaced: getForcedDisplacement({\n          // inHome3 now displaced\n          visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome2.displaceBy),\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome3.descriptor.id,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: false,\n        isInHomeList: true,\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: combining,\n        afterCritical,\n      });\n\n      // backwards movement should displace inHome3\n      const expected: DragImpact = {\n        displaced: getForcedDisplacement({\n          // inHome3 now displaced\n          visible: [\n            { dimension: preset.inHome3, shouldAnimate: true },\n            { dimension: preset.inHome4, shouldAnimate: false },\n          ],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome2.displaceBy),\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inHome2.descriptor.index,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should move forwards past combining with an item that started displaced - but now is not', () => {\n      // inHome2 moved past inHome3 and then backwards onto it\n      const { afterCritical } = getLiftEffect({\n        draggable: preset.inHome2,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n\n      const combining: DragImpact = {\n        displaced: getForcedDisplacement({\n          // preset.inHome3 is no longer displaced\n          visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome2.displaceBy),\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome3.descriptor.id,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n\n      const result: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: true,\n        isInHomeList: true,\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        destination: enableCombine(preset.home),\n        insideDestination: preset.inHomeList,\n        previousImpact: combining,\n        afterCritical,\n      });\n\n      const expected: DragImpact = {\n        // forwards movement off inHome3. It will leave inHome3 in the same spot and go after it\n        displaced: getForcedDisplacement({\n          visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n        }),\n        displacedBy: getDisplacedBy(axis, preset.inHome2.displaceBy),\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inHome3.descriptor.index,\n            droppableId: preset.home.descriptor.id,\n          },\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-to-next-place/move-to-next-index/from-reorder/in-foreign-list.spec.js",
    "content": "// @flow\nimport type {\n  Axis,\n  DragImpact,\n  DisplacedBy,\n} from '../../../../../../../src/types';\nimport { invariant } from '../../../../../../../src/invariant';\nimport { vertical, horizontal } from '../../../../../../../src/state/axis';\nimport { getPreset } from '../../../../../../util/dimension';\nimport moveToNextIndex from '../../../../../../../src/state/move-in-direction/move-to-next-place/move-to-next-index';\nimport getDisplacedBy from '../../../../../../../src/state/get-displaced-by';\nimport getLiftEffect from '../../../../../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../../../../../util/impact';\nimport { emptyGroups } from '../../../../../../../src/state/no-impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const preset = getPreset(axis);\n  const displacedBy: DisplacedBy = getDisplacedBy(\n    axis,\n    preset.inHome1.displaceBy,\n  );\n  const { afterCritical } = getLiftEffect({\n    draggable: preset.inHome1,\n    home: preset.home,\n    draggables: preset.draggables,\n    viewport: preset.viewport,\n  });\n  describe(`on ${axis.direction} axis`, () => {\n    // it was cleaner for these scenarios to be batched together into a clean flow\n    // rather than recreating the impacts for each test\n\n    it('should update the impact when moving after where we started in the foreign start', () => {\n      // inHome1 has made its way into index #2 of foreign after a cross axis move\n\n      const crossAxisMove: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            droppableId: preset.foreign.descriptor.id,\n            index: preset.inForeign2.descriptor.index,\n          },\n        },\n      };\n\n      // moving forward\n      const first: ?DragImpact = moveToNextIndex({\n        isMovingForward: true,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: crossAxisMove,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(first);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign3.descriptor.index,\n            },\n          },\n        };\n        expect(first).toEqual(expected);\n      }\n\n      // moving forward again\n      const second: ?DragImpact = moveToNextIndex({\n        isMovingForward: true,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: first,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(second);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [{ dimension: preset.inForeign4 }],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign4.descriptor.index,\n            },\n          },\n        };\n        expect(second).toEqual(expected);\n      }\n\n      // now moving backwards towards where we started in the foreign list\n\n      // moving backwards\n      const third: ?DragImpact = moveToNextIndex({\n        isMovingForward: false,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: second,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(third);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign3.descriptor.index,\n            },\n          },\n        };\n        expect(third).toEqual(expected);\n      }\n\n      const fourth: ?DragImpact = moveToNextIndex({\n        isMovingForward: false,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: third,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(fourth);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // ordered by closest\n            visible: [\n              { dimension: preset.inForeign2 },\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign2.descriptor.index,\n            },\n          },\n        };\n        expect(fourth).toEqual(expected);\n        // also now back where we started\n        expect(fourth).toEqual(crossAxisMove);\n      }\n    });\n\n    it('should update the impact when moving before where we started in the foreign list', () => {\n      // inHome1 has made its way into index #3 of foreign after a cross axis move\n      const crossAxisMove: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            droppableId: preset.foreign.descriptor.id,\n            index: preset.inForeign3.descriptor.index,\n          },\n        },\n      };\n\n      // moving backwards\n      const first: ?DragImpact = moveToNextIndex({\n        isMovingForward: false,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: crossAxisMove,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(first);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inForeign2 },\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign2.descriptor.index,\n            },\n          },\n        };\n        expect(first).toEqual(expected);\n      }\n\n      // moving backwards again\n      const second: ?DragImpact = moveToNextIndex({\n        isMovingForward: false,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: first,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(second);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inForeign1 },\n              { dimension: preset.inForeign2 },\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign1.descriptor.index,\n            },\n          },\n        };\n        expect(second).toEqual(expected);\n      }\n\n      // now moving forwards towards where we started in the foreign list\n\n      // moving forwards\n      const third: ?DragImpact = moveToNextIndex({\n        isMovingForward: true,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: second,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(third);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // ordered by closest impacted\n            visible: [\n              { dimension: preset.inForeign2 },\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign2.descriptor.index,\n            },\n          },\n        };\n        expect(third).toEqual(expected);\n      }\n\n      // moving forwards again\n      const fourth: ?DragImpact = moveToNextIndex({\n        isMovingForward: true,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: third,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(fourth);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // ordered by closest\n            visible: [\n              { dimension: preset.inForeign3 },\n              { dimension: preset.inForeign4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.foreign.descriptor.id,\n              index: preset.inForeign3.descriptor.index,\n            },\n          },\n        };\n        expect(fourth).toEqual(expected);\n        // also now back where we started\n        expect(fourth).toEqual(crossAxisMove);\n      }\n    });\n\n    it('should not allow displaced before the start of the list', () => {\n      // cross axis move inHome1 before inForeign1\n      const crossAxisMove: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign1 },\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            droppableId: preset.foreign.descriptor.id,\n            index: preset.inForeign1.descriptor.index,\n          },\n        },\n      };\n\n      // cannot move backwards\n\n      const impact: ?DragImpact = moveToNextIndex({\n        isMovingForward: false,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inForeignList,\n        previousImpact: crossAxisMove,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n\n      expect(impact).toBe(null);\n    });\n\n    it('should allow displaced into a spot after the last item in a list', () => {\n      // cross axis move inHome1 before inForeign4\n      const crossAxisMove: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [{ dimension: preset.inForeign4 }],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          // currently in the spot that inForeign4 initially occupied\n          destination: {\n            droppableId: preset.foreign.descriptor.id,\n            index: preset.inForeign4.descriptor.index,\n          },\n        },\n      };\n\n      // move forwards into spot after inForeign4\n\n      const impact: ?DragImpact = moveToNextIndex({\n        isMovingForward: true,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: crossAxisMove,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(impact);\n      const expected: DragImpact = {\n        // nothing is displaced at this point\n        displaced: emptyGroups,\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          // trying to move after spot after inForeign4\n          destination: {\n            droppableId: preset.foreign.descriptor.id,\n            index: preset.inForeign4.descriptor.index + 1,\n          },\n        },\n      };\n      expect(impact).toEqual(expected);\n    });\n\n    const atEndOfForeignList: DragImpact = {\n      // nothing is displaced at this point\n      displaced: emptyGroups,\n      displacedBy,\n      at: {\n        type: 'REORDER',\n        // after inForeign4\n        destination: {\n          droppableId: preset.foreign.descriptor.id,\n          index: preset.inForeign4.descriptor.index + 1,\n        },\n      },\n    };\n\n    it('should not allow displaced after it is already after the last item in a list', () => {\n      const impact: ?DragImpact = moveToNextIndex({\n        isMovingForward: true,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: atEndOfForeignList,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n\n      expect(impact).toBe(null);\n    });\n\n    it('should allow displaced back from after the last item in a list', () => {\n      const impact: ?DragImpact = moveToNextIndex({\n        isMovingForward: false,\n        isInHomeList: false,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        destination: preset.foreign,\n        insideDestination: preset.inForeignList,\n        previousImpact: atEndOfForeignList,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n\n      const expected: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [{ dimension: preset.inForeign4 }],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          // now in position of inForeign4\n          destination: {\n            droppableId: preset.foreign.descriptor.id,\n            index: preset.inForeign4.descriptor.index,\n          },\n        },\n      };\n      expect(impact).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-to-next-place/move-to-next-index/from-reorder/in-home-list.spec.js",
    "content": "// @flow\nimport type {\n  Axis,\n  DragImpact,\n  DisplacedBy,\n} from '../../../../../../../src/types';\nimport { invariant } from '../../../../../../../src/invariant';\nimport { vertical, horizontal } from '../../../../../../../src/state/axis';\nimport { getPreset } from '../../../../../../util/dimension';\nimport moveToNextIndex from '../../../../../../../src/state/move-in-direction/move-to-next-place/move-to-next-index';\nimport getDisplacedBy from '../../../../../../../src/state/get-displaced-by';\nimport getLiftEffect from '../../../../../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../../../../../util/impact';\nimport { emptyGroups } from '../../../../../../../src/state/no-impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const preset = getPreset(axis);\n  describe(`on ${axis.direction} axis`, () => {\n    it('should update the impact when moving with items that started displaced', () => {\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        preset.inHome2.displaceBy,\n      );\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome2,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n\n      const forwardsPastInHome3: ?DragImpact = moveToNextIndex({\n        isMovingForward: true,\n        isInHomeList: true,\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: homeImpact,\n        afterCritical,\n        viewport: preset.viewport,\n      });\n      invariant(forwardsPastInHome3);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              index: preset.inHome3.descriptor.index,\n              droppableId: preset.home.descriptor.id,\n            },\n          },\n        };\n        expect(forwardsPastInHome3).toEqual(expected);\n      }\n      const forwardsPastInHome4: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: true,\n        isInHomeList: true,\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: forwardsPastInHome3,\n        afterCritical,\n      });\n      invariant(forwardsPastInHome4);\n      {\n        const expected: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              index: preset.inHome4.descriptor.index,\n              droppableId: preset.home.descriptor.id,\n            },\n          },\n        };\n        expect(forwardsPastInHome4).toEqual(expected);\n      }\n\n      const backwardsPastInHome4: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: false,\n        isInHomeList: true,\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: forwardsPastInHome4,\n        afterCritical,\n      });\n      invariant(backwardsPastInHome4);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [{ dimension: preset.inHome4 }],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              index: preset.inHome3.descriptor.index,\n              droppableId: preset.home.descriptor.id,\n            },\n          },\n        };\n        expect(backwardsPastInHome4).toEqual(expected);\n      }\n\n      const backwardsToHome: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: false,\n        isInHomeList: true,\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: backwardsPastInHome4,\n        afterCritical,\n      });\n      invariant(backwardsToHome);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inHome3 },\n              { dimension: preset.inHome4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              index: preset.inHome2.descriptor.index,\n              droppableId: preset.home.descriptor.id,\n            },\n          },\n        };\n        expect(backwardsToHome).toEqual(expected);\n      }\n\n      const backwardsPastHome: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: false,\n        isInHomeList: true,\n        draggable: preset.inHome2,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: backwardsToHome,\n        afterCritical,\n      });\n      invariant(backwardsToHome);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inHome1 },\n              { dimension: preset.inHome3 },\n              { dimension: preset.inHome4 },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              index: preset.inHome1.descriptor.index,\n              droppableId: preset.home.descriptor.id,\n            },\n          },\n        };\n        expect(backwardsPastHome).toEqual(expected);\n      }\n    });\n\n    it('should update the impact when moving with items that did not start displaced', () => {\n      // dragging inHome3 backwards away from the start\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        preset.inHome3.displaceBy,\n      );\n      const { afterCritical, impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome3,\n        home: preset.home,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n      });\n\n      const backwardsPastInHome2: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: false,\n        isInHomeList: true,\n        draggable: preset.inHome3,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: homeImpact,\n        afterCritical,\n      });\n      invariant(backwardsPastInHome2);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inHome2, shouldAnimate: true },\n              // initial displacement not animated\n              { dimension: preset.inHome4, shouldAnimate: false },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome2.descriptor.index,\n            },\n          },\n        };\n        expect(backwardsPastInHome2).toEqual(expected);\n      }\n\n      // move backwards again\n      const backwardsPastInHome1: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: false,\n        isInHomeList: true,\n        draggable: preset.inHome3,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: backwardsPastInHome2,\n        afterCritical,\n      });\n      invariant(backwardsPastInHome1);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            // ordered by closest displaced\n            visible: [\n              {\n                dimension: preset.inHome1,\n                shouldAnimate: true,\n              },\n              {\n                dimension: preset.inHome2,\n                shouldAnimate: true,\n              },\n              {\n                // initial displacement not animated\n                dimension: preset.inHome4,\n                shouldAnimate: false,\n              },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome1.descriptor.index,\n            },\n          },\n        };\n        expect(backwardsPastInHome1).toEqual(expected);\n      }\n\n      // move forwards\n      const forwardsPastInHome1: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: true,\n        isInHomeList: true,\n        draggable: preset.inHome3,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: backwardsPastInHome1,\n        afterCritical,\n      });\n      invariant(forwardsPastInHome1);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              {\n                dimension: preset.inHome2,\n                shouldAnimate: true,\n              },\n              {\n                // initial displacement not animated\n                dimension: preset.inHome4,\n                shouldAnimate: false,\n              },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome2.descriptor.index,\n            },\n          },\n        };\n        expect(forwardsPastInHome1).toEqual(expected);\n      }\n\n      const forwardsToHome: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: true,\n        isInHomeList: true,\n        draggable: preset.inHome3,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: forwardsPastInHome1,\n        afterCritical,\n      });\n      invariant(forwardsToHome);\n      {\n        const expected: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [{ dimension: preset.inHome4, shouldAnimate: false }],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome3.descriptor.index,\n            },\n          },\n        };\n        expect(forwardsToHome).toEqual(expected);\n      }\n      const forwardsPastHome: ?DragImpact = moveToNextIndex({\n        viewport: preset.viewport,\n        isMovingForward: true,\n        isInHomeList: true,\n        draggable: preset.inHome3,\n        draggables: preset.draggables,\n        destination: preset.home,\n        insideDestination: preset.inHomeList,\n        previousImpact: forwardsToHome,\n        afterCritical,\n      });\n      invariant(forwardsPastHome);\n      {\n        const expected: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: preset.home.descriptor.id,\n              index: preset.inHome4.descriptor.index,\n            },\n          },\n        };\n        expect(forwardsPastHome).toEqual(expected);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-to-next-place/moving-to-invisible-place/not-visible-in-droppable.spec.js",
    "content": "// @flow\nimport {\n  getRect,\n  type Position,\n  type BoxModel,\n  type Rect,\n  offset,\n} from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DroppableDimension,\n  DraggableDimension,\n  DraggableDimensionMap,\n  DisplacedBy,\n  Viewport,\n} from '../../../../../../src/types';\nimport { invariant } from '../../../../../../src/invariant';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport {\n  getDraggableDimension,\n  getDroppableDimension,\n  getFrame,\n} from '../../../../../util/dimension';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport { createViewport } from '../../../../../util/viewport';\nimport moveToNextPlace from '../../../../../../src/state/move-in-direction/move-to-next-place';\nimport { type PublicResult } from '../../../../../../src/state/move-in-direction/move-in-direction-types';\nimport { origin, subtract, patch } from '../../../../../../src/state/position';\nimport getPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport {\n  isTotallyVisible,\n  isPartiallyVisible,\n} from '../../../../../../src/state/visibility/is-visible';\nimport { toDraggableMap } from '../../../../../../src/state/dimension-structures';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport getClientFromPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-client-border-box-center/get-client-from-page-border-box-center';\nimport scrollDroppable from '../../../../../../src/state/droppable/scroll-droppable';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport { emptyGroups } from '../../../../../../src/state/no-impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const viewport: Viewport = createViewport({\n    frame: getRect({\n      top: 0,\n      left: 0,\n      bottom: 10000,\n      right: 10000,\n    }),\n    scroll: origin,\n    scrollHeight: 10000,\n    scrollWidth: 10000,\n  });\n\n  const home: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'home',\n      type: 'droppable',\n      mode: 'standard',\n    },\n    direction: axis.direction,\n    borderBox: {\n      top: 0,\n      right: 10000,\n      bottom: 10000,\n      left: 0,\n    },\n  });\n  const foreign: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'scrollable foriegn',\n      type: 'droppable',\n      mode: 'standard',\n    },\n    direction: axis.direction,\n    // huge subject that will be cut by frame\n    borderBox: {\n      top: 0,\n      right: 10000,\n      bottom: 10000,\n      left: 0,\n    },\n    closest: {\n      borderBox: {\n        top: 0,\n        right: 1000,\n        bottom: 1000,\n        left: 0,\n      },\n      shouldClipSubject: true,\n      scroll: origin,\n      scrollSize: {\n        scrollWidth: 2000,\n        scrollHeight: 2000,\n      },\n    },\n  });\n  const frameBorderBox: Rect = getFrame(foreign).frameClient.borderBox;\n\n  const inHome: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'in-home',\n      index: 0,\n      droppableId: home.descriptor.id,\n      type: home.descriptor.type,\n    },\n    borderBox: frameBorderBox,\n  });\n  const inForeign: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'in-foreign',\n      index: 0,\n      droppableId: foreign.descriptor.id,\n      type: foreign.descriptor.type,\n    },\n    borderBox: frameBorderBox,\n  });\n  // in home list moving forward\n  const displacedBy: DisplacedBy = getDisplacedBy(axis, inHome.displaceBy);\n  const draggables: DraggableDimensionMap = toDraggableMap([inHome, inForeign]);\n  const { afterCritical } = getLiftEffect({\n    draggable: inHome,\n    draggables,\n    home,\n    viewport,\n  });\n\n  describe(`on ${axis.direction} axis`, () => {\n    describe('moving forward', () => {\n      it('should be setup correctly', () => {\n        // verify visibility is as expected\n        // before scroll\n        expect(\n          isTotallyVisible({\n            target: inHome.page.borderBox,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n            destination: home,\n          }),\n        ).toBe(true);\n        expect(\n          isTotallyVisible({\n            target: inForeign.page.borderBox,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n            destination: foreign,\n          }),\n        ).toBe(true);\n\n        // would be visible if displaced\n        const displaced: BoxModel = offset(\n          inForeign.client,\n          getDisplacedBy(vertical, inHome.displaceBy).point,\n        );\n        expect(\n          isTotallyVisible({\n            target: displaced.borderBox,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n            destination: foreign,\n          }),\n        ).toBe(false);\n      });\n\n      it('should request a jump scroll for movement that is outside of the viewport', () => {\n        const previousPageBorderBoxCenter: Position =\n          inHome.page.borderBox.center;\n        const previousClientSelection: Position =\n          inHome.client.borderBox.center;\n        const previousImpact: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [{ dimension: inForeign }],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: foreign.descriptor.id,\n              index: inForeign.descriptor.index,\n            },\n          },\n        };\n\n        const result: ?PublicResult = moveToNextPlace({\n          isMovingForward: true,\n          draggable: inHome,\n          destination: foreign,\n          draggables,\n          previousImpact,\n          viewport,\n          previousPageBorderBoxCenter,\n          previousClientSelection,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expectedImpact: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: foreign.descriptor.id,\n              index: inForeign.descriptor.index + 1,\n            },\n          },\n        };\n        // if the item would have been visible - where would the center have been?\n        const nonVisibleCenter = getPageBorderBoxCenter({\n          impact: expectedImpact,\n          draggable: inHome,\n          droppable: foreign,\n          draggables,\n          afterCritical,\n        });\n        const expectedScrollJump: Position = subtract(\n          nonVisibleCenter,\n          previousPageBorderBoxCenter,\n        );\n        const expected: PublicResult = {\n          clientSelection: previousClientSelection,\n          impact: expectedImpact,\n          scrollJumpRequest: expectedScrollJump,\n        };\n        expect(result).toEqual(expected);\n      });\n    });\n\n    describe('moving backward', () => {\n      // inHome after inForeign and inForeign is not visible\n      const newScroll: Position = patch(\n        axis.line,\n        frameBorderBox[axis.end] + 1,\n      );\n      const scrolled: DroppableDimension = scrollDroppable(foreign, newScroll);\n\n      it('should be setup correctly', () => {\n        // verify visibility is as expected\n        expect(\n          isTotallyVisible({\n            target: inForeign.page.borderBox,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n            destination: scrolled,\n          }),\n        ).toBe(false);\n        // going further - ensure it is not partially visible\n        expect(\n          isPartiallyVisible({\n            target: inForeign.page.borderBox,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n            destination: scrolled,\n          }),\n        ).toBe(false);\n\n        // checking that if displaced then inForeign would be visible\n        // using raw .displacedBy as we are scolling on\n        const displaced: BoxModel = offset(\n          inForeign.client,\n          getDisplacedBy(axis, inHome.displaceBy).point,\n        );\n        expect(\n          isPartiallyVisible({\n            target: displaced.borderBox,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n            destination: scrolled,\n          }),\n        ).toBe(true);\n      });\n\n      it('should request a jump scroll for movement that is outside of the viewport', () => {\n        // after non-displaced inForeign\n        const previousImpact: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy: getDisplacedBy(axis, inHome.displaceBy),\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: foreign.descriptor.id,\n              index: inForeign.descriptor.index + 1,\n            },\n          },\n        };\n        const previousPageBorderBoxCenter: Position = getPageBorderBoxCenter({\n          impact: previousImpact,\n          afterCritical,\n          draggable: inHome,\n          droppable: scrolled,\n          draggables,\n        });\n        const previousClientSelection: Position = getClientFromPageBorderBoxCenter(\n          {\n            pageBorderBoxCenter: previousPageBorderBoxCenter,\n            draggable: inHome,\n            viewport,\n          },\n        );\n\n        // figure out where we would have been if it was visible\n\n        const result: ?PublicResult = moveToNextPlace({\n          isMovingForward: false,\n          draggable: inHome,\n          destination: scrolled,\n          draggables,\n          previousImpact,\n          viewport,\n          previousPageBorderBoxCenter,\n          previousClientSelection,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expectedImpact: DragImpact = {\n          displaced: getForcedDisplacement({\n            // Even though the item started in an invisible place we force\n            // the displacement to be visible.\n            visible: [{ dimension: inForeign, shouldAnimate: false }],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            // moving into place of inForeign\n            destination: {\n              droppableId: foreign.descriptor.id,\n              index: inForeign.descriptor.index,\n            },\n          },\n        };\n        // if the item would have been visible - where would the center have been?\n        const nonVisibleCenter = getPageBorderBoxCenter({\n          impact: expectedImpact,\n          draggable: inHome,\n          droppable: scrolled,\n          draggables,\n          afterCritical,\n        });\n        const expectedScrollJump: Position = subtract(\n          nonVisibleCenter,\n          previousPageBorderBoxCenter,\n        );\n        const expected: PublicResult = {\n          clientSelection: previousClientSelection,\n          impact: expectedImpact,\n          scrollJumpRequest: expectedScrollJump,\n        };\n        expect(result).toEqual(expected);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/move-in-direction/move-to-next-place/moving-to-invisible-place/not-visible-in-viewport.spec.js",
    "content": "// @flow\nimport { getRect, type Position, type BoxModel, offset } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  DroppableDimension,\n  DraggableDimension,\n  DraggableDimensionMap,\n  DisplacedBy,\n  Viewport,\n} from '../../../../../../src/types';\nimport { invariant } from '../../../../../../src/invariant';\nimport { vertical, horizontal } from '../../../../../../src/state/axis';\nimport {\n  getDraggableDimension,\n  getDroppableDimension,\n} from '../../../../../util/dimension';\nimport getDisplacedBy from '../../../../../../src/state/get-displaced-by';\nimport { createViewport } from '../../../../../util/viewport';\nimport moveToNextPlace from '../../../../../../src/state/move-in-direction/move-to-next-place';\nimport { type PublicResult } from '../../../../../../src/state/move-in-direction/move-in-direction-types';\nimport { origin, subtract, patch } from '../../../../../../src/state/position';\nimport getPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-page-border-box-center';\nimport scrollViewport from '../../../../../../src/state/scroll-viewport';\nimport {\n  isTotallyVisible,\n  isPartiallyVisible,\n} from '../../../../../../src/state/visibility/is-visible';\nimport { toDraggableMap } from '../../../../../../src/state/dimension-structures';\nimport getLiftEffect from '../../../../../../src/state/get-lift-effect';\nimport getClientFromPageBorderBoxCenter from '../../../../../../src/state/get-center-from-impact/get-client-border-box-center/get-client-from-page-border-box-center';\nimport { getForcedDisplacement } from '../../../../../util/impact';\nimport { emptyGroups } from '../../../../../../src/state/no-impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  const viewport: Viewport = createViewport({\n    frame: getRect({\n      top: 0,\n      left: 0,\n      bottom: 1000,\n      right: 1000,\n    }),\n    scroll: origin,\n    scrollHeight: 2000,\n    scrollWidth: 2000,\n  });\n\n  const home: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'home - much bigger than viewport',\n      type: 'huge',\n      mode: 'standard',\n    },\n    direction: axis.direction,\n    borderBox: {\n      top: 0,\n      right: 10000,\n      bottom: 10000,\n      left: 0,\n    },\n  });\n\n  const foreign: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'foreign - much bigger than viewport',\n      type: 'huge',\n      mode: 'standard',\n    },\n    direction: axis.direction,\n    borderBox: {\n      top: 0,\n      right: 10000,\n      bottom: 10000,\n      left: 0,\n    },\n  });\n\n  const inHome: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'in-home',\n      index: 0,\n      droppableId: home.descriptor.id,\n      type: home.descriptor.type,\n    },\n    borderBox: viewport.frame,\n  });\n  const inForeign: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'in-foreign',\n      index: 0,\n      droppableId: foreign.descriptor.id,\n      type: foreign.descriptor.type,\n    },\n    borderBox: viewport.frame,\n  });\n  // in home list moving forward\n  const displacedBy: DisplacedBy = getDisplacedBy(axis, inHome.displaceBy);\n  const draggables: DraggableDimensionMap = toDraggableMap([inHome, inForeign]);\n  const { afterCritical } = getLiftEffect({\n    draggable: inHome,\n    draggables,\n    home,\n    viewport,\n  });\n\n  describe(`on ${axis.direction} axis`, () => {\n    describe('moving forward', () => {\n      it('should be setup correctly', () => {\n        // verify visibility is as expected\n        // before scroll\n        expect(\n          isTotallyVisible({\n            target: inHome.page.borderBox,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n            destination: home,\n          }),\n        ).toBe(true);\n        expect(\n          isTotallyVisible({\n            target: inForeign.page.borderBox,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n            destination: foreign,\n          }),\n        ).toBe(true);\n\n        const displaced: BoxModel = offset(\n          inForeign.client,\n          getDisplacedBy(vertical, inHome.displaceBy).point,\n        );\n\n        expect(\n          isTotallyVisible({\n            target: displaced.borderBox,\n            viewport: viewport.frame,\n            withDroppableDisplacement: true,\n            destination: foreign,\n          }),\n        ).toBe(false);\n      });\n\n      it('should request a jump scroll for movement that is outside of the viewport', () => {\n        const previousPageBorderBoxCenter: Position =\n          inHome.page.borderBox.center;\n        const previousClientSelection: Position =\n          inHome.client.borderBox.center;\n\n        const previousImpact: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [{ dimension: inForeign }],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: foreign.descriptor.id,\n              index: inForeign.descriptor.index,\n            },\n          },\n        };\n\n        const result: ?PublicResult = moveToNextPlace({\n          isMovingForward: true,\n          draggable: inHome,\n          destination: foreign,\n          draggables,\n          previousImpact,\n          viewport,\n          previousPageBorderBoxCenter,\n          previousClientSelection,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expectedImpact: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: foreign.descriptor.id,\n              index: inForeign.descriptor.index + 1,\n            },\n          },\n        };\n        // if the item would have been visible - where would the center have been?\n        const nonVisibleCenter = getPageBorderBoxCenter({\n          impact: expectedImpact,\n          draggable: inHome,\n          droppable: foreign,\n          draggables,\n          afterCritical,\n        });\n        const expectedScrollJump: Position = subtract(\n          nonVisibleCenter,\n          previousPageBorderBoxCenter,\n        );\n        const expected: PublicResult = {\n          clientSelection: previousClientSelection,\n          impact: expectedImpact,\n          scrollJumpRequest: expectedScrollJump,\n        };\n        expect(result).toEqual(expected);\n      });\n    });\n\n    describe('moving backward', () => {\n      // inHome after inForeign and inForeign is not visible\n      const newScroll: Position = patch(\n        axis.line,\n        viewport.frame[axis.end] + 1,\n      );\n      const scrolled: Viewport = scrollViewport(viewport, newScroll);\n\n      it('should be setup correctly', () => {\n        // verify visibility is as expected\n        expect(\n          isTotallyVisible({\n            target: inForeign.page.borderBox,\n            viewport: scrolled.frame,\n            withDroppableDisplacement: true,\n            destination: foreign,\n          }),\n        ).toBe(false);\n        // going further - ensure it is not partially visible\n        expect(\n          isPartiallyVisible({\n            target: inForeign.page.borderBox,\n            viewport: scrolled.frame,\n            withDroppableDisplacement: true,\n            destination: foreign,\n          }),\n        ).toBe(false);\n\n        // checking that if displaced then inForeign would be visible\n        // using raw .displacedBy as we are scolling on\n        const displaced: BoxModel = offset(\n          inForeign.client,\n          getDisplacedBy(axis, inHome.displaceBy).point,\n        );\n        expect(\n          isPartiallyVisible({\n            target: displaced.borderBox,\n            viewport: scrolled.frame,\n            withDroppableDisplacement: true,\n            destination: foreign,\n          }),\n        ).toBe(true);\n      });\n\n      it('should request a jump scroll for movement that is outside of the viewport', () => {\n        // after non-displaced inForeign\n        const previousImpact: DragImpact = {\n          displaced: emptyGroups,\n          displacedBy: getDisplacedBy(axis, inHome.displaceBy),\n          at: {\n            type: 'REORDER',\n            destination: {\n              droppableId: foreign.descriptor.id,\n              index: inForeign.descriptor.index + 1,\n            },\n          },\n        };\n        const previousPageBorderBoxCenter: Position = getPageBorderBoxCenter({\n          impact: previousImpact,\n          afterCritical,\n          draggable: inHome,\n          droppable: foreign,\n          draggables,\n        });\n        const previousClientSelection: Position = getClientFromPageBorderBoxCenter(\n          {\n            pageBorderBoxCenter: previousPageBorderBoxCenter,\n            draggable: inHome,\n            viewport: scrolled,\n          },\n        );\n        // const previousPageBorderBoxCenter: Position =\n        //   initiallyOutsideViewport.page.borderBox.center;\n        // const previousClientSelection: Position =\n        //   initiallyOutsideViewport.client.borderBox.center;\n\n        // figure out where we would have been if it was visible\n\n        const result: ?PublicResult = moveToNextPlace({\n          isMovingForward: false,\n          draggable: inHome,\n          destination: foreign,\n          draggables,\n          previousImpact,\n          viewport: scrolled,\n          previousPageBorderBoxCenter,\n          previousClientSelection,\n          afterCritical,\n        });\n        invariant(result);\n\n        const expectedImpact: DragImpact = {\n          displaced: getForcedDisplacement({\n            // Even though the item started in an invisible place we force\n            // the displacement to be visible.\n            visible: [{ dimension: inForeign, shouldAnimate: false }],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            // moving into place of inForeign\n            destination: {\n              droppableId: foreign.descriptor.id,\n              index: inForeign.descriptor.index,\n            },\n          },\n        };\n        // if the item would have been visible - where would the center have been?\n        const nonVisibleCenter = getPageBorderBoxCenter({\n          impact: expectedImpact,\n          draggable: inHome,\n          droppable: foreign,\n          draggables,\n          afterCritical,\n        });\n        const expectedScrollJump: Position = subtract(\n          nonVisibleCenter,\n          previousPageBorderBoxCenter,\n        );\n        const expected: PublicResult = {\n          clientSelection: previousClientSelection,\n          impact: expectedImpact,\n          scrollJumpRequest: expectedScrollJump,\n        };\n        expect(result).toEqual(expected);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/position.spec.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport {\n  add,\n  apply,\n  subtract,\n  isEqual,\n  negate,\n  patch,\n  distance,\n  closest,\n} from '../../../src/state/position';\n\nconst point1: Position = {\n  x: 10,\n  y: 5,\n};\nconst point2: Position = {\n  x: 2,\n  y: 1,\n};\nconst origin: Position = { x: 0, y: 0 };\n\ndescribe('position', () => {\n  describe('add', () => {\n    it('should add two points together', () => {\n      const expected: Position = { x: 12, y: 6 };\n      expect(add(point1, point2)).toEqual(expected);\n    });\n  });\n\n  describe('subtract', () => {\n    it('should subtract two points together', () => {\n      const expected: Position = { x: 8, y: 4 };\n      expect(subtract(point1, point2)).toEqual(expected);\n    });\n  });\n\n  describe('is equal', () => {\n    it('should return true when two objects are the same', () => {\n      expect(isEqual(point1, point1)).toBe(true);\n    });\n\n    it('should return true when two objects share the same value', () => {\n      const copy = {\n        ...point1,\n      };\n      expect(isEqual(point1, copy)).toBe(true);\n    });\n\n    it('should return false when two objects have different values', () => {\n      expect(isEqual(point1, point2)).toBe(false);\n    });\n\n    it('should return true when -origin is compared with +origin', () => {\n      expect(isEqual({ x: -0, y: -0 }, { x: 0, y: 0 })).toBe(true);\n    });\n  });\n\n  describe('negate', () => {\n    it('should return the inverse of the provided point', () => {\n      const expected: Position = { x: -point1.x, y: -point1.y };\n      expect(negate(point1)).toEqual(expected);\n    });\n\n    it('should not negate 0 to -0', () => {\n      const original: Position = { x: 0, y: 0 };\n      expect(negate(original)).toEqual(original);\n    });\n  });\n\n  describe('patch', () => {\n    it('should patch position with a y value', () => {\n      expect(patch('x', 5)).toEqual({ x: 5, y: 0 });\n    });\n\n    it('should patch a position with a x value', () => {\n      expect(patch('y', 5)).toEqual({ x: 0, y: 5 });\n    });\n\n    it('should allow patching of the non primary line', () => {\n      expect(patch('x', 5, 1)).toEqual({ x: 5, y: 1 });\n      expect(patch('y', 5, 1)).toEqual({ x: 1, y: 5 });\n    });\n  });\n\n  describe('distance', () => {\n    describe('on the same axis', () => {\n      it('should return the distance between two positive values', () => {\n        const a = { x: 0, y: 2 };\n        const b = { x: 0, y: 5 };\n        expect(distance(a, b)).toEqual(3);\n      });\n\n      it('should return the distance between two negative values', () => {\n        const a = { x: 0, y: -2 };\n        const b = { x: 0, y: -5 };\n        expect(distance(a, b)).toEqual(3);\n      });\n\n      it('should return the distance between a positive and negative value', () => {\n        const a = { x: 0, y: -2 };\n        const b = { x: 0, y: 3 };\n        expect(distance(a, b)).toEqual(5);\n      });\n    });\n\n    describe('with axis shift', () => {\n      it('should account for a shift in plane', () => {\n        // a '3, 4, 5' triangle\n        // https://www.mathsisfun.com/pythagoras.html\n        const target = { x: 3, y: 4 };\n        expect(distance(origin, target)).toEqual(5);\n      });\n\n      it('should account for a negative shift in plane', () => {\n        // a reverse '3, 4, 5' triangle shifted down to (-1, -1)\n        const customOrigin = { x: -1, y: -1 };\n        const target = { x: -4, y: -5 };\n        expect(distance(customOrigin, target)).toEqual(5);\n      });\n    });\n  });\n\n  describe('closest', () => {\n    it('should return the closest distance from a series of options', () => {\n      const option1 = { x: 1, y: 1 };\n      const option2 = { x: 2, y: 2 };\n\n      expect(closest(origin, [option1, option2])).toEqual(\n        distance(origin, option1),\n      );\n    });\n  });\n\n  describe('apply', () => {\n    it('should apply the function to both values', () => {\n      const add1 = apply((value: number) => value + 1);\n\n      expect(add1({ x: 1, y: 2 })).toEqual({ x: 2, y: 3 });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/post-reducer/.gitkeep",
    "content": ""
  },
  {
    "path": "test/unit/state/publish-while-dragging/adjust-additions-for-scroll-change.spec.js",
    "content": "// @flow\nimport { offset, type Position } from 'css-box-model';\nimport type {\n  Published,\n  DraggableDimension,\n  DropPendingState,\n  DraggingState,\n  CollectingState,\n  Viewport,\n  DroppableDimension,\n} from '../../../../src/types';\nimport { invariant } from '../../../../src/invariant';\nimport publish from '../../../../src/state/publish-while-dragging-in-virtual';\nimport {\n  getPreset,\n  getDraggableDimension,\n  addDroppable,\n  getFrame,\n} from '../../../util/dimension';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport { empty, withVirtuals, virtualHome } from './util';\nimport { add, negate, origin } from '../../../../src/state/position';\nimport scrollViewport from '../../../../src/state/scroll-viewport';\nimport scrollDroppable from '../../../../src/state/droppable/scroll-droppable';\n\nconst state = getStatePreset();\nconst preset = getPreset();\n\nit('should shift added draggables to account for change in page scroll since start of drag', () => {\n  // change in scroll\n  const scrollChange: Position = { x: 20, y: 40 };\n  // the displacement caused to draggables as a result of the change\n  const scrollDisplacement: Position = negate(scrollChange);\n  const newScroll: Position = add(preset.viewport.scroll.initial, scrollChange);\n  const scrolledViewport: Viewport = scrollViewport(preset.viewport, newScroll);\n  // dimensions\n  const added: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      index: 0,\n      id: 'added',\n      droppableId: preset.home.descriptor.id,\n      type: preset.home.descriptor.type,\n    },\n    // when collected this dimension would have been displaced by the scroll\n    borderBox: offset(preset.inHome1.client, scrollDisplacement).borderBox,\n    windowScroll: add(preset.windowScroll, scrollDisplacement),\n  });\n  const unshifted: DraggableDimension = getDraggableDimension({\n    descriptor: added.descriptor,\n    // unshifted\n    borderBox: preset.inHome1.client.borderBox,\n    windowScroll: preset.windowScroll,\n  });\n  const published: Published = {\n    ...empty,\n    additions: [added],\n    modified: [{ droppableId: virtualHome.descriptor.id, scroll: origin }],\n  };\n  const original: CollectingState = withVirtuals(\n    state.collecting(\n      preset.inHome1.descriptor.id,\n      preset.inHome1.client.borderBox.center,\n      scrolledViewport,\n    ),\n  );\n\n  const result: DraggingState | DropPendingState = publish({\n    state: original,\n    published,\n  });\n\n  invariant(result.phase === 'DRAGGING');\n  expect(result.dimensions.draggables[added.descriptor.id]).toEqual(unshifted);\n});\n\nit('should shift added draggables to account for change in droppable scroll since start of drag', () => {\n  // Scroll droppable\n  const scrollChange: Position = { x: 20, y: 40 };\n  const scrollDisplacement: Position = negate(scrollChange);\n  const newScroll: Position = add(\n    getFrame(virtualHome).scroll.initial,\n    scrollChange,\n  );\n  const scrolled: DroppableDimension = scrollDroppable(virtualHome, newScroll);\n  // validation\n  expect(getFrame(scrolled).scroll.current).toEqual(scrollChange);\n  // dimensions\n  const added: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      index: 0,\n      id: 'added',\n      droppableId: preset.home.descriptor.id,\n      type: preset.home.descriptor.type,\n    },\n    // when collected this dimension would have been displaced by the scroll\n    borderBox: offset(preset.inHome1.client, scrollDisplacement).borderBox,\n    windowScroll: preset.windowScroll,\n  });\n  const unshifted: DraggableDimension = getDraggableDimension({\n    descriptor: added.descriptor,\n    // unshifted\n    borderBox: preset.inHome1.client.borderBox,\n    windowScroll: preset.windowScroll,\n  });\n  const published: Published = {\n    ...empty,\n    additions: [added],\n    modified: [{ droppableId: scrolled.descriptor.id, scroll: newScroll }],\n  };\n  const original: CollectingState = state.collecting(\n    preset.inHome1.descriptor.id,\n  );\n  const withScrolled: CollectingState = (addDroppable(\n    (original: any),\n    scrolled,\n  ): any);\n\n  const result: DraggingState | DropPendingState = publish({\n    state: withScrolled,\n    published,\n  });\n\n  invariant(result.phase === 'DRAGGING');\n  expect(result.dimensions.draggables[added.descriptor.id]).toEqual(unshifted);\n});\n"
  },
  {
    "path": "test/unit/state/publish-while-dragging/displacement-animation.spec.js",
    "content": "// @flow\nimport { invariant } from '../../../../src/invariant';\nimport { getPreset, addDroppable } from '../../../util/dimension';\nimport type {\n  DraggableDimension,\n  CollectingState,\n  Published,\n  DisplacementGroups,\n  DraggingState,\n  DropPendingState,\n  DragImpact,\n} from '../../../../src/types';\nimport { virtualForeign, empty } from './util';\nimport getSimpleStatePreset from '../../../util/get-simple-state-preset';\nimport publish from '../../../../src/state/publish-while-dragging-in-virtual';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport { vertical } from '../../../../src/state/axis';\nimport type { PublicResult } from '../../../../src/state/move-in-direction/move-in-direction-types';\nimport moveInDirection from '../../../../src/state/move-in-direction';\nimport update from '../../../../src/state/post-reducer/when-moving/update';\nimport { getForcedDisplacement } from '../../../util/impact';\nimport { origin } from '../../../../src/state/position';\n\nconst preset = getPreset(vertical);\nconst state = getSimpleStatePreset(vertical);\n\nit('should not animate any displacement', () => {\n  // inHome1 currently in foreign\n  // adding item to foreign list\n  // we are ensuring this displacement is not animated\n\n  const inHomeState: DraggingState = addDroppable(\n    state.dragging(),\n    virtualForeign,\n  );\n  const moveToForeign: ?PublicResult = moveInDirection({\n    state: inHomeState,\n    type: 'MOVE_RIGHT',\n  });\n  invariant(moveToForeign);\n  const inForeignImpact: DragImpact = moveToForeign.impact;\n  // validation\n  {\n    const displaced: DisplacementGroups = getForcedDisplacement({\n      visible: [\n        // initial movement goes after inForeign1\n        { dimension: preset.inForeign2, shouldAnimate: true },\n        { dimension: preset.inForeign3, shouldAnimate: true },\n        { dimension: preset.inForeign4, shouldAnimate: true },\n      ],\n    });\n    const impact: DragImpact = {\n      displaced,\n      displacedBy: getDisplacedBy(vertical, preset.inHome1.displaceBy),\n      at: {\n        type: 'REORDER',\n        destination: {\n          index: preset.inForeign2.descriptor.index,\n          droppableId: preset.foreign.descriptor.id,\n        },\n      },\n    };\n    expect(impact).toEqual(inForeignImpact);\n  }\n  // $ExpectError - casting as different state type\n  const inForeignState: DraggingState = update({\n    state: inHomeState,\n    clientSelection: moveToForeign.clientSelection,\n    impact: inForeignImpact,\n  });\n\n  // adding item after inHome4\n  const added: DraggableDimension = {\n    ...preset.inForeign4,\n    descriptor: {\n      ...preset.inForeign4.descriptor,\n      index: preset.inForeign4.descriptor.index + 1,\n      id: 'added',\n    },\n  };\n  const collectingState: CollectingState = {\n    phase: 'COLLECTING',\n    ...inForeignState,\n    // appeasing flow\n    // eslint-disable-next-line\n    phase: 'COLLECTING',\n  };\n  const published: Published = {\n    ...empty,\n    additions: [added],\n    modified: [{ droppableId: virtualForeign.descriptor.id, scroll: origin }],\n  };\n\n  const result: DraggingState | DropPendingState = publish({\n    state: collectingState,\n    published,\n  });\n  invariant(result.phase === 'DRAGGING');\n\n  const displaced: DisplacementGroups = getForcedDisplacement({\n    visible: [\n      // original animation unchanged\n      { dimension: preset.inForeign2, shouldAnimate: true },\n      { dimension: preset.inForeign3, shouldAnimate: true },\n      { dimension: preset.inForeign4, shouldAnimate: true },\n      // addition\n      { dimension: added, shouldAnimate: true },\n    ],\n  });\n  const expected: DragImpact = {\n    // same destination\n    ...inForeignImpact,\n    displaced,\n  };\n  expect(result.impact).toEqual(expected);\n});\n"
  },
  {
    "path": "test/unit/state/publish-while-dragging/droppable-scroll-change.spec.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { invariant } from '../../../../src/invariant';\nimport scrollDroppable from '../../../../src/state/droppable/scroll-droppable';\nimport publish from '../../../../src/state/publish-while-dragging-in-virtual';\nimport {\n  addDroppable,\n  getFrame,\n  getPreset,\n  makeVirtual,\n} from '../../../util/dimension';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport { empty } from './util';\nimport type {\n  DroppableDimension,\n  CollectingState,\n  Published,\n  DraggingState,\n  DropPendingState,\n} from '../../../../src/types';\n\nconst preset = getPreset();\nconst state = getStatePreset();\n\nit('should adjust the current droppable scroll in response to a change', () => {\n  // sometimes the scroll of a droppable is impacted by the adding or removing of droppables\n  // we need to ensure that the droppable has the correct current scroll and diffs based on the insertion\n\n  const originalScroll: Position = { x: 0, y: 20 };\n  const currentScroll: Position = { x: 0, y: 5 };\n\n  // Dragging inHome2 and inHome1 is removed\n  const virtualHome: DroppableDimension = makeVirtual(\n    preset.home,\n    originalScroll.y,\n  );\n  const beforeRemoval: DroppableDimension = scrollDroppable(\n    virtualHome,\n    originalScroll,\n  );\n\n  // $FlowFixMe - wrong type\n  const original: CollectingState = addDroppable(\n    // $FlowFixMe - wrong type\n    state.collecting(preset.inHome2.descriptor.id),\n    beforeRemoval,\n  );\n\n  const published: Published = {\n    ...empty,\n    removals: [preset.inHome1.descriptor.id],\n    modified: [\n      { droppableId: virtualHome.descriptor.id, scroll: currentScroll },\n    ],\n  };\n\n  const result: DraggingState | DropPendingState = publish({\n    state: original,\n    published,\n  });\n\n  invariant(result.phase === 'DRAGGING');\n\n  const updated: DroppableDimension =\n    result.dimensions.droppables[preset.home.descriptor.id];\n  // current scroll set to the\n  expect(getFrame(updated).scroll.current).toEqual(currentScroll);\n});\n"
  },
  {
    "path": "test/unit/state/publish-while-dragging/nothing-changed.spec.js",
    "content": "// @flow\nimport type {\n  DropPendingState,\n  DraggingState,\n  CollectingState,\n} from '../../../../src/types';\nimport { invariant } from '../../../../src/invariant';\nimport publish from '../../../../src/state/publish-while-dragging-in-virtual';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport { empty, withVirtuals } from './util';\n\nconst state = getStatePreset();\n\nit('should do not modify the dimensions when nothing has changed', () => {\n  const original: CollectingState = withVirtuals(state.collecting());\n\n  const result: DraggingState | DropPendingState = publish({\n    state: original,\n    published: empty,\n  });\n\n  invariant(result.phase === 'DRAGGING');\n\n  // only minor modifications on original\n  const expected: DraggingState = {\n    phase: 'DRAGGING',\n    ...original,\n    // appeasing flow\n    // eslint-disable-next-line\n    phase: 'DRAGGING',\n    // we force no animation of the moving item\n    forceShouldAnimate: false,\n  };\n  expect(result).toEqual(expected);\n});\n"
  },
  {
    "path": "test/unit/state/publish-while-dragging/phase-change.spec.js",
    "content": "// @flow\n\nimport { invariant } from '../../../../src/invariant';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport type { DropPendingState, DraggingState } from '../../../../src/types';\nimport publish from '../../../../src/state/publish-while-dragging-in-virtual';\nimport { empty } from './util';\n\nconst state = getStatePreset();\n\nit('should move to the DRAGGING phase if was in the COLLECTING phase', () => {\n  const result: DraggingState | DropPendingState = publish({\n    state: state.collecting(),\n    published: empty,\n  });\n\n  expect(result.phase).toBe('DRAGGING');\n});\n\nit('should move into a non-waiting DROP_PENDING phase if was in a DROP_PENDING phase', () => {\n  const result: DraggingState | DropPendingState = publish({\n    state: state.dropPending(),\n    published: empty,\n  });\n\n  expect(result.phase).toBe('DROP_PENDING');\n  invariant(result.phase === 'DROP_PENDING');\n  expect(result.reason).toBe(state.dropPending().reason);\n});\n"
  },
  {
    "path": "test/unit/state/publish-while-dragging/recompute-after-critical.spec.js",
    "content": "// @flow\nimport { invariant } from '../../../../src/invariant';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport type {\n  Published,\n  DraggableDimension,\n  DropPendingState,\n  DraggingState,\n  DragImpact,\n  DisplacementGroups,\n  DisplacedBy,\n  CollectingState,\n  LiftEffect,\n} from '../../../../src/types';\nimport publish from '../../../../src/state/publish-while-dragging-in-virtual';\nimport { getPreset } from '../../../util/dimension';\nimport { empty, withVirtuals, virtualHome } from './util';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport { vertical } from '../../../../src/state/axis';\nimport { origin } from '../../../../src/state/position';\nimport { getForcedDisplacement } from '../../../util/impact';\n\nconst state = getStatePreset();\nconst preset = getPreset(vertical);\n\nit('should recalculate after critical (something added)', () => {\n  const displacedBy: DisplacedBy = getDisplacedBy(\n    vertical,\n    preset.inHome1.displaceBy,\n  );\n  const added: DraggableDimension = {\n    ...preset.inHome4,\n    descriptor: {\n      ...preset.inHome4.descriptor,\n      index: preset.inHome4.descriptor.index + 1,\n      id: 'added',\n    },\n  };\n  const published: Published = {\n    ...empty,\n    additions: [added],\n    modified: [{ droppableId: virtualHome.descriptor.id, scroll: origin }],\n  };\n\n  const original: CollectingState = withVirtuals(state.collecting());\n  const result: DraggingState | DropPendingState = publish({\n    state: original,\n    published,\n  });\n\n  invariant(result.phase === 'DRAGGING');\n\n  {\n    const expected: LiftEffect = {\n      inVirtualList: true,\n      effected: {\n        // part of the original onLift\n        [preset.inHome2.descriptor.id]: true,\n        [preset.inHome3.descriptor.id]: true,\n        [preset.inHome4.descriptor.id]: true,\n        // added\n        [added.descriptor.id]: true,\n      },\n      displacedBy,\n    };\n\n    expect(result.afterCritical).toEqual(expected);\n  }\n\n  {\n    const displaced: DisplacementGroups = getForcedDisplacement({\n      visible: [\n        { dimension: preset.inHome2, shouldAnimate: false },\n        { dimension: preset.inHome3, shouldAnimate: false },\n        { dimension: preset.inHome4, shouldAnimate: false },\n        { dimension: added, shouldAnimate: false },\n      ],\n    });\n    const expected: DragImpact = {\n      displacedBy,\n      displaced,\n      at: original.onLiftImpact.at,\n    };\n    expect(result.onLiftImpact).toEqual(expected);\n  }\n});\n\nit('should recalculate after critical (something removed)', () => {\n  const displacedBy: DisplacedBy = getDisplacedBy(\n    vertical,\n    preset.inHome1.displaceBy,\n  );\n  const published: Published = {\n    removals: [preset.inHome4.descriptor.id],\n    additions: [],\n    modified: [{ droppableId: virtualHome.descriptor.id, scroll: origin }],\n  };\n\n  const original: CollectingState = withVirtuals(state.collecting());\n  const result: DraggingState | DropPendingState = publish({\n    state: original,\n    published,\n  });\n\n  invariant(result.phase === 'DRAGGING');\n\n  {\n    const expected: LiftEffect = {\n      inVirtualList: true,\n      effected: {\n        [preset.inHome2.descriptor.id]: true,\n        [preset.inHome3.descriptor.id]: true,\n        // preset.inHome4 is gone\n      },\n      displacedBy,\n    };\n\n    expect(result.afterCritical).toEqual(expected);\n  }\n\n  {\n    const displaced: DisplacementGroups = getForcedDisplacement({\n      visible: [\n        { dimension: preset.inHome2, shouldAnimate: false },\n        { dimension: preset.inHome3, shouldAnimate: false },\n      ],\n    });\n    const expected: DragImpact = {\n      displacedBy,\n      displaced,\n      at: original.onLiftImpact.at,\n    };\n    expect(result.onLiftImpact).toEqual(expected);\n  }\n});\n"
  },
  {
    "path": "test/unit/state/publish-while-dragging/util.js",
    "content": "// @flow\nimport { createBox, type BoxModel, type Position } from 'css-box-model';\nimport { getPreset, addDroppable, makeVirtual } from '../../../util/dimension';\nimport type {\n  Published,\n  DraggableDimension,\n  DroppableDimension,\n  CollectingState,\n  LiftEffect,\n} from '../../../../src/types';\nimport offsetDraggable from '../../../../src/state/publish-while-dragging-in-virtual/offset-draggable';\n\nconst preset = getPreset();\n\nexport const empty: Published = {\n  additions: [],\n  removals: [],\n  modified: [],\n};\n\ntype ShiftArgs = {|\n  draggable: DraggableDimension,\n  change: Position,\n  newIndex: number,\n|};\n\nexport const shift = ({\n  draggable,\n  change,\n  newIndex,\n}: ShiftArgs): DraggableDimension => {\n  const moved: DraggableDimension = offsetDraggable({\n    draggable,\n    offset: change,\n    initialWindowScroll: preset.windowScroll,\n  });\n\n  const result: DraggableDimension = {\n    ...moved,\n    descriptor: {\n      ...moved.descriptor,\n      index: newIndex,\n    },\n  };\n\n  return result;\n};\n\nexport const virtualHome: DroppableDimension = makeVirtual(preset.home);\nexport const virtualForeign: DroppableDimension = makeVirtual(preset.foreign);\n\nexport const withVirtuals = (state: CollectingState): CollectingState => {\n  // $ExpectError\n  const base: CollectingState = addDroppable(\n    // $ExpectError\n    addDroppable(state, virtualHome),\n    virtualForeign,\n  );\n  const afterCritical: LiftEffect = {\n    ...base.afterCritical,\n    inVirtualList: true,\n  };\n  return {\n    ...base,\n    afterCritical,\n  };\n};\n\nexport const adjustBox = (box: BoxModel, point: Position): BoxModel =>\n  createBox({\n    borderBox: {\n      // top and left cannot change as a result of this adjustment\n      top: box.borderBox.top,\n      left: box.borderBox.left,\n      // only growing in one direction\n      right: box.borderBox.right + point.x,\n      bottom: box.borderBox.bottom + point.y,\n    },\n    margin: box.margin,\n    border: box.border,\n    padding: box.padding,\n  });\n"
  },
  {
    "path": "test/unit/state/recompute-placeholders.spec.js",
    "content": "// @flow\nimport type {\n  DisplacedBy,\n  Axis,\n  DragImpact,\n  DroppableDimension,\n  DroppableDimensionMap,\n} from '../../../src/types';\nimport { getPreset } from '../../util/dimension';\nimport getDisplacedBy from '../../../src/state/get-displaced-by';\nimport { horizontal, vertical } from '../../../src/state/axis';\nimport recomputePlaceholders from '../../../src/state/recompute-placeholders';\nimport noImpact from '../../../src/state/no-impact';\nimport { addPlaceholder } from '../../../src/state/droppable/with-placeholder';\nimport patchDroppableMap from '../../../src/state/patch-droppable-map';\nimport getLiftEffect from '../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../util/impact';\n\n[horizontal, vertical].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const { impact: homeImpact } = getLiftEffect({\n      draggable: preset.inHome1,\n      draggables: preset.draggables,\n      home: preset.home,\n      viewport: preset.viewport,\n    });\n\n    it('should not do anything if there is no destination change', () => {\n      const result: DroppableDimensionMap = recomputePlaceholders({\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: preset.droppables,\n        impact: homeImpact,\n        previousImpact: homeImpact,\n      });\n\n      expect(result).toEqual(preset.droppables);\n    });\n\n    it('should not do anything if there is no destination', () => {\n      const result1: DroppableDimensionMap = recomputePlaceholders({\n        previousImpact: homeImpact,\n        impact: noImpact,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: preset.droppables,\n      });\n      const result2: DroppableDimensionMap = recomputePlaceholders({\n        previousImpact: noImpact,\n        impact: noImpact,\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: preset.droppables,\n      });\n\n      expect(result1).toEqual(preset.droppables);\n      expect(result2).toEqual(preset.droppables);\n    });\n\n    it('should add a placeholder if moving to a foreign list', () => {\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        preset.inHome1.displaceBy,\n      );\n      const overForeign: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign1 },\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inForeign1.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      const first: DroppableDimensionMap = recomputePlaceholders({\n        draggables: preset.draggables,\n        droppables: preset.droppables,\n        previousImpact: homeImpact,\n        impact: overForeign,\n        draggable: preset.inHome1,\n      });\n\n      expect(first).not.toEqual(preset.droppables);\n      const withPlaceholder: DroppableDimension = addPlaceholder(\n        preset.foreign,\n        preset.inHome1,\n        preset.draggables,\n      );\n      expect(first).toEqual(\n        patchDroppableMap(preset.droppables, withPlaceholder),\n      );\n\n      const overForeign2: DragImpact = {\n        displaced: getForcedDisplacement({\n          // now moving forward (should not add another placeholder)\n          visible: [\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inForeign2.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n      const second: DroppableDimensionMap = recomputePlaceholders({\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        droppables: preset.droppables,\n        previousImpact: overForeign,\n        impact: overForeign2,\n      });\n\n      expect(second).toEqual(first);\n    });\n\n    it('should remove a placeholder if moving from a foreign list', () => {\n      const displacedBy: DisplacedBy = getDisplacedBy(\n        axis,\n        preset.inHome1.displaceBy,\n      );\n      const overForeign: DragImpact = {\n        displaced: getForcedDisplacement({\n          visible: [\n            { dimension: preset.inForeign1 },\n            { dimension: preset.inForeign2 },\n            { dimension: preset.inForeign3 },\n            { dimension: preset.inForeign4 },\n          ],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            index: preset.inForeign1.descriptor.index,\n            droppableId: preset.foreign.descriptor.id,\n          },\n        },\n      };\n\n      // has a placeholder when moving over foreign\n      {\n        const toForeign: DroppableDimensionMap = recomputePlaceholders({\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: homeImpact,\n          impact: overForeign,\n          draggable: preset.inHome1,\n        });\n\n        expect(toForeign).not.toEqual(preset.droppables);\n        expect(\n          toForeign[preset.foreign.descriptor.id].subject.withPlaceholder,\n        ).toBeTruthy();\n      }\n      // no placeholder when moving back over home\n      {\n        const toHome: DroppableDimensionMap = recomputePlaceholders({\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: overForeign,\n          impact: homeImpact,\n          draggable: preset.inHome1,\n        });\n\n        expect(toHome).toEqual(preset.droppables);\n      }\n\n      // no placeholder when moving over nothing\n      {\n        const toNoWhere: DroppableDimensionMap = recomputePlaceholders({\n          draggables: preset.draggables,\n          droppables: preset.droppables,\n          previousImpact: overForeign,\n          impact: noImpact,\n          draggable: preset.inHome1,\n        });\n\n        expect(toNoWhere).toEqual(preset.droppables);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/registry/cleanup.spec.js",
    "content": "// @flow\nimport type {\n  Registry,\n  DraggableEntry,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\nimport { getPreset } from '../../../util/dimension';\nimport { getDraggableEntry, getDroppableEntry } from '../../../util/registry';\n\nconst preset = getPreset();\n\nit('should remove any registrations', () => {\n  const registry: Registry = createRegistry();\n\n  registry.draggable.register(\n    getDraggableEntry({ uniqueId: '1', dimension: preset.inHome1 }),\n  );\n  registry.droppable.register(\n    getDroppableEntry({ uniqueId: '1', dimension: preset.home }),\n  );\n  expect(registry.draggable.exists(preset.inHome1.descriptor.id)).toBe(true);\n  expect(registry.droppable.exists(preset.home.descriptor.id)).toBe(true);\n\n  registry.clean();\n\n  // now cannot find entries\n  expect(registry.draggable.exists(preset.inHome1.descriptor.id)).toBe(false);\n  expect(registry.droppable.exists(preset.home.descriptor.id)).toBe(false);\n});\n\nit('should remove unsubscribe any event listeners', () => {\n  const listener1 = jest.fn();\n  const listener2 = jest.fn();\n  const registry: Registry = createRegistry();\n\n  const unsubscribe1 = registry.subscribe(listener1);\n  const unsubscribe2 = registry.subscribe(listener2);\n\n  registry.clean();\n\n  const entry: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  registry.draggable.register(entry);\n\n  expect(listener1).not.toHaveBeenCalled();\n  expect(listener2).not.toHaveBeenCalled();\n\n  // manually unsubscribing does nothing and does not throw\n  expect(() => {\n    unsubscribe1();\n    unsubscribe2();\n  }).not.toThrow();\n});\n"
  },
  {
    "path": "test/unit/state/registry/draggable-registration.spec.js",
    "content": "// @flow\nimport type {\n  Registry,\n  DraggableEntry,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\nimport { getPreset } from '../../../util/dimension';\nimport { getDraggableEntry } from '../../../util/registry';\n\nconst preset = getPreset();\n\nit('should allow registration', () => {\n  const registry: Registry = createRegistry();\n  const entry: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n\n  registry.draggable.register(entry);\n\n  expect(registry.draggable.findById(entry.descriptor.id)).toBe(entry);\n});\n\nit('should allow unregistration', () => {\n  const registry: Registry = createRegistry();\n  const entry: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n\n  registry.draggable.register(entry);\n  registry.draggable.unregister(entry);\n\n  expect(registry.draggable.findById(entry.descriptor.id)).toBe(null);\n});\n\nit('should allow for updating existing entries', () => {\n  const registry: Registry = createRegistry();\n  const initial: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  const updated: DraggableEntry = {\n    uniqueId: initial.uniqueId,\n    descriptor: preset.inHome1.descriptor,\n    options: {\n      canDragInteractiveElements: true,\n      // updated\n      shouldRespectForcePress: true,\n      isEnabled: true,\n    },\n    getDimension: () => preset.inHome1,\n  };\n\n  registry.draggable.register(initial);\n  registry.draggable.update(updated, initial);\n\n  expect(registry.draggable.findById(updated.descriptor.id)).toBe(updated);\n});\n\nit('should throw away updates if the uniqueId is outdated', () => {\n  const registry: Registry = createRegistry();\n  const initial: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  const updated: DraggableEntry = {\n    // new uniqueId\n    uniqueId: '2',\n    descriptor: preset.inHome1.descriptor,\n    options: {\n      canDragInteractiveElements: true,\n      // updated\n      shouldRespectForcePress: true,\n      isEnabled: true,\n    },\n    getDimension: () => preset.inHome1,\n  };\n\n  registry.draggable.register(initial);\n  registry.draggable.update(updated, initial);\n\n  expect(registry.draggable.findById(updated.descriptor.id)).toBe(initial);\n});\n\nit('should allow for entry overwriting', () => {\n  const registry: Registry = createRegistry();\n  const entry1: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  const entry2: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n\n  registry.draggable.register(entry1);\n  registry.draggable.register(entry2);\n\n  // overwritten entry 2\n  expect(registry.draggable.findById(entry1.descriptor.id)).toBe(entry2);\n});\n\nit('should not unregister with an outdated uniqueId', () => {\n  const registry: Registry = createRegistry();\n  const entry1: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  const entry2: DraggableEntry = getDraggableEntry({\n    uniqueId: '2',\n    dimension: preset.inHome1,\n  });\n\n  registry.draggable.register(entry1);\n  registry.draggable.register(entry2);\n\n  // overwritten entry 1\n\n  expect(registry.draggable.findById(entry1.descriptor.id)).toBe(entry2);\n\n  // entry 1 is now outdated, so this won't be removed\n  registry.draggable.unregister(entry1);\n  expect(registry.draggable.findById(entry1.descriptor.id)).toBe(entry2);\n});\n\nit('should allow unregistrations when there is no entry', () => {\n  // this can happen if an unregistration occurs after a .clean\n  const registry: Registry = createRegistry();\n  const entry1: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n\n  // no registration\n  expect(registry.draggable.findById(entry1.descriptor.id)).toBe(null);\n\n  expect(() => {\n    registry.draggable.unregister(entry1);\n  }).not.toThrow();\n});\n"
  },
  {
    "path": "test/unit/state/registry/droppable-registration.spec.js",
    "content": "// @flow\nimport type {\n  Registry,\n  DroppableEntry,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\nimport { getPreset } from '../../../util/dimension';\nimport { getDroppableEntry } from '../../../util/registry';\n\nconst preset = getPreset();\n\nit('should allow registration', () => {\n  const registry: Registry = createRegistry();\n  const entry: DroppableEntry = getDroppableEntry({\n    uniqueId: '1',\n    dimension: preset.home,\n  });\n\n  registry.droppable.register(entry);\n\n  expect(registry.droppable.findById(entry.descriptor.id)).toBe(entry);\n});\n\nit('should allow unregistration', () => {\n  const registry: Registry = createRegistry();\n  const entry: DroppableEntry = getDroppableEntry({\n    uniqueId: '1',\n    dimension: preset.home,\n  });\n\n  registry.droppable.register(entry);\n  registry.droppable.unregister(entry);\n\n  expect(registry.droppable.findById(entry.descriptor.id)).toBe(null);\n});\n\nit('should allow for entry overwriting', () => {\n  const registry: Registry = createRegistry();\n  const entry1: DroppableEntry = getDroppableEntry({\n    uniqueId: '1',\n    dimension: preset.home,\n  });\n  const entry2: DroppableEntry = getDroppableEntry({\n    uniqueId: '1',\n    dimension: preset.home,\n  });\n\n  registry.droppable.register(entry1);\n  registry.droppable.register(entry2);\n\n  // overwritten entry 2\n  expect(registry.droppable.findById(entry1.descriptor.id)).toBe(entry2);\n});\n\nit('should not unregister with an outdated uniqueId', () => {\n  const registry: Registry = createRegistry();\n  const entry1: DroppableEntry = getDroppableEntry({\n    uniqueId: '1',\n    dimension: preset.home,\n  });\n  const entry2: DroppableEntry = getDroppableEntry({\n    uniqueId: '2',\n    dimension: preset.home,\n  });\n\n  registry.droppable.register(entry1);\n  // will overwrite with an updated uniqueId\n  registry.droppable.register(entry2);\n\n  // overwritten entry1\n  expect(registry.droppable.findById(entry1.descriptor.id)).toBe(entry2);\n\n  // entry1 is now outdated, so entry2 won't be removed\n  registry.droppable.unregister(entry1);\n  expect(registry.droppable.findById(entry1.descriptor.id)).toBe(entry2);\n});\n\nit('should allow unregistrations when there is no entry', () => {\n  const registry: Registry = createRegistry();\n  const entry1: DroppableEntry = getDroppableEntry({\n    uniqueId: '1',\n    dimension: preset.home,\n  });\n\n  // no registration\n  expect(registry.droppable.findById(entry1.descriptor.id)).toBe(null);\n\n  expect(() => {\n    registry.droppable.unregister(entry1);\n  }).not.toThrow();\n});\n"
  },
  {
    "path": "test/unit/state/registry/event-listeners.spec.js",
    "content": "// @flow\nimport type {\n  Registry,\n  DraggableEntry,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\nimport { getPreset } from '../../../util/dimension';\nimport { getDraggableEntry } from '../../../util/registry';\n\nconst preset = getPreset();\n\nit('should allow adding event listeners', () => {\n  const listener1 = jest.fn();\n  const listener2 = jest.fn();\n  const registry: Registry = createRegistry();\n\n  registry.subscribe(listener1);\n  registry.subscribe(listener2);\n\n  const entry: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  registry.draggable.register(entry);\n\n  expect(listener1).toHaveBeenCalledWith({ type: 'ADDITION', value: entry });\n  expect(listener2).toHaveBeenCalledWith({ type: 'ADDITION', value: entry });\n});\n\nit('should allow removing event listeners', () => {\n  const toBeRemoved = jest.fn();\n  const persistent = jest.fn();\n  const registry: Registry = createRegistry();\n\n  const unsubscribe = registry.subscribe(toBeRemoved);\n  registry.subscribe(persistent);\n\n  unsubscribe();\n\n  const entry: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  registry.draggable.register(entry);\n\n  expect(toBeRemoved).not.toHaveBeenCalled();\n  expect(persistent).toHaveBeenCalledWith({ type: 'ADDITION', value: entry });\n});\n\nit('should not error on a double unsubscribe', () => {\n  const toBeRemoved = jest.fn();\n  const persistent = jest.fn();\n  const registry: Registry = createRegistry();\n\n  const unsubscribe = registry.subscribe(toBeRemoved);\n  registry.subscribe(persistent);\n\n  unsubscribe();\n  unsubscribe();\n  unsubscribe();\n\n  const entry: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  registry.draggable.register(entry);\n\n  // not called\n  expect(toBeRemoved).not.toHaveBeenCalled();\n  // unaffected\n  expect(persistent).toHaveBeenCalledWith({ type: 'ADDITION', value: entry });\n});\n"
  },
  {
    "path": "test/unit/state/registry/queries.spec.js",
    "content": "// @flow\nimport type {\n  Registry,\n  DraggableEntry,\n  DroppableEntry,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\nimport { getPreset } from '../../../util/dimension';\nimport { getDraggableEntry, getDroppableEntry } from '../../../util/registry';\n\nconst preset = getPreset();\n\ndescribe('draggable', () => {\n  const registry: Registry = createRegistry();\n  const inHome1: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  const inHome2: DraggableEntry = getDraggableEntry({\n    uniqueId: '2',\n    dimension: preset.inHome2,\n  });\n  const ofAnotherType: DraggableEntry = getDraggableEntry({\n    uniqueId: '3',\n    dimension: {\n      ...preset.inHome3,\n      descriptor: {\n        id: 'of another type',\n        type: 'some other type',\n        index: 1,\n        droppableId: 'some other droppable id',\n      },\n    },\n  });\n  [inHome1, inHome2, ofAnotherType].forEach((entry: DraggableEntry) => {\n    registry.draggable.register(entry);\n  });\n\n  describe('getById', () => {\n    it('should return an item', () => {\n      expect(registry.draggable.getById(preset.inHome1.descriptor.id)).toBe(\n        inHome1,\n      );\n    });\n    it('should throw if no item exists', () => {\n      expect(() => registry.draggable.getById('some unknown id')).toThrow();\n    });\n  });\n  describe('findById', () => {\n    it('should return an item if it exists', () => {\n      expect(registry.draggable.findById(preset.inHome1.descriptor.id)).toBe(\n        inHome1,\n      );\n    });\n    it('should return null if an item does not exist', () => {\n      expect(registry.draggable.findById('unknown id')).toBe(null);\n    });\n  });\n  describe('exists', () => {\n    it('should return true if an item exists', () => {\n      expect(registry.draggable.exists(preset.inHome1.descriptor.id)).toBe(\n        true,\n      );\n    });\n    it('should return null if an item does not exist', () => {\n      expect(registry.draggable.exists('unknown id')).toBe(false);\n    });\n  });\n  describe('getAllByType', () => {\n    it('should only return items of the correct type', () => {\n      expect(\n        registry.draggable.getAllByType(preset.inHome1.descriptor.type),\n      ).toEqual([inHome1, inHome2]);\n    });\n  });\n});\n\ndescribe('droppable', () => {\n  const registry: Registry = createRegistry();\n  const home: DroppableEntry = getDroppableEntry({\n    uniqueId: '1',\n    dimension: preset.home,\n  });\n  const foreign: DroppableEntry = getDroppableEntry({\n    uniqueId: '2',\n    dimension: preset.foreign,\n  });\n  const ofAnotherType: DroppableEntry = getDroppableEntry({\n    uniqueId: '3',\n    dimension: {\n      ...preset.foreign,\n      descriptor: {\n        id: 'of another type',\n        type: 'some other type',\n        mode: 'standard',\n      },\n    },\n  });\n  [home, foreign, ofAnotherType].forEach((entry: DroppableEntry) => {\n    registry.droppable.register(entry);\n  });\n\n  describe('getById', () => {\n    it('should return an item', () => {\n      expect(registry.droppable.getById(preset.home.descriptor.id)).toBe(home);\n    });\n    it('should throw if no item exists', () => {\n      expect(() => registry.droppable.getById('some unknown id')).toThrow();\n    });\n  });\n  describe('findById', () => {\n    it('should return an item if it exists', () => {\n      expect(registry.droppable.findById(preset.home.descriptor.id)).toBe(home);\n    });\n    it('should return null if an item does not exist', () => {\n      expect(registry.droppable.findById('unknown id')).toBe(null);\n    });\n  });\n  describe('exists', () => {\n    it('should return true if an item exists', () => {\n      expect(registry.droppable.exists(preset.home.descriptor.id)).toBe(true);\n    });\n    it('should return null if an item does not exist', () => {\n      expect(registry.droppable.exists('unknown id')).toBe(false);\n    });\n  });\n  describe('getAllByType', () => {\n    it('should only return items of the correct type', () => {\n      expect(\n        registry.droppable.getAllByType(preset.home.descriptor.type),\n      ).toEqual([home, foreign]);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/registry/use-registry.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport type {\n  Registry,\n  DraggableEntry,\n} from '../../../../src/state/registry/registry-types';\nimport type { DraggableId } from '../../../../src/types';\nimport { invariant } from '../../../../src/invariant';\nimport { getPreset } from '../../../util/dimension';\nimport { getDraggableEntry } from '../../../util/registry';\nimport useRegistry from '../../../../src/state/registry/use-registry';\n\nconst preset = getPreset();\n\nit('should remove any registrations', () => {\n  let registry: Registry;\n  const entry: DraggableEntry = getDraggableEntry({\n    uniqueId: '1',\n    dimension: preset.inHome1,\n  });\n  const id: DraggableId = preset.inHome1.descriptor.id;\n  function App() {\n    registry = useRegistry();\n    return null;\n  }\n\n  const { unmount } = render(<App />);\n  invariant(registry);\n\n  // initial registration\n  registry.draggable.register(entry);\n  expect(registry.draggable.exists(id)).toBe(true);\n\n  // still available after a unmount\n  unmount();\n  expect(registry.draggable.exists(id)).toBe(true);\n\n  // cleared after frame\n  requestAnimationFrame.step();\n  expect(registry.draggable.exists(id)).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/state/scroll-viewport.spec.js",
    "content": "// @flow\nimport { getRect, type Position, type Rect } from 'css-box-model';\nimport type { Viewport } from '../../../src/types';\nimport { add, negate, subtract } from '../../../src/state/position';\nimport scrollViewport from '../../../src/state/scroll-viewport';\nimport { offsetByPosition } from '../../../src/state/spacing';\n\nconst origin: Position = { x: 0, y: 0 };\n\nit('should update the window details scroll', () => {\n  const original: Viewport = {\n    frame: getRect({\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 100,\n    }),\n    scroll: {\n      initial: origin,\n      current: origin,\n      max: { x: 1000, y: 1000 },\n      diff: {\n        value: origin,\n        displacement: origin,\n      },\n    },\n  };\n  const newScroll: Position = { x: 100, y: 50 };\n  const expected: Viewport = {\n    frame: getRect({\n      // shifted 50\n      top: 50,\n      bottom: 150,\n      // shifted 100\n      left: 100,\n      right: 200,\n    }),\n    scroll: {\n      initial: origin,\n      current: newScroll,\n      max: { x: 1000, y: 1000 },\n      diff: {\n        value: newScroll,\n        displacement: negate(newScroll),\n      },\n    },\n  };\n\n  const updated: Viewport = scrollViewport(original, newScroll);\n\n  expect(updated).toEqual(expected);\n});\n\nit('should correctly update scroll across multiple movements (forwards)', () => {\n  const original: Rect = getRect({\n    top: 0,\n    left: 0,\n    right: 100,\n    bottom: 100,\n  });\n\n  const max: Position = { x: 200, y: 200 };\n\n  let lastViewport: Viewport = {\n    frame: original,\n    scroll: {\n      initial: origin,\n      current: origin,\n      max,\n      diff: {\n        value: origin,\n        displacement: origin,\n      },\n    },\n  };\n\n  let lastScroll: Position = origin;\n  let runCount: number = 0;\n\n  while (lastScroll.y < max.y && lastScroll.x < max.x) {\n    const newScroll: Position = add(lastScroll, { x: 10, y: 20 });\n    const updated: Viewport = scrollViewport(lastViewport, newScroll);\n\n    const expected: Viewport = {\n      frame: getRect(offsetByPosition(original, newScroll)),\n      scroll: {\n        initial: origin,\n        current: newScroll,\n        max,\n        diff: {\n          value: newScroll,\n          displacement: negate(newScroll),\n        },\n      },\n    };\n    expect(updated).toEqual(expected);\n    expect(updated.frame.top).toEqual(newScroll.y);\n    expect(updated.frame.left).toEqual(newScroll.x);\n\n    lastScroll = newScroll;\n    lastViewport = updated;\n    runCount++;\n  }\n\n  // Simply asserting our loop ran a few times\n  expect(runCount).toBeGreaterThan(2);\n});\n\nit('should correctly update scroll across multiple movements (backwards)', () => {\n  const original: Rect = getRect({\n    top: 0,\n    left: 0,\n    right: 100,\n    bottom: 100,\n  });\n\n  const max: Position = { x: 200, y: 200 };\n\n  let lastViewport: Viewport = {\n    frame: original,\n    scroll: {\n      initial: max,\n      current: max,\n      max,\n      diff: {\n        value: origin,\n        displacement: origin,\n      },\n    },\n  };\n\n  let lastScroll: Position = max;\n  let runCount: number = 0;\n  while (lastScroll.y > 0 && lastScroll.x > 0) {\n    const newScroll: Position = subtract(lastScroll, { x: 10, y: 20 });\n    const updated: Viewport = scrollViewport(lastViewport, newScroll);\n\n    const diff: Position = subtract(newScroll, lastViewport.scroll.initial);\n\n    const expected: Viewport = {\n      frame: getRect(offsetByPosition(original, newScroll)),\n      scroll: {\n        initial: max,\n        current: newScroll,\n        max,\n        diff: {\n          value: diff,\n          displacement: negate(diff),\n        },\n      },\n    };\n    expect(updated).toEqual(expected);\n    expect(updated.frame.top).toEqual(newScroll.y);\n    expect(updated.frame.left).toEqual(newScroll.x);\n\n    lastScroll = newScroll;\n    lastViewport = updated;\n    runCount++;\n  }\n\n  // Simply asserting our loop ran a few times\n  expect(runCount).toBeGreaterThan(2);\n});\n"
  },
  {
    "path": "test/unit/state/spacing.spec.js",
    "content": "// @flow\nimport { type Position, type Spacing } from 'css-box-model';\nimport {\n  getCorners,\n  expandByPosition,\n  offsetByPosition,\n} from '../../../src/state/spacing';\n\nconst base: Spacing = {\n  top: 8,\n  right: 16,\n  bottom: 23,\n  left: 5,\n};\n\ndescribe('spacing', () => {\n  describe('expandByPosition', () => {\n    it('should increase the size of the spacing', () => {\n      const spacing: Spacing = {\n        top: 0,\n        right: 10,\n        bottom: 10,\n        left: 0,\n      };\n      const position = {\n        x: 5,\n        y: 5,\n      };\n      const expected = {\n        top: -5,\n        right: 15,\n        bottom: 15,\n        left: -5,\n      };\n\n      expect(expandByPosition(spacing, position)).toEqual(expected);\n    });\n  });\n\n  describe('offsetByPosition', () => {\n    it('should add x/y values to top/right/bottom/left dimensions', () => {\n      const offsetPosition: Position = {\n        x: 10,\n        y: 5,\n      };\n      const expected: Spacing = {\n        top: 13,\n        right: 26,\n        bottom: 28,\n        left: 15,\n      };\n      expect(offsetByPosition(base, offsetPosition)).toEqual(expected);\n    });\n  });\n\n  describe('getCorners', () => {\n    it('should return the corners of a spacing box in the order TL, TR, BL, BR', () => {\n      const spacing: Spacing = {\n        top: 1,\n        right: 2,\n        bottom: 3,\n        left: 4,\n      };\n      const expected = [\n        { x: 4, y: 1 },\n        { x: 2, y: 1 },\n        { x: 4, y: 3 },\n        { x: 2, y: 3 },\n      ];\n      expect(getCorners(spacing)).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/update-displacement-visibility/recompute.spec.js",
    "content": "// @flow\nimport type { DisplacedBy, Axis, DragImpact } from '../../../../src/types';\nimport { getPreset } from '../../../util/dimension';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport recompute from '../../../../src/state/update-displacement-visibility/recompute';\nimport { horizontal, vertical } from '../../../../src/state/axis';\nimport { getForcedDisplacement } from '../../../util/impact';\n\n[horizontal, vertical].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    const preset = getPreset(axis);\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      axis,\n      preset.inHome1.displaceBy,\n    );\n    // moving inHome1 down past inHome2 and inHome3\n    const impact: DragImpact = {\n      displaced: getForcedDisplacement({\n        // pretending the displacement is not visible\n        invisible: [preset.inHome2, preset.inHome3],\n      }),\n      displacedBy,\n      at: {\n        type: 'REORDER',\n        destination: {\n          droppableId: preset.home.descriptor.id,\n          index: preset.inHome3.descriptor.index,\n        },\n      },\n    };\n\n    it('should recompute a displacement', () => {\n      const recomputed: DragImpact = recompute({\n        impact,\n        viewport: preset.viewport,\n        destination: preset.home,\n        draggables: preset.draggables,\n      });\n\n      const expected: DragImpact = {\n        ...impact,\n        displaced: getForcedDisplacement({\n          // visibility recalculated\n          visible: [\n            // not animated as previously invisible\n            { dimension: preset.inHome2, shouldAnimate: false },\n            { dimension: preset.inHome3, shouldAnimate: false },\n          ],\n        }),\n      };\n      expect(recomputed).toEqual(expected);\n    });\n\n    it('should allow the displacement animation to be forced', () => {\n      const recomputed: DragImpact = recompute({\n        impact,\n        viewport: preset.viewport,\n        destination: preset.home,\n        draggables: preset.draggables,\n        forceShouldAnimate: true,\n      });\n\n      const expected: DragImpact = {\n        ...impact,\n        displaced: getForcedDisplacement({\n          // visibility recalculated\n          visible: [\n            // forced animation\n            { dimension: preset.inHome2, shouldAnimate: true },\n            { dimension: preset.inHome3, shouldAnimate: true },\n          ],\n        }),\n      };\n      expect(recomputed).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/update-displacement-visibility/speculative-displacement.spec.js",
    "content": "// @flow\nimport { getRect } from 'css-box-model';\nimport type {\n  Axis,\n  DragImpact,\n  Viewport,\n  DroppableId,\n  TypeId,\n  DraggableDimension,\n  DroppableDimension,\n  DisplacedBy,\n  DraggableDimensionMap,\n} from '../../../../src/types';\nimport {\n  getPreset,\n  getDraggableDimension,\n  getDroppableDimension,\n} from '../../../util/dimension';\nimport speculativelyIncrease from '../../../../src/state/update-displacement-visibility/speculatively-increase';\nimport noImpact from '../../../../src/state/no-impact';\nimport { createViewport } from '../../../util/viewport';\nimport { origin, patch } from '../../../../src/state/position';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport { toDraggableMap } from '../../../../src/state/dimension-structures';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport { isPartiallyVisible } from '../../../../src/state/visibility/is-visible';\nimport getLiftEffect from '../../../../src/state/get-lift-effect';\nimport { getForcedDisplacement } from '../../../util/impact';\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on ${axis.direction} axis`, () => {\n    it('should do nothing when there is no displacement', () => {\n      const preset = getPreset(axis);\n      const { impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        home: preset.home,\n        viewport: preset.viewport,\n      });\n\n      const impact1: DragImpact = speculativelyIncrease({\n        impact: homeImpact,\n        viewport: preset.viewport,\n        destination: preset.home,\n        draggables: preset.draggables,\n        maxScrollChange: { x: 1000, y: 1000 },\n      });\n      expect(impact1).toEqual(homeImpact);\n\n      const impact2: DragImpact = speculativelyIncrease({\n        impact: noImpact,\n        viewport: preset.viewport,\n        destination: preset.home,\n        draggables: preset.draggables,\n        maxScrollChange: { x: 1000, y: 1000 },\n      });\n      expect(impact2).toEqual(noImpact);\n    });\n\n    const foreignId: DroppableId = 'foreign';\n    const typeId: TypeId = 'our-type';\n    const homeCrossAxisStart: number = 0;\n    const homeCrossAxisEnd: number = 100;\n    const foreignCrossAxisStart: number = 100;\n    const foreignCrossAxisEnd: number = 200;\n    const itemSize: number = 50;\n\n    const home: DroppableDimension = getDroppableDimension({\n      descriptor: {\n        id: 'home',\n        type: typeId,\n        mode: 'standard',\n      },\n      direction: axis.direction,\n      borderBox: {\n        [axis.crossAxisStart]: homeCrossAxisStart,\n        [axis.crossAxisEnd]: homeCrossAxisEnd,\n        [axis.start]: 0,\n        [axis.end]: 10000,\n      },\n    });\n    const inHome1: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'inhome1',\n        type: home.descriptor.type,\n        droppableId: home.descriptor.id,\n        index: 0,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: homeCrossAxisStart,\n        [axis.crossAxisEnd]: homeCrossAxisEnd,\n        [axis.start]: 0,\n        [axis.end]: itemSize,\n      },\n    });\n    const inForeign1: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'inForeign1',\n        type: typeId,\n        droppableId: foreignId,\n        index: 0,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: foreignCrossAxisStart,\n        [axis.crossAxisEnd]: foreignCrossAxisEnd,\n        [axis.start]: 0,\n        [axis.end]: itemSize,\n      },\n    });\n    const inForeign2: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'inForeign2',\n        type: typeId,\n        droppableId: foreignId,\n        index: 1,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: foreignCrossAxisStart,\n        [axis.crossAxisEnd]: foreignCrossAxisEnd,\n        [axis.start]: inForeign1.page.borderBox[axis.end],\n        [axis.end]: inForeign1.page.borderBox[axis.end] + itemSize,\n      },\n    });\n    const inForeign3: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'inForeign3',\n        type: typeId,\n        droppableId: foreignId,\n        index: 2,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: foreignCrossAxisStart,\n        [axis.crossAxisEnd]: foreignCrossAxisEnd,\n        [axis.start]: inForeign2.page.borderBox[axis.end],\n        [axis.end]: inForeign2.page.borderBox[axis.end] + itemSize,\n      },\n    });\n    const inForeign4: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'inForeign4',\n        type: typeId,\n        droppableId: foreignId,\n        index: 3,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: foreignCrossAxisStart,\n        [axis.crossAxisEnd]: foreignCrossAxisEnd,\n        [axis.start]: inForeign3.page.borderBox[axis.end],\n        [axis.end]: inForeign3.page.borderBox[axis.end] + itemSize,\n      },\n    });\n    const inForeign5: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'inForeign5',\n        type: typeId,\n        droppableId: foreignId,\n        index: 4,\n      },\n      borderBox: {\n        [axis.crossAxisStart]: foreignCrossAxisStart,\n        [axis.crossAxisEnd]: foreignCrossAxisEnd,\n        [axis.start]: inForeign4.page.borderBox[axis.end],\n        [axis.end]: inForeign4.page.borderBox[axis.end] + itemSize,\n      },\n    });\n    const draggables: DraggableDimensionMap = toDraggableMap([\n      inHome1,\n      inForeign1,\n      inForeign2,\n      inForeign3,\n      inForeign4,\n      inForeign5,\n    ]);\n\n    it('should increase the visible displacement in the window by the amount of the max scroll change', () => {\n      const foreign: DroppableDimension = getDroppableDimension({\n        descriptor: {\n          id: foreignId,\n          type: 'huge',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        borderBox: {\n          [axis.crossAxisStart]: foreignCrossAxisStart,\n          [axis.crossAxisEnd]: foreignCrossAxisEnd,\n          [axis.start]: 0,\n          [axis.end]: 10000,\n        },\n      });\n      // Viewport is big enough to fit inForeign1 and inForeign2\n      const sizeOfViewport: number = itemSize + itemSize - 1;\n\n      const viewport: Viewport = createViewport({\n        frame: getRect({\n          [axis.crossAxisStart]: 0,\n          [axis.crossAxisEnd]: 10000,\n          [axis.start]: 0,\n          [axis.end]: sizeOfViewport,\n        }),\n        scroll: origin,\n        // some massive number\n        scrollHeight: 20000,\n        scrollWidth: 20000,\n      });\n      // visiblity validation\n      // in the foreign list, these should be visible\n      expect(\n        isPartiallyVisible({\n          target: inForeign1.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(true);\n      expect(\n        isPartiallyVisible({\n          target: inForeign2.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(true);\n      // the rest should be invisible\n      expect(\n        isPartiallyVisible({\n          target: inForeign3.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(false);\n      expect(\n        isPartiallyVisible({\n          target: inForeign4.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(false);\n      expect(\n        isPartiallyVisible({\n          target: inForeign5.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(false);\n\n      // inHome1 has moved into the foreign list below inForeign1\n      const displacedBy: DisplacedBy = getDisplacedBy(axis, inHome1.displaceBy);\n\n      const previousImpact: DragImpact = {\n        displaced: getForcedDisplacement({\n          // would normally be visible in viewport\n          visible: [{ dimension: inForeign2 }],\n          // normally not visible in viewport\n          invisible: [inForeign3, inForeign4, inForeign5],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            droppableId: foreign.descriptor.id,\n            index: inForeign2.descriptor.index,\n          },\n        },\n      };\n\n      const result: DragImpact = speculativelyIncrease({\n        impact: previousImpact,\n        viewport,\n        destination: foreign,\n        draggables,\n        maxScrollChange: patch(axis.line, itemSize),\n      });\n\n      const expected: DragImpact = {\n        // unchanged locations\n        ...previousImpact,\n        displaced: getForcedDisplacement({\n          visible: [\n            // already visibly displaced: inside viewport\n            { dimension: inForeign2, shouldAnimate: true },\n            // speculatively increased. Forced to not animate\n            { dimension: inForeign3, shouldAnimate: false },\n            { dimension: inForeign4, shouldAnimate: false },\n          ],\n          // Bigger than 2x the size of the viewport - outside of the overscanning reach\n          invisible: [inForeign5],\n        }),\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should increase the visible displacement in the droppable by the amount of the max scroll change', () => {\n      // when moving into the foreign list there will be enough room for inHome1 and inForeign1\n      // inHome1 and inForeign1 can be visible in the viewport at the same time\n      const sizeOfDroppable: number = itemSize + itemSize - 1;\n\n      const foreign: DroppableDimension = getDroppableDimension({\n        descriptor: {\n          id: foreignId,\n          type: 'huge',\n          mode: 'standard',\n        },\n        direction: axis.direction,\n        // large subject\n        borderBox: {\n          [axis.crossAxisStart]: foreignCrossAxisStart,\n          [axis.crossAxisEnd]: foreignCrossAxisEnd,\n          [axis.start]: 0,\n          [axis.end]: 10000,\n        },\n        // small frame (will clip subject)\n        closest: {\n          borderBox: {\n            [axis.crossAxisStart]: foreignCrossAxisStart,\n            [axis.crossAxisEnd]: foreignCrossAxisEnd,\n            [axis.start]: 0,\n            [axis.end]: sizeOfDroppable,\n          },\n          shouldClipSubject: true,\n          scroll: origin,\n          scrollSize: {\n            scrollHeight: 10000,\n            scrollWidth: 10000,\n          },\n        },\n      });\n      // huge viewport\n      const viewport: Viewport = createViewport({\n        frame: getRect({\n          [axis.crossAxisStart]: 0,\n          [axis.crossAxisEnd]: 10000,\n          [axis.start]: 0,\n          [axis.end]: 10000,\n        }),\n        scroll: origin,\n        scrollHeight: 10000,\n        scrollWidth: 10000,\n      });\n      // visiblity validation\n      // in the foreign list, these should be visible\n      expect(\n        isPartiallyVisible({\n          target: inForeign1.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(true);\n      expect(\n        isPartiallyVisible({\n          target: inForeign2.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(true);\n      // the rest should be invisible\n      expect(\n        isPartiallyVisible({\n          target: inForeign3.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(false);\n      expect(\n        isPartiallyVisible({\n          target: inForeign4.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(false);\n      expect(\n        isPartiallyVisible({\n          target: inForeign5.page.borderBox,\n          destination: foreign,\n          viewport: viewport.frame,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(false);\n\n      // inHome1 has moved into the foreign list below inForeign1\n      const displacedBy: DisplacedBy = getDisplacedBy(axis, inHome1.displaceBy);\n\n      const previousImpact: DragImpact = {\n        displaced: getForcedDisplacement({\n          // would normally be visible in viewport\n          visible: [{ dimension: inForeign2 }],\n          // normally not visible in viewport\n          invisible: [inForeign3, inForeign4, inForeign5],\n        }),\n        displacedBy,\n        at: {\n          type: 'REORDER',\n          destination: {\n            droppableId: foreign.descriptor.id,\n            index: inForeign2.descriptor.index,\n          },\n        },\n      };\n\n      const result: DragImpact = speculativelyIncrease({\n        impact: previousImpact,\n        viewport,\n        destination: foreign,\n        draggables,\n        maxScrollChange: patch(axis.line, itemSize),\n      });\n\n      const expected: DragImpact = {\n        // unchanged locations\n        ...previousImpact,\n        displaced: getForcedDisplacement({\n          visible: [\n            // already visibly displaced\n            { dimension: inForeign2, shouldAnimate: true },\n            // speculatively increased. Forced to not animate\n            { dimension: inForeign3, shouldAnimate: false },\n            { dimension: inForeign4, shouldAnimate: false },\n          ],\n          // not speculatively increased\n          invisible: [inForeign5],\n        }),\n      };\n      expect(result).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/visibility/is-partially-visible-through-frame.spec.js",
    "content": "// @flow\nimport { type Spacing } from 'css-box-model';\nimport isPartiallyVisibleThroughFrame from '../../../../src/state/visibility/is-partially-visible-through-frame';\nimport { offsetByPosition } from '../../../../src/state/spacing';\nimport { expandBySpacing } from '../../../util/spacing';\n\nconst frame: Spacing = {\n  top: 0,\n  left: 0,\n  right: 100,\n  bottom: 100,\n};\n\ndescribe('is partially visible through frame', () => {\n  describe('subject is smaller than frame', () => {\n    describe('completely outside frame', () => {\n      it('should return false if subject is outside frame on any side', () => {\n        const outside: Spacing[] = [\n          // outside on top\n          offsetByPosition(frame, { x: 0, y: -101 }),\n          // outside on right\n          offsetByPosition(frame, { x: 101, y: 0 }),\n          // outside on bottom\n          offsetByPosition(frame, { x: 0, y: 101 }),\n          // outside on left\n          offsetByPosition(frame, { x: -101, y: 0 }),\n        ];\n\n        outside.forEach((subject: Spacing) => {\n          expect(isPartiallyVisibleThroughFrame(frame)(subject)).toBe(false);\n        });\n      });\n    });\n\n    describe('contained in frame', () => {\n      it('should return true when subject is contained within frame', () => {\n        const subject: Spacing = {\n          top: 10,\n          left: 10,\n          right: 90,\n          bottom: 90,\n        };\n\n        expect(isPartiallyVisibleThroughFrame(frame)(subject)).toBe(true);\n      });\n    });\n\n    describe('partially visible', () => {\n      it('should return true if partially visible horizontally and vertically', () => {\n        const subject: Spacing = {\n          // visible\n          top: 10,\n          // not visible\n          bottom: 110,\n          // visible\n          left: 50,\n          // not visible\n          right: 150,\n        };\n\n        expect(isPartiallyVisibleThroughFrame(frame)(subject)).toBe(true);\n      });\n    });\n  });\n\n  describe('subject is equal to frame', () => {\n    it('should return true when the frame is equal to the subject', () => {\n      expect(isPartiallyVisibleThroughFrame(frame)(frame)).toBe(true);\n      expect(isPartiallyVisibleThroughFrame(frame)({ ...frame })).toBe(true);\n    });\n  });\n\n  describe('subject is bigger than frame', () => {\n    const bigSubject: Spacing = expandBySpacing(frame, frame);\n\n    it('should return false if the subject has no overlap with the frame', () => {\n      const subject: Spacing = offsetByPosition(bigSubject, {\n        x: 1000,\n        y: 1000,\n      });\n\n      expect(isPartiallyVisibleThroughFrame(frame)(subject)).toBe(false);\n    });\n\n    it('should return true if subject is bigger on every side', () => {\n      expect(isPartiallyVisibleThroughFrame(frame)(bigSubject)).toBe(true);\n    });\n\n    describe('partially visible', () => {\n      it('should return true if partially visible horizontally and vertically on any side', () => {\n        // bigger on every edge except one\n        const subjects: Spacing[] = [\n          // top is not above edge\n          { top: 1, left: -100, right: 500, bottom: 500 },\n          // left is after edge\n          { top: -100, left: 1, right: 500, bottom: 500 },\n          // bottom is before edge\n          { top: -100, left: -100, right: 500, bottom: 99 },\n          // right is before edge\n          { top: -100, left: -100, right: 99, bottom: 500 },\n        ];\n\n        subjects.forEach((subject: Spacing) => {\n          expect(isPartiallyVisibleThroughFrame(frame)(subject)).toBe(true);\n        });\n      });\n\n      it('should return false when only partially visible horizontally', () => {\n        const subject: Spacing = {\n          // not visible\n          top: 101,\n          bottom: 500,\n          // visible\n          left: 1,\n          right: 500,\n        };\n\n        expect(isPartiallyVisibleThroughFrame(frame)(subject)).toEqual(false);\n      });\n\n      it('should return false when only partially visible vertically', () => {\n        const subject: Spacing = {\n          // visible\n          top: 1,\n          bottom: 500,\n          // not visible\n          left: 101,\n          right: 500,\n        };\n\n        expect(isPartiallyVisibleThroughFrame(frame)(subject)).toEqual(false);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/visibility/is-partially-visible.spec.js",
    "content": "// @flow\nimport { getRect, type Rect, type Spacing } from 'css-box-model';\nimport { isPartiallyVisible } from '../../../../src/state/visibility/is-visible';\nimport scrollDroppable from '../../../../src/state/droppable/scroll-droppable';\nimport { offsetByPosition } from '../../../../src/state/spacing';\nimport { getDroppableDimension, getFrame } from '../../../util/dimension';\nimport type { DroppableDimension } from '../../../../src/types';\n\nconst viewport: Rect = getRect({\n  right: 800,\n  top: 0,\n  left: 0,\n  bottom: 600,\n});\n\nconst asBigAsViewport: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'same-as-viewport',\n    type: 'TYPE',\n    mode: 'standard',\n  },\n  borderBox: viewport,\n});\n\nconst inViewport1: Spacing = {\n  top: 10,\n  left: 10,\n  right: 100,\n  bottom: 100,\n};\n\nconst inViewport2: Spacing = {\n  top: 10,\n  left: 200,\n  right: 400,\n  bottom: 100,\n};\n\nconst notInViewport: Spacing = {\n  top: 0,\n  right: 1000,\n  left: 900,\n  bottom: 600,\n};\n\nconst asBigAsInViewport1: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'subset',\n    type: 'TYPE',\n    mode: 'standard',\n  },\n  borderBox: inViewport1,\n});\n\ndescribe('is partially visible', () => {\n  describe('viewport', () => {\n    describe('without changes in droppable scroll', () => {\n      it('should return false if the item is not in the viewport', () => {\n        expect(\n          isPartiallyVisible({\n            target: notInViewport,\n            viewport,\n            destination: asBigAsViewport,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(false);\n      });\n\n      it('should return true if item takes up entire viewport', () => {\n        expect(\n          isPartiallyVisible({\n            target: viewport,\n            viewport,\n            destination: asBigAsViewport,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(true);\n      });\n\n      it('should return true if the item is totally visible in the viewport', () => {\n        expect(\n          isPartiallyVisible({\n            target: inViewport1,\n            viewport,\n            destination: asBigAsViewport,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(true);\n      });\n\n      it('should return true if the item is partially visible in the viewport', () => {\n        const partials: Spacing[] = [\n          // bleed over top\n          offsetByPosition(viewport, { x: 0, y: -1 }),\n          // bleed over right\n          offsetByPosition(viewport, { x: 1, y: 0 }),\n          // bleed over bottom\n          offsetByPosition(viewport, { x: 0, y: 1 }),\n          // bleed over left\n          offsetByPosition(viewport, { x: -1, y: 0 }),\n        ];\n\n        partials.forEach((partial: Spacing) => {\n          expect(\n            isPartiallyVisible({\n              target: partial,\n              viewport,\n              destination: asBigAsViewport,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(true);\n        });\n      });\n    });\n\n    describe('with changes in droppable scroll', () => {\n      const clippedByViewport: DroppableDimension = getDroppableDimension({\n        descriptor: {\n          id: 'clipped',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        borderBox: {\n          top: viewport.top,\n          // stretches out the bottom of the viewport\n          bottom: viewport.bottom + 100,\n          left: viewport.left,\n          right: viewport.right,\n        },\n        closest: {\n          borderBox: viewport,\n          scrollSize: {\n            scrollWidth: viewport.width,\n            scrollHeight: viewport.bottom + 100,\n          },\n          scroll: { x: 0, y: 0 },\n          shouldClipSubject: true,\n        },\n      });\n\n      describe('originally invisible but now invisible', () => {\n        it('should take into account the droppable scroll when detecting visibility', () => {\n          const originallyInvisible: Spacing = {\n            top: viewport.bottom + 1,\n            bottom: viewport.bottom + 100,\n            right: viewport.left + 1,\n            left: viewport.left + 100,\n          };\n\n          // originally invisible\n          expect(\n            isPartiallyVisible({\n              target: originallyInvisible,\n              destination: clippedByViewport,\n              viewport,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(false);\n\n          // after scroll the target is now visible\n          expect(\n            isPartiallyVisible({\n              target: originallyInvisible,\n              destination: scrollDroppable(clippedByViewport, { x: 0, y: 100 }),\n              viewport,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(true);\n        });\n      });\n\n      describe('originally visible but now visible', () => {\n        it('should take into account the droppable scroll when detecting visibility', () => {\n          const originallyVisible: Spacing = {\n            top: viewport.top,\n            bottom: viewport.top + 50,\n            right: viewport.left + 1,\n            left: viewport.left + 100,\n          };\n\n          // originally visible\n          expect(\n            isPartiallyVisible({\n              target: originallyVisible,\n              destination: clippedByViewport,\n              viewport,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(true);\n\n          // after scroll the target is now invisible\n          expect(\n            isPartiallyVisible({\n              target: originallyVisible,\n              destination: scrollDroppable(clippedByViewport, { x: 0, y: 100 }),\n              viewport,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(false);\n        });\n      });\n    });\n  });\n\n  describe('droppable', () => {\n    const borderBox: Rect = getRect({\n      top: 0,\n      left: 0,\n      right: 600,\n      bottom: 600,\n    });\n    const frameBorderBox: Spacing = {\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 100,\n    };\n\n    const scrollable: DroppableDimension = getDroppableDimension({\n      descriptor: {\n        id: 'clipped',\n        type: 'TYPE',\n        mode: 'standard',\n      },\n      borderBox,\n      closest: {\n        borderBox: frameBorderBox,\n        scrollSize: {\n          scrollWidth: borderBox.width,\n          scrollHeight: borderBox.height,\n        },\n        scroll: { x: 0, y: 0 },\n        shouldClipSubject: true,\n      },\n    });\n\n    describe('without changes in droppable scroll', () => {\n      it('should return false if outside the droppable', () => {\n        expect(\n          isPartiallyVisible({\n            target: inViewport2,\n            viewport,\n            destination: asBigAsInViewport1,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(false);\n      });\n\n      it('should return true if the target is bigger than the droppable', () => {\n        expect(\n          isPartiallyVisible({\n            target: viewport,\n            viewport,\n            destination: asBigAsInViewport1,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(true);\n      });\n\n      it('should return true if the same size of the droppable', () => {\n        expect(\n          isPartiallyVisible({\n            target: inViewport1,\n            viewport,\n            destination: asBigAsInViewport1,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(true);\n      });\n\n      it('should return true if within the droppable', () => {\n        const insideDroppable: Spacing = {\n          top: 20,\n          left: 20,\n          right: 80,\n          bottom: 80,\n        };\n\n        expect(\n          isPartiallyVisible({\n            target: insideDroppable,\n            viewport,\n            destination: asBigAsInViewport1,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(true);\n      });\n\n      it('should return true if partially within the droppable', () => {\n        const partials: Spacing[] = [\n          // bleed over top\n          offsetByPosition(inViewport1, { x: 0, y: -1 }),\n          // bleed over right\n          offsetByPosition(inViewport1, { x: 1, y: 0 }),\n          // bleed over bottom\n          offsetByPosition(inViewport1, { x: 0, y: 1 }),\n          // bleed over left\n          offsetByPosition(inViewport1, { x: -1, y: 0 }),\n        ];\n\n        partials.forEach((partial: Spacing) => {\n          expect(\n            isPartiallyVisible({\n              target: partial,\n              viewport,\n              destination: asBigAsInViewport1,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(true);\n        });\n      });\n\n      it('should return false if falling on clipped area of droppable', () => {\n        const ourFrame: Rect = getRect({\n          top: 10,\n          left: 10,\n          right: 100,\n          // cuts the droppable short\n          bottom: 100,\n        });\n        const clippedDroppable: DroppableDimension = getDroppableDimension({\n          descriptor: {\n            id: 'clipped',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          borderBox: {\n            ...ourFrame,\n            // stretches out past frame\n            bottom: 600,\n          },\n          closest: {\n            borderBox: ourFrame,\n            scrollSize: {\n              scrollHeight: 600,\n              scrollWidth: ourFrame.width,\n            },\n            scroll: { x: 0, y: 0 },\n            shouldClipSubject: true,\n          },\n        });\n        const inSubjectOutsideFrame: Spacing = {\n          ...frameBorderBox,\n          top: 110,\n          bottom: 200,\n        };\n\n        expect(\n          isPartiallyVisible({\n            target: inSubjectOutsideFrame,\n            destination: clippedDroppable,\n            withDroppableDisplacement: true,\n            viewport,\n          }),\n        ).toBe(false);\n      });\n    });\n\n    describe('with changes in droppable scroll', () => {\n      describe('originally invisible but now invisible', () => {\n        it('should take into account the droppable scroll when detecting visibility', () => {\n          const originallyInvisible: Spacing = {\n            left: frameBorderBox.left,\n            right: frameBorderBox.right,\n            top: frameBorderBox.bottom + 10,\n            bottom: frameBorderBox.bottom + 20,\n          };\n\n          // originally invisible\n          expect(\n            isPartiallyVisible({\n              target: originallyInvisible,\n              destination: scrollable,\n              withDroppableDisplacement: true,\n              viewport,\n            }),\n          ).toBe(false);\n\n          // after scroll the target is now visible\n          expect(\n            isPartiallyVisible({\n              target: originallyInvisible,\n              destination: scrollDroppable(scrollable, { x: 0, y: 100 }),\n              viewport,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(true);\n        });\n      });\n\n      describe('originally visible but now visible', () => {\n        it('should take into account the droppable scroll when detecting visibility', () => {\n          const originallyVisible: Spacing = {\n            ...frameBorderBox,\n            top: 10,\n            bottom: 20,\n          };\n\n          // originally visible\n          expect(\n            isPartiallyVisible({\n              target: originallyVisible,\n              destination: scrollable,\n              viewport,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(true);\n\n          // after scroll the target is now invisible\n          expect(\n            isPartiallyVisible({\n              target: originallyVisible,\n              destination: scrollDroppable(scrollable, { x: 0, y: 100 }),\n              viewport,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(false);\n        });\n      });\n\n      it('should not consider droppable scroll changes if asked to ignore them', () => {\n        const originallyInvisible: Spacing = {\n          left: frameBorderBox.left,\n          right: frameBorderBox.right,\n          top: frameBorderBox.bottom + 10,\n          bottom: frameBorderBox.bottom + 20,\n        };\n\n        // originally invisible\n        expect(\n          isPartiallyVisible({\n            target: originallyInvisible,\n            destination: scrollable,\n            withDroppableDisplacement: true,\n            viewport,\n          }),\n        ).toBe(false);\n\n        const scrolled: DroppableDimension = scrollDroppable(scrollable, {\n          x: 0,\n          y: 100,\n        });\n        // still invisible if asked not to consider scroll\n        expect(\n          isPartiallyVisible({\n            target: originallyInvisible,\n            destination: scrolled,\n            viewport,\n            // key change\n            withDroppableDisplacement: false,\n          }),\n        ).toBe(false);\n        // validation: when asked to consider scroll the target is now visible\n        expect(\n          isPartiallyVisible({\n            target: originallyInvisible,\n            destination: scrolled,\n            viewport,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(true);\n      });\n    });\n\n    describe('with invisible subject', () => {\n      it('should return false when subject is totally invisible', () => {\n        // creating a droppable where the frame is bigger than the subject\n        const droppable: DroppableDimension = getDroppableDimension({\n          descriptor: {\n            id: 'droppable',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          borderBox: {\n            top: 0,\n            left: 0,\n            bottom: 100,\n            right: 100,\n          },\n          closest: {\n            borderBox: {\n              top: 0,\n              left: 0,\n              bottom: 100,\n              right: 100,\n            },\n            scrollSize: {\n              scrollHeight: 600,\n              scrollWidth: 600,\n            },\n            scroll: { x: 0, y: 0 },\n            shouldClipSubject: true,\n          },\n        });\n\n        const originallyVisible: Spacing = {\n          ...frameBorderBox,\n          top: 10,\n          bottom: 20,\n        };\n\n        // originally visible\n        expect(\n          isPartiallyVisible({\n            target: originallyVisible,\n            destination: droppable,\n            viewport,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(true);\n\n        // subject is now totally invisible\n        const scrolled: DroppableDimension = scrollDroppable(\n          droppable,\n          getFrame(droppable).scroll.max,\n        );\n        // asserting frame is not visible\n        expect(scrolled.subject.active).toBe(null);\n\n        // now asserting that this check will fail\n        expect(\n          isPartiallyVisible({\n            target: originallyVisible,\n            destination: scrolled,\n            viewport,\n            withDroppableDisplacement: true,\n          }),\n        ).toBe(false);\n      });\n    });\n  });\n\n  describe('viewport + droppable', () => {\n    it('should return true if visible in the viewport and the droppable', () => {\n      expect(\n        isPartiallyVisible({\n          target: inViewport1,\n          viewport,\n          destination: asBigAsInViewport1,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(true);\n    });\n\n    it('should return false if not visible in the droppable even if visible in the viewport', () => {\n      expect(\n        isPartiallyVisible({\n          target: inViewport2,\n          viewport,\n          destination: asBigAsInViewport1,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(false);\n    });\n\n    it('should return false if not visible in the viewport even if visible in the droppable', () => {\n      const notVisibleDroppable = getDroppableDimension({\n        descriptor: {\n          id: 'not-visible',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        borderBox: notInViewport,\n      });\n\n      expect(\n        isPartiallyVisible({\n          // is visibile in the droppable\n          target: notInViewport,\n          // but not visible in the viewport\n          viewport,\n          destination: notVisibleDroppable,\n          withDroppableDisplacement: true,\n        }),\n      ).toBe(false);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/visibility/is-position-in-frame.spec.js",
    "content": "// @flow\nimport { getRect, type Rect, type Position } from 'css-box-model';\nimport isPositionInFrame from '../../../../src/state/visibility/is-position-in-frame';\n\ndescribe('is position in frame', () => {\n  const frame: Rect = getRect({\n    top: 0,\n    left: 0,\n    right: 100,\n    bottom: 100,\n  });\n\n  it('should return true if inside the frame', () => {\n    expect(isPositionInFrame(frame)(frame.center)).toBe(true);\n  });\n\n  it('should return true for all corners', () => {\n    const corners: Position[] = [\n      // top left\n      { x: 0, y: 0 },\n      // top right\n      { x: 100, y: 0 },\n      // bottom left\n      { x: 0, y: 100 },\n      // bottom right\n      { x: 100, y: 100 },\n    ];\n\n    corners.forEach((corner: Position) => {\n      expect(isPositionInFrame(frame)(corner)).toBe(true);\n    });\n  });\n\n  it('should return false if outside on any side', () => {\n    const points: Position[] = [\n      // top\n      { x: 50, y: -1 },\n      // right\n      { x: 101, y: 50 },\n      // bottom\n      { x: 50, y: 101 },\n      // left\n      { x: -1, y: 50 },\n    ];\n\n    points.forEach((point: Position) => {\n      expect(isPositionInFrame(frame)(point)).toBe(false);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/visibility/is-totally-visible-on-axis.spec.js",
    "content": "// @flow\nimport { getRect, type Rect, type Spacing } from 'css-box-model';\nimport type { DroppableDimension, Axis } from '../../../../src/types';\nimport { isTotallyVisibleOnAxis } from '../../../../src/state/visibility/is-visible';\nimport { getDroppableDimension } from '../../../util/dimension';\nimport { vertical, horizontal } from '../../../../src/state/axis';\nimport { offsetByPosition } from '../../../../src/state/spacing';\nimport { patch } from '../../../../src/state/position';\n\n// These tests are an extension of the standard\n\nconst viewport: Rect = getRect({\n  right: 1000,\n  top: 0,\n  left: 0,\n  bottom: 1000,\n});\n\nconst inViewport: Spacing = {\n  top: 10,\n  left: 10,\n  right: 100,\n  bottom: 100,\n};\n\n[vertical, horizontal].forEach((axis: Axis) => {\n  describe(`on the ${axis.direction} axis`, () => {\n    const destination: DroppableDimension = getDroppableDimension({\n      descriptor: {\n        id: 'subset',\n        type: 'TYPE',\n        mode: 'standard',\n      },\n      borderBox: inViewport,\n      direction: axis.direction,\n    });\n\n    it('should return true when visible on the main axis, even if not on the cross axis', () => {\n      const targets: Spacing[] = [\n        // not totally visible on the crossAxisStart\n        offsetByPosition(inViewport, patch(axis.crossAxisLine, -1)),\n        // not totally visible on the crossAxisEnd\n        offsetByPosition(inViewport, patch(axis.crossAxisLine, 1)),\n      ];\n\n      targets.forEach((target: Spacing) => {\n        const isVisible: boolean = isTotallyVisibleOnAxis({\n          withDroppableDisplacement: true,\n          target,\n          destination,\n          viewport,\n        });\n        expect(isVisible).toBe(true);\n      });\n    });\n\n    it('should return false when visible on the main axis, even if visible on the main axis', () => {\n      const targets: Spacing[] = [\n        // not totally visible on the mainAxisStart\n        offsetByPosition(inViewport, patch(axis.line, -1)),\n        // not totally visible on the mainAxisEnd\n        offsetByPosition(inViewport, patch(axis.line, 1)),\n      ];\n\n      targets.forEach((target: Spacing) => {\n        const isVisible: boolean = isTotallyVisibleOnAxis({\n          withDroppableDisplacement: true,\n          target,\n          destination,\n          viewport,\n        });\n        expect(isVisible).toBe(false);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/visibility/is-totally-visible-through-frame.spec.js",
    "content": "// @flow\nimport { type Spacing } from 'css-box-model';\nimport isTotallyVisibleThroughFrame from '../../../../src/state/visibility/is-totally-visible-through-frame';\nimport { offsetByPosition } from '../../../../src/state/spacing';\nimport { expandBySpacing } from '../../../util/spacing';\n\nconst frame: Spacing = {\n  top: 0,\n  left: 0,\n  right: 100,\n  bottom: 100,\n};\n\ndescribe('is totally visible through frame', () => {\n  describe('subject is smaller than frame', () => {\n    describe('completely outside frame', () => {\n      it('should return false if subject is outside frame on any side', () => {\n        const outside: Spacing[] = [\n          // outside on top\n          offsetByPosition(frame, { x: 0, y: -101 }),\n          // outside on right\n          offsetByPosition(frame, { x: 101, y: 0 }),\n          // outside on bottom\n          offsetByPosition(frame, { x: 0, y: 101 }),\n          // outside on left\n          offsetByPosition(frame, { x: -101, y: 0 }),\n        ];\n\n        outside.forEach((subject: Spacing) => {\n          expect(isTotallyVisibleThroughFrame(frame)(subject)).toBe(false);\n        });\n      });\n    });\n\n    describe('contained in frame', () => {\n      it('should return true when subject is contained within frame', () => {\n        const subject: Spacing = {\n          top: 10,\n          left: 10,\n          right: 90,\n          bottom: 90,\n        };\n\n        expect(isTotallyVisibleThroughFrame(frame)(subject)).toBe(true);\n      });\n    });\n\n    describe('partially visible', () => {\n      it('should return false if partially visible horizontally and vertically', () => {\n        const subject: Spacing = {\n          // visible\n          top: 10,\n          // not visible\n          bottom: 110,\n          // visible\n          left: 50,\n          // not visible\n          right: 150,\n        };\n\n        expect(isTotallyVisibleThroughFrame(frame)(subject)).toBe(false);\n      });\n    });\n  });\n\n  describe('subject is equal to frame', () => {\n    it('should return true when the frame is equal to the subject', () => {\n      expect(isTotallyVisibleThroughFrame(frame)(frame)).toBe(true);\n      expect(isTotallyVisibleThroughFrame(frame)({ ...frame })).toBe(true);\n    });\n  });\n\n  describe('subject is bigger than frame', () => {\n    const bigSubject: Spacing = expandBySpacing(frame, frame);\n\n    it('should return false if the subject has no overlap with the frame', () => {\n      const subject: Spacing = offsetByPosition(bigSubject, {\n        x: 1000,\n        y: 1000,\n      });\n\n      expect(isTotallyVisibleThroughFrame(frame)(subject)).toBe(false);\n    });\n\n    it('should return false if subject is bigger on every side', () => {\n      expect(isTotallyVisibleThroughFrame(frame)(bigSubject)).toBe(false);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/state/visibility/is-totally-visible.spec.js",
    "content": "// @flow\nimport { getRect, type Rect, type Spacing } from 'css-box-model';\nimport {\n  isTotallyVisible,\n  isPartiallyVisible,\n} from '../../../../src/state/visibility/is-visible';\nimport scrollDroppable from '../../../../src/state/droppable/scroll-droppable';\nimport { offsetByPosition } from '../../../../src/state/spacing';\nimport { getDroppableDimension, getFrame } from '../../../util/dimension';\nimport type { DroppableDimension } from '../../../../src/types';\n\nconst viewport: Rect = getRect({\n  right: 800,\n  top: 0,\n  left: 0,\n  bottom: 600,\n});\n\nconst asBigAsViewport: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'same-as-viewport',\n    type: 'TYPE',\n    mode: 'standard',\n  },\n  borderBox: viewport,\n});\n\nconst inViewport1: Spacing = {\n  top: 10,\n  left: 10,\n  right: 100,\n  bottom: 100,\n};\n\nconst inViewport2: Spacing = {\n  top: 10,\n  left: 200,\n  right: 400,\n  bottom: 100,\n};\n\nconst notInViewport: Spacing = {\n  top: 0,\n  right: 1000,\n  left: 900,\n  bottom: 600,\n};\n\nconst asBigAsInViewport1: DroppableDimension = getDroppableDimension({\n  descriptor: {\n    id: 'subset',\n    type: 'TYPE',\n    mode: 'standard',\n  },\n  borderBox: inViewport1,\n});\n\ndescribe('is totally visible', () => {\n  describe('viewport', () => {\n    describe('without changes in droppable scroll', () => {\n      it('should return false if the item is not in the viewport', () => {\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: notInViewport,\n            viewport,\n            destination: asBigAsViewport,\n          }),\n        ).toBe(false);\n      });\n\n      it('should return true if item takes up entire viewport', () => {\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: viewport,\n            viewport,\n            destination: asBigAsViewport,\n          }),\n        ).toBe(true);\n      });\n\n      it('should return true if the item is totally visible in the viewport', () => {\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: inViewport1,\n            viewport,\n            destination: asBigAsViewport,\n          }),\n        ).toBe(true);\n      });\n\n      it('should return false if the item is partially visible in the viewport', () => {\n        const partials: Spacing[] = [\n          // bleed over top\n          offsetByPosition(viewport, { x: 0, y: -1 }),\n          // bleed over right\n          offsetByPosition(viewport, { x: 1, y: 0 }),\n          // bleed over bottom\n          offsetByPosition(viewport, { x: 0, y: 1 }),\n          // bleed over left\n          offsetByPosition(viewport, { x: -1, y: 0 }),\n        ];\n\n        partials.forEach((partial: Spacing) => {\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: partial,\n              viewport,\n              destination: asBigAsViewport,\n            }),\n          ).toBe(false);\n\n          // validation\n          expect(\n            isPartiallyVisible({\n              withDroppableDisplacement: true,\n              target: partial,\n              viewport,\n              destination: asBigAsViewport,\n            }),\n          ).toBe(true);\n        });\n      });\n    });\n\n    describe('with changes in droppable scroll', () => {\n      const clippedByViewport: DroppableDimension = getDroppableDimension({\n        descriptor: {\n          id: 'clipped',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        borderBox: {\n          top: viewport.top,\n          // stretches out the bottom of the viewport\n          bottom: viewport.bottom + 100,\n          left: viewport.left,\n          right: viewport.right,\n        },\n        closest: {\n          borderBox: viewport,\n          scrollSize: {\n            scrollWidth: viewport.width,\n            scrollHeight: viewport.bottom + 100,\n          },\n          scroll: { x: 0, y: 0 },\n          shouldClipSubject: true,\n        },\n      });\n\n      describe('originally invisible but now invisible', () => {\n        it('should take into account the droppable scroll when detecting visibility', () => {\n          const originallyInvisible: Spacing = {\n            top: viewport.bottom + 1,\n            bottom: viewport.bottom + 100,\n            right: viewport.left + 1,\n            left: viewport.left + 100,\n          };\n\n          // originally invisible\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: originallyInvisible,\n              destination: clippedByViewport,\n              viewport,\n            }),\n          ).toBe(false);\n\n          // after scroll the target is now visible\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: originallyInvisible,\n              destination: scrollDroppable(clippedByViewport, { x: 0, y: 100 }),\n              viewport,\n            }),\n          ).toBe(true);\n        });\n      });\n\n      describe('originally visible but now visible', () => {\n        it('should take into account the droppable scroll when detecting visibility', () => {\n          const originallyVisible: Spacing = {\n            top: viewport.top,\n            bottom: viewport.top + 50,\n            right: viewport.left + 1,\n            left: viewport.left + 100,\n          };\n\n          // originally visible\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: originallyVisible,\n              destination: clippedByViewport,\n              viewport,\n            }),\n          ).toBe(true);\n\n          // after scroll the target is now invisible\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: originallyVisible,\n              destination: scrollDroppable(clippedByViewport, { x: 0, y: 100 }),\n              viewport,\n            }),\n          ).toBe(false);\n        });\n      });\n    });\n  });\n\n  describe('droppable', () => {\n    const borderBox: Rect = getRect({\n      top: 0,\n      left: 0,\n      right: 600,\n      bottom: 600,\n    });\n    const frame: Rect = getRect({\n      top: 0,\n      left: 0,\n      right: 100,\n      bottom: 100,\n    });\n\n    const scrollable: DroppableDimension = getDroppableDimension({\n      descriptor: {\n        id: 'clipped',\n        type: 'TYPE',\n        mode: 'standard',\n      },\n      borderBox,\n      closest: {\n        borderBox: frame,\n        scroll: { x: 0, y: 0 },\n        scrollSize: {\n          scrollHeight: borderBox.height,\n          scrollWidth: borderBox.width,\n        },\n        shouldClipSubject: true,\n      },\n    });\n\n    describe('without changes in droppable scroll', () => {\n      it('should return false if outside the droppable', () => {\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: inViewport2,\n            viewport,\n            destination: asBigAsInViewport1,\n          }),\n        ).toBe(false);\n      });\n\n      it('should return false if the target is bigger than the droppable', () => {\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: viewport,\n            viewport,\n            destination: asBigAsInViewport1,\n          }),\n        ).toBe(false);\n      });\n\n      it('should return true if the same size of the droppable', () => {\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: inViewport1,\n            viewport,\n            destination: asBigAsInViewport1,\n          }),\n        ).toBe(true);\n      });\n\n      it('should return true if within the droppable', () => {\n        const insideDroppable: Spacing = {\n          top: 20,\n          left: 20,\n          right: 80,\n          bottom: 80,\n        };\n\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: insideDroppable,\n            viewport,\n            destination: asBigAsInViewport1,\n          }),\n        ).toBe(true);\n      });\n\n      it('should return false if partially within the droppable', () => {\n        const partials: Spacing[] = [\n          // bleed over top\n          offsetByPosition(inViewport1, { x: 0, y: -1 }),\n          // bleed over right\n          offsetByPosition(inViewport1, { x: 1, y: 0 }),\n          // bleed over bottom\n          offsetByPosition(inViewport1, { x: 0, y: 1 }),\n          // bleed over left\n          offsetByPosition(inViewport1, { x: -1, y: 0 }),\n        ];\n\n        partials.forEach((partial: Spacing) => {\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: partial,\n              viewport,\n              destination: asBigAsInViewport1,\n            }),\n          ).toBe(false);\n\n          // validation\n          expect(\n            isPartiallyVisible({\n              target: partial,\n              viewport,\n              destination: asBigAsInViewport1,\n              withDroppableDisplacement: true,\n            }),\n          ).toBe(true);\n        });\n      });\n\n      it('should return false if falling on clipped area of droppable', () => {\n        const ourFrame: Spacing = {\n          top: 10,\n          left: 10,\n          right: 100,\n          // cuts the droppable short\n          bottom: 100,\n        };\n        const clippedDroppable: DroppableDimension = getDroppableDimension({\n          descriptor: {\n            id: 'clipped',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          borderBox: {\n            ...ourFrame,\n            // stretches out past frame\n            bottom: 600,\n          },\n          closest: {\n            borderBox: ourFrame,\n            scrollSize: {\n              scrollHeight: 600,\n              scrollWidth: getRect(ourFrame).width,\n            },\n            scroll: { x: 0, y: 0 },\n            shouldClipSubject: true,\n          },\n        });\n        const inSubjectOutsideFrame: Spacing = {\n          ...frame,\n          top: 110,\n          bottom: 200,\n        };\n\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: inSubjectOutsideFrame,\n            destination: clippedDroppable,\n            viewport,\n          }),\n        ).toBe(false);\n      });\n    });\n\n    describe('with changes in droppable scroll', () => {\n      describe('originally invisible but now invisible', () => {\n        it('should take into account the droppable scroll when detecting visibility', () => {\n          const originallyInvisible: Spacing = {\n            left: frame.left,\n            right: frame.right,\n            top: frame.bottom + 10,\n            bottom: frame.bottom + 20,\n          };\n\n          // originally invisible\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: originallyInvisible,\n              destination: scrollable,\n              viewport,\n            }),\n          ).toBe(false);\n\n          // after scroll the target is now visible\n          const scrolled: DroppableDimension = scrollDroppable(scrollable, {\n            x: 0,\n            y: 100,\n          });\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: originallyInvisible,\n              destination: scrolled,\n              viewport,\n            }),\n          ).toBe(true);\n        });\n      });\n\n      describe('originally visible but now visible', () => {\n        it('should take into account the droppable scroll when detecting visibility', () => {\n          const originallyVisible: Spacing = {\n            ...frame,\n            top: 10,\n            bottom: 20,\n          };\n\n          // originally visible\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: originallyVisible,\n              destination: scrollable,\n              viewport,\n            }),\n          ).toBe(true);\n\n          // after scroll the target is now invisible\n          expect(\n            isTotallyVisible({\n              withDroppableDisplacement: true,\n              target: originallyVisible,\n              destination: scrollDroppable(scrollable, { x: 0, y: 100 }),\n              viewport,\n            }),\n          ).toBe(false);\n        });\n      });\n\n      it('should ignore droppable scroll if asked to', () => {\n        const originallyVisible: Spacing = {\n          ...frame,\n          top: 10,\n          bottom: 20,\n        };\n\n        // originally visible\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: originallyVisible,\n            destination: scrollable,\n            viewport,\n          }),\n        ).toBe(true);\n\n        const scrolled: DroppableDimension = scrollDroppable(scrollable, {\n          x: 0,\n          y: 100,\n        });\n        expect(\n          isTotallyVisible({\n            // still visible because we are not considering the droppable scroll\n            withDroppableDisplacement: false,\n            target: originallyVisible,\n            destination: scrolled,\n            viewport,\n          }),\n        ).toBe(true);\n        // validation: with scroll the item would not be invisible\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: originallyVisible,\n            destination: scrolled,\n            viewport,\n          }),\n        ).toBe(false);\n      });\n    });\n\n    describe('with invisible subject', () => {\n      it('should return false when subject is totally invisible', () => {\n        // creating a droppable where the frame is bigger than the subject\n        const droppable: DroppableDimension = getDroppableDimension({\n          descriptor: {\n            id: 'droppable',\n            type: 'TYPE',\n            mode: 'standard',\n          },\n          borderBox: {\n            top: 0,\n            left: 0,\n            bottom: 100,\n            right: 100,\n          },\n          closest: {\n            borderBox: {\n              top: 0,\n              left: 0,\n              bottom: 100,\n              right: 100,\n            },\n            scrollSize: {\n              scrollHeight: 600,\n              scrollWidth: 600,\n            },\n            scroll: { x: 0, y: 0 },\n            shouldClipSubject: true,\n          },\n        });\n\n        const originallyVisible: Spacing = {\n          ...frame,\n          top: 10,\n          bottom: 20,\n        };\n\n        // originally visible\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: originallyVisible,\n            destination: droppable,\n            viewport,\n          }),\n        ).toBe(true);\n\n        // subject is now totally invisible\n        const scrolled: DroppableDimension = scrollDroppable(\n          droppable,\n          getFrame(droppable).scroll.max,\n        );\n        // asserting frame is not visible\n        expect(scrolled.subject.active).toBe(null);\n\n        // now asserting that this check will fail\n        expect(\n          isTotallyVisible({\n            withDroppableDisplacement: true,\n            target: originallyVisible,\n            destination: scrolled,\n            viewport,\n          }),\n        ).toBe(false);\n      });\n    });\n  });\n\n  describe('viewport + droppable', () => {\n    it('should return true if visible in the viewport and the droppable', () => {\n      expect(\n        isTotallyVisible({\n          withDroppableDisplacement: true,\n          target: inViewport1,\n          viewport,\n          destination: asBigAsInViewport1,\n        }),\n      ).toBe(true);\n    });\n\n    it('should return false if not visible in the droppable even if visible in the viewport', () => {\n      expect(\n        isTotallyVisible({\n          withDroppableDisplacement: true,\n          target: inViewport2,\n          viewport,\n          destination: asBigAsInViewport1,\n        }),\n      ).toBe(false);\n    });\n\n    it('should return false if not visible in the viewport even if visible in the droppable', () => {\n      const notVisibleDroppable = getDroppableDimension({\n        descriptor: {\n          id: 'not-visible',\n          type: 'TYPE',\n          mode: 'standard',\n        },\n        borderBox: notInViewport,\n      });\n\n      expect(\n        isTotallyVisible({\n          withDroppableDisplacement: true,\n          // is visible in the droppable\n          target: notInViewport,\n          // but not visible in the viewport\n          viewport,\n          destination: notVisibleDroppable,\n        }),\n      ).toBe(false);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/view/animate-in-out/animate-in-out.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport AnimateInOut, {\n  type AnimateProvided,\n} from '../../../../src/view/animate-in-out/animate-in-out';\n\nit('should allow children not to be rendered (no animation allowed)', () => {\n  const child = jest.fn().mockReturnValue(<div>hi</div>);\n\n  const { container } = render(\n    <AnimateInOut on={null} shouldAnimate={false}>\n      {child}\n    </AnimateInOut>,\n  );\n\n  expect(container.innerHTML).toBe('');\n  expect(child).not.toHaveBeenCalled();\n});\n\nit('should allow children not to be rendered (even when animation is allowed)', () => {\n  const child = jest.fn().mockReturnValue(<div>hi</div>);\n\n  const { container } = render(\n    <AnimateInOut on={null} shouldAnimate>\n      {child}\n    </AnimateInOut>,\n  );\n\n  expect(container.innerHTML).toBe('');\n  expect(child).not.toHaveBeenCalled();\n});\n\nit('should pass data through to children', () => {\n  const child = jest.fn().mockReturnValue(<div>hi</div>);\n  const data = { hello: 'world' };\n\n  render(\n    <AnimateInOut on={data} shouldAnimate={false}>\n      {child}\n    </AnimateInOut>,\n  );\n\n  const expected: AnimateProvided = {\n    data,\n    animate: 'none',\n    // $ExpectError - wrong type\n    onClose: expect.any(Function),\n  };\n  expect(child).toHaveBeenCalledWith(expected);\n});\n\nit('should open instantly if required', () => {\n  const child = jest.fn().mockReturnValue(<div>hi</div>);\n  const data = { hello: 'world' };\n\n  render(\n    <AnimateInOut on={data} shouldAnimate={false}>\n      {child}\n    </AnimateInOut>,\n  );\n\n  const expected: AnimateProvided = {\n    data,\n    animate: 'none',\n    // $ExpectError - wrong type\n    onClose: expect.any(Function),\n  };\n  expect(child).toHaveBeenCalledWith(expected);\n});\n\nit('should animate open if requested', () => {\n  const child = jest.fn().mockReturnValue(<div>hi</div>);\n  const data = { hello: 'world' };\n\n  render(\n    <AnimateInOut on={data} shouldAnimate>\n      {child}\n    </AnimateInOut>,\n  );\n\n  const expected: AnimateProvided = {\n    data,\n    animate: 'open',\n    // $ExpectError - wrong type\n    onClose: expect.any(Function),\n  };\n  expect(child).toHaveBeenCalledWith(expected);\n});\n\nit('should close instantly if required', () => {\n  const child = jest.fn().mockReturnValue(<div>hi</div>);\n  const data = { hello: 'world' };\n  function App({ value }: { value: ?Object }) {\n    return (\n      <AnimateInOut on={value} shouldAnimate={false}>\n        {child}\n      </AnimateInOut>\n    );\n  }\n\n  const { rerender, container } = render(<App value={data} />);\n\n  const initial: AnimateProvided = {\n    data,\n    animate: 'none',\n    // $ExpectError - wrong type\n    onClose: expect.any(Function),\n  };\n  expect(child).toHaveBeenCalledWith(initial);\n  expect(container.innerHTML).toEqual('<div>hi</div>');\n  child.mockClear();\n\n  // start closing\n  // data is gone! this should trigger a close\n  rerender(<App value={null} />);\n  expect(container.innerHTML).toEqual('');\n  expect(child).not.toHaveBeenCalled();\n});\n\nit('should animate closed if required', () => {\n  const child = jest.fn().mockReturnValue(<div>hi</div>);\n  const data = { hello: 'world' };\n\n  type Props = {|\n    value: ?Object,\n    shouldAnimate: boolean,\n  |};\n\n  function App({ value, shouldAnimate }: Props) {\n    return (\n      <AnimateInOut on={value} shouldAnimate={shouldAnimate}>\n        {child}\n      </AnimateInOut>\n    );\n  }\n\n  const { container, rerender } = render(\n    <App value={data} shouldAnimate={false} />,\n  );\n\n  const initial: AnimateProvided = {\n    data,\n    animate: 'none',\n    // $ExpectError - wrong type\n    onClose: expect.any(Function),\n  };\n  expect(child).toHaveBeenCalledWith(initial);\n  expect(child).toHaveBeenCalledTimes(1);\n  expect(container.innerHTML).toEqual('<div>hi</div>');\n  child.mockClear();\n\n  // start closing\n  // data is gone! this should trigger a close\n  rerender(<App value={null} shouldAnimate />);\n\n  const second: AnimateProvided = {\n    // data is still provided to child for final render\n    data,\n    // still visible while animating\n    animate: 'close',\n    // $ExpectError - wrong type\n    onClose: expect.any(Function),\n  };\n  expect(child).toHaveBeenCalledWith(second);\n\n  // telling AnimateInOut that the animation is finished\n  const provided: AnimateProvided = child.mock.calls[0][0];\n  child.mockClear();\n  // this will trigger a setState that will stop rendering the child\n  provided.onClose();\n\n  expect(container.innerHTML).toEqual('');\n  expect(child).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/view/animate-in-out/child-rendering.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { render, act } from '@testing-library/react';\nimport AnimateInOut, {\n  type AnimateProvided,\n} from '../../../../src/view/animate-in-out/animate-in-out';\n\ntype ChildProps = {|\n  provided: AnimateProvided,\n|};\n\nclass Child extends React.Component<ChildProps> {\n  render() {\n    return <div>{this.props.provided.animate}</div>;\n  }\n}\n\nit('should render children', () => {\n  const { getByText } = render(\n    <AnimateInOut on=\"hey\" shouldAnimate={false}>\n      {(provided: AnimateProvided) => <Child provided={provided} />}\n    </AnimateInOut>,\n  );\n\n  expect(getByText('none')).toBeTruthy();\n});\n\nit('should allow children not to be rendered', () => {\n  {\n    const { unmount, container } = render(\n      <AnimateInOut on={null} shouldAnimate={false}>\n        {(provided: AnimateProvided) => <Child provided={provided} />}\n      </AnimateInOut>,\n    );\n\n    expect(container.innerHTML).toEqual('');\n    unmount();\n  }\n  // initial animation set to true\n  {\n    const { container, unmount } = render(\n      <AnimateInOut on={null} shouldAnimate>\n        {(provided: AnimateProvided) => <Child provided={provided} />}\n      </AnimateInOut>,\n    );\n\n    expect(container.innerHTML).toEqual('');\n    unmount();\n  }\n});\n\nit('should allow children not to be rendered after a close animation', () => {\n  const child = jest\n    .fn()\n    .mockImplementation((provided: AnimateProvided) => (\n      <Child provided={provided} />\n    ));\n\n  type Props = {|\n    on: ?mixed,\n    shouldAnimate: boolean,\n  |};\n  function App({ on, shouldAnimate }: Props) {\n    return (\n      <AnimateInOut on={on} shouldAnimate={shouldAnimate}>\n        {(provided: AnimateProvided) => child(provided)}\n      </AnimateInOut>\n    );\n  }\n\n  const { rerender, container } = render(<App on=\"hey\" shouldAnimate />);\n  expect(container.textContent).toEqual('open');\n\n  // data is gone - will animate closed\n  rerender(<App on={null} shouldAnimate />);\n  expect(container.textContent).toEqual('close');\n\n  // letting animate-in-out know that the animation is finished\n  act(() => {\n    child.mock.calls[child.mock.calls.length - 1][0].onClose();\n  });\n\n  expect(container.innerHTML).toEqual('');\n});\n"
  },
  {
    "path": "test/unit/view/announcer.spec.js",
    "content": "// @flow\nimport React, { type Node } from 'react';\nimport { render } from '@testing-library/react';\nimport { invariant } from '../../../src/invariant';\nimport type { Announce, ContextId } from '../../../src/types';\nimport useAnnouncer from '../../../src/view/use-announcer';\nimport { getId } from '../../../src/view/use-announcer/use-announcer';\n\njest.useFakeTimers();\n\ntype Props = {|\n  contextId: ContextId,\n  children: (announce: Announce) => Node,\n|};\n\nfunction WithAnnouncer(props: Props) {\n  const announce: Announce = useAnnouncer(props.contextId);\n  return props.children(announce);\n}\n\nconst getAnnounce = (myMock): Announce => myMock.mock.calls[0][0];\nconst getMock = () => jest.fn().mockImplementation(() => null);\n\n// A little helper as react-testing-library does not have a getById function\nconst getElement = (contextId: ContextId): ?HTMLElement =>\n  document.getElementById(getId(contextId));\n\nit('should create a new element when mounting', () => {\n  render(<WithAnnouncer contextId=\"5\">{getMock()}</WithAnnouncer>);\n\n  const el: ?HTMLElement = getElement('5');\n\n  expect(el).toBeTruthy();\n});\n\nit('should apply the appropriate aria attributes and non visibility styles', () => {\n  render(<WithAnnouncer contextId=\"5\">{getMock()}</WithAnnouncer>);\n\n  const el: ?HTMLElement = getElement('5');\n  invariant(el, 'Cannot find node');\n\n  expect(el.getAttribute('aria-live')).toBe('assertive');\n  expect(el.getAttribute('aria-atomic')).toBe('true');\n\n  // not checking all the styles - just enough to know we are doing something\n  expect(el.style.overflow).toBe('hidden');\n});\n\nit('should remove the element when unmounting after a timeout', () => {\n  const { unmount } = render(\n    <WithAnnouncer contextId=\"5\">{getMock()}</WithAnnouncer>,\n  );\n\n  unmount();\n  // not unmounted straight away\n  expect(getElement('5')).toBeTruthy();\n\n  jest.runOnlyPendingTimers();\n  expect(getElement('5')).not.toBeTruthy();\n});\n\nit('should set the text content of the announcement element', () => {\n  // arrange\n  const mock = getMock();\n  render(<WithAnnouncer contextId=\"6\">{mock}</WithAnnouncer>);\n  const el: ?HTMLElement = getElement('6');\n  invariant(el, 'Could not find announcer');\n\n  // act\n  const announce: Announce = getAnnounce(mock);\n  announce('test');\n\n  // assert\n  expect(el.textContent).toBe('test');\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/child-render-behaviour.spec.js",
    "content": "// @flow\nimport React, { Component, type Node } from 'react';\nimport { render } from '@testing-library/react';\nimport { DragDropContext } from '../../../../src';\nimport { getPreset } from '../../../util/dimension';\nimport Draggable from '../../../../src/view/draggable/connected-draggable';\nimport type { Provided } from '../../../../src/view/draggable/draggable-types';\nimport DroppableContext, {\n  type DroppableContextValue,\n} from '../../../../src/view/context/droppable-context';\n\nconst preset = getPreset();\n\nconst droppableContext: DroppableContextValue = {\n  type: preset.home.descriptor.type,\n  droppableId: preset.home.descriptor.id,\n  isUsingCloneFor: null,\n};\n\nclass Person extends Component<{ name: string, provided: Provided }> {\n  render() {\n    const { provided, name } = this.props;\n    return (\n      <div\n        ref={(ref) => provided.innerRef(ref)}\n        {...provided.draggableProps}\n        {...provided.dragHandleProps}\n      >\n        {name}\n      </div>\n    );\n  }\n}\n\ntype Props = {|\n  currentUser: string,\n  children: (currentUser: string, dragProvided: Provided) => Node,\n|};\n\nfunction App({ currentUser, children }: Props) {\n  return (\n    <DragDropContext onDragEnd={() => {}}>\n      <DroppableContext.Provider value={droppableContext}>\n        <Draggable draggableId=\"drag-1\" index={0}>\n          {(dragProvided) => children(currentUser, dragProvided)}\n        </Draggable>\n      </DroppableContext.Provider>\n    </DragDropContext>\n  );\n}\n\nfunction getMock() {\n  return jest.fn((currentUser: string, provided: Provided) => (\n    <Person name={currentUser} provided={provided} />\n  ));\n}\n\nit('should render the child function when the parent renders', () => {\n  const child = getMock();\n  const { container } = render(<App currentUser=\"Jake\">{child}</App>);\n\n  expect(child).toHaveBeenCalledTimes(1);\n  expect(container.textContent).toBe('Jake');\n});\n\nit('should render the child function when the parent re-renders', () => {\n  const child = getMock();\n  // $FlowFixMe: not sure why flow is complaining about only this usage\n  const { container, rerender } = render(<App currentUser=\"Jake\">{child}</App>);\n  expect(child).toHaveBeenCalledTimes(1);\n\n  rerender(<App currentUser=\"Jake\">{child}</App>);\n  expect(child).toHaveBeenCalledTimes(2);\n\n  expect(container.textContent).toBe('Jake');\n});\n\nit('should render the child function when the parents props changes that cause a re-render', () => {\n  const child = getMock();\n  const { container, rerender } = render(<App currentUser=\"Jake\">{child}</App>);\n  expect(child).toHaveBeenCalledTimes(1);\n\n  rerender(<App currentUser=\"Finn\">{child}</App>);\n  expect(child).toHaveBeenCalledTimes(2);\n\n  expect(container.textContent).toBe('Finn');\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/combine-target-for.spec.js",
    "content": "// @flow\nimport type { DragImpact } from '../../../../src/types';\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n} from '../../../../src/view/draggable/draggable-types';\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport { getPreset } from '../../../util/dimension';\nimport {\n  draggingStates,\n  withImpact,\n  type IsDraggingState,\n} from '../../../util/dragging-state';\nimport getOwnProps from './util/get-own-props';\nimport { getSecondarySnapshot } from './util/get-snapshot';\n\nconst preset = getPreset();\nconst ownProps: OwnProps = getOwnProps(preset.inHome2);\n\ndraggingStates.forEach((withoutMerge: IsDraggingState) => {\n  describe(`in phase: ${withoutMerge.phase}`, () => {\n    const impact: DragImpact = {\n      ...withoutMerge.impact,\n      at: {\n        type: 'COMBINE',\n        combine: {\n          draggableId: preset.inHome2.descriptor.id,\n          droppableId: preset.inHome2.descriptor.droppableId,\n        },\n      },\n    };\n\n    const withMerge: IsDraggingState = withImpact(withoutMerge, impact);\n\n    it('should indicate that it is a combine target', () => {\n      const selector: Selector = makeMapStateToProps();\n      const result: MapProps = selector(withMerge, ownProps);\n\n      const expected: MapProps = {\n        mapped: {\n          type: 'SECONDARY',\n          offset: impact.displacedBy.point,\n          shouldAnimateDisplacement: false,\n          combineTargetFor: preset.inHome1.descriptor.id,\n          snapshot: getSecondarySnapshot({\n            combineTargetFor: preset.inHome1.descriptor.id,\n          }),\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should give resting props if not the combine target', () => {\n      const selector: Selector = makeMapStateToProps();\n      const unrelatedOwnProps: OwnProps = getOwnProps(preset.inForeign1);\n      const atRest: MapProps = selector(withoutMerge, unrelatedOwnProps);\n      const result: MapProps = selector(withMerge, unrelatedOwnProps);\n\n      expect(result).toBe(atRest);\n    });\n\n    it('should not break memoization on multiple calls with the same impact', () => {\n      const selector: Selector = makeMapStateToProps();\n      const expected: MapProps = {\n        mapped: {\n          type: 'SECONDARY',\n          offset: impact.displacedBy.point,\n          shouldAnimateDisplacement: false,\n          combineTargetFor: preset.inHome1.descriptor.id,\n          snapshot: getSecondarySnapshot({\n            combineTargetFor: preset.inHome1.descriptor.id,\n          }),\n        },\n      };\n\n      const result1: MapProps = selector(withMerge, ownProps);\n      const result2: MapProps = selector(\n        JSON.parse(JSON.stringify(withMerge)),\n        ownProps,\n      );\n\n      expect(result1).toEqual(expected);\n      expect(result1).toBe(result2);\n    });\n\n    it('should break memoization on multiple calls if changing combine', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const result1: MapProps = selector(withMerge, ownProps);\n      const result2: MapProps = selector(withoutMerge, ownProps);\n\n      expect(result1).not.toBe(result2);\n      expect(result1).not.toEqual(result2);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/combine-with.spec.js",
    "content": "// @flow\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport type { Axis, DragImpact, DisplacedBy } from '../../../../src/types';\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n} from '../../../../src/view/draggable/draggable-types';\nimport { getPreset } from '../../../util/dimension';\nimport {\n  move,\n  draggingStates,\n  withImpact,\n  type IsDraggingState,\n} from '../../../util/dragging-state';\nimport getOwnProps from './util/get-own-props';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport { getDraggingSnapshot } from './util/get-snapshot';\nimport { getForcedDisplacement } from '../../../util/impact';\n\nconst preset = getPreset();\nconst ownProps: OwnProps = getOwnProps(preset.inHome1);\nconst axis: Axis = preset.home.axis;\nconst displacedBy: DisplacedBy = getDisplacedBy(\n  axis,\n  preset.inHome1.displaceBy,\n);\nconst impact: DragImpact = {\n  displaced: getForcedDisplacement({\n    visible: [\n      { dimension: preset.inHome2, shouldAnimate: false },\n      { dimension: preset.inHome3, shouldAnimate: false },\n      { dimension: preset.inHome4, shouldAnimate: false },\n    ],\n  }),\n  displacedBy,\n  at: {\n    type: 'COMBINE',\n    combine: {\n      draggableId: preset.inHome2.descriptor.id,\n      droppableId: preset.inHome2.descriptor.droppableId,\n    },\n  },\n};\n\ndraggingStates.forEach((withoutMerge: IsDraggingState) => {\n  describe(`in phase: ${withoutMerge.phase}`, () => {\n    const withMerge: IsDraggingState = withImpact(withoutMerge, impact);\n\n    it('should move the dragging item to the current offset and update combineWith', () => {\n      const selector: Selector = makeMapStateToProps();\n      const result: MapProps = selector(\n        move(withMerge, { x: 1, y: 2 }),\n        ownProps,\n      );\n\n      const expected: MapProps = {\n        mapped: {\n          type: 'DRAGGING',\n          offset: { x: 1, y: 2 },\n          mode: 'FLUID',\n          dimension: preset.inHome1,\n          // still over home\n          draggingOver: preset.home.descriptor.id,\n          combineWith: preset.inHome2.descriptor.id,\n          dropping: null,\n          forceShouldAnimate: null,\n          snapshot: getDraggingSnapshot({\n            mode: 'FLUID',\n            draggingOver: preset.home.descriptor.id,\n            combineWith: preset.inHome2.descriptor.id,\n            dropping: null,\n          }),\n        },\n      };\n\n      expect(result).toEqual(expected);\n    });\n\n    it('should not break memoization on multiple calls to the same offset', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const result1: MapProps = selector(\n        move(withMerge, { x: 1, y: 2 }),\n        ownProps,\n      );\n      const newReference: IsDraggingState = {\n        phase: 'DRAGGING',\n        ...withMerge,\n        // eslint-disable-next-line\n        phase: withMerge.phase,\n      };\n      const result2: MapProps = selector(\n        move(newReference, { x: 1, y: 2 }),\n        ownProps,\n      );\n\n      expect(result1).toBe(result2);\n    });\n\n    it('should break memoization on multiple calls if changing combine', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const result1: MapProps = selector(withMerge, ownProps);\n      const result2: MapProps = selector(withoutMerge, ownProps);\n\n      expect(result1).not.toBe(result2);\n      expect(result1).not.toEqual(result2);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/dragging.spec.js",
    "content": "// @flow\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport { getPreset } from '../../../util/dimension';\nimport noImpact from '../../../../src/state/no-impact';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n  DraggingMapProps,\n} from '../../../../src/view/draggable/draggable-types';\nimport {\n  move,\n  draggingStates,\n  withImpact,\n  type IsDraggingState,\n} from '../../../util/dragging-state';\nimport getOwnProps from './util/get-own-props';\nimport getDraggingMapProps from './util/get-dragging-map-props';\nimport getLiftEffect from '../../../../src/state/get-lift-effect';\nimport { getDraggingSnapshot } from './util/get-snapshot';\n\nconst preset = getPreset();\nconst state = getStatePreset();\nconst ownProps: OwnProps = getOwnProps(preset.inHome1);\n\ndraggingStates.forEach((current: IsDraggingState) => {\n  describe(`in phase: ${current.phase}`, () => {\n    it('should move the dragging item to the current offset', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const result: MapProps = selector(\n        move(current, { x: 20, y: 30 }),\n        ownProps,\n      );\n\n      const expected: MapProps = {\n        mapped: {\n          type: 'DRAGGING',\n          offset: { x: 20, y: 30 },\n          mode: 'FLUID',\n          dimension: preset.inHome1,\n          draggingOver: preset.home.descriptor.id,\n          dropping: null,\n          combineWith: null,\n          forceShouldAnimate: null,\n          snapshot: getDraggingSnapshot({\n            mode: 'FLUID',\n            draggingOver: preset.home.descriptor.id,\n            combineWith: null,\n            dropping: null,\n          }),\n        },\n      };\n      expect(result).toEqual(expected);\n    });\n\n    it('should allow force control of drag animation', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      expect(\n        getDraggingMapProps(selector(current, ownProps)).forceShouldAnimate,\n      ).toBe(null);\n\n      const withAnimation: IsDraggingState = ({\n        ...current,\n        forceShouldAnimate: true,\n      }: any);\n\n      expect(\n        getDraggingMapProps(selector(withAnimation, ownProps))\n          .forceShouldAnimate,\n      ).toBe(true);\n\n      const withoutAnimation: IsDraggingState = ({\n        ...current,\n        forceShouldAnimate: false,\n      }: any);\n\n      expect(\n        getDraggingMapProps(selector(withoutAnimation, ownProps))\n          .forceShouldAnimate,\n      ).toBe(false);\n    });\n\n    it('should indicate when over a droppable', () => {\n      const selector: Selector = makeMapStateToProps();\n      const { impact: homeImpact } = getLiftEffect({\n        draggable: preset.inHome1,\n        draggables: preset.draggables,\n        viewport: preset.viewport,\n        home: preset.home,\n      });\n\n      const inHome: IsDraggingState = withImpact(current, homeImpact);\n      const overHome: DraggingMapProps = getDraggingMapProps(\n        selector(inHome, ownProps),\n      );\n      const noWhere: IsDraggingState = withImpact(current, noImpact);\n      const overNothing: DraggingMapProps = getDraggingMapProps(\n        selector(noWhere, ownProps),\n      );\n\n      expect(overHome.draggingOver).toBe(state.critical.droppable.id);\n      expect(overNothing.draggingOver).toBe(null);\n    });\n\n    it('should not break memoization on multiple calls to the same offset', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const result1: MapProps = selector(\n        move(current, { x: 100, y: 200 }),\n        ownProps,\n      );\n      const result2: MapProps = selector(\n        move(current, { x: 100, y: 200 }),\n        ownProps,\n      );\n\n      expect(result1).toBe(result2);\n\n      // also checking with new top level reference\n      const newCurrent: IsDraggingState = ({ ...current }: any);\n      const result3: MapProps = selector(\n        move(newCurrent, { x: 100, y: 200 }),\n        ownProps,\n      );\n\n      expect(result1).toBe(result3);\n    });\n\n    it('should break memoization on multiple calls if moving to a new offset', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const result1: MapProps = selector(\n        move(current, { x: 100, y: 200 }),\n        ownProps,\n      );\n      const result2: MapProps = selector(\n        move(current, { x: 101, y: 200 }),\n        ownProps,\n      );\n\n      expect(result1).not.toBe(result2);\n      expect(result1).not.toEqual(result2);\n    });\n  });\n});\n\nit('should not break memoization when moving between dragging phases', () => {\n  const selector: Selector = makeMapStateToProps();\n\n  const first: MapProps = selector(state.dragging(), ownProps);\n  const second: MapProps = selector(state.collecting(), ownProps);\n  const third: MapProps = selector(state.dropPending(), ownProps);\n\n  expect(first).toBe(second);\n  expect(second).toBe(third);\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/dropping-something-else.spec.js",
    "content": "// @flow\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport { getPreset } from '../../../util/dimension';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport {\n  draggingStates,\n  withImpact,\n  type IsDraggingState,\n} from '../../../util/dragging-state';\nimport getOwnProps from './util/get-own-props';\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n} from '../../../../src/view/draggable/draggable-types';\nimport type {\n  Axis,\n  DragImpact,\n  DropAnimatingState,\n  DisplacedBy,\n} from '../../../../src/types';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport getSecondaryMapProps from './util/get-secondary-map-props';\nimport { getSecondarySnapshot } from './util/get-snapshot';\n\nconst preset = getPreset();\nconst state = getStatePreset();\nconst axis: Axis = preset.home.axis;\n\nconst displacedBy: DisplacedBy = getDisplacedBy(\n  axis,\n  preset.inHome1.displaceBy,\n);\n\nconst impact: DragImpact = state.dropAnimating().completed.impact;\n\ndraggingStates.forEach((current: IsDraggingState) => {\n  describe(`in phase ${current.phase}`, () => {\n    describe('was displaced before drop', () => {\n      const ownProps: OwnProps = getOwnProps(preset.inHome2);\n      it('should continue to be moved out of the way', () => {\n        const selector: Selector = makeMapStateToProps();\n\n        const dragging: IsDraggingState = withImpact(current, impact);\n        const whileDragging: MapProps = selector(dragging, ownProps);\n\n        const expected: MapProps = {\n          mapped: {\n            type: 'SECONDARY',\n            offset: displacedBy.point,\n            combineTargetFor: null,\n            shouldAnimateDisplacement: false,\n            snapshot: getSecondarySnapshot({\n              combineTargetFor: null,\n            }),\n          },\n        };\n        expect(whileDragging).toEqual(expected);\n      });\n\n      it('should not break memoization from the dragging phase', () => {\n        const selector: Selector = makeMapStateToProps();\n        const dragging: IsDraggingState = withImpact(current, impact);\n        const whileDragging: MapProps = selector(dragging, ownProps);\n\n        // little validation\n        expect(getSecondaryMapProps(whileDragging).offset).toEqual(\n          displacedBy.point,\n        );\n\n        const dropping: DropAnimatingState = JSON.parse(\n          JSON.stringify(state.dropAnimating()),\n        );\n        const whileDropping: MapProps = selector(dropping, ownProps);\n        expect(whileDropping).toBe(whileDragging);\n      });\n    });\n\n    describe('was not displaced before drop', () => {\n      it('should not break memoization', () => {\n        const ownProps: OwnProps = getOwnProps(preset.inForeign1);\n        const selector: Selector = makeMapStateToProps();\n        const expected: MapProps = {\n          mapped: {\n            type: 'SECONDARY',\n            offset: { x: 0, y: 0 },\n            shouldAnimateDisplacement: true,\n            combineTargetFor: null,\n            snapshot: getSecondarySnapshot({\n              combineTargetFor: null,\n            }),\n          },\n        };\n\n        const resting: MapProps = selector(state.idle, ownProps);\n        expect(resting).toEqual(expected);\n        const dragging: MapProps = selector(state.dragging(), ownProps);\n        expect(dragging).toBe(resting);\n        const dropping: MapProps = selector(state.userCancel(), ownProps);\n        expect(dropping).toBe(resting);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/dropping-with-result-mismatch.spec.js",
    "content": "// @flow\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport { getPreset } from '../../../util/dimension';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport getOwnProps from './util/get-own-props';\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n  DropAnimation,\n} from '../../../../src/view/draggable/draggable-types';\nimport type { DropAnimatingState } from '../../../../src/types';\nimport { curves } from '../../../../src/animation';\nimport { getDraggingSnapshot } from './util/get-snapshot';\nimport { tryGetDestination } from '../../../../src/state/get-impact-location';\n\nconst preset = getPreset();\nconst state = getStatePreset();\nconst ownProps: OwnProps = getOwnProps(preset.inHome1);\n\nit('should use result for providing data and not the impact', () => {\n  const current: DropAnimatingState = state.userCancel();\n\n  // little validation: the result is null, but the impact has a destination\n  expect(current.completed.result.destination).toBe(null);\n  expect(tryGetDestination(current.completed.impact)).toBeTruthy();\n\n  const selector: Selector = makeMapStateToProps();\n\n  const dropping: DropAnimation = {\n    duration: current.dropDuration,\n    curve: curves.drop,\n    moveTo: current.newHomeClientOffset,\n    opacity: null,\n    scale: null,\n  };\n\n  const expected: MapProps = {\n    mapped: {\n      type: 'DRAGGING',\n      dimension: preset.inHome1,\n      // using result\n      draggingOver: null,\n      forceShouldAnimate: null,\n      offset: current.newHomeClientOffset,\n      mode: current.completed.result.mode,\n      combineWith: null,\n      dropping,\n      snapshot: getDraggingSnapshot({\n        mode: current.completed.result.mode,\n        // using result\n        draggingOver: null,\n        combineWith: null,\n        dropping,\n      }),\n    },\n  };\n\n  const whileDropping: MapProps = selector(current, ownProps);\n\n  expect(whileDropping).toEqual(expected);\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/dropping.spec.js",
    "content": "// @flow\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport { getPreset } from '../../../util/dimension';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport getOwnProps from './util/get-own-props';\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n  DropAnimation,\n} from '../../../../src/view/draggable/draggable-types';\nimport type {\n  DropAnimatingState,\n  DragImpact,\n  Combine,\n} from '../../../../src/types';\nimport { curves, combine as combineStyle } from '../../../../src/animation';\nimport getLiftEffect from '../../../../src/state/get-lift-effect';\nimport { getDraggingSnapshot } from './util/get-snapshot';\n\nconst preset = getPreset();\nconst state = getStatePreset();\nconst ownProps: OwnProps = getOwnProps(preset.inHome1);\n\nit('should move to the new home offset', () => {\n  const current: DropAnimatingState = state.dropAnimating();\n  const selector: Selector = makeMapStateToProps();\n  const dropping: DropAnimation = {\n    duration: current.dropDuration,\n    curve: curves.drop,\n    moveTo: current.newHomeClientOffset,\n    opacity: null,\n    scale: null,\n  };\n  const expected: MapProps = {\n    mapped: {\n      type: 'DRAGGING',\n      dimension: preset.inHome1,\n      draggingOver: preset.home.descriptor.id,\n      forceShouldAnimate: null,\n      offset: current.newHomeClientOffset,\n      mode: current.completed.result.mode,\n      combineWith: null,\n      dropping,\n      snapshot: getDraggingSnapshot({\n        draggingOver: preset.home.descriptor.id,\n        mode: current.completed.result.mode,\n        combineWith: null,\n        dropping,\n      }),\n    },\n  };\n\n  const whileDropping: MapProps = selector(current, ownProps);\n\n  expect(whileDropping).toEqual(expected);\n});\n\nit('should maintain combine information', () => {\n  const { afterCritical, impact: homeImpact } = getLiftEffect({\n    draggable: preset.inHome1,\n    home: preset.home,\n    draggables: preset.draggables,\n    viewport: preset.viewport,\n  });\n  const combine: Combine = {\n    draggableId: preset.inHome2.descriptor.id,\n    droppableId: preset.inHome2.descriptor.droppableId,\n  };\n  const impact: DragImpact = {\n    ...homeImpact,\n    at: {\n      type: 'COMBINE',\n      combine,\n    },\n  };\n  const withoutCombine: DropAnimatingState = state.dropAnimating();\n  const withCombine: DropAnimatingState = {\n    ...withoutCombine,\n    completed: {\n      critical: withoutCombine.completed.critical,\n      afterCritical,\n      impact,\n      result: {\n        ...withoutCombine.completed.result,\n        destination: null,\n        combine,\n      },\n    },\n  };\n\n  const selector: Selector = makeMapStateToProps();\n  const dropping: DropAnimation = {\n    duration: withCombine.dropDuration,\n    curve: curves.drop,\n    moveTo: withCombine.newHomeClientOffset,\n    scale: combineStyle.scale.drop,\n    opacity: combineStyle.opacity.drop,\n  };\n  const expected: MapProps = {\n    mapped: {\n      type: 'DRAGGING',\n      dimension: preset.inHome1,\n      draggingOver: preset.home.descriptor.id,\n      forceShouldAnimate: null,\n      offset: withCombine.newHomeClientOffset,\n      mode: withCombine.completed.result.mode,\n      combineWith: preset.inHome2.descriptor.id,\n      dropping,\n      snapshot: getDraggingSnapshot({\n        mode: withCombine.completed.result.mode,\n        combineWith: preset.inHome2.descriptor.id,\n        dropping,\n        draggingOver: preset.home.descriptor.id,\n      }),\n    },\n  };\n\n  const whileDropping: MapProps = selector(withCombine, ownProps);\n\n  expect(whileDropping).toEqual(expected);\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/nothing-is-dragging.spec.js",
    "content": "// @flow\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n} from '../../../../src/view/draggable/draggable-types';\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport { getPreset } from '../../../util/dimension';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport getOwnProps from './util/get-own-props';\nimport { getSecondarySnapshot } from './util/get-snapshot';\n\nconst preset = getPreset();\nconst state = getStatePreset();\n\nit('should return the default map props and not break memoization', () => {\n  const ownProps: OwnProps = getOwnProps(preset.inHome1);\n  const selector: Selector = makeMapStateToProps();\n  const expected: MapProps = {\n    mapped: {\n      type: 'SECONDARY',\n      offset: { x: 0, y: 0 },\n      shouldAnimateDisplacement: true,\n      combineTargetFor: null,\n      snapshot: getSecondarySnapshot({\n        combineTargetFor: null,\n      }),\n    },\n  };\n\n  const first: MapProps = selector(state.idle, ownProps);\n\n  expect(first).toEqual(expected);\n\n  expect(selector(state.idle, ownProps)).toBe(first);\n  expect(selector({ ...state.idle }, ownProps)).toBe(first);\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/selector-isolation.spec.js",
    "content": "// @flow\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport { getPreset } from '../../../util/dimension';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport getOwnProps from './util/get-own-props';\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n} from '../../../../src/view/draggable/draggable-types';\nimport type { State } from '../../../../src/types';\n\nconst preset = getPreset();\nconst state = getStatePreset();\n\nit('should not break memoization across selectors', () => {\n  const inHome1Selector: Selector = makeMapStateToProps();\n  const inHome1OwnProps: OwnProps = getOwnProps(preset.inHome1);\n  const inForeign1Selector: Selector = makeMapStateToProps();\n  const inForeign1OwnProps: OwnProps = getOwnProps(preset.inForeign2);\n  const defaultInForeign1MapProps: MapProps = inForeign1Selector(\n    state.idle,\n    inForeign1OwnProps,\n  );\n\n  state.allPhases(preset.inHome1.descriptor.id).forEach((current: State) => {\n    // independent selector\n    inHome1Selector(current, inHome1OwnProps);\n    // should not break memoization of inForeign1\n    expect(inForeign1Selector(current, inForeign1OwnProps)).toBe(\n      defaultInForeign1MapProps,\n    );\n  });\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/something-else-dragging-in-virtual.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n} from '../../../../src/view/draggable/draggable-types';\nimport type { DragImpact, DraggingState } from '../../../../src/types';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport getHomeLocation from '../../../../src/state/get-home-location';\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport { getPreset } from '../../../util/dimension';\nimport { type IsDraggingState, withImpact } from '../../../util/dragging-state';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport { getForcedDisplacement } from '../../../util/impact';\nimport { withVirtuals } from '../../state/publish-while-dragging/util';\nimport getOwnProps from './util/get-own-props';\nimport { getSecondarySnapshot } from './util/get-snapshot';\nimport noImpact from '../../../../src/state/no-impact';\nimport { negate } from '../../../../src/state/position';\n\nconst preset = getPreset();\nconst state = getStatePreset();\nconst ownProps: OwnProps = getOwnProps(preset.inHome2);\n\ndescribe('before critical', () => {\n  it('should return the default props if not impacted by the drag and before critical in virtual list', () => {\n    const selector: Selector = makeMapStateToProps();\n    const defaultMapProps: MapProps = selector(state.idle, ownProps);\n    // inHome2 is before inHome3 and so won't be impacted by the drag\n    const current: DraggingState = (withVirtuals(\n      (state.dragging(preset.inHome3.descriptor.id): any),\n    ): any);\n\n    expect(selector(current, ownProps)).toBe(defaultMapProps);\n  });\n});\n\ndescribe('after critical', () => {\n  it('should stay in the original visual spot when displaced', () => {\n    const selector: Selector = makeMapStateToProps();\n    const defaultMapProps: MapProps = selector(state.idle, ownProps);\n    const current: DraggingState = (withVirtuals(\n      (state.dragging(preset.inHome1.descriptor.id): any),\n    ): any);\n    const impact: DragImpact = {\n      displaced: getForcedDisplacement({\n        visible: [\n          { dimension: preset.inHome2, shouldAnimate: false },\n          { dimension: preset.inHome3, shouldAnimate: false },\n          { dimension: preset.inHome4, shouldAnimate: false },\n        ],\n      }),\n      displacedBy: getDisplacedBy(preset.home.axis, preset.inHome1.displaceBy),\n      at: {\n        type: 'REORDER',\n        destination: getHomeLocation(preset.inHome1.descriptor),\n      },\n    };\n    const impacted: IsDraggingState = withImpact(current, impact);\n\n    expect(selector(impacted, ownProps)).toBe(defaultMapProps);\n  });\n\n  it('should return the resting props if currently invisible', () => {\n    const selector: Selector = makeMapStateToProps();\n    const defaultMapProps: MapProps = selector(state.idle, ownProps);\n    const current: DraggingState = (withVirtuals(\n      (state.dragging(preset.inHome1.descriptor.id): any),\n    ): any);\n    const impact: DragImpact = {\n      displaced: getForcedDisplacement({\n        visible: [\n          { dimension: preset.inHome3, shouldAnimate: false },\n          { dimension: preset.inHome4, shouldAnimate: false },\n        ],\n        invisible: [preset.inHome2],\n      }),\n      displacedBy: getDisplacedBy(preset.home.axis, preset.inHome1.displaceBy),\n      at: {\n        type: 'REORDER',\n        destination: getHomeLocation(preset.inHome1.descriptor),\n      },\n    };\n    const impacted: IsDraggingState = withImpact(current, impact);\n\n    expect(selector(impacted, ownProps)).toBe(defaultMapProps);\n  });\n\n  it('should animate backwards to close the gap when moving out of a list', () => {\n    const selector: Selector = makeMapStateToProps();\n    const current: DraggingState = (withVirtuals(\n      (state.dragging(preset.inHome1.descriptor.id): any),\n    ): any);\n    const impacted: IsDraggingState = withImpact(current, noImpact);\n\n    // moving backwards by the size of the dragging item to close the gap\n    const offset: Position = negate(\n      getDisplacedBy(preset.home.axis, preset.inHome1.displaceBy).point,\n    );\n\n    const expected: MapProps = {\n      mapped: {\n        type: 'SECONDARY',\n        // animating backwards\n        shouldAnimateDisplacement: true,\n        offset,\n        combineTargetFor: null,\n        snapshot: getSecondarySnapshot({\n          combineTargetFor: null,\n        }),\n      },\n    };\n    expect(selector(impacted, ownProps)).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/something-else-is-dragging.spec.js",
    "content": "// @flow\nimport { makeMapStateToProps } from '../../../../src/view/draggable/connected-draggable';\nimport { getPreset } from '../../../util/dimension';\nimport noImpact from '../../../../src/state/no-impact';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport {\n  draggingStates,\n  withImpact,\n  move,\n  type IsDraggingState,\n} from '../../../util/dragging-state';\nimport getOwnProps from './util/get-own-props';\nimport type {\n  Selector,\n  OwnProps,\n  MapProps,\n} from '../../../../src/view/draggable/draggable-types';\nimport type {\n  Axis,\n  DragImpact,\n  DraggableLocation,\n  DisplacedBy,\n} from '../../../../src/types';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport getHomeLocation from '../../../../src/state/get-home-location';\nimport cloneImpact from '../../../util/clone-impact';\nimport { getSecondarySnapshot } from './util/get-snapshot';\nimport { getForcedDisplacement } from '../../../util/impact';\n\nconst preset = getPreset();\nconst state = getStatePreset();\nconst ownProps: OwnProps = getOwnProps(preset.inHome2);\nconst axis: Axis = preset.home.axis;\nconst inHome1Location: DraggableLocation = getHomeLocation(\n  preset.inHome1.descriptor,\n);\nconst displacedBy: DisplacedBy = getDisplacedBy(\n  axis,\n  preset.inHome1.displaceBy,\n);\n\nit('should not break memoization on multiple calls', () => {\n  const selector: Selector = makeMapStateToProps();\n  const defaultMapProps: MapProps = selector(state.idle, ownProps);\n\n  expect(\n    selector(\n      withImpact(move(state.dragging(), { x: 1, y: 2 }), noImpact),\n      ownProps,\n    ),\n  ).toBe(defaultMapProps);\n  expect(\n    selector(\n      withImpact(move(state.dragging(), { x: 1, y: 3 }), noImpact),\n      ownProps,\n    ),\n  ).toBe(defaultMapProps);\n  expect(\n    selector(\n      withImpact(move(state.dragging(), { x: 1, y: 4 }), noImpact),\n      ownProps,\n    ),\n  ).toBe(defaultMapProps);\n});\n\ndraggingStates.forEach((current: IsDraggingState) => {\n  describe(`in phase: ${current.phase}`, () => {\n    it('should return the default props if not impacted by the drag', () => {\n      const selector: Selector = makeMapStateToProps();\n      const defaultMapProps: MapProps = selector(state.idle, ownProps);\n\n      expect(selector(withImpact(state.dragging(), noImpact), ownProps)).toBe(\n        defaultMapProps,\n      );\n    });\n\n    describe('being displaced by drag', () => {\n      it('should move out of the way (no animation)', () => {\n        const selector: Selector = makeMapStateToProps();\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inHome2, shouldAnimate: false },\n              { dimension: preset.inHome3, shouldAnimate: false },\n              { dimension: preset.inHome4, shouldAnimate: false },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: inHome1Location,\n          },\n        };\n        const impacted: IsDraggingState = withImpact(current, impact);\n\n        const expected: MapProps = {\n          mapped: {\n            type: 'SECONDARY',\n            shouldAnimateDisplacement: false,\n            offset: displacedBy.point,\n            combineTargetFor: null,\n            snapshot: getSecondarySnapshot({\n              combineTargetFor: null,\n            }),\n          },\n        };\n        expect(selector(impacted, ownProps)).toEqual(expected);\n      });\n\n      it('should move out of the way (with animation)', () => {\n        const selector: Selector = makeMapStateToProps();\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inHome2, shouldAnimate: true },\n              { dimension: preset.inHome3, shouldAnimate: true },\n              { dimension: preset.inHome4, shouldAnimate: true },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: inHome1Location,\n          },\n        };\n        const impacted: IsDraggingState = withImpact(current, impact);\n\n        const expected: MapProps = {\n          mapped: {\n            type: 'SECONDARY',\n            shouldAnimateDisplacement: true,\n            offset: displacedBy.point,\n            combineTargetFor: null,\n            snapshot: getSecondarySnapshot({\n              combineTargetFor: null,\n            }),\n          },\n        };\n        expect(selector(impacted, ownProps)).toEqual(expected);\n      });\n\n      it('should not move if displacement is not visible, and not break memoization', () => {\n        const selector: Selector = makeMapStateToProps();\n        const defaultMapProps: MapProps = selector(state.idle, ownProps);\n\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            invisible: [preset.inHome2, preset.inHome3, preset.inHome4],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: inHome1Location,\n          },\n        };\n        const impacted: IsDraggingState = withImpact(current, impact);\n\n        // testing value and also that memoization has not broken\n        expect(selector(impacted, ownProps)).toBe(defaultMapProps);\n      });\n\n      it('should not break memoization on multiple calls', () => {\n        const selector: Selector = makeMapStateToProps();\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inHome2, shouldAnimate: true },\n              { dimension: preset.inHome3, shouldAnimate: true },\n              { dimension: preset.inHome4, shouldAnimate: true },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: inHome1Location,\n          },\n        };\n        const first: MapProps = selector(withImpact(current, impact), ownProps);\n\n        const expected: MapProps = {\n          mapped: {\n            type: 'SECONDARY',\n            offset: displacedBy.point,\n            shouldAnimateDisplacement: true,\n            combineTargetFor: null,\n            snapshot: getSecondarySnapshot({\n              combineTargetFor: null,\n            }),\n          },\n        };\n        expect(first).toEqual(expected);\n\n        expect(\n          selector(withImpact(current, cloneImpact(impact)), ownProps),\n        ).toBe(first);\n        expect(\n          selector(withImpact(current, cloneImpact(impact)), ownProps),\n        ).toBe(first);\n        expect(\n          selector(withImpact(current, cloneImpact(impact)), ownProps),\n        ).toBe(first);\n      });\n\n      it('should not break memoization moving between different dragging phases', () => {\n        const selector: Selector = makeMapStateToProps();\n        const impact: DragImpact = {\n          displaced: getForcedDisplacement({\n            visible: [\n              { dimension: preset.inHome2, shouldAnimate: false },\n              { dimension: preset.inHome3, shouldAnimate: false },\n              { dimension: preset.inHome4, shouldAnimate: false },\n            ],\n          }),\n          displacedBy,\n          at: {\n            type: 'REORDER',\n            destination: inHome1Location,\n          },\n        };\n\n        const first: MapProps = selector(\n          withImpact(state.dragging(), cloneImpact(impact)),\n          ownProps,\n        );\n        const second: MapProps = selector(\n          withImpact(state.collecting(), cloneImpact(impact)),\n          ownProps,\n        );\n        const third: MapProps = selector(\n          withImpact(state.dropPending(), cloneImpact(impact)),\n          ownProps,\n        );\n\n        expect(first).toBe(second);\n        expect(second).toBe(third);\n      });\n    });\n  });\n});\n\nit('should not break memoization moving between different dragging phases (no impact)', () => {\n  const selector: Selector = makeMapStateToProps();\n  const defaultMapProps: MapProps = selector(state.idle, ownProps);\n\n  expect(selector(withImpact(state.dragging(), noImpact), ownProps)).toBe(\n    defaultMapProps,\n  );\n  expect(selector(withImpact(state.collecting(), noImpact), ownProps)).toBe(\n    defaultMapProps,\n  );\n  expect(selector(withImpact(state.dropPending(), noImpact), ownProps)).toBe(\n    defaultMapProps,\n  );\n});\n\nit('should not break memoization moving between different dragging phases (something else impacted)', () => {\n  const selector: Selector = makeMapStateToProps();\n  const impact: DragImpact = {\n    displaced: getForcedDisplacement({\n      visible: [\n        { dimension: preset.inHome2, shouldAnimate: false },\n        { dimension: preset.inHome3, shouldAnimate: false },\n        { dimension: preset.inHome4, shouldAnimate: false },\n      ],\n    }),\n    displacedBy,\n    at: {\n      type: 'REORDER',\n      destination: inHome1Location,\n    },\n  };\n  // drag should have no impact on inForeign1\n  const unrelatedToDrag: OwnProps = getOwnProps(preset.inForeign1);\n  const unrelatedDefault: MapProps = selector(state.idle, unrelatedToDrag);\n\n  const first: MapProps = selector(\n    withImpact(state.dragging(), impact),\n    unrelatedToDrag,\n  );\n  const second: MapProps = selector(\n    withImpact(state.collecting(), impact),\n    unrelatedToDrag,\n  );\n  const third: MapProps = selector(\n    withImpact(state.dropPending(), impact),\n    unrelatedToDrag,\n  );\n\n  expect(first).toBe(unrelatedDefault);\n  expect(second).toBe(unrelatedDefault);\n  expect(third).toBe(unrelatedDefault);\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/util/get-dragging-map-props.js",
    "content": "// @flow\nimport type {\n  MappedProps,\n  MapProps,\n  DraggingMapProps,\n} from '../../../../../src/view/draggable/draggable-types';\nimport { invariant } from '../../../../../src/invariant';\n\nexport default (mapProps: MapProps): DraggingMapProps => {\n  const mapped: MappedProps = mapProps.mapped;\n  invariant(mapped.type === 'DRAGGING');\n  return mapped;\n};\n"
  },
  {
    "path": "test/unit/view/connected-draggable/util/get-own-props.js",
    "content": "// @flow\nimport type { OwnProps } from '../../../../../src/view/draggable/draggable-types';\nimport type { DraggableDimension } from '../../../../../src/types';\n\nexport default (dimension: DraggableDimension): OwnProps => ({\n  // Public own props\n  draggableId: dimension.descriptor.id,\n  index: dimension.descriptor.index,\n  children: () => null,\n\n  // Private own props\n  isClone: false,\n  isEnabled: true,\n  canDragInteractiveElements: false,\n  shouldRespectForcePress: true,\n});\n"
  },
  {
    "path": "test/unit/view/connected-draggable/util/get-secondary-map-props.js",
    "content": "// @flow\nimport type {\n  MapProps,\n  MappedProps,\n  SecondaryMapProps,\n} from '../../../../../src/view/draggable/draggable-types';\nimport { invariant } from '../../../../../src/invariant';\n\nexport default (mapProps: MapProps): SecondaryMapProps => {\n  const mapped: MappedProps = mapProps.mapped;\n  invariant(mapped.type === 'SECONDARY');\n  return mapped;\n};\n"
  },
  {
    "path": "test/unit/view/connected-draggable/util/get-snapshot.js",
    "content": "// @flow\nimport type {\n  StateSnapshot,\n  DropAnimation,\n} from '../../../../../src/view/draggable/draggable-types';\nimport type {\n  MovementMode,\n  DroppableId,\n  DraggableId,\n} from '../../../../../src/types';\n\ntype GetDraggingSnapshotArgs = {|\n  mode: MovementMode,\n  draggingOver: ?DroppableId,\n  combineWith: ?DraggableId,\n  dropping: ?DropAnimation,\n  isClone?: ?boolean,\n|};\n\nexport const getDraggingSnapshot = ({\n  mode,\n  draggingOver,\n  combineWith,\n  dropping,\n  isClone,\n}: GetDraggingSnapshotArgs): StateSnapshot => ({\n  isDragging: true,\n  isDropAnimating: Boolean(dropping),\n  dropAnimation: dropping,\n  mode,\n  draggingOver,\n  combineWith,\n  combineTargetFor: null,\n  isClone: Boolean(isClone),\n});\n\ntype GetSecondarySnapshotArgs = {|\n  combineTargetFor: ?DraggableId,\n|};\n\nexport const getSecondarySnapshot = ({\n  combineTargetFor,\n}: GetSecondarySnapshotArgs): StateSnapshot => ({\n  isDragging: false,\n  isClone: false,\n  isDropAnimating: false,\n  dropAnimation: null,\n  mode: null,\n  draggingOver: null,\n  combineTargetFor,\n  combineWith: null,\n});\n"
  },
  {
    "path": "test/unit/view/connected-droppable/child-render-behaviour.spec.js",
    "content": "// @flow\nimport React, { Component } from 'react';\nimport { mount } from 'enzyme';\nimport type { Provided } from '../../../../src/view/droppable/droppable-types';\nimport Droppable from '../../../../src/view/droppable/connected-droppable';\nimport forceUpdate from '../../../util/force-update';\nimport { DragDropContext } from '../../../../src';\n\nclass Person extends Component<{ name: string, provided: Provided }> {\n  render() {\n    const { provided, name } = this.props;\n    return (\n      <div ref={(ref) => provided.innerRef(ref)} {...provided.droppableProps}>\n        hello {name}\n      </div>\n    );\n  }\n}\n\nclass App extends Component<{ currentUser: string }> {\n  render() {\n    return (\n      <DragDropContext onDragEnd={() => {}}>\n        <Droppable droppableId=\"drop-1\">\n          {(provided: Provided) => (\n            <Person name={this.props.currentUser} provided={provided} />\n          )}\n        </Droppable>\n      </DragDropContext>\n    );\n  }\n}\n\nbeforeEach(() => {\n  jest.spyOn(Person.prototype, 'render');\n});\n\nafterEach(() => {\n  Person.prototype.render.mockRestore();\n});\n\nit('should render the child function when the parent renders', () => {\n  const wrapper = mount(<App currentUser=\"Jake\" />);\n\n  expect(Person.prototype.render).toHaveBeenCalledTimes(1);\n  expect(wrapper.find(Person).props().name).toBe('Jake');\n\n  wrapper.unmount();\n});\n\nit('should render the child function when the parent re-renders', () => {\n  const wrapper = mount(<App currentUser=\"Jake\" />);\n\n  forceUpdate(wrapper);\n\n  expect(Person.prototype.render).toHaveBeenCalledTimes(2);\n  expect(wrapper.find(Person).props().name).toBe('Jake');\n\n  wrapper.unmount();\n});\n\nit('should render the child function when the parents props changes that cause a re-render', () => {\n  const wrapper = mount(<App currentUser=\"Jake\" />);\n\n  wrapper.setProps({\n    currentUser: 'Finn',\n  });\n\n  expect(Person.prototype.render).toHaveBeenCalledTimes(2);\n  expect(wrapper.find(Person).props().name).toBe('Finn');\n\n  wrapper.unmount();\n});\n"
  },
  {
    "path": "test/unit/view/connected-droppable/disabled.spec.js",
    "content": "// @flow\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport { makeMapStateToProps } from '../../../../src/view/droppable/connected-droppable';\nimport type { State, DraggingState } from '../../../../src/types';\nimport type {\n  OwnProps,\n  Selector,\n  MapProps,\n} from '../../../../src/view/droppable/droppable-types';\nimport getOwnProps from './util/get-own-props';\nimport { getPreset, disableDroppable } from '../../../util/dimension';\nimport resting from './util/resting-props';\nimport noImpact from '../../../../src/state/no-impact';\nimport cloneImpact from '../../../util/clone-impact';\nimport patchDimensionMap from '../../../../src/state/patch-dimension-map';\n\nconst preset = getPreset();\nconst state = getStatePreset();\n\ndescribe('home list', () => {\n  const ownProps: OwnProps = getOwnProps(preset.home);\n  ownProps.isDropDisabled = true;\n  const selector: Selector = makeMapStateToProps();\n\n  it('should have the expected disabled props while resting', () => {\n    const defaultDisabledProps: MapProps = selector(state.idle, ownProps);\n    expect(defaultDisabledProps).toEqual(resting);\n  });\n\n  it('should display a placeholder even when disabled', () => {\n    const base: DraggingState = state.dragging(preset.inHome1.descriptor.id);\n    const getNoWhere = (): DraggingState => ({\n      ...base,\n      dimensions: patchDimensionMap(\n        base.dimensions,\n        disableDroppable(preset.home),\n      ),\n      impact: cloneImpact(noImpact),\n    });\n    const isHomeButNotOver: MapProps = {\n      placeholder: preset.inHome1.placeholder,\n      shouldAnimatePlaceholder: false,\n      snapshot: {\n        isDraggingOver: false,\n        draggingOverWith: null,\n        draggingFromThisWith: preset.inHome1.descriptor.id,\n        isUsingPlaceholder: true,\n      },\n      useClone: null,\n    };\n\n    const result: MapProps = selector(getNoWhere(), ownProps);\n    expect(result).toEqual(isHomeButNotOver);\n\n    // memoization\n    expect(selector(getNoWhere(), ownProps)).toBe(result);\n    expect(selector(getNoWhere(), ownProps)).toBe(result);\n  });\n});\n\ndescribe('in foreign list', () => {\n  const ownProps: OwnProps = getOwnProps(preset.foreign);\n  ownProps.isDropDisabled = true;\n  const selector: Selector = makeMapStateToProps();\n  const defaultDisabledProps: MapProps = selector(state.idle, ownProps);\n\n  it('should have the expected disabled props while resting', () => {\n    expect(defaultDisabledProps).toEqual(resting);\n  });\n\n  // always dragging inside of home\n  state.allPhases(preset.inHome1.descriptor.id).forEach((current: State) => {\n    it(`should return disabled map props when in phase ${current.phase}`, () => {\n      const result: MapProps = selector(current, ownProps);\n      // memoization check\n      expect(result).toBe(defaultDisabledProps);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/view/connected-droppable/dragging.spec.js",
    "content": "// @flow\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport { makeMapStateToProps } from '../../../../src/view/droppable/connected-droppable';\nimport type {\n  DraggingState,\n  DragImpact,\n  DisplacedBy,\n  Combine,\n} from '../../../../src/types';\nimport type {\n  OwnProps,\n  Selector,\n  MapProps,\n} from '../../../../src/view/droppable/droppable-types';\nimport getOwnProps from './util/get-own-props';\nimport { getPreset } from '../../../util/dimension';\nimport {\n  move,\n  type IsDraggingState,\n  withImpact,\n} from '../../../util/dragging-state';\nimport noImpact, { emptyGroups } from '../../../../src/state/no-impact';\nimport getDisplacedBy from '../../../../src/state/get-displaced-by';\nimport withCombineImpact from './util/with-combine-impact';\nimport restingProps from './util/resting-props';\n\nconst preset = getPreset();\nconst state = getStatePreset();\n\ndescribe('home list', () => {\n  const ownProps: OwnProps = getOwnProps(preset.home);\n  const isOverMapProps: MapProps = {\n    placeholder: preset.inHome1.placeholder,\n    shouldAnimatePlaceholder: false,\n    snapshot: {\n      isDraggingOver: true,\n      draggingOverWith: preset.inHome1.descriptor.id,\n      draggingFromThisWith: preset.inHome1.descriptor.id,\n      isUsingPlaceholder: true,\n    },\n    useClone: null,\n  };\n\n  describe('is dragging over', () => {\n    it('should indicate that it is being dragged over', () => {\n      const selector: Selector = makeMapStateToProps();\n      const props: MapProps = selector(\n        state.dragging(preset.inHome1.descriptor.id),\n        ownProps,\n      );\n\n      expect(props).toEqual(isOverMapProps);\n    });\n\n    it('should indicate that it is being combined over', () => {\n      const selector: Selector = makeMapStateToProps();\n      const base: IsDraggingState = state.dragging(\n        preset.inHome1.descriptor.id,\n      );\n      const combine: Combine = {\n        draggableId: preset.inHome2.descriptor.id,\n        droppableId: preset.home.descriptor.id,\n      };\n      const withCombine: IsDraggingState = withImpact(\n        base,\n        withCombineImpact(base.impact, combine),\n      );\n      const props: MapProps = selector(withCombine, ownProps);\n\n      expect(props).toEqual(isOverMapProps);\n    });\n\n    it('should not break memoization between moves', () => {\n      const selector: Selector = makeMapStateToProps();\n      const base: DraggingState = state.dragging(preset.inHome1.descriptor.id);\n\n      const first: IsDraggingState = move(base, { x: 1, y: 1 });\n      const second: IsDraggingState = move(first, { x: 0, y: 1 });\n      const third: IsDraggingState = move(second, { x: -1, y: 0 });\n      const combine: Combine = {\n        draggableId: preset.inHome2.descriptor.id,\n        droppableId: preset.home.descriptor.id,\n      };\n      const fourth: IsDraggingState = withImpact(\n        third,\n        withCombineImpact(third.impact, combine),\n      );\n      const props1: MapProps = selector(first, ownProps);\n      const props2: MapProps = selector(second, ownProps);\n      const props3: MapProps = selector(third, ownProps);\n      const props4: MapProps = selector(fourth, ownProps);\n\n      expect(props1).toEqual(isOverMapProps);\n      // memoization check\n      expect(props2).toBe(props1);\n      expect(props3).toBe(props1);\n      expect(props4).toBe(props1);\n    });\n  });\n\n  describe('is not dragging over', () => {\n    const getNoWhere = (): DraggingState => ({\n      ...state.dragging(preset.inHome1.descriptor.id),\n      impact: { ...noImpact },\n    });\n\n    const isHomeButNotOver: MapProps = {\n      placeholder: preset.inHome1.placeholder,\n      shouldAnimatePlaceholder: false,\n      snapshot: {\n        isDraggingOver: false,\n        draggingOverWith: null,\n        draggingFromThisWith: preset.inHome1.descriptor.id,\n        isUsingPlaceholder: true,\n      },\n      useClone: null,\n    };\n\n    it('should indicate that it is not being dragged over', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const first: MapProps = selector(getNoWhere(), ownProps);\n      expect(first).toEqual(isHomeButNotOver);\n    });\n\n    it('should not break memoization between moves', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const first: MapProps = selector(getNoWhere(), ownProps);\n      expect(first).toEqual(isHomeButNotOver);\n\n      expect(selector(move(getNoWhere(), { x: 1, y: 1 }), ownProps)).toBe(\n        first,\n      );\n      expect(selector(move(getNoWhere(), { x: 1, y: 1 }), ownProps)).toBe(\n        first,\n      );\n      expect(selector(move(getNoWhere(), { x: 1, y: 1 }), ownProps)).toBe(\n        first,\n      );\n      const combine: Combine = {\n        draggableId: preset.inForeign1.descriptor.id,\n        droppableId: preset.foreign.descriptor.id,\n      };\n      const withCombine: IsDraggingState = withImpact(\n        state.dragging(),\n        withCombineImpact(state.dragging().impact, combine),\n      );\n      expect(selector(withCombine, ownProps)).toBe(first);\n    });\n  });\n});\n\ndescribe('foreign list', () => {\n  const ownProps: OwnProps = getOwnProps(preset.foreign);\n\n  describe('is dragging over', () => {\n    const displacedBy: DisplacedBy = getDisplacedBy(\n      preset.foreign.axis,\n      preset.inHome1.displaceBy,\n    );\n    const overForeign: DragImpact = {\n      displaced: emptyGroups,\n      displacedBy,\n      at: {\n        type: 'REORDER',\n        destination: {\n          index: 0,\n          droppableId: preset.foreign.descriptor.id,\n        },\n      },\n    };\n\n    const isOverForeignMapProps: MapProps = {\n      placeholder: preset.inHome1.placeholder,\n      shouldAnimatePlaceholder: true,\n      snapshot: {\n        isDraggingOver: true,\n        draggingFromThisWith: null,\n        draggingOverWith: preset.inHome1.descriptor.id,\n        isUsingPlaceholder: true,\n      },\n      useClone: null,\n    };\n\n    it('should indicate that it is being dragged over', () => {\n      const selector: Selector = makeMapStateToProps();\n      const current: IsDraggingState = withImpact(\n        state.dragging(preset.inHome1.descriptor.id),\n        overForeign,\n      );\n      const props: MapProps = selector(current, ownProps);\n\n      expect(props).toEqual(isOverForeignMapProps);\n    });\n    it('should indicate that it is being combined over', () => {\n      const selector: Selector = makeMapStateToProps();\n      const base: IsDraggingState = state.dragging(\n        preset.inHome1.descriptor.id,\n      );\n      const combine: Combine = {\n        draggableId: preset.inForeign1.descriptor.id,\n        droppableId: preset.foreign.descriptor.id,\n      };\n      const withCombine: IsDraggingState = withImpact(\n        base,\n        withCombineImpact(base.impact, combine),\n      );\n      const props: MapProps = selector(withCombine, ownProps);\n      expect(props).toEqual(isOverForeignMapProps);\n    });\n\n    it('should not break memoization between moves', () => {\n      const selector: Selector = makeMapStateToProps();\n      const base: IsDraggingState = withImpact(\n        state.dragging(preset.inHome1.descriptor.id),\n        overForeign,\n      );\n      const first: IsDraggingState = move(base, { x: 1, y: 1 });\n      const second: IsDraggingState = move(first, { x: 0, y: 1 });\n      const third: IsDraggingState = move(second, { x: -1, y: 0 });\n      const props1: MapProps = selector(first, ownProps);\n      const props2: MapProps = selector(second, ownProps);\n      const props3: MapProps = selector(third, ownProps);\n\n      expect(props1).toEqual(isOverForeignMapProps);\n      // memoization check\n      expect(props2).toBe(props1);\n      expect(props3).toBe(props1);\n    });\n  });\n\n  describe('is not dragging over', () => {\n    const getNoWhere = (): DraggingState => ({\n      ...state.dragging(preset.inHome1.descriptor.id),\n      impact: { ...noImpact },\n    });\n\n    const isNotOver: MapProps = {\n      ...restingProps,\n      shouldAnimatePlaceholder: true,\n    };\n\n    it('should indicate that it is not being dragged over', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const first: MapProps = selector(getNoWhere(), ownProps);\n      expect(first).toEqual(isNotOver);\n    });\n\n    it('should not break memoization between moves', () => {\n      const selector: Selector = makeMapStateToProps();\n\n      const first: MapProps = selector(getNoWhere(), ownProps);\n      expect(first).toEqual(isNotOver);\n\n      expect(selector(move(getNoWhere(), { x: 1, y: 1 }), ownProps)).toBe(\n        first,\n      );\n      expect(selector(move(getNoWhere(), { x: 1, y: 1 }), ownProps)).toBe(\n        first,\n      );\n      expect(selector(move(getNoWhere(), { x: 1, y: 1 }), ownProps)).toBe(\n        first,\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/view/connected-droppable/dropping.spec.js",
    "content": "// @flow\nimport type {\n  DragImpact,\n  DraggingState,\n  DropAnimatingState,\n} from '../../../../src/types';\nimport type {\n  OwnProps,\n  Selector,\n  MapProps,\n} from '../../../../src/view/droppable/droppable-types';\nimport { makeMapStateToProps } from '../../../../src/view/droppable/connected-droppable';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport getOwnProps from './util/get-own-props';\nimport { withImpact } from '../../../util/dragging-state';\nimport noImpact from '../../../../src/state/no-impact';\nimport cloneImpact from '../../../util/clone-impact';\nimport { tryGetDestination } from '../../../../src/state/get-impact-location';\n\nconst state = getStatePreset();\nconst preset = state.preset;\n\ndescribe('home list', () => {\n  describe('was being dragged over', () => {\n    const isOverMapProps: MapProps = {\n      placeholder: preset.inHome1.placeholder,\n      shouldAnimatePlaceholder: false,\n      snapshot: {\n        isDraggingOver: true,\n        draggingOverWith: preset.inHome1.descriptor.id,\n        draggingFromThisWith: preset.inHome1.descriptor.id,\n        isUsingPlaceholder: true,\n      },\n      useClone: null,\n    };\n\n    it('should not break memoization from a reorder', () => {\n      const ownProps: OwnProps = getOwnProps(preset.home);\n      const selector: Selector = makeMapStateToProps();\n\n      const whileDragging: MapProps = selector(state.dragging(), ownProps);\n      const whileDropping: MapProps = selector(state.dropAnimating(), ownProps);\n\n      expect(whileDragging).toEqual(isOverMapProps);\n      // referential equality: memoization check\n      expect(whileDragging).toBe(whileDropping);\n    });\n\n    it('should not break memoization from a combine', () => {\n      const ownProps: OwnProps = getOwnProps(preset.home);\n      const selector: Selector = makeMapStateToProps();\n      const combine: DragImpact = {\n        ...state.dragging().impact,\n        at: {\n          type: 'COMBINE',\n          combine: {\n            draggableId: preset.inHome2.descriptor.id,\n            droppableId: preset.inHome2.descriptor.droppableId,\n          },\n        },\n      };\n      const base: DropAnimatingState = state.dropAnimating();\n      const droppingState: DropAnimatingState = {\n        ...base,\n        completed: {\n          ...base.completed,\n          impact: combine,\n        },\n      };\n\n      const whileDragging: MapProps = selector(\n        withImpact(state.dragging(), combine),\n        ownProps,\n      );\n      const whileDropping: MapProps = selector(droppingState, ownProps);\n\n      expect(whileDragging).toEqual(isOverMapProps);\n      // referential equality: memoization check\n      expect(whileDragging).toBe(whileDropping);\n    });\n\n    it('should use the completed.result and not the completed.impact for determining if over', () => {\n      const ownProps: OwnProps = getOwnProps(preset.home);\n      const selector: Selector = makeMapStateToProps();\n\n      const stateWhenDropping: DropAnimatingState = state.userCancel();\n      // the impact has the home destination\n      expect(\n        tryGetDestination(stateWhenDropping.completed.impact),\n      ).toBeTruthy();\n      // the user facing result has been cleared\n      expect(stateWhenDropping.completed.result.destination).toBe(null);\n\n      const whileDropping: MapProps = selector(stateWhenDropping, ownProps);\n      const expected: MapProps = {\n        // placeholder is still present\n        placeholder: preset.inHome1.placeholder,\n        shouldAnimatePlaceholder: false,\n        snapshot: {\n          // is using a placeholder\n          isUsingPlaceholder: true,\n          // still the home list so this is populated\n          draggingFromThisWith: preset.inHome1.descriptor.id,\n          // cleared from result and cleared version is given to consumer\n          isDraggingOver: false,\n          draggingOverWith: null,\n        },\n        useClone: null,\n      };\n      expect(whileDropping).toEqual(expected);\n    });\n  });\n\n  describe('was not being dragged over', () => {\n    it('should maintain a placeholder and not break memoization', () => {\n      const ownProps: OwnProps = getOwnProps(preset.home);\n      const selector: Selector = makeMapStateToProps();\n      const isHomeButNotOver: MapProps = {\n        placeholder: preset.inHome1.placeholder,\n        shouldAnimatePlaceholder: false,\n        snapshot: {\n          isDraggingOver: false,\n          draggingOverWith: null,\n          draggingFromThisWith: preset.inHome1.descriptor.id,\n          isUsingPlaceholder: true,\n        },\n        useClone: null,\n      };\n\n      const whileDragging: DraggingState = {\n        ...state.dragging(preset.inHome1.descriptor.id),\n        impact: cloneImpact(noImpact),\n      };\n      const base: DropAnimatingState = state.dropAnimating();\n      const whileDropping: DropAnimatingState = {\n        ...base,\n        completed: {\n          ...base.completed,\n          impact: cloneImpact(noImpact),\n          result: {\n            ...base.completed.result,\n            destination: null,\n          },\n        },\n      };\n\n      // correct value\n      const first: MapProps = selector(whileDropping, ownProps);\n      expect(first).toEqual(isHomeButNotOver);\n\n      // no memoization break between steps\n      expect(selector(whileDragging, ownProps)).toBe(first);\n      expect(selector(whileDropping, ownProps)).toBe(first);\n    });\n  });\n});\n\nit('should return the dragging props for every dragging phase for a foreign list', () => {\n  const ownProps: OwnProps = getOwnProps(preset.foreign);\n  const selector: Selector = makeMapStateToProps();\n  const defaultProps: MapProps = selector(state.idle, ownProps);\n\n  const dragging: MapProps = selector(state.dragging(), ownProps);\n  // flag swapped when drag starts\n  const expected: MapProps = {\n    ...defaultProps,\n    shouldAnimatePlaceholder: true,\n  };\n  expect(dragging).toEqual(expected);\n\n  expect(selector(state.dropAnimating(), ownProps)).toBe(dragging);\n  expect(selector(state.userCancel(), ownProps)).toBe(dragging);\n});\n"
  },
  {
    "path": "test/unit/view/connected-droppable/post-drop.spec.js",
    "content": "// @flow\nimport type {\n  DragImpact,\n  Combine,\n  DropAnimatingState,\n  IdleState,\n} from '../../../../src/types';\nimport type {\n  OwnProps,\n  Selector,\n  MapProps,\n} from '../../../../src/view/droppable/droppable-types';\nimport { makeMapStateToProps } from '../../../../src/view/droppable/connected-droppable';\nimport { getPreset } from '../../../util/dimension';\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport getOwnProps from './util/get-own-props';\n\nconst preset = getPreset();\nconst state = getStatePreset();\n\nconst isOverHomeMapProps: MapProps = {\n  placeholder: preset.inHome1.placeholder,\n  shouldAnimatePlaceholder: false,\n  snapshot: {\n    isDraggingOver: true,\n    draggingOverWith: preset.inHome1.descriptor.id,\n    draggingFromThisWith: preset.inHome1.descriptor.id,\n    isUsingPlaceholder: true,\n  },\n  useClone: null,\n};\n\ndescribe('was over - reordering', () => {\n  it('should immediately remove a placeholder', () => {\n    const ownProps: OwnProps = getOwnProps(preset.home);\n    const selector: Selector = makeMapStateToProps();\n    // initial value: not animated\n    const atRest: MapProps = selector(state.idle, ownProps);\n    expect(atRest.shouldAnimatePlaceholder).toBe(false);\n\n    // while dropping\n    const dropping: DropAnimatingState = state.dropAnimating(\n      preset.inHome1.descriptor.id,\n    );\n    const whileDropping: MapProps = selector(dropping, ownProps);\n    expect(whileDropping).toEqual(isOverHomeMapProps);\n\n    // drop complete\n    const idle: IdleState = {\n      phase: 'IDLE',\n      completed: dropping.completed,\n      shouldFlush: false,\n    };\n    const postDrop: MapProps = selector(idle, ownProps);\n    expect(postDrop).toBe(atRest);\n  });\n});\n\ndescribe('was over - merging', () => {\n  it('should animate a placeholder closed', () => {\n    const ownProps: OwnProps = getOwnProps(preset.home);\n    const selector: Selector = makeMapStateToProps();\n    const atRest: MapProps = selector(state.idle, ownProps);\n\n    // while dropping\n    const combine: Combine = {\n      draggableId: preset.inHome2.descriptor.id,\n      droppableId: preset.inHome2.descriptor.droppableId,\n    };\n    const base: DropAnimatingState = state.dropAnimating();\n    const combineImpact: DragImpact = {\n      ...base.completed.impact,\n      at: {\n        type: 'COMBINE',\n        combine,\n      },\n    };\n    const dropping: DropAnimatingState = {\n      ...base,\n      completed: {\n        ...base.completed,\n        impact: combineImpact,\n        result: {\n          ...base.completed.result,\n          destination: null,\n          combine,\n        },\n      },\n    };\n    const whileDropping: MapProps = selector(dropping, ownProps);\n    expect(whileDropping).toEqual(isOverHomeMapProps);\n\n    // drop complete\n    const idle: IdleState = {\n      phase: 'IDLE',\n      completed: dropping.completed,\n      shouldFlush: false,\n    };\n    const postDrop: MapProps = selector(idle, ownProps);\n    // we animate the placeholder closed after dropping\n    const expected: MapProps = {\n      ...atRest,\n      shouldAnimatePlaceholder: true,\n    };\n    expect(postDrop).toEqual(expected);\n  });\n});\n\ndescribe('was not over', () => {\n  it('should animate a placeholder closed', () => {\n    const ownProps: OwnProps = getOwnProps(preset.foreign);\n    const selector: Selector = makeMapStateToProps();\n    const atRest: MapProps = selector(state.idle, ownProps);\n\n    // while dropping\n    const dropping: DropAnimatingState = state.dropAnimating();\n    const whileDropping: MapProps = selector(dropping, ownProps);\n    const expected: MapProps = {\n      ...atRest,\n      shouldAnimatePlaceholder: true,\n    };\n    expect(whileDropping).toEqual(expected);\n\n    // drop complete\n    const idle: IdleState = {\n      phase: 'IDLE',\n      completed: dropping.completed,\n      shouldFlush: false,\n    };\n    const postDrop: MapProps = selector(idle, ownProps);\n    expect(postDrop).toBe(atRest);\n  });\n});\n\ndescribe('flushed', () => {\n  it('should cut an animation', () => {\n    const ownProps: OwnProps = getOwnProps(preset.home);\n    const selector: Selector = makeMapStateToProps();\n    const atRest: MapProps = selector(state.idle, ownProps);\n\n    // while dropping\n    const combine: Combine = {\n      draggableId: preset.inHome2.descriptor.id,\n      droppableId: preset.inHome2.descriptor.droppableId,\n    };\n    const base: DropAnimatingState = state.dropAnimating();\n    const combineImpact: DragImpact = {\n      ...base.completed.impact,\n      at: {\n        type: 'COMBINE',\n        combine,\n      },\n    };\n    const dropping: DropAnimatingState = {\n      ...base,\n      completed: {\n        ...base.completed,\n        impact: combineImpact,\n        result: {\n          ...base.completed.result,\n          destination: null,\n          combine,\n        },\n      },\n    };\n\n    // drop complete\n    const withFlush: IdleState = {\n      phase: 'IDLE',\n      completed: dropping.completed,\n      shouldFlush: true,\n    };\n    const postDrop: MapProps = selector(withFlush, ownProps);\n    const expected: MapProps = {\n      ...atRest,\n      shouldAnimatePlaceholder: false,\n    };\n    expect(postDrop).toBe(atRest);\n    expect(postDrop).toEqual(expected);\n  });\n\n  it('should cut animation in a list that was not animating', () => {\n    const ownProps: OwnProps = getOwnProps(preset.foreign);\n    const selector: Selector = makeMapStateToProps();\n    const atRest: MapProps = selector(state.idle, ownProps);\n\n    // drop complete\n    const withFlush: IdleState = {\n      phase: 'IDLE',\n      completed: state.dropAnimating().completed,\n      shouldFlush: true,\n    };\n    const postDrop: MapProps = selector(withFlush, ownProps);\n    const expected: MapProps = {\n      ...atRest,\n      shouldAnimatePlaceholder: false,\n    };\n    expect(postDrop).toBe(atRest);\n    expect(postDrop).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/unit/view/connected-droppable/selector-isolation.spec.js",
    "content": "// @flow\nimport getStatePreset from '../../../util/get-simple-state-preset';\nimport { makeMapStateToProps } from '../../../../src/view/droppable/connected-droppable';\nimport type { State } from '../../../../src/types';\nimport type {\n  OwnProps,\n  Selector,\n} from '../../../../src/view/droppable/droppable-types';\nimport getOwnProps from './util/get-own-props';\nimport { getPreset } from '../../../util/dimension';\n\nconst preset = getPreset();\nconst state = getStatePreset();\n\nit('should not break memoization across selectors', () => {\n  const homeSelector: Selector = makeMapStateToProps();\n  const homeOwnProps: OwnProps = getOwnProps(preset.home);\n  const foreignSelector: Selector = makeMapStateToProps();\n  const foreignOwnProps: OwnProps = getOwnProps(preset.foreign);\n\n  state.allPhases(preset.inHome1.descriptor.id).forEach((current: State) => {\n    const home1 = homeSelector(current, homeOwnProps);\n    const foreign1 = foreignSelector(current, foreignOwnProps);\n\n    const home2 = homeSelector(current, homeOwnProps);\n    const foreign2 = foreignSelector(current, foreignOwnProps);\n\n    expect(home1).toBe(home2);\n    expect(foreign1).toBe(foreign2);\n  });\n});\n"
  },
  {
    "path": "test/unit/view/connected-droppable/util/get-own-props.js",
    "content": "// @flow\nimport type { DroppableDimension } from '../../../../../src/types';\nimport type { OwnProps } from '../../../../../src/view/droppable/droppable-types';\nimport getBodyElement from '../../../../../src/view/get-body-element';\n\nexport default (dimension: DroppableDimension): OwnProps => ({\n  droppableId: dimension.descriptor.id,\n  type: dimension.descriptor.type,\n  isDropDisabled: false,\n  isCombineEnabled: true,\n  direction: dimension.axis.direction,\n  ignoreContainerClipping: false,\n  children: () => null,\n  getContainerForClone: getBodyElement,\n  mode: 'standard',\n  renderClone: null,\n});\n"
  },
  {
    "path": "test/unit/view/connected-droppable/util/resting-props.js",
    "content": "// @flow\nimport type { MapProps } from '../../../../../src/view/droppable/droppable-types';\n\nconst restingProps: MapProps = {\n  placeholder: null,\n  shouldAnimatePlaceholder: false,\n  snapshot: {\n    isDraggingOver: false,\n    draggingOverWith: null,\n    draggingFromThisWith: null,\n    isUsingPlaceholder: false,\n  },\n  useClone: null,\n};\n\nexport default restingProps;\n"
  },
  {
    "path": "test/unit/view/connected-droppable/util/with-combine-impact.js",
    "content": "// @flow\nimport type { DragImpact, Combine } from '../../../../../src/types';\n\nexport default (impact: DragImpact, combine: Combine): DragImpact => ({\n  ...impact,\n  at: {\n    type: 'COMBINE',\n    combine,\n  },\n});\n"
  },
  {
    "path": "test/unit/view/dimension-marshal/droppable-passthrough.spec.js",
    "content": "// @flow\nimport createDimensionMarshal from '../../../../src/state/dimension-marshal/dimension-marshal';\nimport { getPreset } from '../../../util/dimension';\nimport type {\n  Callbacks,\n  DimensionMarshal,\n} from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport { getCallbacksStub } from '../../../util/dimension-marshal';\nimport { critical, defaultRequest, justCritical } from './util';\nimport createRegistry from '../../../../src/state/registry/create-registry';\nimport type { Registry } from '../../../../src/state/registry/registry-types';\nimport { populate, type DimensionWatcher } from '../../../util/registry';\n\nconst preset = getPreset();\n\ndescribe('force scrolling a droppable', () => {\n  it('should scroll the droppable', () => {\n    const registry: Registry = createRegistry();\n    const callbacks: Callbacks = getCallbacksStub();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    const watcher: DimensionWatcher = populate(registry);\n\n    // initial lift\n    marshal.startPublishing(defaultRequest);\n    expect(watcher.droppable.scroll).not.toHaveBeenCalled();\n\n    // scroll\n    marshal.scrollDroppable(critical.droppable.id, { x: 10, y: 20 });\n    expect(watcher.droppable.scroll).toHaveBeenCalledWith(\n      critical.droppable.id,\n      { x: 10, y: 20 },\n    );\n  });\n\n  it('should throw if the droppable cannot be found', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, justCritical);\n\n    // initial lift\n    marshal.startPublishing(defaultRequest);\n\n    // scroll\n    expect(() => {\n      marshal.scrollDroppable(preset.foreign.descriptor.id, { x: 10, y: 20 });\n    }).toThrow();\n  });\n\n  it('should not scroll the droppable if no collection is occurring', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    const watcher: DimensionWatcher = populate(registry);\n\n    marshal.scrollDroppable(critical.droppable.id, { x: 10, y: 20 });\n    expect(watcher.droppable.scroll).not.toHaveBeenCalled();\n  });\n});\n\ndescribe('responding to scroll changes', () => {\n  it('should let consumers know', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    const watcher: DimensionWatcher = populate(registry);\n\n    // initial lift\n    marshal.startPublishing(defaultRequest);\n    expect(watcher.droppable.scroll).not.toHaveBeenCalled();\n\n    marshal.updateDroppableScroll(critical.droppable.id, { x: 10, y: 20 });\n    expect(callbacks.updateDroppableScroll).toHaveBeenCalledWith({\n      id: critical.droppable.id,\n      newScroll: { x: 10, y: 20 },\n    });\n  });\n\n  it('should throw if the droppable cannot be found', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, justCritical);\n\n    // initial lift\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.updateDroppableScroll).not.toHaveBeenCalled();\n\n    expect(() => {\n      marshal.updateDroppableScroll(preset.foreign.descriptor.id, {\n        x: 10,\n        y: 20,\n      });\n    }).toThrow(\n      'Invariant failed: Cannot update the scroll on Droppable foreign as it is not registered',\n    );\n  });\n\n  it('should not let consumers know if know drag is occurring', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, justCritical);\n\n    marshal.updateDroppableScroll(critical.droppable.id, { x: 10, y: 20 });\n    expect(callbacks.updateDroppableScroll).not.toHaveBeenCalled();\n  });\n});\n\ndescribe('is enabled changes', () => {\n  it('should let consumers know', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry);\n\n    // initial lift\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.updateDroppableIsEnabled).not.toHaveBeenCalled();\n\n    marshal.updateDroppableIsEnabled(critical.droppable.id, false);\n    expect(callbacks.updateDroppableIsEnabled).toHaveBeenCalledWith({\n      id: critical.droppable.id,\n      isEnabled: false,\n    });\n  });\n\n  it('should throw if the droppable cannot be found', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, justCritical);\n\n    // initial lift\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.updateDroppableIsEnabled).not.toHaveBeenCalled();\n\n    expect(() =>\n      marshal.updateDroppableIsEnabled(preset.foreign.descriptor.id, false),\n    ).toThrow(\n      'Invariant failed: Cannot update is enabled flag of Droppable foreign as it is not registered',\n    );\n  });\n\n  it('should not let consumers know if no collection is occurring', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, justCritical);\n\n    marshal.updateDroppableIsEnabled(critical.droppable.id, false);\n    expect(callbacks.updateDroppableIsEnabled).not.toHaveBeenCalled();\n  });\n});\n"
  },
  {
    "path": "test/unit/view/dimension-marshal/initial-publish.spec.js",
    "content": "// @flow\nimport createDimensionMarshal from '../../../../src/state/dimension-marshal/dimension-marshal';\nimport { getCallbacksStub } from '../../../util/dimension-marshal';\nimport { copy, critical, preset } from '../../../util/preset-action-args';\nimport type {\n  DimensionMarshal,\n  StartPublishingResult,\n} from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport type {\n  LiftRequest,\n  DraggableDimension,\n  DroppableDimension,\n  DimensionMap,\n  Viewport,\n} from '../../../../src/types';\nimport { setViewport } from '../../../util/viewport';\nimport type {\n  Registry,\n  DraggableEntry,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\nimport {\n  getDraggableEntry,\n  getDroppableEntry,\n  populate,\n} from '../../../util/registry';\n\nconst viewport: Viewport = preset.viewport;\nsetViewport(viewport);\n\nconst defaultRequest: LiftRequest = {\n  draggableId: critical.draggable.id,\n  scrollOptions: {\n    shouldPublishImmediately: false,\n  },\n};\n\nconst foreignWithNewType: DroppableDimension = {\n  ...preset.foreign,\n  descriptor: {\n    ...preset.foreign.descriptor,\n    id: 'new foreign id',\n    type: 'some cool new type',\n  },\n};\n\nconst inForeignWithNewType: DraggableDimension = {\n  ...preset.inForeign1,\n  descriptor: {\n    ...preset.inForeign1.descriptor,\n    id: 'new in foreign 1 id',\n    type: foreignWithNewType.descriptor.type,\n  },\n};\n\nconst withNewType: DimensionMap = {\n  draggables: {\n    ...preset.dimensions.draggables,\n    [inForeignWithNewType.descriptor.id]: inForeignWithNewType,\n  },\n  droppables: {\n    ...preset.dimensions.droppables,\n    [foreignWithNewType.descriptor.id]: foreignWithNewType,\n  },\n};\n\nit('should publish the registered dimensions (simple)', () => {\n  const registry: Registry = createRegistry();\n  const marshal: DimensionMarshal = createDimensionMarshal(\n    registry,\n    getCallbacksStub(),\n  );\n\n  registry.draggable.register(getDraggableEntry({ dimension: preset.inHome1 }));\n  registry.draggable.register(getDraggableEntry({ dimension: preset.inHome2 }));\n  registry.droppable.register(getDroppableEntry({ dimension: preset.home }));\n\n  const result: StartPublishingResult = marshal.startPublishing(defaultRequest);\n  const expected: StartPublishingResult = {\n    critical,\n    viewport,\n    dimensions: {\n      draggables: {\n        [preset.inHome1.descriptor.id]: preset.inHome1,\n        [preset.inHome2.descriptor.id]: preset.inHome2,\n      },\n      droppables: {\n        [preset.home.descriptor.id]: preset.home,\n      },\n    },\n  };\n  expect(expected).toEqual(result);\n});\n\n// Just checking our preset behaves how we expect\nit('should publish the registered dimensions (preset)', () => {\n  const registry: Registry = createRegistry();\n  const marshal: DimensionMarshal = createDimensionMarshal(\n    registry,\n    getCallbacksStub(),\n  );\n  populate(registry);\n\n  const result: StartPublishingResult = marshal.startPublishing(defaultRequest);\n  const expected: StartPublishingResult = {\n    critical,\n    dimensions: preset.dimensions,\n    viewport,\n  };\n\n  expect(result).toEqual(expected);\n});\n\nit('should not publish dimensions that do not have the same type as the critical droppable', () => {\n  const registry: Registry = createRegistry();\n  const marshal: DimensionMarshal = createDimensionMarshal(\n    registry,\n    getCallbacksStub(),\n  );\n  populate(registry, withNewType);\n\n  const result: StartPublishingResult = marshal.startPublishing(defaultRequest);\n\n  const expected: StartPublishingResult = {\n    critical,\n    // dimensions with new type not gathered\n    dimensions: preset.dimensions,\n    viewport,\n  };\n\n  expect(result).toEqual(expected);\n});\n\nit('should not publish dimensions that have been unregistered', () => {\n  const registry: Registry = createRegistry();\n  const marshal: DimensionMarshal = createDimensionMarshal(\n    registry,\n    getCallbacksStub(),\n  );\n  populate(registry, preset.dimensions);\n  const expectedMap: DimensionMap = copy(preset.dimensions);\n\n  // removing inHome2\n  registry.draggable.unregister(\n    registry.draggable.getById(preset.inHome2.descriptor.id),\n  );\n  delete expectedMap.draggables[preset.inHome2.descriptor.id];\n\n  // removing foreign\n  registry.droppable.unregister(\n    registry.droppable.getById(preset.foreign.descriptor.id),\n  );\n  delete expectedMap.droppables[preset.foreign.descriptor.id];\n\n  // Being a good citizen and also unregistering all of the foreign draggables\n  preset.inForeignList.forEach((draggable: DraggableDimension) => {\n    registry.draggable.unregister(\n      registry.draggable.getById(draggable.descriptor.id),\n    );\n    delete expectedMap.draggables[draggable.descriptor.id];\n  });\n\n  const result: StartPublishingResult = marshal.startPublishing(defaultRequest);\n\n  expect(result).toEqual({\n    critical,\n    dimensions: expectedMap,\n    viewport,\n  });\n  expect(result).not.toEqual({\n    critical,\n    dimensions: preset.dimensions,\n    viewport,\n  });\n});\n\nit('should publish draggables that have been updated (index change)', () => {\n  const registry: Registry = createRegistry();\n  const marshal: DimensionMarshal = createDimensionMarshal(\n    registry,\n    getCallbacksStub(),\n  );\n  populate(registry, preset.dimensions);\n\n  const updatedInHome2: DraggableDimension = {\n    ...preset.inHome2,\n    descriptor: {\n      ...preset.inHome2.descriptor,\n      index: 10000,\n    },\n  };\n  const last: DraggableEntry = registry.draggable.getById(\n    preset.inHome2.descriptor.id,\n  );\n  const updated: DraggableEntry = getDraggableEntry({\n    uniqueId: last.uniqueId,\n    dimension: updatedInHome2,\n  });\n  registry.draggable.update(updated, last);\n\n  const result: StartPublishingResult = marshal.startPublishing(defaultRequest);\n  const expected: DimensionMap = copy(preset.dimensions);\n  expected.draggables[preset.inHome2.descriptor.id] = updatedInHome2;\n  expect(result).toEqual({\n    critical,\n    dimensions: expected,\n    viewport,\n  });\n});\n\nit('should publish droppables that have been updated (id change)', () => {\n  const registry: Registry = createRegistry();\n  const marshal: DimensionMarshal = createDimensionMarshal(\n    registry,\n    getCallbacksStub(),\n  );\n  populate(registry, preset.dimensions);\n  const expected: DimensionMap = copy(preset.dimensions);\n\n  // changing the id of home\n  const updatedHome: DroppableDimension = {\n    ...preset.home,\n    descriptor: {\n      ...preset.home.descriptor,\n      id: 'some new id',\n    },\n  };\n  registry.droppable.unregister(\n    registry.droppable.getById(preset.home.descriptor.id),\n  );\n  registry.droppable.register(getDroppableEntry({ dimension: updatedHome }));\n  delete expected.droppables[preset.home.descriptor.id];\n  expected.droppables[updatedHome.descriptor.id] = updatedHome;\n\n  // changing the droppable id of all the draggables in home\n  preset.inHomeList.forEach((draggable: DraggableDimension) => {\n    const updated: DraggableDimension = {\n      ...draggable,\n      descriptor: {\n        ...draggable.descriptor,\n        droppableId: updatedHome.descriptor.id,\n      },\n    };\n    const last: DraggableEntry = registry.draggable.getById(\n      draggable.descriptor.id,\n    );\n    const fresh: DraggableEntry = getDraggableEntry({\n      uniqueId: last.uniqueId,\n      dimension: updated,\n    });\n    registry.draggable.update(fresh, last);\n    expected.draggables[draggable.descriptor.id] = updated;\n  });\n\n  const result: StartPublishingResult = marshal.startPublishing(defaultRequest);\n\n  const wanted: StartPublishingResult = {\n    viewport,\n    critical: {\n      draggable: {\n        ...critical.draggable,\n        droppableId: updatedHome.descriptor.id,\n      },\n      droppable: updatedHome.descriptor,\n    },\n    dimensions: expected,\n  };\n  expect(result).toEqual(wanted);\n});\n\ndescribe('subsequent calls', () => {\n  const start = (marshal: DimensionMarshal) =>\n    marshal.startPublishing(defaultRequest);\n  const stop = (marshal: DimensionMarshal) => marshal.stopPublishing();\n\n  it('should return dimensions a subsequent call', () => {\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      getCallbacksStub(),\n    );\n    populate(registry, preset.dimensions);\n    const expected: StartPublishingResult = {\n      critical,\n      dimensions: preset.dimensions,\n      viewport,\n    };\n\n    expect(start(marshal)).toEqual(expected);\n    stop(marshal);\n    expect(start(marshal)).toEqual(expected);\n    stop(marshal);\n    expect(start(marshal)).toEqual(expected);\n    stop(marshal);\n  });\n\n  it('should throw if starting asked to start before stopping', () => {\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      getCallbacksStub(),\n    );\n    populate(registry, preset.dimensions);\n\n    start(marshal);\n    expect(() => start(marshal)).toThrow();\n  });\n\n  it('should account for changes after the last call', () => {\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      getCallbacksStub(),\n    );\n    populate(registry, preset.dimensions);\n\n    // Start first publish\n    const result1: StartPublishingResult = start(marshal);\n    expect(result1).toEqual({\n      critical,\n      dimensions: preset.dimensions,\n      viewport,\n    });\n\n    // Update while first drag is occurring\n\n    const updatedInHome2: DraggableDimension = {\n      ...preset.inHome2,\n      descriptor: {\n        ...preset.inHome2.descriptor,\n        index: 10000,\n      },\n    };\n    const last: DraggableEntry = registry.draggable.getById(\n      preset.inHome2.descriptor.id,\n    );\n    const fresh: DraggableEntry = getDraggableEntry({\n      uniqueId: last.uniqueId,\n      dimension: updatedInHome2,\n    });\n    registry.draggable.update(fresh, last);\n    const expected: DimensionMap = copy(preset.dimensions);\n    expected.draggables[updatedInHome2.descriptor.id] = updatedInHome2;\n\n    // Stop the first publish\n    stop(marshal);\n\n    // Start the second publish\n    const result2: StartPublishingResult = start(marshal);\n    expect(result2).toEqual({\n      critical,\n      dimensions: expected,\n      viewport,\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/view/dimension-marshal/publish-while-dragging.spec.js",
    "content": "// @flow\nimport createDimensionMarshal from '../../../../src/state/dimension-marshal/dimension-marshal';\nimport type {\n  Callbacks,\n  DimensionMarshal,\n  StartPublishingResult,\n} from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport type {\n  DraggableDimension,\n  DroppableDimension,\n  DimensionMap,\n  Published,\n  Viewport,\n  Critical,\n} from '../../../../src/types';\nimport { preset } from '../../../util/preset-action-args';\nimport { getCallbacksStub } from '../../../util/dimension-marshal';\nimport { defaultRequest } from './util';\nimport { makeScrollable } from '../../../util/dimension';\nimport { setViewport } from '../../../util/viewport';\nimport getFrame from '../../../../src/state/get-frame';\nimport type { Registry } from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\nimport {\n  getDraggableEntry,\n  getDroppableEntry,\n  populate,\n  type DimensionWatcher,\n} from '../../../util/registry';\nimport { origin } from '../../../../src/state/position';\nimport patchDimensionMap from '../../../../src/state/patch-dimension-map';\nimport { withWarn } from '../../../util/console';\n\nconst viewport: Viewport = preset.viewport;\nsetViewport(viewport);\n\nconst empty: Published = {\n  removals: [],\n  additions: [],\n  modified: [],\n};\n\nfunction makeVirtual(droppable: DroppableDimension): DroppableDimension {\n  return {\n    ...droppable,\n    descriptor: {\n      ...droppable.descriptor,\n      mode: 'virtual',\n    },\n  };\n}\n\nconst scrollableHome: DroppableDimension = makeScrollable(\n  makeVirtual(preset.home),\n);\nconst scrollableForeign: DroppableDimension = makeScrollable(\n  makeVirtual(preset.foreign),\n);\nconst withScrollables: DimensionMap = {\n  draggables: preset.dimensions.draggables,\n  droppables: {\n    ...preset.dimensions.droppables,\n    [scrollableHome.descriptor.id]: scrollableHome,\n    [scrollableForeign.descriptor.id]: scrollableForeign,\n  },\n};\n\nconst ofAnotherType: DroppableDimension = {\n  ...preset.foreign,\n  descriptor: {\n    type: 'some rogue type',\n    id: 'another droppable',\n    mode: 'virtual',\n  },\n};\nconst inAnotherType: DraggableDimension = {\n  ...preset.inHome1,\n  descriptor: {\n    type: ofAnotherType.descriptor.type,\n    droppableId: ofAnotherType.descriptor.id,\n    id: 'addition!',\n    index: 0,\n  },\n};\nconst anotherDroppable: DroppableDimension = {\n  ...preset.foreign,\n  descriptor: {\n    ...preset.foreign.descriptor,\n    id: 'another droppable',\n  },\n};\n\nconst critical: Critical = {\n  draggable: preset.inHome1.descriptor,\n  droppable: scrollableHome.descriptor,\n};\n\nconst justCritical: DimensionMap = {\n  draggables: {\n    [preset.inHome1.descriptor.id]: preset.inHome1,\n  },\n  droppables: {\n    [preset.home.descriptor.id]: scrollableHome,\n  },\n};\n\nafterEach(() => {\n  requestAnimationFrame.reset();\n});\n\ndescribe('draggable additions', () => {\n  it('should collect and publish the draggables', () => {\n    const beforeInHome1: DraggableDimension = {\n      ...preset.inHome1,\n      descriptor: {\n        ...preset.inHome1.descriptor,\n        id: 'addition1',\n        index: 0,\n      },\n    };\n    const beforeInHome2: DraggableDimension = {\n      ...preset.inHome2,\n      descriptor: {\n        ...preset.inHome2.descriptor,\n        id: 'addition2',\n        index: 1,\n      },\n    };\n    const registry: Registry = createRegistry();\n    const callbacks: Callbacks = getCallbacksStub();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, withScrollables);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    registry.draggable.register(\n      getDraggableEntry({ dimension: beforeInHome1 }),\n    );\n    registry.draggable.register(\n      getDraggableEntry({ dimension: beforeInHome2 }),\n    );\n    expect(callbacks.collectionStarting).toHaveBeenCalled();\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    // Fire the collection / publish step\n    requestAnimationFrame.step();\n    const expected: Published = {\n      ...empty,\n      additions: [beforeInHome1, beforeInHome2],\n      modified: [{ droppableId: scrollableHome.descriptor.id, scroll: origin }],\n    };\n    expect(callbacks.publishWhileDragging).toHaveBeenCalledWith(expected);\n  });\n\n  it('should not do anything if trying to add a draggable that does not have the same type as the dragging item', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, withScrollables);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.collectionStarting).not.toHaveBeenCalled();\n\n    // Registering a new draggable (inserted before inHome1)\n\n    registry.draggable.register(\n      getDraggableEntry({ dimension: inAnotherType }),\n    );\n    expect(callbacks.collectionStarting).not.toHaveBeenCalled();\n  });\n\n  it('should order published draggables by their index', () => {\n    const beforeInHome1: DraggableDimension = {\n      ...preset.inHome1,\n      descriptor: {\n        ...preset.inHome1.descriptor,\n        id: 'b',\n        index: 0,\n      },\n    };\n    const beforeInHome2: DraggableDimension = {\n      ...preset.inHome2,\n      descriptor: {\n        ...preset.inHome2.descriptor,\n        // if ordered by a key, this would be first\n        id: 'a',\n        index: 1,\n      },\n    };\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, withScrollables);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    // publishing the higher index value first\n    registry.draggable.register(\n      getDraggableEntry({ dimension: beforeInHome2 }),\n    );\n    // publishing the lower index value second\n    registry.draggable.register(\n      getDraggableEntry({ dimension: beforeInHome1 }),\n    );\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    // Fire the collection / publish step\n    requestAnimationFrame.step();\n    const expected: Published = {\n      ...empty,\n      // we expect this to be ordered by index\n      additions: [beforeInHome1, beforeInHome2],\n      modified: [{ droppableId: scrollableHome.descriptor.id, scroll: origin }],\n    };\n    expect(callbacks.publishWhileDragging).toHaveBeenCalledWith(expected);\n  });\n\n  it('should log a warning if trying to add or remove a draggable from a non-virtual list', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    const notVirtual: DroppableDimension = {\n      ...scrollableHome,\n      descriptor: {\n        ...scrollableHome.descriptor,\n        mode: 'standard',\n      },\n    };\n    const map: DimensionMap = patchDimensionMap(withScrollables, notVirtual);\n    populate(registry, map);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.collectionStarting).not.toHaveBeenCalled();\n\n    // additions log a warning\n    withWarn(() => {\n      const beforeInHome1: DraggableDimension = {\n        ...preset.inHome1,\n        descriptor: {\n          ...preset.inHome1.descriptor,\n          id: 'b',\n          index: 0,\n        },\n      };\n      registry.draggable.register(\n        getDraggableEntry({ dimension: beforeInHome1 }),\n      );\n    });\n    // removals log a warning\n    withWarn(() => {\n      registry.draggable.unregister(\n        registry.draggable.getById(preset.inHome2.descriptor.id),\n      );\n    });\n\n    // neither cause a collection to start\n    expect(callbacks.collectionStarting).not.toHaveBeenCalled();\n  });\n});\n\ndescribe('draggable removals', () => {\n  it('should publish a removal', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, withScrollables);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    registry.draggable.unregister(\n      registry.draggable.getById(preset.inHome2.descriptor.id),\n    );\n    registry.draggable.unregister(\n      registry.draggable.getById(preset.inHome3.descriptor.id),\n    );\n    registry.draggable.unregister(\n      registry.draggable.getById(preset.inForeign1.descriptor.id),\n    );\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    // Fire the collection / publish step\n    requestAnimationFrame.flush();\n    const expected: Published = {\n      additions: [],\n      removals: [\n        preset.inHome2.descriptor.id,\n        preset.inHome3.descriptor.id,\n        preset.inForeign1.descriptor.id,\n      ],\n      modified: [\n        { droppableId: scrollableHome.descriptor.id, scroll: origin },\n        { droppableId: scrollableForeign.descriptor.id, scroll: origin },\n      ],\n    };\n    expect(callbacks.publishWhileDragging).toHaveBeenCalledWith(expected);\n  });\n\n  it('should do nothing if tying to remove a draggable of a different type', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    const dimensions: DimensionMap = {\n      draggables: {\n        ...withScrollables.draggables,\n        [inAnotherType.descriptor.id]: inAnotherType,\n      },\n      droppables: {\n        ...withScrollables.droppables,\n        [ofAnotherType.descriptor.id]: ofAnotherType,\n      },\n    };\n    populate(registry, dimensions);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n\n    registry.draggable.unregister(\n      registry.draggable.getById(inAnotherType.descriptor.id),\n    );\n\n    expect(callbacks.collectionStarting).not.toHaveBeenCalled();\n  });\n\n  it('should do nothing if removing the critical draggable', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, withScrollables);\n\n    marshal.startPublishing(defaultRequest);\n\n    registry.draggable.unregister(\n      registry.draggable.getById(critical.draggable.id),\n    );\n\n    expect(callbacks.collectionStarting).not.toHaveBeenCalled();\n  });\n});\n\ndescribe('droppables', () => {\n  it('should not do anything if a droppable is added', () => {\n    const registry: Registry = createRegistry();\n    const callbacks: Callbacks = getCallbacksStub();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, withScrollables);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    registry.droppable.register(\n      getDroppableEntry({ dimension: anotherDroppable }),\n    );\n\n    expect(callbacks.collectionStarting).not.toHaveBeenCalled();\n  });\n\n  it('should not do anything if a droppable is removed', () => {\n    const registry: Registry = createRegistry();\n    const callbacks: Callbacks = getCallbacksStub();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, withScrollables);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    registry.droppable.unregister(\n      registry.droppable.getById(scrollableForeign.descriptor.id),\n    );\n\n    expect(callbacks.collectionStarting).not.toHaveBeenCalled();\n  });\n\n  it('should recollect the scroll from droppables that had draggable additions', () => {\n    const beforeInHome2: DraggableDimension = {\n      ...preset.inHome2,\n      descriptor: {\n        ...preset.inHome2.descriptor,\n        id: 'addition2',\n        index: 1,\n      },\n    };\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    const watcher: DimensionWatcher = populate(registry, withScrollables);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    registry.draggable.register(\n      getDraggableEntry({ dimension: beforeInHome2 }),\n    );\n    expect(callbacks.collectionStarting).toHaveBeenCalled();\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n    expect(watcher.droppable.getScrollWhileDragging).not.toHaveBeenCalled();\n\n    // Fire the collection / publish step\n    requestAnimationFrame.flush();\n\n    // not hiding placeholder in home list\n\n    expect(watcher.droppable.getScrollWhileDragging).toHaveBeenCalledWith(\n      scrollableHome.descriptor.id,\n      getFrame(scrollableHome).scroll.current,\n    );\n\n    const expected: Published = {\n      additions: [beforeInHome2],\n      removals: [],\n      modified: [{ droppableId: scrollableHome.descriptor.id, scroll: origin }],\n    };\n    expect(callbacks.publishWhileDragging).toHaveBeenCalledWith(expected);\n  });\n\n  it('should recollect the scroll from droppables that had draggable removals', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    const watcher: DimensionWatcher = populate(registry, withScrollables);\n\n    // A publish has started\n    marshal.startPublishing(defaultRequest);\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    registry.draggable.unregister(\n      registry.draggable.getById(preset.inHome2.descriptor.id),\n    );\n    expect(callbacks.collectionStarting).toHaveBeenCalled();\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n    expect(watcher.droppable.getScrollWhileDragging).not.toHaveBeenCalled();\n\n    // Fire the collection / publish step\n    requestAnimationFrame.flush();\n\n    // not hiding placeholder in home list\n\n    expect(watcher.droppable.getScrollWhileDragging).toHaveBeenCalledWith(\n      scrollableHome.descriptor.id,\n      getFrame(scrollableHome).scroll.current,\n    );\n\n    const expected: Published = {\n      additions: [],\n      removals: [preset.inHome2.descriptor.id],\n      modified: [{ droppableId: scrollableHome.descriptor.id, scroll: origin }],\n    };\n    expect(callbacks.publishWhileDragging).toHaveBeenCalledWith(expected);\n  });\n});\n\ndescribe('cancelling mid publish', () => {\n  it('should cancel any pending collections', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n\n    populate(registry, justCritical);\n\n    const result: StartPublishingResult = marshal.startPublishing(\n      defaultRequest,\n    );\n    const expected: StartPublishingResult = {\n      critical,\n      dimensions: justCritical,\n      viewport,\n    };\n    expect(result).toEqual(expected);\n\n    registry.draggable.register(\n      getDraggableEntry({ dimension: preset.inHome2 }),\n    );\n    expect(callbacks.collectionStarting).toHaveBeenCalled();\n    // no request animation fired yet\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n\n    // marshal told to stop - which should cancel any pending publishes\n    marshal.stopPublishing();\n\n    // flushing any frames\n    requestAnimationFrame.flush();\n    expect(callbacks.publishWhileDragging).not.toHaveBeenCalled();\n  });\n});\n\ndescribe('subsequent', () => {\n  it('should allow subsequent publishes in the same drag', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, justCritical);\n\n    marshal.startPublishing(defaultRequest);\n\n    registry.draggable.register(\n      getDraggableEntry({ dimension: preset.inHome2 }),\n    );\n    requestAnimationFrame.step();\n    expect(callbacks.publishWhileDragging).toHaveBeenCalledTimes(1);\n    // $FlowFixMe\n    callbacks.publishWhileDragging.mockReset();\n\n    registry.draggable.register(\n      getDraggableEntry({ dimension: preset.inHome3 }),\n    );\n    requestAnimationFrame.step();\n    expect(callbacks.publishWhileDragging).toHaveBeenCalledTimes(1);\n  });\n\n  it('should allow subsequent publishes between drags', () => {\n    const callbacks: Callbacks = getCallbacksStub();\n    const registry: Registry = createRegistry();\n    const marshal: DimensionMarshal = createDimensionMarshal(\n      registry,\n      callbacks,\n    );\n    populate(registry, justCritical);\n\n    marshal.startPublishing(defaultRequest);\n\n    registry.draggable.register(\n      getDraggableEntry({ dimension: preset.inHome2 }),\n    );\n    requestAnimationFrame.step();\n    expect(callbacks.publishWhileDragging).toHaveBeenCalledTimes(1);\n    // $FlowFixMe\n    callbacks.publishWhileDragging.mockReset();\n\n    marshal.stopPublishing();\n\n    // second drag\n    marshal.startPublishing(defaultRequest);\n\n    registry.draggable.register(\n      getDraggableEntry({ dimension: preset.inHome3 }),\n    );\n    requestAnimationFrame.step();\n    expect(callbacks.publishWhileDragging).toHaveBeenCalledTimes(1);\n  });\n});\n"
  },
  {
    "path": "test/unit/view/dimension-marshal/util.js",
    "content": "// @flow\nimport { getPreset } from '../../../util/dimension';\nimport type {\n  DimensionMap,\n  LiftRequest,\n  Critical,\n} from '../../../../src/types';\n\nconst preset = getPreset();\n\nexport const defaultRequest: LiftRequest = {\n  draggableId: preset.inHome1.descriptor.id,\n  scrollOptions: {\n    shouldPublishImmediately: false,\n  },\n};\n\nexport const critical: Critical = {\n  draggable: preset.inHome1.descriptor,\n  droppable: preset.home.descriptor,\n};\n\nexport const justCritical: DimensionMap = {\n  draggables: {\n    [preset.inHome1.descriptor.id]: preset.inHome1,\n  },\n  droppables: {\n    [preset.home.descriptor.id]: preset.home,\n  },\n};\n"
  },
  {
    "path": "test/unit/view/drag-drop-context/content-security-protection-nonce.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { mount, type ReactWrapper } from 'enzyme';\nimport DragDropContext from '../../../../src/view/drag-drop-context';\nimport { resetServerContext } from '../../../../src';\nimport * as attributes from '../../../../src/view/data-attributes';\n\nit('should insert nonce into style tag', () => {\n  const nonce = 'ThisShouldBeACryptographicallySecurePseudorandomNumber';\n\n  resetServerContext();\n  const wrapper1: ReactWrapper<*> = mount(\n    <DragDropContext nonce={nonce} onDragEnd={() => {}}>\n      {null}\n    </DragDropContext>,\n  );\n  const styleTag = document.querySelector(`[${attributes.prefix}-always=\"0\"]`);\n  const nonceAttribute = styleTag ? styleTag.getAttribute('nonce') : '';\n  expect(nonceAttribute).toEqual(nonce);\n\n  wrapper1.unmount();\n});\n"
  },
  {
    "path": "test/unit/view/droppable/home-list-placeholder-cleanup.spec.js",
    "content": "// @flow\nimport { act } from 'react-dom/test-utils';\nimport type { ReactWrapper } from 'enzyme';\nimport mount from './util/mount';\nimport {\n  homeOwnProps,\n  isNotOverHome,\n  homeAtRest,\n  homePostDropAnimation,\n} from './util/get-props';\nimport Placeholder from '../../../../src/view/placeholder';\n\nit('should not display a placeholder after a flushed drag end in the home list', () => {\n  // dropping\n  const wrapper: ReactWrapper<*> = mount({\n    ownProps: homeOwnProps,\n    mapProps: isNotOverHome,\n  });\n\n  expect(wrapper.find(Placeholder)).toHaveLength(1);\n\n  wrapper.setProps({\n    ...homeAtRest,\n  });\n  wrapper.update();\n\n  expect(wrapper.find(Placeholder)).toHaveLength(0);\n});\n\nit('should animate a placeholder closed in a home list after a drag', () => {\n  // dropping\n  const wrapper: ReactWrapper<*> = mount({\n    ownProps: homeOwnProps,\n    mapProps: isNotOverHome,\n  });\n\n  expect(wrapper.find(Placeholder)).toHaveLength(1);\n\n  wrapper.setProps({\n    ...homePostDropAnimation,\n  });\n  wrapper.update();\n\n  expect(wrapper.find(Placeholder)).toHaveLength(1);\n  expect(homePostDropAnimation.shouldAnimatePlaceholder).toBe(true);\n\n  // finishing the animation\n  act(() => {\n    wrapper.find(Placeholder).props().onClose();\n  });\n\n  // let the wrapper know the react tree has changed\n  wrapper.update();\n\n  // placeholder is now gone\n  expect(wrapper.find(Placeholder)).toHaveLength(0);\n});\n"
  },
  {
    "path": "test/unit/view/droppable/inner-ref-validation.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport type { Provided } from '../../../../src/view/droppable/droppable-types';\nimport mount from './util/mount';\nimport { withError } from '../../../util/console';\n\nit('should warn a consumer if they have not provided a ref', () => {\n  class NoRef extends React.Component<{ provided: Provided }> {\n    render() {\n      const provided: Provided = this.props.provided;\n\n      return (\n        <div {...provided.droppableProps}>\n          Hello there\n          {provided.placeholder}\n        </div>\n      );\n    }\n  }\n\n  withError(() => {\n    mount({ WrappedComponent: NoRef });\n  });\n});\n\nit('should throw a consumer if they have provided an SVGElement', () => {\n  class WithSVG extends React.Component<{ provided: Provided }> {\n    render() {\n      const provided: Provided = this.props.provided;\n\n      return (\n        // $FlowFixMe - flow is correctly stating this is not a HTMLElement\n        <svg {...provided.droppableProps} ref={provided.innerRef}>\n          Hello there\n          {provided.placeholder}\n        </svg>\n      );\n    }\n  }\n\n  withError(() => {\n    mount({ WrappedComponent: WithSVG });\n  });\n});\n"
  },
  {
    "path": "test/unit/view/droppable/own-props-validation.spec.js",
    "content": "// @flow\nimport type { OwnProps } from '../../../../src/view/droppable/droppable-types';\nimport mount from './util/mount';\nimport { homeOwnProps as defaultOwnProps } from './util/get-props';\nimport { withError } from '../../../util/console';\n\nbeforeAll(() => {\n  jest.spyOn(console, 'error').mockImplementation(() => {});\n});\n\nafterAll(() => {\n  // $FlowFixMe\n  console.error.mockReset();\n});\n\nit('should throw if no droppableId is provided', () => {\n  const ownProps: OwnProps = {\n    ...defaultOwnProps,\n  };\n\n  withError(() => {\n    // $ExpectError - not provided\n    ownProps.droppableId = undefined;\n    mount({ ownProps });\n  });\n\n  withError(() => {\n    // $ExpectError - not a string\n    ownProps.droppableId = null;\n    mount({ ownProps });\n  });\n\n  withError(() => {\n    // $ExpectError - using number\n    ownProps.droppableId = 3;\n    mount({ ownProps });\n  });\n});\n\nit('should throw if isDropDisabled is set to null', () => {\n  const ownProps: OwnProps = {\n    ...defaultOwnProps,\n  };\n  withError(() => {\n    // $ExpectError - null\n    ownProps.isDropDisabled = null;\n    mount({ ownProps });\n  });\n});\n\nit('should throw if isCombineEnabled is set to null', () => {\n  const ownProps: OwnProps = {\n    ...defaultOwnProps,\n  };\n  withError(() => {\n    // $ExpectError - null\n    ownProps.isCombineEnabled = null;\n    mount({ ownProps });\n  });\n});\n\nit('should throw if ignoreContainerClipping is set to null', () => {\n  const ownProps: OwnProps = {\n    ...defaultOwnProps,\n  };\n  withError(() => {\n    // $ExpectError - null\n    ownProps.ignoreContainerClipping = null;\n    mount({ ownProps });\n  });\n});\n"
  },
  {
    "path": "test/unit/view/droppable/pass-through-snapshot.spec.js",
    "content": "// @flow\nimport type { ReactWrapper } from 'enzyme';\nimport mount from './util/mount';\nimport getStubber from './util/get-stubber';\nimport {\n  isNotOverHome,\n  isOverHome,\n  homeAtRest,\n  isOverForeign,\n  foreignOwnProps,\n} from './util/get-props';\n\nconst getLastSnapshot = (myMock: any) => {\n  return myMock.mock.calls[myMock.mock.calls.length - 1][0].snapshot;\n};\n\nit('should let a consumer know when a foreign list is being dragged over', () => {\n  const myMock = jest.fn();\n  mount({\n    ownProps: foreignOwnProps,\n    mapProps: isOverForeign,\n    WrappedComponent: getStubber(myMock),\n  });\n\n  expect(getLastSnapshot(myMock)).toEqual(isOverForeign.snapshot);\n});\n\nit('should update snapshot as dragging over changes', () => {\n  const myMock = jest.fn();\n\n  const wrapper: ReactWrapper<*> = mount({\n    mapProps: homeAtRest,\n    WrappedComponent: getStubber(myMock),\n  });\n  expect(getLastSnapshot(myMock)).toBe(homeAtRest.snapshot);\n\n  wrapper.setProps(isOverHome);\n  expect(getLastSnapshot(myMock)).toBe(isOverHome.snapshot);\n\n  // now over foreign list\n  wrapper.setProps(isNotOverHome);\n  expect(getLastSnapshot(myMock)).toBe(isNotOverHome.snapshot);\n\n  // drag is now over\n  wrapper.setProps(homeAtRest);\n  expect(getLastSnapshot(myMock)).toBe(homeAtRest.snapshot);\n});\n"
  },
  {
    "path": "test/unit/view/droppable/placeholder-setup-warning.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport type { ReactWrapper } from 'enzyme';\nimport type { Provided } from '../../../../src/view/droppable/droppable-types';\nimport {\n  homeAtRest,\n  foreignOwnProps,\n  isOverForeign,\n  isNotOverForeign,\n} from './util/get-props';\nimport mount from './util/mount';\n\nclass WithNoPlaceholder extends React.Component<{|\n  provided: Provided,\n|}> {\n  render() {\n    return (\n      <div\n        ref={this.props.provided.innerRef}\n        {...this.props.provided.droppableProps}\n      >\n        Not rendering placeholder\n      </div>\n    );\n  }\n}\n\nbeforeEach(() => {\n  jest.spyOn(console, 'warn').mockImplementation(() => {});\n});\nafterEach(() => {\n  // $FlowFixMe\n  console.warn.mockRestore();\n});\n\ndescribe('is over foreign', () => {\n  it('should log a warning when mounting', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: foreignOwnProps,\n      mapProps: isOverForeign,\n      WrappedComponent: WithNoPlaceholder,\n    });\n\n    expect(console.warn).toHaveBeenCalled();\n\n    wrapper.unmount();\n  });\n\n  it('should log a warning when updating', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: foreignOwnProps,\n      mapProps: homeAtRest,\n      WrappedComponent: WithNoPlaceholder,\n    });\n    expect(console.warn).not.toHaveBeenCalled();\n\n    wrapper.setProps(isOverForeign);\n    expect(console.warn).toHaveBeenCalled();\n\n    wrapper.unmount();\n  });\n});\n\ndescribe('is not over foreign', () => {\n  it('should not log a warning when mounting', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: foreignOwnProps,\n      mapProps: isNotOverForeign,\n      WrappedComponent: WithNoPlaceholder,\n    });\n\n    expect(console.warn).not.toHaveBeenCalled();\n\n    wrapper.unmount();\n  });\n\n  it('should not log a warning when updating', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: foreignOwnProps,\n      mapProps: homeAtRest,\n      WrappedComponent: WithNoPlaceholder,\n    });\n    expect(console.warn).not.toHaveBeenCalled();\n\n    wrapper.setProps(isNotOverForeign);\n    expect(console.warn).not.toHaveBeenCalled();\n\n    wrapper.unmount();\n  });\n});\n"
  },
  {
    "path": "test/unit/view/droppable/placeholder.spec.js",
    "content": "// @flow\nimport type { ReactWrapper } from 'enzyme';\nimport mount from './util/mount';\nimport {\n  foreignOwnProps,\n  isOverForeign,\n  homeOwnProps,\n  isOverHome,\n  isNotOverHome,\n  homeAtRest,\n  isNotOverForeign,\n} from './util/get-props';\nimport Placeholder from '../../../../src/view/placeholder';\n\ndescribe('home list', () => {\n  it('should not render a placeholder when not dragging', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: homeOwnProps,\n      mapProps: homeAtRest,\n    });\n\n    expect(wrapper.find(Placeholder)).toHaveLength(0);\n  });\n\n  it('should render a placeholder when dragging over', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: homeOwnProps,\n      mapProps: isOverHome,\n    });\n\n    expect(wrapper.find(Placeholder)).toHaveLength(1);\n  });\n\n  it('should render a placeholder when dragging over nothing', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: homeOwnProps,\n      mapProps: isNotOverHome,\n    });\n\n    expect(wrapper.find(Placeholder)).toHaveLength(1);\n  });\n\n  it('should render a placeholder when dragging over a foreign list', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: homeOwnProps,\n      mapProps: isOverForeign,\n    });\n\n    expect(wrapper.find(Placeholder)).toHaveLength(1);\n  });\n});\n\ndescribe('foreign', () => {\n  it('should not render a placeholder when not dragging', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: foreignOwnProps,\n      mapProps: homeAtRest,\n    });\n\n    expect(wrapper.find(Placeholder)).toHaveLength(0);\n  });\n\n  it('should render a placeholder when dragging over', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: foreignOwnProps,\n      mapProps: isOverForeign,\n    });\n\n    expect(wrapper.find(Placeholder)).toHaveLength(1);\n  });\n\n  it('should not render a placeholder when over nothing', () => {\n    const wrapper: ReactWrapper<*> = mount({\n      ownProps: foreignOwnProps,\n      mapProps: isNotOverForeign,\n    });\n\n    expect(wrapper.find(Placeholder)).toHaveLength(0);\n  });\n});\n"
  },
  {
    "path": "test/unit/view/droppable/update-max-window-scroll.spec.js",
    "content": "// @flow\nimport type { ReactWrapper } from 'enzyme';\nimport mount from './util/mount';\nimport { homeOwnProps, isOverHome, isNotOverHome } from './util/get-props';\nimport type { DispatchProps } from '../../../../src/view/droppable/droppable-types';\nimport getMaxWindowScroll from '../../../../src/view/window/get-max-window-scroll';\nimport Placeholder from '../../../../src/view/placeholder';\n\nit('should update when a placeholder animation finishes', () => {\n  const dispatchProps: DispatchProps = {\n    updateViewportMaxScroll: jest.fn(),\n  };\n  const wrapper: ReactWrapper<*> = mount({\n    ownProps: homeOwnProps,\n    mapProps: isOverHome,\n    dispatchProps,\n    isMovementAllowed: () => true,\n  });\n\n  wrapper.find(Placeholder).props().onTransitionEnd();\n\n  expect(dispatchProps.updateViewportMaxScroll).toHaveBeenCalledWith({\n    maxScroll: getMaxWindowScroll(),\n  });\n});\n\nit('should update when a placeholder finishes and the list is not dragged over', () => {\n  const dispatchProps: DispatchProps = {\n    updateViewportMaxScroll: jest.fn(),\n  };\n  const wrapper: ReactWrapper<*> = mount({\n    ownProps: homeOwnProps,\n    mapProps: isNotOverHome,\n    dispatchProps,\n    isMovementAllowed: () => true,\n  });\n\n  wrapper.find(Placeholder).props().onTransitionEnd();\n\n  expect(dispatchProps.updateViewportMaxScroll).toHaveBeenCalledWith({\n    maxScroll: getMaxWindowScroll(),\n  });\n});\n\nit('should not update when dropping', () => {\n  const dispatchProps: DispatchProps = {\n    updateViewportMaxScroll: jest.fn(),\n  };\n  const wrapper: ReactWrapper<*> = mount({\n    ownProps: homeOwnProps,\n    mapProps: isNotOverHome,\n    dispatchProps,\n    // when dropping there is no movement allowed\n    isMovementAllowed: () => false,\n  });\n\n  wrapper.find(Placeholder).props().onTransitionEnd();\n\n  expect(dispatchProps.updateViewportMaxScroll).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/view/droppable/util/get-props.js",
    "content": "// @flow\nimport { getPreset } from '../../../../util/dimension';\nimport type {\n  MapProps,\n  OwnProps,\n  DispatchProps,\n} from '../../../../../src/view/droppable/droppable-types';\nimport getBodyElement from '../../../../../src/view/get-body-element';\n\nexport const preset = getPreset();\n\nexport const homeOwnProps: OwnProps = {\n  droppableId: preset.home.descriptor.id,\n  type: preset.home.descriptor.type,\n  mode: preset.home.descriptor.mode,\n  isDropDisabled: false,\n  isCombineEnabled: false,\n  direction: preset.home.axis.direction,\n  ignoreContainerClipping: false,\n  children: () => null,\n  getContainerForClone: getBodyElement,\n  renderClone: null,\n};\n\nexport const foreignOwnProps: OwnProps = {\n  ...homeOwnProps,\n  droppableId: preset.foreign.descriptor.id,\n  type: preset.foreign.descriptor.type,\n  direction: preset.foreign.axis.direction,\n};\n\nexport const homeAtRest: MapProps = {\n  placeholder: null,\n  shouldAnimatePlaceholder: false,\n  snapshot: {\n    isDraggingOver: false,\n    draggingOverWith: null,\n    draggingFromThisWith: null,\n    isUsingPlaceholder: false,\n  },\n  useClone: null,\n};\n\nexport const isOverHome: MapProps = {\n  placeholder: preset.inHome1.placeholder,\n  // this can change during a drag\n  shouldAnimatePlaceholder: false,\n  snapshot: {\n    isUsingPlaceholder: true,\n    isDraggingOver: true,\n    draggingOverWith: preset.inHome1.descriptor.id,\n    draggingFromThisWith: preset.inHome1.descriptor.id,\n  },\n  useClone: null,\n};\n\nexport const isNotOverHome: MapProps = {\n  placeholder: preset.inHome1.placeholder,\n  // this can change during a drag\n  shouldAnimatePlaceholder: false,\n  snapshot: {\n    isUsingPlaceholder: true,\n    isDraggingOver: false,\n    draggingOverWith: null,\n    draggingFromThisWith: preset.inHome1.descriptor.id,\n  },\n  useClone: null,\n};\n\nexport const homePostDropAnimation: MapProps = {\n  placeholder: null,\n  shouldAnimatePlaceholder: true,\n  snapshot: {\n    isUsingPlaceholder: false,\n    isDraggingOver: false,\n    draggingOverWith: null,\n    draggingFromThisWith: null,\n  },\n  useClone: null,\n};\n\nexport const isOverForeign: MapProps = {\n  placeholder: preset.inHome1.placeholder,\n  shouldAnimatePlaceholder: true,\n  snapshot: {\n    isUsingPlaceholder: true,\n    isDraggingOver: true,\n    draggingOverWith: preset.inHome1.descriptor.id,\n    draggingFromThisWith: null,\n  },\n  useClone: null,\n};\n\nexport const isNotOverForeign: MapProps = {\n  placeholder: null,\n  shouldAnimatePlaceholder: false,\n  snapshot: {\n    isUsingPlaceholder: false,\n    isDraggingOver: false,\n    draggingOverWith: null,\n    draggingFromThisWith: null,\n  },\n  useClone: null,\n};\n\nexport const dispatchProps: DispatchProps = {\n  // $ExpectError\n  updateViewportMaxScroll: () => {},\n};\n"
  },
  {
    "path": "test/unit/view/droppable/util/get-stubber.js",
    "content": "// @flow\nimport React from 'react';\nimport type {\n  Provided,\n  StateSnapshot,\n} from '../../../../../src/view/droppable/droppable-types';\n\nexport default (mock?: Function = () => {}) =>\n  class Stubber extends React.Component<{\n    provided: Provided,\n    snapshot: StateSnapshot,\n  }> {\n    render() {\n      const { provided, snapshot } = this.props;\n      mock({\n        provided,\n        snapshot,\n      });\n      return (\n        <div ref={provided.innerRef} {...provided.droppableProps}>\n          Hey there\n          {provided.placeholder}\n        </div>\n      );\n    }\n  };\n"
  },
  {
    "path": "test/unit/view/droppable/util/mount.js",
    "content": "// @flow\nimport React, { useMemo } from 'react';\nimport { mount } from 'enzyme';\nimport type {\n  MapProps,\n  OwnProps,\n  Provided,\n  DispatchProps,\n  StateSnapshot,\n} from '../../../../../src/view/droppable/droppable-types';\nimport Droppable from '../../../../../src/view/droppable/droppable';\nimport {\n  homeOwnProps,\n  homeAtRest,\n  dispatchProps as defaultDispatchProps,\n} from './get-props';\nimport getStubber from './get-stubber';\nimport { getMarshalStub } from '../../../../util/dimension-marshal';\nimport AppContext, {\n  type AppContextValue,\n} from '../../../../../src/view/context/app-context';\nimport createRegistry from '../../../../../src/state/registry/create-registry';\nimport useFocusMarshal from '../../../../../src/view/use-focus-marshal';\n\ntype MountArgs = {|\n  WrappedComponent?: any,\n  ownProps?: OwnProps,\n  mapProps?: MapProps,\n  dispatchProps?: DispatchProps,\n  isMovementAllowed?: () => boolean,\n|};\n\ntype AppProps = {|\n  ...OwnProps,\n  ...MapProps,\n  ...DispatchProps,\n  isMovementAllowed: () => boolean,\n  WrappedComponent: any,\n|};\n\nfunction App(props: AppProps) {\n  const { WrappedComponent, isMovementAllowed, ...rest } = props;\n  const contextId = '1';\n\n  const focus = useFocusMarshal(contextId);\n  const context: AppContextValue = useMemo(\n    () => ({\n      focus,\n      contextId,\n      canLift: () => true,\n      isMovementAllowed,\n      dragHandleUsageInstructionsId: 'fake-id',\n      marshal: getMarshalStub(),\n      registry: createRegistry(),\n    }),\n    [focus, isMovementAllowed],\n  );\n\n  return (\n    <AppContext.Provider value={context}>\n      <Droppable {...rest}>\n        {(provided: Provided, snapshot: StateSnapshot) => (\n          <WrappedComponent provided={provided} snapshot={snapshot} />\n        )}\n      </Droppable>\n    </AppContext.Provider>\n  );\n}\n\nexport default ({\n  WrappedComponent = getStubber(),\n  ownProps = homeOwnProps,\n  mapProps = homeAtRest,\n  dispatchProps = defaultDispatchProps,\n  isMovementAllowed = () => true,\n}: MountArgs = {}) =>\n  mount<any>(\n    <App\n      {...ownProps}\n      {...mapProps}\n      {...dispatchProps}\n      isMovementAllowed={isMovementAllowed}\n      WrappedComponent={WrappedComponent}\n    />,\n  );\n"
  },
  {
    "path": "test/unit/view/is-type-of-element/is-element.spec.js",
    "content": "// @flow\nimport { JSDOM } from 'jsdom';\nimport isElement from '../../../../src/view/is-type-of-element/is-element';\nimport getSvg from './util/get-svg';\n\nit('should allow all elements through', () => {\n  const anchor: HTMLElement = document.createElement('a');\n  // $FlowFixMe - does not know what SVGElement is\n  const svg: SVGElement = getSvg(document);\n\n  expect(isElement(anchor)).toBe(true);\n  expect(isElement(svg)).toBe(true);\n});\n\nit('should not let other types through', () => {\n  [null, 1, true, {}, () => {}].forEach((value: mixed) =>\n    expect(isElement(value)).toBe(false),\n  );\n});\n\nit('should not allow svg elements from another window', () => {\n  const other = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);\n  const anchor: HTMLElement = other.window.document.createElement('a');\n  const svg: HTMLElement = getSvg(other.window.document);\n\n  expect(isElement(anchor)).toBe(true);\n  expect(isElement(svg)).toBe(true);\n\n  // validation\n  expect(svg instanceof Element).toBe(false);\n  expect(svg instanceof other.window.Element).toBe(true);\n  expect(anchor instanceof Element).toBe(false);\n  expect(anchor instanceof other.window.Element).toBe(true);\n});\n"
  },
  {
    "path": "test/unit/view/is-type-of-element/is-html-element.spec.js",
    "content": "// @flow\nimport { JSDOM } from 'jsdom';\nimport isHtmlElement from '../../../../src/view/is-type-of-element/is-html-element';\nimport isSvgElement from '../../../../src/view/is-type-of-element/is-svg-element';\nimport getSvg from './util/get-svg';\n\nit('should allow html elements through', () => {\n  const anchor: HTMLElement = document.createElement('a');\n\n  expect(isHtmlElement(anchor)).toBe(true);\n  // validation\n  expect(anchor instanceof HTMLElement).toBe(true);\n});\n\nit('should not allow svg elements through', () => {\n  // $FlowFixMe - does not know what SVGElement is\n  const svg: SVGElement = getSvg(document);\n\n  expect(isHtmlElement(svg)).toBe(false);\n  // validation\n  expect(svg instanceof SVGElement).toBe(true);\n  expect(isSvgElement(svg)).toBe(true);\n});\n\nit('should allow html elements from another window', () => {\n  const other = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);\n  const anchor: HTMLElement = other.window.document.createElement('a');\n\n  // normally would not pass an instanceof check\n  expect(anchor instanceof HTMLElement).toBe(false);\n  expect(anchor instanceof other.window.HTMLElement).toBe(true);\n\n  // passes our html element check\n  expect(isHtmlElement(anchor)).toBe(true);\n});\n\nit('should not allow svg elements from another window', () => {\n  const other = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);\n  const svg: HTMLElement = getSvg(other.window.document);\n\n  expect(isHtmlElement(svg)).toBe(false);\n  // validation\n  // $FlowFixMe - does not know what SVGElement is\n  expect(svg instanceof SVGElement).toBe(false);\n  expect(svg instanceof other.window.SVGElement).toBe(true);\n  expect(isSvgElement(svg)).toBe(true);\n});\n"
  },
  {
    "path": "test/unit/view/is-type-of-element/is-svg-element.spec.js",
    "content": "// @flow\nimport { JSDOM } from 'jsdom';\nimport isSvgElement from '../../../../src/view/is-type-of-element/is-svg-element';\nimport getSvg from './util/get-svg';\n\nit('should allow svg elements through', () => {\n  // $FlowFixMe - does not know what SVGElement is\n  const svg: SVGElement = getSvg(document);\n\n  expect(svg instanceof SVGElement).toBe(true);\n  expect(isSvgElement(svg)).toBe(true);\n});\n\nit('should not allow html elements through', () => {\n  const anchor: HTMLElement = document.createElement('a');\n\n  expect(isSvgElement(anchor)).toBe(false);\n});\n\nit('should allow svg elements from another window', () => {\n  const other = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);\n  const svg: HTMLElement = getSvg(other.window.document);\n\n  expect(isSvgElement(svg)).toBe(true);\n  // validation\n  // $FlowFixMe - does not know what SVGElement is\n  expect(svg instanceof SVGElement).toBe(false);\n  expect(svg instanceof other.window.SVGElement).toBe(true);\n});\n\nit('should not allow html elements from another window', () => {\n  const other = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);\n  const anchor: HTMLElement = other.window.document.createElement('a');\n\n  // normally would not pass an instanceof check\n  expect(anchor instanceof HTMLElement).toBe(false);\n  expect(anchor instanceof other.window.HTMLElement).toBe(true);\n\n  expect(isSvgElement(anchor)).toBe(false);\n});\n\nit('should not crash if the environment does not support SVGElement', () => {\n  const other = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);\n  const anchor: HTMLElement = other.window.document.createElement('a');\n  anchor.ownerDocument.defaultView.SVGElement = undefined;\n\n  expect(isSvgElement(anchor)).toBe(false);\n});\n"
  },
  {
    "path": "test/unit/view/is-type-of-element/util/get-svg.js",
    "content": "// @flow\n// $FlowFixMe - flow does not know what a SVGElement is\nexport default (doc: HTMLElement): SVGElement =>\n  doc.createElementNS('http://www.w3.org/2000/svg', 'svg');\n"
  },
  {
    "path": "test/unit/view/placeholder/animated-mount.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { mount, type ReactWrapper } from 'enzyme';\nimport { act } from 'react-dom/test-utils';\nimport Placeholder from './util/placeholder-with-class';\nimport type { PlaceholderStyle } from '../../../../src/view/placeholder/placeholder-types';\nimport { expectIsEmpty, expectIsFull } from './util/expect';\nimport { placeholder } from './util/data';\nimport getPlaceholderStyle from './util/get-placeholder-style';\nimport * as attributes from '../../../../src/view/data-attributes';\n\njest.useFakeTimers();\nconst contextId: string = 'hello-there';\n\nlet spy;\n\nbeforeEach(() => {\n  spy = jest.spyOn(React, 'createElement');\n});\n\nafterEach(() => {\n  spy.mockRestore();\n});\n\nconst getCreatePlaceholderCalls = () => {\n  return spy.mock.calls.filter((call) => {\n    return call[1] && call[1][attributes.placeholder.contextId] === contextId;\n  });\n};\n\nit('should animate a mount', () => {\n  const wrapper: ReactWrapper<*> = mount(\n    <Placeholder\n      contextId={contextId}\n      animate=\"open\"\n      placeholder={placeholder}\n      onClose={jest.fn()}\n      onTransitionEnd={jest.fn()}\n    />,\n  );\n\n  expect(getCreatePlaceholderCalls().length).toBe(1);\n\n  // first call had an empty size\n  const onMount: PlaceholderStyle = getPlaceholderStyle(wrapper);\n  expectIsEmpty(onMount);\n\n  // Will trigger a .setState\n  act(() => {\n    jest.runOnlyPendingTimers();\n  });\n\n  // tell enzyme that something has changed\n  wrapper.update();\n\n  const postMount: PlaceholderStyle = getPlaceholderStyle(wrapper);\n  expectIsFull(postMount);\n});\n\nit('should not animate a mount if interrupted', () => {\n  const wrapper: ReactWrapper<*> = mount(\n    <Placeholder\n      animate=\"open\"\n      contextId={contextId}\n      placeholder={placeholder}\n      onClose={jest.fn()}\n      onTransitionEnd={jest.fn()}\n    />,\n  );\n  const onMount: PlaceholderStyle = getPlaceholderStyle(wrapper);\n  expectIsEmpty(onMount);\n\n  expect(getCreatePlaceholderCalls()).toHaveLength(1);\n\n  // interrupting animation\n  wrapper.setProps({\n    animate: 'none',\n  });\n\n  // render 1: normal\n  // render 2: useEffect calling setState\n  // render 3: result of setState\n  expect(getCreatePlaceholderCalls()).toHaveLength(3);\n\n  // no timers are run\n  // let enzyme know that the react tree has changed due to the set state\n  wrapper.update();\n\n  const postMount: PlaceholderStyle = getPlaceholderStyle(wrapper);\n  expectIsFull(postMount);\n\n  // validation - no further updates\n  spy.mockClear();\n  jest.runOnlyPendingTimers();\n  wrapper.update();\n  expectIsFull(getPlaceholderStyle(wrapper));\n  expect(getCreatePlaceholderCalls()).toHaveLength(0);\n});\n\nit('should not animate in if unmounted', () => {\n  const error = jest.spyOn(console, 'error');\n\n  const wrapper: ReactWrapper<*> = mount(\n    <Placeholder\n      animate=\"open\"\n      contextId={contextId}\n      placeholder={placeholder}\n      onClose={jest.fn()}\n      onTransitionEnd={jest.fn()}\n    />,\n  );\n  expectIsEmpty(getPlaceholderStyle(wrapper));\n\n  wrapper.unmount();\n  jest.runOnlyPendingTimers();\n\n  // an internal setState would be triggered the timer was\n  // not cleared when unmounting\n  expect(error).not.toHaveBeenCalled();\n  error.mockRestore();\n});\n"
  },
  {
    "path": "test/unit/view/placeholder/on-close.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { mount, type ReactWrapper } from 'enzyme';\nimport Placeholder from './util/placeholder-with-class';\nimport { expectIsFull } from './util/expect';\nimport getPlaceholderStyle from './util/get-placeholder-style';\nimport { placeholder } from './util/data';\n\nit('should only fire a single onClose event', () => {\n  const onClose = jest.fn();\n\n  const wrapper: ReactWrapper<*> = mount(\n    <Placeholder\n      contextId=\"1\"\n      animate=\"none\"\n      placeholder={placeholder}\n      onClose={onClose}\n      onTransitionEnd={jest.fn()}\n    />,\n  );\n  expectIsFull(getPlaceholderStyle(wrapper));\n\n  wrapper.setProps({\n    animate: 'close',\n  });\n\n  // $ExpectError - not a complete event\n  const height: TransitionEvent = {\n    propertyName: 'height',\n  };\n  wrapper.simulate('transitionend', height);\n  expect(onClose).toHaveBeenCalledTimes(1);\n  onClose.mockClear();\n\n  // transition events while animate=\"closed\" of different properties will not trigger\n\n  // $ExpectError - not a complete event\n  const margin: TransitionEvent = {\n    propertyName: 'margin',\n  };\n  // $ExpectError - not a complete event\n  const width: TransitionEvent = {\n    propertyName: 'width',\n  };\n  wrapper.simulate('transitionend', margin);\n  wrapper.simulate('transitionend', width);\n  expect(onClose).not.toHaveBeenCalled();\n});\n\nit('should not fire an onClose if not closing when a transitionend occurs', () => {\n  const onClose = jest.fn();\n\n  const wrapper: ReactWrapper<*> = mount(\n    <Placeholder\n      animate=\"none\"\n      contextId=\"1\"\n      placeholder={placeholder}\n      onClose={onClose}\n      onTransitionEnd={jest.fn()}\n    />,\n  );\n  const assert = () => {\n    // $ExpectError - not a complete event\n    const height: TransitionEvent = {\n      propertyName: 'height',\n    };\n    wrapper.simulate('transitionend', height);\n    expect(onClose).not.toHaveBeenCalled();\n    onClose.mockClear();\n  };\n  expectIsFull(getPlaceholderStyle(wrapper));\n  assert();\n\n  wrapper.setProps({ animate: 'open' });\n  assert();\n});\n"
  },
  {
    "path": "test/unit/view/placeholder/on-transition-end.spec.js",
    "content": "// @flow\nimport React from 'react';\nimport { mount, type ReactWrapper } from 'enzyme';\nimport { act } from 'react-dom/test-utils';\nimport Placeholder from './util/placeholder-with-class';\nimport { expectIsFull } from './util/expect';\nimport getPlaceholderStyle from './util/get-placeholder-style';\nimport { placeholder } from './util/data';\n\njest.useFakeTimers();\n\nit('should only fire a single transitionend event a single time when transitioning multiple properties', () => {\n  const onTransitionEnd = jest.fn();\n  const onClose = jest.fn();\n\n  const wrapper: ReactWrapper<*> = mount(\n    <Placeholder\n      animate=\"open\"\n      placeholder={placeholder}\n      onClose={onClose}\n      onTransitionEnd={onTransitionEnd}\n      contextId=\"hey\"\n    />,\n  );\n  // finish the animate open timer\n  act(() => {\n    jest.runOnlyPendingTimers();\n  });\n  // let enzyme know that the react tree has changed due to the set state\n  wrapper.update();\n  expectIsFull(getPlaceholderStyle(wrapper));\n\n  // first event: a 'height' event will trigger the handler\n\n  // $ExpectError - not a complete event\n  const height: TransitionEvent = {\n    propertyName: 'height',\n  };\n  wrapper.simulate('transitionend', height);\n  expect(onTransitionEnd).toHaveBeenCalledTimes(1);\n  onTransitionEnd.mockClear();\n\n  // subsequent transition events will not trigger\n\n  // $ExpectError - not a complete event\n  const margin: TransitionEvent = {\n    propertyName: 'margin',\n  };\n  // $ExpectError - not a complete event\n  const width: TransitionEvent = {\n    propertyName: 'width',\n  };\n  wrapper.simulate('transitionend', margin);\n  wrapper.simulate('transitionend', width);\n  expect(onTransitionEnd).not.toHaveBeenCalled();\n\n  // another transition event of height would trigger the handler\n  wrapper.simulate('transitionend', height);\n  expect(onTransitionEnd).toHaveBeenCalledTimes(1);\n\n  // validate: this should not have triggered any close events\n  expect(onClose).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/view/placeholder/util/data.js",
    "content": "// @flow\nimport type { Placeholder } from '../../../../../src/types';\nimport { getPreset } from '../../../../util/dimension';\n\nexport const preset = getPreset();\nexport const placeholder: Placeholder = preset.inHome1.placeholder;\n"
  },
  {
    "path": "test/unit/view/placeholder/util/expect.js",
    "content": "// @flow\nimport type { PlaceholderStyle } from '../../../../../src/view/placeholder/placeholder-types';\nimport { placeholder } from './data';\n\nexport const expectIsEmpty = (style: PlaceholderStyle) => {\n  expect(style.width).toBe(0);\n  expect(style.height).toBe(0);\n  expect(style.marginTop).toBe(0);\n  expect(style.marginRight).toBe(0);\n  expect(style.marginBottom).toBe(0);\n  expect(style.marginLeft).toBe(0);\n};\n\nexport const expectIsFull = (style: PlaceholderStyle) => {\n  expect(style.width).toBe(placeholder.client.borderBox.width);\n  expect(style.height).toBe(placeholder.client.borderBox.height);\n  expect(style.marginTop).toBe(placeholder.client.margin.top);\n  expect(style.marginRight).toBe(placeholder.client.margin.right);\n  expect(style.marginBottom).toBe(placeholder.client.margin.bottom);\n  expect(style.marginLeft).toBe(placeholder.client.margin.left);\n};\n"
  },
  {
    "path": "test/unit/view/placeholder/util/get-placeholder-style.js",
    "content": "// @flow\nimport type { ReactWrapper } from 'enzyme';\nimport type { PlaceholderStyle } from '../../../../../src/view/placeholder/placeholder-types';\nimport { placeholder } from './data';\n\nexport default (wrapper: ReactWrapper<*>): PlaceholderStyle =>\n  wrapper.find(placeholder.tagName).props().style;\n"
  },
  {
    "path": "test/unit/view/placeholder/util/placeholder-with-class.js",
    "content": "// @flow\nimport React from 'react';\nimport { WithoutMemo } from '../../../../../src/view/placeholder/placeholder';\nimport type { Props } from '../../../../../src/view/placeholder/placeholder';\n\n// enzyme does not work well with memo, so exporting the non-memo version\n// Using PureComponent to match behaviour of React.memo\nexport default class PlaceholderWithClass extends React.PureComponent<Props> {\n  render() {\n    return <WithoutMemo {...this.props} />;\n  }\n}\n"
  },
  {
    "path": "test/unit/view/style-marshal/get-styles.spec.js",
    "content": "// @flow\nimport stylelint from 'stylelint';\nimport getStyles, {\n  type Styles,\n} from '../../../../src/view/use-style-marshal/get-styles';\n\nconst styles: Styles = getStyles('hey');\n\nObject.keys(styles).forEach((key: string) => {\n  it(`should generate valid ${key} styles`, () =>\n    stylelint\n      .lint({\n        code: styles[key],\n        config: {\n          // just using the recommended config as it only checks for errors and not formatting\n          extends: ['stylelint-config-recommended'],\n          // basic semi colin rules\n          rules: {\n            'no-extra-semicolons': true,\n            'declaration-block-semicolon-space-after': 'always-single-line',\n          },\n        },\n      })\n      .then((result) => {\n        expect(result.errored).toBe(false);\n        // asserting that some CSS was actually generated!\n        // eslint-disable-next-line no-underscore-dangle\n        expect(result.results[0]._postcssResult.css.length).toBeGreaterThan(1);\n      }));\n});\n"
  },
  {
    "path": "test/unit/view/style-marshal/style-marshal.spec.js",
    "content": "// @flow\nimport React, { type Node } from 'react';\nimport { mount, type ReactWrapper } from 'enzyme';\nimport type { ContextId } from '../../../../src/types';\nimport useStyleMarshal from '../../../../src/view/use-style-marshal';\nimport getStyles, {\n  type Styles,\n} from '../../../../src/view/use-style-marshal/get-styles';\nimport type { StyleMarshal } from '../../../../src/view/use-style-marshal/style-marshal-types';\nimport { prefix } from '../../../../src/view/data-attributes';\n\nconst getMarshal = (myMock): StyleMarshal => myMock.mock.calls[0][0];\nconst getMock = () => jest.fn().mockImplementation(() => null);\n\ntype Props = {|\n  contextId: ContextId,\n  nonce?: string,\n  children: (marshal: StyleMarshal) => Node,\n|};\n\nfunction WithMarshal(props: Props) {\n  const marshal: StyleMarshal = useStyleMarshal(props.contextId, props.nonce);\n  return props.children(marshal);\n}\n\nconst getDynamicStyleTagSelector = (contextId: ContextId) =>\n  `style[${prefix}-dynamic=\"${contextId}\"]`;\n\nconst getAlwaysStyleTagSelector = (contextId: ContextId) =>\n  `style[${prefix}-always=\"${contextId}\"]`;\n\nconst getDynamicStyleTag = (contextId: ContextId): HTMLStyleElement => {\n  const selector: string = getDynamicStyleTagSelector(contextId);\n  const el: HTMLStyleElement = (document.querySelector(selector): any);\n  return el;\n};\n\nconst getAlwaysStyleTag = (contextId: ContextId): HTMLStyleElement => {\n  const selector: string = getAlwaysStyleTagSelector(contextId);\n  const el: HTMLStyleElement = (document.querySelector(selector): any);\n  return el;\n};\n\nconst getDynamicStyleFromTag = (contextId: ContextId): string => {\n  return getDynamicStyleTag(contextId).innerHTML;\n};\n\nconst getAlwaysStyleFromTag = (contextId: ContextId): string => {\n  return getAlwaysStyleTag(contextId).innerHTML;\n};\n\nit('should not mount style tags until mounted', () => {\n  const contextId: ContextId = '1';\n  const dynamicSelector: string = getDynamicStyleTagSelector(contextId);\n  const alwaysSelector: string = getAlwaysStyleTagSelector(contextId);\n\n  // initially there is no style tag\n  expect(document.querySelector(dynamicSelector)).toBeFalsy();\n  expect(document.querySelector(alwaysSelector)).toBeFalsy();\n\n  // now mounting\n  const wrapper: ReactWrapper<*> = mount(\n    <WithMarshal contextId={contextId}>{getMock()}</WithMarshal>,\n  );\n\n  // elements should now exist\n  expect(document.querySelector(alwaysSelector)).toBeInstanceOf(\n    HTMLStyleElement,\n  );\n  expect(document.querySelector(dynamicSelector)).toBeInstanceOf(\n    HTMLStyleElement,\n  );\n\n  wrapper.unmount();\n});\n\nit('should apply the resting dyanmic styles by default', () => {\n  const contextId: ContextId = '2';\n  const wrapper: ReactWrapper<*> = mount(\n    <WithMarshal contextId={contextId}>{getMock()}</WithMarshal>,\n  );\n\n  const active: string = getDynamicStyleFromTag(contextId);\n  expect(active).toEqual(getStyles(`${contextId}`).resting);\n\n  wrapper.unmount();\n});\n\nit('should apply the resting always styles by default', () => {\n  const contextId: ContextId = '2';\n  const wrapper: ReactWrapper<*> = mount(\n    <WithMarshal contextId={contextId}>{getMock()}</WithMarshal>,\n  );\n\n  const always: string = getAlwaysStyleFromTag(contextId);\n  expect(always).toEqual(getStyles(`${contextId}`).always);\n\n  wrapper.unmount();\n});\n\nit('should apply the dragging styles when asked', () => {\n  const contextId: ContextId = '2';\n  const mock = getMock();\n  const wrapper: ReactWrapper<*> = mount(\n    <WithMarshal contextId={contextId}>{mock}</WithMarshal>,\n  );\n  const marshal: StyleMarshal = getMarshal(mock);\n\n  marshal.dragging();\n\n  const active: string = getDynamicStyleFromTag(contextId);\n  expect(active).toEqual(getStyles(`${contextId}`).dragging);\n\n  wrapper.unmount();\n});\n\nit('should apply the drop animating styles when asked', () => {\n  const contextId: ContextId = '2';\n  const mock = getMock();\n  const wrapper: ReactWrapper<*> = mount(\n    <WithMarshal contextId={contextId}>{mock}</WithMarshal>,\n  );\n  const marshal: StyleMarshal = getMarshal(mock);\n\n  marshal.dropping('DROP');\n  const active: string = getDynamicStyleFromTag(contextId);\n  expect(active).toEqual(getStyles(`${contextId}`).dropAnimating);\n\n  wrapper.unmount();\n});\n\nit('should apply the user cancel styles when asked', () => {\n  const contextId: ContextId = '2';\n  const mock = getMock();\n  const wrapper: ReactWrapper<*> = mount(\n    <WithMarshal contextId={contextId}>{mock}</WithMarshal>,\n  );\n  const marshal: StyleMarshal = getMarshal(mock);\n\n  marshal.dropping('CANCEL');\n  const active: string = getDynamicStyleFromTag(contextId);\n  expect(active).toEqual(getStyles(`${contextId}`).userCancel);\n\n  wrapper.unmount();\n});\n\nit('should remove the style tag from the head when unmounting', () => {\n  const contextId: ContextId = '2';\n  const wrapper: ReactWrapper<*> = mount(\n    <WithMarshal contextId={contextId}>{getMock()}</WithMarshal>,\n  );\n  const selector1: string = getDynamicStyleTagSelector(contextId);\n  const selector2: string = getAlwaysStyleTagSelector(contextId);\n\n  // the style tag exists\n  expect(document.querySelector(selector1)).toBeTruthy();\n  expect(document.querySelector(selector2)).toBeTruthy();\n\n  // now unmounted\n  wrapper.unmount();\n\n  expect(document.querySelector(selector1)).not.toBeTruthy();\n  expect(document.querySelector(selector2)).not.toBeTruthy();\n});\n\nit('should allow subsequent updates', () => {\n  const contextId: ContextId = '10';\n  const styles: Styles = getStyles(`${contextId}`);\n  const mock = getMock();\n  const wrapper: ReactWrapper<*> = mount(\n    <WithMarshal contextId={contextId}>{mock}</WithMarshal>,\n  );\n  const marshal: StyleMarshal = getMarshal(mock);\n\n  Array.from({ length: 4 }).forEach(() => {\n    marshal.resting();\n    expect(getDynamicStyleFromTag(contextId)).toEqual(styles.resting);\n\n    marshal.dragging();\n    expect(getDynamicStyleFromTag(contextId)).toEqual(styles.dragging);\n\n    marshal.dropping('DROP');\n    expect(getDynamicStyleFromTag(contextId)).toEqual(styles.dropAnimating);\n  });\n\n  wrapper.unmount();\n});\n\nit('should insert nonce into tag attribute', () => {\n  const contextId: ContextId = '2';\n  const nonce = 'ThisShouldBeACryptographicallySecurePseudoRandomNumber';\n  const mock = getMock();\n  const wrapper: ReactWrapper<*> = mount(\n    <WithMarshal contextId={contextId} nonce={nonce}>\n      {mock}\n    </WithMarshal>,\n  );\n  const dynamicStyleTag = getDynamicStyleTag(contextId);\n  const dynamicStyleTagNonce = dynamicStyleTag\n    ? dynamicStyleTag.getAttribute('nonce')\n    : '';\n  const alwaysStyleTag = getAlwaysStyleTag(contextId);\n  const alwaysStyleTagNonce = alwaysStyleTag\n    ? alwaysStyleTag.getAttribute('nonce')\n    : '';\n\n  // the style tag exists\n  expect(dynamicStyleTagNonce).toEqual(nonce);\n  expect(alwaysStyleTagNonce).toEqual(nonce);\n\n  // now unmounted\n  wrapper.unmount();\n});\n"
  },
  {
    "path": "test/unit/view/use-draggable-publisher.spec.js",
    "content": "// @flow\nimport React, { useRef, useCallback } from 'react';\nimport { type Spacing, type Rect } from 'css-box-model';\nimport { mount, type ReactWrapper } from 'enzyme';\nimport { useMemo } from 'use-memo-one';\nimport { invariant } from '../../../src/invariant';\nimport useDraggablePublisher from '../../../src/view/use-draggable-publisher';\nimport {\n  getPreset,\n  getDraggableDimension,\n  getComputedSpacing,\n} from '../../util/dimension';\nimport forceUpdate from '../../util/force-update';\nimport tryCleanPrototypeStubs from '../../util/try-clean-prototype-stubs';\nimport type {\n  DraggableId,\n  DraggableDimension,\n  DraggableDescriptor,\n  DraggableOptions,\n} from '../../../src/types';\nimport type {\n  Registry,\n  DraggableEntry,\n  GetDraggableDimensionFn,\n} from '../../../src/state/registry/registry-types';\nimport createRegistry from '../../../src/state/registry/create-registry';\n\nconst preset = getPreset();\nconst noComputedSpacing = getComputedSpacing({});\n\ntype ItemProps = {|\n  index?: number,\n  draggableId?: DraggableId,\n  registry: Registry,\n|};\n\nconst defaultOptions: DraggableOptions = {\n  canDragInteractiveElements: false,\n  shouldRespectForcePress: false,\n  isEnabled: true,\n};\n\nfunction Item(props: ItemProps) {\n  const {\n    registry,\n    draggableId = preset.inHome1.descriptor.id,\n    index = preset.inHome1.descriptor.index,\n  } = props;\n  const ref = useRef<?HTMLElement>(null);\n  const setRef = useCallback((value: ?HTMLElement) => {\n    ref.current = value;\n  }, []);\n  const getRef = useCallback((): ?HTMLElement => ref.current, []);\n  const descriptor: DraggableDescriptor = useMemo(\n    () => ({\n      id: draggableId,\n      index,\n      type: preset.inHome1.descriptor.type,\n      droppableId: preset.inHome1.descriptor.droppableId,\n    }),\n    [draggableId, index],\n  );\n\n  useDraggablePublisher({\n    descriptor,\n    getDraggableRef: getRef,\n    registry,\n    ...defaultOptions,\n  });\n\n  return <div ref={setRef}>hi</div>;\n}\n\nbeforeEach(() => {\n  // having issues on CI\n  tryCleanPrototypeStubs();\n  jest.spyOn(console, 'error').mockImplementation(() => {});\n});\n\nafterEach(() => {\n  // $FlowFixMe\n  console.error.mockRestore();\n  tryCleanPrototypeStubs();\n});\n\ndescribe('dimension registration', () => {\n  it('should register itself when mounting', () => {\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.draggable, 'register');\n    mount(<Item registry={registry} />);\n\n    const expected: DraggableEntry = {\n      // $ExpectError\n      uniqueId: expect.any(String),\n      descriptor: preset.inHome1.descriptor,\n      options: defaultOptions,\n      // $ExpectError\n      getDimension: expect.any(Function),\n    };\n    expect(registerSpy).toHaveBeenCalledTimes(1);\n    expect(registerSpy).toHaveBeenCalledWith(expected);\n  });\n\n  it('should unregister itself when unmounting', () => {\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.draggable, 'register');\n    const unregisterSpy = jest.spyOn(registry.draggable, 'unregister');\n    const wrapper = mount(<Item registry={registry} />);\n\n    const expected: DraggableEntry = {\n      // $ExpectError\n      uniqueId: expect.any(String),\n      descriptor: preset.inHome1.descriptor,\n      options: defaultOptions,\n      // $ExpectError\n      getDimension: expect.any(Function),\n    };\n\n    expect(unregisterSpy).not.toHaveBeenCalled();\n    expect(registerSpy).toHaveBeenCalledTimes(1);\n    expect(registerSpy).toHaveBeenCalledWith(expected);\n    const entry = registerSpy.mock.calls[0][0];\n    expect(entry).toEqual(expected);\n\n    wrapper.unmount();\n    expect(unregisterSpy).toHaveBeenCalledTimes(1);\n    expect(unregisterSpy.mock.calls[0][0]).toBe(entry);\n  });\n\n  it('should update its registration when a descriptor property changes', () => {\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.draggable, 'register');\n    const updateSpy = jest.spyOn(registry.draggable, 'update');\n    const unregisterSpy = jest.spyOn(registry.draggable, 'unregister');\n    const wrapper = mount(<Item registry={registry} />);\n\n    const expectedInitial: DraggableEntry = {\n      // $ExpectError\n      uniqueId: expect.any(String),\n      descriptor: preset.inHome1.descriptor,\n      options: defaultOptions,\n      // $ExpectError\n      getDimension: expect.any(Function),\n    };\n\n    // asserting shape of original publish\n    expect(registerSpy).toHaveBeenCalledTimes(1);\n    expect(registerSpy).toHaveBeenCalledWith(expectedInitial);\n    const entry = registerSpy.mock.calls[0][0];\n    expect(entry).toEqual(expectedInitial);\n\n    expect(updateSpy).not.toHaveBeenCalled();\n    expect(unregisterSpy).not.toHaveBeenCalled();\n\n    registerSpy.mockReset();\n\n    // updating the index\n    wrapper.setProps({\n      index: 1000,\n    });\n\n    // Descriptor updated\n    const expectedUpdate: DraggableEntry = {\n      uniqueId: entry.uniqueId,\n      descriptor: {\n        ...preset.inHome1.descriptor,\n        index: 1000,\n      },\n      options: defaultOptions,\n      // $ExpectError\n      getDimension: expect.any(Function),\n    };\n    expect(updateSpy).toHaveBeenCalledTimes(1);\n    // new descriptor\n    expect(updateSpy.mock.calls[0][0]).toEqual(expectedUpdate);\n    // late reference: same reference\n    expect(updateSpy.mock.calls[0][1]).toBe(entry);\n\n    // Nothing else changed\n    expect(registerSpy).not.toHaveBeenCalled();\n    expect(unregisterSpy).not.toHaveBeenCalled();\n  });\n\n  it('should not update its registration when a descriptor property does not change on an update', () => {\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.draggable, 'register');\n    const updateSpy = jest.spyOn(registry.draggable, 'update');\n    const wrapper = mount(<Item registry={registry} />);\n\n    expect(registerSpy).toHaveBeenCalledTimes(1);\n\n    forceUpdate(wrapper);\n    expect(updateSpy).not.toHaveBeenCalled();\n  });\n});\n\ndescribe('dimension publishing', () => {\n  // we are doing this rather than spying on the prototype.\n  // Sometimes setRef was being provided with an element that did not have the mocked prototype :|\n  const setBoundingClientRect = (wrapper: ReactWrapper<*>, borderBox: Rect) => {\n    const ref: ?HTMLElement = wrapper.getDOMNode();\n    invariant(ref);\n\n    // $FlowFixMe - normally a read only thing. Muhaha\n    ref.getBoundingClientRect = () => borderBox;\n  };\n\n  it('should publish the dimensions of the target when requested', () => {\n    const expected: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'fake-id',\n        droppableId: preset.home.descriptor.id,\n        type: preset.home.descriptor.type,\n        index: 10,\n      },\n      borderBox: {\n        top: 0,\n        right: 100,\n        bottom: 100,\n        left: 0,\n      },\n    });\n    jest\n      .spyOn(window, 'getComputedStyle')\n      .mockImplementation(() => noComputedSpacing);\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.draggable, 'register');\n\n    const wrapper: ReactWrapper<*> = mount(\n      <Item\n        registry={registry}\n        draggableId={expected.descriptor.id}\n        index={expected.descriptor.index}\n      />,\n    );\n\n    setBoundingClientRect(wrapper, expected.client.borderBox);\n\n    // pull the get dimension function out\n    const getDimension: GetDraggableDimensionFn =\n      registerSpy.mock.calls[0][0].getDimension;\n    // execute it to get the dimension\n    const result: DraggableDimension = getDimension({ x: 0, y: 0 });\n\n    expect(result).toEqual(expected);\n  });\n\n  it('should consider any margins when calculating dimensions', () => {\n    const margin: Spacing = {\n      top: 10,\n      right: 30,\n      bottom: 40,\n      left: 50,\n    };\n    const expected: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'fake-id',\n        droppableId: preset.home.descriptor.id,\n        type: preset.home.descriptor.type,\n        index: 10,\n      },\n      borderBox: {\n        top: 0,\n        right: 100,\n        bottom: 100,\n        left: 0,\n      },\n      margin,\n    });\n    jest\n      .spyOn(window, 'getComputedStyle')\n      .mockImplementation(() => getComputedSpacing({ margin }));\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.draggable, 'register');\n\n    const wrapper: ReactWrapper<*> = mount(\n      <Item\n        registry={registry}\n        draggableId={expected.descriptor.id}\n        index={expected.descriptor.index}\n      />,\n    );\n\n    setBoundingClientRect(wrapper, expected.client.borderBox);\n\n    // pull the get dimension function out\n    const getDimension: GetDraggableDimensionFn =\n      registerSpy.mock.calls[0][0].getDimension;\n    // execute it to get the dimension\n    const result: DraggableDimension = getDimension({ x: 0, y: 0 });\n\n    expect(result).toEqual(expected);\n  });\n\n  it('should consider the window scroll when calculating dimensions', () => {\n    const expected: DraggableDimension = getDraggableDimension({\n      descriptor: {\n        id: 'fake-id',\n        droppableId: preset.home.descriptor.id,\n        type: preset.home.descriptor.type,\n        index: 10,\n      },\n      borderBox: {\n        top: 0,\n        right: 100,\n        bottom: 100,\n        left: 0,\n      },\n      windowScroll: preset.windowScroll,\n    });\n    jest\n      .spyOn(window, 'getComputedStyle')\n      .mockImplementation(() => noComputedSpacing);\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.draggable, 'register');\n\n    const wrapper: ReactWrapper<*> = mount(\n      <Item\n        draggableId={expected.descriptor.id}\n        index={expected.descriptor.index}\n        registry={registry}\n      />,\n    );\n\n    setBoundingClientRect(wrapper, expected.client.borderBox);\n\n    // pull the get dimension function out\n    const getDimension: GetDraggableDimensionFn =\n      registerSpy.mock.calls[0][0].getDimension;\n    // execute it to get the dimension\n    const result: DraggableDimension = getDimension(preset.windowScroll);\n\n    expect(result).toEqual(expected);\n  });\n\n  it('should throw an error if no ref is provided when attempting to get a dimension', () => {\n    function NoRefItem(props: ItemProps) {\n      const {\n        registry,\n        draggableId = preset.inHome1.descriptor.id,\n        index = preset.inHome1.descriptor.index,\n      } = props;\n      const ref = useRef<?HTMLElement>(null);\n      const getRef = useCallback((): ?HTMLElement => ref.current, []);\n      const descriptor: DraggableDescriptor = useMemo(\n        () => ({\n          id: draggableId,\n          index,\n          type: preset.inHome1.descriptor.type,\n          droppableId: preset.inHome1.descriptor.droppableId,\n        }),\n        [draggableId, index],\n      );\n\n      useDraggablePublisher({\n        descriptor,\n        getDraggableRef: getRef,\n        registry,\n        ...defaultOptions,\n      });\n\n      // No ref\n      return <div>hi</div>;\n    }\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.draggable, 'register');\n    const wrapper: ReactWrapper<*> = mount(\n      <NoRefItem registry={registry} draggableId=\"draggable\" />,\n    );\n    // pull the get dimension function out\n    const getDimension: GetDraggableDimensionFn =\n      registerSpy.mock.calls[0][0].getDimension;\n    // when we call the get dimension function without a ref things will explode\n    expect(getDimension).toThrow();\n    wrapper.unmount();\n  });\n});\n"
  },
  {
    "path": "test/unit/view/use-droppable-publisher/forced-scroll.spec.js",
    "content": "// @flow\nimport { mount } from 'enzyme';\nimport React from 'react';\nimport { invariant } from '../../../../src/invariant';\nimport type { DimensionMarshal } from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport { getMarshalStub } from '../../../util/dimension-marshal';\nimport { setViewport } from '../../../util/viewport';\nimport {\n  App,\n  immediate,\n  smallFrameClient,\n  bigClient,\n  preset,\n  scheduled,\n  ScrollableItem,\n  WithAppContext,\n} from './util/shared';\nimport tryCleanPrototypeStubs from '../../../util/try-clean-prototype-stubs';\nimport type {\n  Registry,\n  DroppableCallbacks,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\n\nsetViewport(preset.viewport);\n\nafterEach(() => {\n  tryCleanPrototypeStubs();\n});\n\nit('should throw if the droppable has no closest scrollable', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  // no scroll parent\n  const wrapper = mount(\n    <WithAppContext marshal={marshal} registry={registry}>\n      <App parentIsScrollable={false} droppableIsScrollable={false} />,\n    </WithAppContext>,\n  );\n  const droppable: ?HTMLElement = wrapper.find('.droppable').getDOMNode();\n  invariant(droppable);\n  const parent: ?HTMLElement = wrapper.find('.scroll-parent').getDOMNode();\n  invariant(parent);\n  jest\n    .spyOn(droppable, 'getBoundingClientRect')\n    .mockImplementation(() => smallFrameClient.borderBox);\n  jest\n    .spyOn(parent, 'getBoundingClientRect')\n    .mockImplementation(() => bigClient.borderBox);\n\n  // validating no initial scroll\n  expect(parent.scrollTop).toBe(0);\n  expect(parent.scrollLeft).toBe(0);\n  expect(droppable.scrollTop).toBe(0);\n  expect(droppable.scrollLeft).toBe(0);\n\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  // request the droppable start listening for scrolling\n  callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n  // ask it to scroll\n  expect(() => callbacks.scroll({ x: 100, y: 100 })).toThrow();\n\n  // no scroll changes\n  expect(parent.scrollTop).toBe(0);\n  expect(parent.scrollLeft).toBe(0);\n  expect(droppable.scrollTop).toBe(0);\n  expect(droppable.scrollLeft).toBe(0);\n});\n\ndescribe('there is a closest scrollable', () => {\n  it('should update the scroll of the closest scrollable', () => {\n    const marshal: DimensionMarshal = getMarshalStub();\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext marshal={marshal} registry={registry}>\n        <ScrollableItem />\n      </WithAppContext>,\n    );\n    const container: ?HTMLElement = wrapper\n      .find('.scroll-container')\n      .getDOMNode();\n    invariant(container);\n\n    expect(container.scrollTop).toBe(0);\n    expect(container.scrollLeft).toBe(0);\n\n    // tell the droppable to watch for scrolling\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n    // watch scroll will only be called after the dimension is requested\n    callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n    callbacks.scroll({ x: 500, y: 1000 });\n\n    expect(container.scrollLeft).toBe(500);\n    expect(container.scrollTop).toBe(1000);\n  });\n\n  it('should throw if asked to scoll while scroll is not currently being watched', () => {\n    const marshal: DimensionMarshal = getMarshalStub();\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext marshal={marshal} registry={registry}>\n        <ScrollableItem />\n      </WithAppContext>,\n    );\n\n    const container: ?HTMLElement = wrapper\n      .find('.scroll-container')\n      .getDOMNode();\n    invariant(container);\n    expect(container.scrollTop).toBe(0);\n    expect(container.scrollLeft).toBe(0);\n\n    // dimension not returned yet\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n    expect(() => callbacks.scroll({ x: 500, y: 1000 })).toThrow();\n\n    // now watching scroll\n    callbacks.getDimensionAndWatchScroll(preset.windowScroll, immediate);\n\n    // no longer watching scroll\n    callbacks.dragStopped();\n    expect(() => callbacks.scroll({ x: 500, y: 1000 })).toThrow();\n  });\n});\n"
  },
  {
    "path": "test/unit/view/use-droppable-publisher/is-combined-enabled-change.spec.js",
    "content": "// @flow\nimport { mount } from 'enzyme';\nimport React from 'react';\nimport type { DimensionMarshal } from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport { getMarshalStub } from '../../../util/dimension-marshal';\nimport { setViewport } from '../../../util/viewport';\nimport {\n  preset,\n  scheduled,\n  ScrollableItem,\n  WithAppContext,\n} from './util/shared';\nimport forceUpdate from '../../../util/force-update';\nimport PassThroughProps from '../../../util/pass-through-props';\nimport type {\n  Registry,\n  DroppableCallbacks,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\n\nsetViewport(preset.viewport);\n\nit('should publish updates to the enabled state when dragging', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <PassThroughProps>\n      {(extra) => (\n        <WithAppContext marshal={marshal} registry={registry}>\n          <ScrollableItem isCombineEnabled {...extra} />\n        </WithAppContext>\n      )}\n    </PassThroughProps>,\n  );\n  // not called yet\n  expect(marshal.updateDroppableIsCombineEnabled).not.toHaveBeenCalled();\n\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n  // changing to false\n  wrapper.setProps({\n    isCombineEnabled: false,\n  });\n  expect(marshal.updateDroppableIsCombineEnabled).toHaveBeenCalledTimes(1);\n  expect(marshal.updateDroppableIsCombineEnabled).toHaveBeenCalledWith(\n    preset.home.descriptor.id,\n    false,\n  );\n  // $FlowFixMe\n  marshal.updateDroppableIsCombineEnabled.mockClear();\n\n  // now setting to true\n  wrapper.setProps({\n    isCombineEnabled: true,\n  });\n  expect(marshal.updateDroppableIsCombineEnabled).toHaveBeenCalledTimes(1);\n  expect(marshal.updateDroppableIsCombineEnabled).toHaveBeenCalledWith(\n    preset.home.descriptor.id,\n    true,\n  );\n});\n\nit('should not publish updates to the enabled state when there is no drag', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const wrapper = mount(\n    <PassThroughProps>\n      {(extra) => (\n        <WithAppContext marshal={marshal} registry={registry}>\n          <ScrollableItem isCombineEnabled {...extra} />,\n        </WithAppContext>\n      )}\n    </PassThroughProps>,\n  );\n\n  // not called yet\n  expect(marshal.updateDroppableIsCombineEnabled).not.toHaveBeenCalled();\n\n  // no yet dragging\n\n  wrapper.setProps({\n    isCombineEnabled: false,\n  });\n\n  expect(marshal.updateDroppableIsCombineEnabled).not.toHaveBeenCalled();\n});\n\nit('should not publish updates when there is no change', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <PassThroughProps>\n      {(extra) => (\n        <WithAppContext marshal={marshal} registry={registry}>\n          <ScrollableItem isCombineEnabled {...extra} />,\n        </WithAppContext>\n      )}\n    </PassThroughProps>,\n  );\n\n  // not called yet\n  expect(marshal.updateDroppableIsCombineEnabled).not.toHaveBeenCalled();\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n  // no change\n  wrapper.setProps({\n    isCombineEnabled: true,\n  });\n\n  expect(marshal.updateDroppableIsCombineEnabled).not.toHaveBeenCalled();\n  // $FlowFixMe\n  marshal.updateDroppableIsCombineEnabled.mockReset();\n\n  forceUpdate(wrapper);\n  expect(marshal.updateDroppableIsCombineEnabled).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/view/use-droppable-publisher/is-element-scrollable.spec.js",
    "content": "// @flow\nimport { invariant } from '../../../../src/invariant';\nimport getClosestScrollable from '../../../../src/view/use-droppable-publisher/get-closest-scrollable';\n\nit('should return true if an element has overflow:auto or overflow:scroll', () => {\n  ['overflowY', 'overflowX'].forEach((overflow: string) => {\n    ['auto', 'scroll'].forEach((value: string) => {\n      const el: HTMLElement = document.createElement('div');\n      // $ExpectError - flow being mean\n      el.style[overflow] = value;\n      expect(getClosestScrollable(el)).toBe(el);\n    });\n  });\n});\n\nit('should return false if an element has overflow:visible', () => {\n  ['overflowY', 'overflowX'].forEach((overflow: string) => {\n    const el: HTMLElement = document.createElement('div');\n    // $ExpectError - flow being mean\n    el.style[overflow] = 'visible';\n    expect(getClosestScrollable(el)).toBe(null);\n  });\n});\n\ndescribe('body detection', () => {\n  // The `body` is considered a scroll container when:\n  // 1. The `body` has `overflow-[x|y]: auto | scroll` AND\n  // 2. The parent of `body` (`html`) has an `overflow-[x|y]` set to anything except `visible` AND\n  // 3. There is a current overflow in the `body`\n  const body: ?Element = document.body;\n  invariant(body);\n  invariant(body instanceof HTMLBodyElement);\n  const html: ?Element = body.parentElement;\n  invariant(html);\n  invariant(html === document.documentElement);\n  invariant(html instanceof HTMLElement);\n\n  const reset = (el: Element) => {\n    invariant(el instanceof HTMLElement);\n    el.style.overflowX = 'visible';\n    el.style.overflowY = 'visible';\n  };\n\n  beforeEach(() => {\n    reset(body);\n    reset(html);\n    jest.spyOn(console, 'warn').mockImplementation(() => {});\n  });\n\n  afterEach(() => {\n    // $ExpectError\n    console.warn.mockReset();\n  });\n\n  afterAll(() => {\n    reset(body);\n    reset(html);\n  });\n\n  it('should warn if the body might be a scroll container', () => {\n    body.style.overflowX = 'auto';\n    html.style.overflowY = 'auto';\n\n    expect(getClosestScrollable(body)).toBe(null);\n    expect(console.warn).toHaveBeenCalled();\n  });\n\n  it('should not mark the body as a scroll container if it does not have any overflow set', () => {\n    body.style.overflowX = 'visible';\n    expect(getClosestScrollable(body)).toBe(null);\n    expect(console.warn).not.toHaveBeenCalled();\n  });\n\n  it('should not mark the body as a scroll container if the html element has visible overflow', () => {\n    body.style.overflowX = 'auto';\n    html.style.overflowY = 'visible';\n    expect(getClosestScrollable(body)).toBe(null);\n    expect(console.warn).not.toHaveBeenCalled();\n  });\n});\n"
  },
  {
    "path": "test/unit/view/use-droppable-publisher/is-enabled-change.spec.js",
    "content": "// @flow\nimport { mount } from 'enzyme';\nimport React from 'react';\nimport type { DimensionMarshal } from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport { getMarshalStub } from '../../../util/dimension-marshal';\nimport { setViewport } from '../../../util/viewport';\nimport {\n  preset,\n  scheduled,\n  ScrollableItem,\n  WithAppContext,\n} from './util/shared';\nimport forceUpdate from '../../../util/force-update';\nimport PassThroughProps from '../../../util/pass-through-props';\nimport type {\n  Registry,\n  DroppableCallbacks,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\n\nsetViewport(preset.viewport);\n\nit('should publish updates to the enabled state when dragging', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <PassThroughProps>\n      {(extra) => (\n        <WithAppContext marshal={marshal} registry={registry}>\n          <ScrollableItem isDropDisabled={false} {...extra} />\n        </WithAppContext>\n      )}\n    </PassThroughProps>,\n  );\n  // not called yet\n  expect(marshal.updateDroppableIsEnabled).not.toHaveBeenCalled();\n\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n  const isDropDisabled: boolean = true;\n  wrapper.setProps({\n    isDropDisabled,\n  });\n\n  expect(marshal.updateDroppableIsEnabled).toHaveBeenCalledTimes(1);\n  expect(marshal.updateDroppableIsEnabled).toHaveBeenCalledWith(\n    preset.home.descriptor.id,\n    !isDropDisabled,\n  );\n});\n\nit('should not publish updates to the enabled state when there is no drag', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const wrapper = mount(\n    <PassThroughProps>\n      {(extra) => (\n        <WithAppContext marshal={marshal} registry={registry}>\n          <ScrollableItem isDropDisabled={false} {...extra} />\n        </WithAppContext>\n      )}\n    </PassThroughProps>,\n  );\n\n  // not called yet\n  expect(marshal.updateDroppableIsEnabled).not.toHaveBeenCalled();\n\n  // no yet dragging\n\n  wrapper.setProps({\n    isDropDisabled: true,\n  });\n\n  expect(marshal.updateDroppableIsEnabled).not.toHaveBeenCalled();\n});\n\nit('should not publish updates when there is no change', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <PassThroughProps>\n      {(extra) => (\n        <WithAppContext marshal={marshal} registry={registry}>\n          <ScrollableItem isDropDisabled={false} {...extra} />\n        </WithAppContext>\n      )}\n    </PassThroughProps>,\n  );\n\n  // not called yet\n  expect(marshal.updateDroppableIsEnabled).not.toHaveBeenCalled();\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n  // no change\n  wrapper.setProps({\n    isDropDisabled: false,\n  });\n\n  expect(marshal.updateDroppableIsEnabled).not.toHaveBeenCalled();\n  // $ExpectError\n  marshal.updateDroppableIsEnabled.mockReset();\n\n  forceUpdate(wrapper);\n  expect(marshal.updateDroppableIsEnabled).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/view/use-droppable-publisher/publishing.spec.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { mount, type ReactWrapper } from 'enzyme';\nimport React from 'react';\nimport { invariant } from '../../../../src/invariant';\nimport type { DroppableDimension, ScrollSize } from '../../../../src/types';\nimport { negate } from '../../../../src/state/position';\nimport { offsetByPosition } from '../../../../src/state/spacing';\nimport { getDroppableDimension } from '../../../util/dimension';\nimport setWindowScroll from '../../../util/set-window-scroll';\nimport {\n  App,\n  ScrollableItem,\n  WithAppContext,\n  scheduled,\n  immediate,\n  preset,\n  bigClient,\n  margin,\n  padding,\n  border,\n  descriptor,\n  smallFrameClient,\n} from './util/shared';\nimport { setViewport } from '../../../util/viewport';\nimport tryCleanPrototypeStubs from '../../../util/try-clean-prototype-stubs';\nimport type {\n  Registry,\n  DroppableCallbacks,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\n\nbeforeEach(() => {\n  setViewport(preset.viewport);\n});\n\nafterEach(() => {\n  tryCleanPrototypeStubs();\n});\n\nit('should publish the dimensions of the target', () => {\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const expected: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'fake-id',\n      type: 'fake',\n      mode: 'standard',\n    },\n    borderBox: bigClient.borderBox,\n    margin,\n    padding,\n    border,\n    windowScroll: { x: 0, y: 0 },\n  });\n  const wrapper: ReactWrapper<*> = mount(\n    <WithAppContext registry={registry}>\n      <ScrollableItem\n        droppableId={expected.descriptor.id}\n        type={expected.descriptor.type}\n        isScrollable={false}\n      />\n    </WithAppContext>,\n  );\n  const el: ?HTMLElement = wrapper.getDOMNode();\n  invariant(el);\n  jest\n    .spyOn(el, 'getBoundingClientRect')\n    .mockImplementation(() => bigClient.borderBox);\n\n  // pull the get dimension function out\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  // execute it to get the dimension\n  const result: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n    { x: 0, y: 0 },\n    scheduled,\n  );\n\n  expect(result).toEqual(expected);\n  // Goes without saying, but just being really clear here\n  expect(result.client.border).toEqual(border);\n  expect(result.client.margin).toEqual(margin);\n  expect(result.client.padding).toEqual(padding);\n});\n\nit('should consider the window scroll when calculating dimensions', () => {\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const windowScroll: Position = {\n    x: 500,\n    y: 1000,\n  };\n  setWindowScroll(windowScroll, { shouldPublish: false });\n  const expected: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'fake-id',\n      type: 'fake',\n      mode: 'standard',\n    },\n    borderBox: bigClient.borderBox,\n    margin,\n    padding,\n    border,\n    windowScroll,\n  });\n\n  const wrapper: ReactWrapper<*> = mount(\n    <WithAppContext registry={registry}>\n      <ScrollableItem\n        droppableId={expected.descriptor.id}\n        type={expected.descriptor.type}\n        isScrollable={false}\n      />\n    </WithAppContext>,\n  );\n  const el: ?HTMLElement = wrapper.getDOMNode();\n  invariant(el);\n  jest\n    .spyOn(el, 'getBoundingClientRect')\n    .mockImplementation(() => bigClient.borderBox);\n\n  // pull the get dimension function out\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  // execute it to get the dimension\n  const result: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n    windowScroll,\n    scheduled,\n  );\n\n  expect(result).toEqual(expected);\n});\n\ndescribe('no closest scrollable', () => {\n  it('should return null for the closest scrollable if there is no scroll container', () => {\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const expected: DroppableDimension = getDroppableDimension({\n      descriptor,\n      borderBox: bigClient.borderBox,\n      border,\n      margin,\n      padding,\n      windowScroll: preset.windowScroll,\n    });\n    const wrapper = mount(\n      <WithAppContext registry={registry}>\n        <App parentIsScrollable={false} />\n      </WithAppContext>,\n    );\n    const el: ?HTMLElement = wrapper.find('.droppable').getDOMNode();\n    invariant(el);\n    jest\n      .spyOn(el, 'getBoundingClientRect')\n      .mockImplementation(() => bigClient.borderBox);\n\n    // pull the get dimension function out\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n    // execute it to get the dimension\n    const result: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n      preset.windowScroll,\n      immediate,\n    );\n\n    expect(result).toEqual(expected);\n  });\n});\n\ndescribe('droppable is scrollable', () => {\n  it('should collect information about the scrollable', () => {\n    // When collecting a droppable that is itself scrollable we store\n    // the client: BoxModel as if it did not have a frame. This brings\n    // its usage into line with elements that have a wrapping scrollable\n    // element.\n\n    const expected: DroppableDimension = getDroppableDimension({\n      descriptor,\n      // as expected\n      borderBox: bigClient.borderBox,\n      margin,\n      padding,\n      border,\n      windowScroll: preset.windowScroll,\n      closest: {\n        // we are using the smallFrameClient as a stand in for the elements\n        // actual borderBox which is cut off when it is a scroll container\n        borderBox: smallFrameClient.borderBox,\n        margin,\n        padding,\n        border,\n        // scroll width and height are based on the padding box\n        scrollSize: {\n          scrollWidth: bigClient.paddingBox.width,\n          scrollHeight: bigClient.paddingBox.height,\n        },\n        scroll: { x: 0, y: 0 },\n        shouldClipSubject: true,\n      },\n    });\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    // both the droppable and the parent are scrollable\n    const wrapper = mount(\n      <WithAppContext registry={registry}>\n        <App droppableIsScrollable />\n      </WithAppContext>,\n    );\n    const el: ?HTMLElement = wrapper.find('.droppable').getDOMNode();\n    invariant(el);\n    // returning smaller border box as this is what occurs when the element is scrollable\n    jest\n      .spyOn(el, 'getBoundingClientRect')\n      .mockImplementation(() => smallFrameClient.borderBox);\n    // scrollWidth / scrollHeight are based on the paddingBox of an element\n    Object.defineProperty(el, 'scrollWidth', {\n      value: bigClient.paddingBox.width,\n    });\n    Object.defineProperty(el, 'scrollHeight', {\n      value: bigClient.paddingBox.height,\n    });\n\n    // pull the get dimension function out\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n    // execute it to get the dimension\n    const result: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n      preset.windowScroll,\n      immediate,\n    );\n\n    expect(result).toEqual(expected);\n  });\n\n  it('should account for a change in scroll when crafting its custom borderBox', () => {\n    const scroll: Position = {\n      x: 10,\n      y: 10,\n    };\n    // the displacement of a scroll is in the opposite direction to a scroll\n    const displacement: Position = negate(scroll);\n    const expected: DroppableDimension = getDroppableDimension({\n      descriptor,\n      // as expected\n      borderBox: offsetByPosition(bigClient.borderBox, displacement),\n      margin,\n      padding,\n      border,\n      closest: {\n        // we are using the smallFrameClient as a stand in for the elements\n        // actual borderBox which is cut off when it is a scroll container\n        borderBox: smallFrameClient.borderBox,\n        margin,\n        padding,\n        border,\n        scrollSize: {\n          scrollWidth: bigClient.paddingBox.width,\n          scrollHeight: bigClient.paddingBox.height,\n        },\n        scroll,\n        shouldClipSubject: true,\n      },\n      windowScroll: preset.windowScroll,\n    });\n\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    // both the droppable and the parent are scrollable\n    const wrapper = mount(\n      <WithAppContext registry={registry}>\n        <App droppableIsScrollable />\n      </WithAppContext>,\n    );\n    const el: ?HTMLElement = wrapper.find('.droppable').getDOMNode();\n    invariant(el);\n    // returning smaller border box as this is what occurs when the element is scrollable\n    jest\n      .spyOn(el, 'getBoundingClientRect')\n      .mockImplementation(() => smallFrameClient.borderBox);\n    // scrollWidth / scrollHeight are based on the paddingBox of an element\n    Object.defineProperty(el, 'scrollWidth', {\n      value: bigClient.paddingBox.width,\n    });\n    Object.defineProperty(el, 'scrollHeight', {\n      value: bigClient.paddingBox.height,\n    });\n    el.scrollTop = scroll.y;\n    el.scrollLeft = scroll.x;\n\n    // pull the get dimension function out\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n    // execute it to get the dimension\n    const result: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n      preset.windowScroll,\n      immediate,\n    );\n\n    expect(result).toEqual(expected);\n  });\n});\n\ndescribe('parent of droppable is scrollable', () => {\n  it('should collect information about the scrollable', () => {\n    const scrollSize: ScrollSize = {\n      scrollHeight: bigClient.paddingBox.height,\n      scrollWidth: bigClient.paddingBox.width,\n    };\n    const expected: DroppableDimension = getDroppableDimension({\n      descriptor,\n      borderBox: bigClient.borderBox,\n      margin,\n      padding,\n      border,\n      closest: {\n        borderBox: smallFrameClient.borderBox,\n        margin,\n        padding,\n        border,\n        scrollSize,\n        scroll: { x: 0, y: 0 },\n        shouldClipSubject: true,\n      },\n      windowScroll: preset.windowScroll,\n    });\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext registry={registry}>\n        <App parentIsScrollable droppableIsScrollable={false} />\n      </WithAppContext>,\n    );\n    const droppable: ?HTMLElement = wrapper.find('.droppable').getDOMNode();\n    invariant(droppable);\n    jest\n      .spyOn(droppable, 'getBoundingClientRect')\n      .mockImplementation(() => bigClient.borderBox);\n    const parent: HTMLElement = wrapper.find('.scroll-parent').getDOMNode();\n    jest\n      .spyOn(parent, 'getBoundingClientRect')\n      .mockImplementation(() => smallFrameClient.borderBox);\n    Object.defineProperty(parent, 'scrollWidth', {\n      value: scrollSize.scrollWidth,\n    });\n    Object.defineProperty(parent, 'scrollHeight', {\n      value: scrollSize.scrollHeight,\n    });\n    // pull the get dimension function out\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n    // execute it to get the dimension\n    const result: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n      preset.windowScroll,\n      immediate,\n    );\n\n    expect(result).toEqual(expected);\n  });\n});\n\ndescribe('both droppable and parent is scrollable', () => {\n  it('should log a warning as the use case is not supported', () => {\n    jest.spyOn(console, 'warn').mockImplementation(() => {});\n    const expected: DroppableDimension = getDroppableDimension({\n      descriptor,\n      borderBox: bigClient.borderBox,\n      margin,\n      padding,\n      border,\n      closest: {\n        borderBox: smallFrameClient.borderBox,\n        margin,\n        padding,\n        border,\n        scrollSize: {\n          scrollWidth: bigClient.paddingBox.width,\n          scrollHeight: bigClient.paddingBox.height,\n        },\n        scroll: { x: 0, y: 0 },\n        shouldClipSubject: true,\n      },\n      windowScroll: preset.windowScroll,\n    });\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext registry={registry}>\n        <App parentIsScrollable droppableIsScrollable />,\n      </WithAppContext>,\n    );\n    const droppable: ?HTMLElement = wrapper.find('.droppable').getDOMNode();\n    invariant(droppable);\n    const parent: HTMLElement = wrapper.find('.scroll-parent').getDOMNode();\n    jest\n      .spyOn(droppable, 'getBoundingClientRect')\n      .mockImplementation(() => smallFrameClient.borderBox);\n    Object.defineProperty(droppable, 'scrollWidth', {\n      value: bigClient.paddingBox.width,\n    });\n    Object.defineProperty(droppable, 'scrollHeight', {\n      value: bigClient.paddingBox.height,\n    });\n    // should never be called!\n    jest.spyOn(parent, 'getBoundingClientRect').mockImplementation(() => {\n      throw new Error(\n        'Should not be getting the boundingClientRect on the parent',\n      );\n    });\n\n    // pull the get dimension function out\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n    // execute it to get the dimension\n    expect(console.warn).not.toHaveBeenCalled();\n    const result: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n      preset.windowScroll,\n      immediate,\n    );\n    expect(console.warn).toHaveBeenCalled();\n\n    expect(result).toEqual(expected);\n    // $FlowFixMe\n    console.warn.mockRestore();\n  });\n});\n\nit('should capture the initial scroll of the closest scrollable', () => {\n  // in this case the parent of the droppable is the closest scrollable\n  const frameScroll: Position = { x: 10, y: 20 };\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <WithAppContext registry={registry}>\n      <App parentIsScrollable droppableIsScrollable={false} />,\n    </WithAppContext>,\n  );\n  const droppable: ?HTMLElement = wrapper.find('.droppable').getDOMNode();\n  invariant(droppable);\n  const parent: HTMLElement = wrapper.find('.scroll-parent').getDOMNode();\n  invariant(parent);\n  // manually setting the scroll of the parent node\n  parent.scrollTop = frameScroll.y;\n  parent.scrollLeft = frameScroll.x;\n  Object.defineProperty(parent, 'scrollWidth', {\n    value: bigClient.paddingBox.width,\n  });\n  Object.defineProperty(parent, 'scrollHeight', {\n    value: bigClient.paddingBox.height,\n  });\n  jest\n    .spyOn(droppable, 'getBoundingClientRect')\n    .mockImplementation(() => bigClient.borderBox);\n  jest\n    .spyOn(parent, 'getBoundingClientRect')\n    .mockImplementation(() => smallFrameClient.borderBox);\n  const expected: DroppableDimension = getDroppableDimension({\n    descriptor,\n    borderBox: bigClient.borderBox,\n    margin,\n    border,\n    padding,\n    closest: {\n      borderBox: smallFrameClient.borderBox,\n      margin,\n      border,\n      padding,\n      scrollSize: {\n        scrollWidth: bigClient.paddingBox.width,\n        scrollHeight: bigClient.paddingBox.height,\n      },\n      scroll: frameScroll,\n      shouldClipSubject: true,\n    },\n    windowScroll: preset.windowScroll,\n  });\n\n  // pull the get dimension function out\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  // execute it to get the dimension\n  const result: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n    preset.windowScroll,\n    immediate,\n  );\n\n  expect(result).toEqual(expected);\n});\n\nit('should indicate if subject clipping is permitted based on the ignoreContainerClipping prop', () => {\n  // in this case the parent of the droppable is the closest scrollable\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <WithAppContext registry={registry}>\n      <App\n        parentIsScrollable\n        droppableIsScrollable={false}\n        ignoreContainerClipping\n      />\n    </WithAppContext>,\n  );\n  const droppable: ?HTMLElement = wrapper.find('.droppable').getDOMNode();\n  invariant(droppable);\n  const parent: HTMLElement = wrapper.find('.scroll-parent').getDOMNode();\n  const scrollSize: ScrollSize = {\n    scrollWidth: bigClient.paddingBox.width,\n    scrollHeight: bigClient.paddingBox.height,\n  };\n  Object.defineProperty(parent, 'scrollWidth', {\n    value: scrollSize.scrollWidth,\n  });\n  Object.defineProperty(parent, 'scrollHeight', {\n    value: scrollSize.scrollHeight,\n  });\n  jest\n    .spyOn(droppable, 'getBoundingClientRect')\n    .mockImplementation(() => bigClient.borderBox);\n  jest\n    .spyOn(parent, 'getBoundingClientRect')\n    .mockImplementation(() => smallFrameClient.borderBox);\n  const expected: DroppableDimension = getDroppableDimension({\n    descriptor,\n    borderBox: bigClient.borderBox,\n    margin,\n    padding,\n    border,\n    closest: {\n      borderBox: smallFrameClient.borderBox,\n      margin,\n      padding,\n      border,\n      scrollSize,\n      scroll: { x: 0, y: 0 },\n      shouldClipSubject: false,\n    },\n    windowScroll: preset.windowScroll,\n  });\n\n  // pull the get dimension function out\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  // execute it to get the dimension\n  const result: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n    preset.windowScroll,\n    immediate,\n  );\n\n  expect(result).toEqual(expected);\n});\n"
  },
  {
    "path": "test/unit/view/use-droppable-publisher/recollection.spec.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport { mount } from 'enzyme';\nimport React from 'react';\nimport { invariant } from '../../../../src/invariant';\nimport type { DimensionMarshal } from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport type { DroppableDimension } from '../../../../src/types';\nimport { getDroppableDimension } from '../../../util/dimension';\nimport { getMarshalStub } from '../../../util/dimension-marshal';\nimport tryCleanPrototypeStubs from '../../../util/try-clean-prototype-stubs';\nimport { setViewport } from '../../../util/viewport';\nimport {\n  App,\n  bigClient,\n  border,\n  descriptor,\n  immediate,\n  margin,\n  padding,\n  preset,\n  smallFrameClient,\n  WithAppContext,\n} from './util/shared';\nimport type {\n  Registry,\n  DroppableCallbacks,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\n\nbeforeEach(() => {\n  setViewport(preset.viewport);\n});\n\nafterEach(() => {\n  tryCleanPrototypeStubs();\n});\n\nconst expected: DroppableDimension = getDroppableDimension({\n  descriptor,\n  // as expected\n  borderBox: bigClient.borderBox,\n  margin,\n  padding,\n  border,\n  windowScroll: preset.windowScroll,\n  closest: {\n    // we are using the smallFrameClient as a stand in for the elements\n    // actual borderBox which is cut off when it is a scroll container\n    borderBox: smallFrameClient.borderBox,\n    margin,\n    padding,\n    border,\n    // scroll width and height are based on the padding box\n    scrollSize: {\n      scrollWidth: bigClient.paddingBox.width,\n      scrollHeight: bigClient.paddingBox.height,\n    },\n    scroll: { x: 0, y: 0 },\n    shouldClipSubject: true,\n  },\n});\n\nit('should recollect scroll if requested', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  // both the droppable and the parent are scrollable\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <WithAppContext marshal={marshal} registry={registry}>\n      <App droppableIsScrollable />\n    </WithAppContext>,\n  );\n  const el: ?HTMLElement = wrapper.find('.droppable').getDOMNode();\n  invariant(el);\n  // returning smaller border box as this is what occurs when the element is scrollable\n  jest\n    .spyOn(el, 'getBoundingClientRect')\n    .mockImplementation(() => smallFrameClient.borderBox);\n  // scrollWidth / scrollHeight are based on the paddingBox of an element\n  Object.defineProperty(el, 'scrollWidth', {\n    value: bigClient.paddingBox.width,\n  });\n  Object.defineProperty(el, 'scrollHeight', {\n    value: bigClient.paddingBox.height,\n  });\n\n  // pull the get dimension function out\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n  // execute it to get the dimension\n  const initial: DroppableDimension = callbacks.getDimensionAndWatchScroll(\n    preset.windowScroll,\n    immediate,\n  );\n\n  expect(initial).toEqual(expected);\n\n  // ensuring that we have the updated scroll\n  const newScroll: Position = { x: 100, y: 200 };\n  callbacks.scroll(newScroll);\n  const result: Position = callbacks.getScrollWhileDragging();\n  expect(result).toEqual(newScroll);\n});\n\nit('should throw if there is no drag occurring when a recollection is requested', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  // both the droppable and the parent are scrollable\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  mount(\n    <WithAppContext marshal={marshal} registry={registry}>\n      <App droppableIsScrollable showPlaceholder />\n    </WithAppContext>,\n  );\n\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n\n  expect(() => callbacks.getScrollWhileDragging()).toThrow();\n});\n\nit('should throw if there if recollecting from droppable that is not a scroll container', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  // both the droppable and the parent are scrollable\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  mount(\n    <WithAppContext marshal={marshal} registry={registry}>\n      <App />\n    </WithAppContext>,\n  );\n\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n\n  callbacks.getDimensionAndWatchScroll(preset.windowScroll, immediate);\n\n  expect(() => callbacks.getScrollWhileDragging()).toThrow();\n});\n"
  },
  {
    "path": "test/unit/view/use-droppable-publisher/registration.spec.js",
    "content": "// @flow\n/* eslint-disable react/no-multi-comp */\nimport { mount } from 'enzyme';\nimport React from 'react';\nimport type { DroppableDescriptor } from '../../../../src/types';\nimport forceUpdate from '../../../util/force-update';\nimport { preset, ScrollableItem, WithAppContext } from './util/shared';\nimport { setViewport } from '../../../util/viewport';\nimport PassThroughProps from '../../../util/pass-through-props';\nimport type {\n  Registry,\n  DroppableEntry,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\n\nsetViewport(preset.viewport);\n\nit('should register itself when mounting', () => {\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n\n  mount(\n    <WithAppContext registry={registry}>\n      <ScrollableItem />\n    </WithAppContext>,\n  );\n\n  expect(registerSpy).toHaveBeenCalledTimes(1);\n\n  // $ExpectError: using awesome matchers\n  const expected: DroppableEntry = {\n    uniqueId: expect.any(String),\n    descriptor: preset.home.descriptor,\n    callbacks: expect.any(Object),\n  };\n\n  expect(registerSpy).toHaveBeenCalledWith(expected);\n});\n\nit('should unregister itself when unmounting', () => {\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const unregisterSpy = jest.spyOn(registry.droppable, 'unregister');\n\n  const wrapper = mount(\n    <WithAppContext registry={registry}>\n      <ScrollableItem />\n    </WithAppContext>,\n  );\n  expect(registerSpy).toHaveBeenCalled();\n  expect(unregisterSpy).not.toHaveBeenCalled();\n\n  const entry = registerSpy.mock.calls[0][0];\n\n  wrapper.unmount();\n  expect(unregisterSpy).toHaveBeenCalledTimes(1);\n  expect(unregisterSpy).toHaveBeenCalledWith(entry);\n});\n\nit('should update its registration when a descriptor property changes', () => {\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const unregisterSpy = jest.spyOn(registry.droppable, 'unregister');\n\n  const wrapper = mount(\n    <PassThroughProps>\n      {(extra) => (\n        <WithAppContext registry={registry}>\n          <ScrollableItem {...extra} />\n        </WithAppContext>\n      )}\n    </PassThroughProps>,\n  );\n\n  // $ExpectError: using awesome matchers\n  const expectedFirst: DroppableEntry = {\n    uniqueId: expect.any(String),\n    descriptor: preset.home.descriptor,\n    callbacks: expect.any(Object),\n  };\n\n  // asserting shape of original publish\n  const first = registerSpy.mock.calls[0][0];\n  expect(first).toEqual(expectedFirst);\n\n  registerSpy.mockClear();\n\n  // updating the index\n  wrapper.setProps({\n    droppableId: 'some-new-id',\n  });\n  const updated: DroppableDescriptor = {\n    ...preset.home.descriptor,\n    id: 'some-new-id',\n  };\n\n  // old descriptor removed\n  expect(unregisterSpy).toHaveBeenCalledTimes(1);\n  expect(unregisterSpy).toHaveBeenCalledWith(first);\n\n  // new descriptor added\n  // $ExpectError: using awesome matchers\n  const expectedSecond: DroppableEntry = {\n    uniqueId: first.uniqueId,\n    descriptor: updated,\n    callbacks: expect.any(Object),\n  };\n  expect(registerSpy.mock.calls[0][0]).toEqual(expectedSecond);\n});\n\nit('should not update its registration when a descriptor property does not change on an update', () => {\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const unregisterSpy = jest.spyOn(registry.droppable, 'unregister');\n\n  const wrapper = mount(\n    <WithAppContext registry={registry}>\n      <ScrollableItem />\n    </WithAppContext>,\n  );\n  expect(registerSpy).toHaveBeenCalledTimes(1);\n  expect(unregisterSpy).not.toHaveBeenCalled();\n  registerSpy.mockClear();\n\n  forceUpdate(wrapper);\n  expect(unregisterSpy).not.toHaveBeenCalled();\n  expect(registerSpy).not.toHaveBeenCalled();\n});\n"
  },
  {
    "path": "test/unit/view/use-droppable-publisher/scroll-watching.spec.js",
    "content": "// @flow\nimport { mount } from 'enzyme';\nimport React from 'react';\nimport { type Position } from 'css-box-model';\nimport { invariant } from '../../../../src/invariant';\nimport type { DimensionMarshal } from '../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport { getMarshalStub } from '../../../util/dimension-marshal';\nimport { setViewport } from '../../../util/viewport';\nimport {\n  immediate,\n  preset,\n  scheduled,\n  ScrollableItem,\n  WithAppContext,\n} from './util/shared';\nimport type {\n  Registry,\n  DroppableCallbacks,\n} from '../../../../src/state/registry/registry-types';\nimport createRegistry from '../../../../src/state/registry/create-registry';\n\nconst scroll = (el: HTMLElement, target: Position) => {\n  el.scrollTop = target.y;\n  el.scrollLeft = target.x;\n  el.dispatchEvent(new Event('scroll'));\n};\n\nsetViewport(preset.viewport);\n\ndescribe('should immediately publish updates', () => {\n  it('should immediately publish the scroll offset of the closest scrollable', () => {\n    const marshal: DimensionMarshal = getMarshalStub();\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext marshal={marshal} registry={registry}>\n        <ScrollableItem />\n      </WithAppContext>,\n    );\n    const container: ?HTMLElement = wrapper\n      .find('.scroll-container')\n      .getDOMNode();\n    invariant(container);\n\n    // tell the droppable to watch for scrolling\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n    // watch scroll will only be called after the dimension is requested\n    callbacks.getDimensionAndWatchScroll(preset.windowScroll, immediate);\n\n    scroll(container, { x: 500, y: 1000 });\n\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledWith(\n      preset.home.descriptor.id,\n      { x: 500, y: 1000 },\n    );\n  });\n\n  it('should not fire a scroll if the value has not changed since the previous call', () => {\n    // this can happen if you scroll backward and forward super quick\n    const marshal: DimensionMarshal = getMarshalStub();\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext marshal={marshal} registry={registry}>\n        <ScrollableItem />\n      </WithAppContext>,\n    );\n    const container: ?HTMLElement = wrapper\n      .find('.scroll-container')\n      .getDOMNode();\n    invariant(container);\n    // tell the droppable to watch for scrolling\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n\n    // watch scroll will only be called after the dimension is requested\n    callbacks.getDimensionAndWatchScroll(preset.windowScroll, immediate);\n\n    // first event\n    scroll(container, { x: 500, y: 1000 });\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledTimes(1);\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledWith(\n      preset.home.descriptor.id,\n      { x: 500, y: 1000 },\n    );\n    // $ExpectError\n    marshal.updateDroppableScroll.mockReset();\n\n    // second event - scroll to same spot\n    scroll(container, { x: 500, y: 1000 });\n    expect(marshal.updateDroppableScroll).not.toHaveBeenCalled();\n\n    // third event - new value\n    scroll(container, { x: 500, y: 1001 });\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledWith(\n      preset.home.descriptor.id,\n      { x: 500, y: 1001 },\n    );\n  });\n});\n\ndescribe('should schedule publish updates', () => {\n  it('should publish the scroll offset of the closest scrollable', () => {\n    const marshal: DimensionMarshal = getMarshalStub();\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext marshal={marshal} registry={registry}>\n        <ScrollableItem />\n      </WithAppContext>,\n    );\n    const container: ?HTMLElement = wrapper\n      .find('.scroll-container')\n      .getDOMNode();\n    invariant(container);\n\n    // tell the droppable to watch for scrolling\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n    // watch scroll will only be called after the dimension is requested\n    callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n    scroll(container, { x: 500, y: 1000 });\n    // release the update animation frame\n    requestAnimationFrame.step();\n\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledWith(\n      preset.home.descriptor.id,\n      { x: 500, y: 1000 },\n    );\n  });\n\n  it('should throttle multiple scrolls into a animation frame', () => {\n    const marshal: DimensionMarshal = getMarshalStub();\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext marshal={marshal} registry={registry}>\n        <ScrollableItem />\n      </WithAppContext>,\n    );\n    const container: ?HTMLElement = wrapper\n      .find('.scroll-container')\n      .getDOMNode();\n    invariant(container);\n    // tell the droppable to watch for scrolling\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n\n    // watch scroll will only be called after the dimension is requested\n    callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n    // first event\n    scroll(container, { x: 500, y: 1000 });\n    // second event in same frame\n    scroll(container, { x: 200, y: 800 });\n\n    // release the update animation frame\n    requestAnimationFrame.step();\n\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledTimes(1);\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledWith(\n      preset.home.descriptor.id,\n      { x: 200, y: 800 },\n    );\n\n    // also checking that no loose frames are stored up\n    requestAnimationFrame.flush();\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledTimes(1);\n  });\n\n  it('should not fire a scroll if the value has not changed since the previous frame', () => {\n    // this can happen if you scroll backward and forward super quick\n    const marshal: DimensionMarshal = getMarshalStub();\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext marshal={marshal} registry={registry}>\n        <ScrollableItem />\n      </WithAppContext>,\n    );\n    const container: ?HTMLElement = wrapper\n      .find('.scroll-container')\n      .getDOMNode();\n    invariant(container);\n    // tell the droppable to watch for scrolling\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n\n    // watch scroll will only be called after the dimension is requested\n    callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n    // first event\n    scroll(container, { x: 500, y: 1000 });\n    // release the frame\n    requestAnimationFrame.step();\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledTimes(1);\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledWith(\n      preset.home.descriptor.id,\n      { x: 500, y: 1000 },\n    );\n    // $ExpectError\n    marshal.updateDroppableScroll.mockReset();\n\n    // second event\n    scroll(container, { x: 501, y: 1001 });\n    // no frame to release change yet\n\n    // third event - back to original value\n    scroll(container, { x: 500, y: 1000 });\n    // release the frame\n    requestAnimationFrame.step();\n    expect(marshal.updateDroppableScroll).not.toHaveBeenCalled();\n  });\n\n  it('should not publish a scroll update after requested not to update while an animation frame is occurring', () => {\n    const marshal: DimensionMarshal = getMarshalStub();\n    const registry: Registry = createRegistry();\n    const registerSpy = jest.spyOn(registry.droppable, 'register');\n    const wrapper = mount(\n      <WithAppContext marshal={marshal} registry={registry}>\n        <ScrollableItem />\n      </WithAppContext>,\n    );\n    const container: ?HTMLElement = wrapper\n      .find('.scroll-container')\n      .getDOMNode();\n    invariant(container);\n    // tell the droppable to watch for scrolling\n    const callbacks: DroppableCallbacks =\n      registerSpy.mock.calls[0][0].callbacks;\n\n    // watch scroll will only be called after the dimension is requested\n    callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n    // first event\n    scroll(container, { x: 500, y: 1000 });\n    requestAnimationFrame.step();\n    expect(marshal.updateDroppableScroll).toHaveBeenCalledTimes(1);\n    // $ExpectError\n    marshal.updateDroppableScroll.mockReset();\n\n    // second event\n    scroll(container, { x: 400, y: 100 });\n    // no animation frame to release event fired yet\n\n    // unwatching before frame fired\n    callbacks.dragStopped();\n\n    // flushing any frames\n    requestAnimationFrame.flush();\n    expect(marshal.updateDroppableScroll).not.toHaveBeenCalled();\n  });\n});\n\nit('should stop watching scroll when no longer required to publish', () => {\n  // this can happen if you scroll backward and forward super quick\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <WithAppContext marshal={marshal} registry={registry}>\n      <ScrollableItem />\n    </WithAppContext>,\n  );\n  const container: ?HTMLElement = wrapper\n    .find('.scroll-container')\n    .getDOMNode();\n  invariant(container);\n  // tell the droppable to watch for scrolling\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n\n  // watch scroll will only be called after the dimension is requested\n  callbacks.getDimensionAndWatchScroll(preset.windowScroll, immediate);\n\n  // first event\n  scroll(container, { x: 500, y: 1000 });\n  expect(marshal.updateDroppableScroll).toHaveBeenCalledTimes(1);\n  // $ExpectError\n  marshal.updateDroppableScroll.mockReset();\n\n  callbacks.dragStopped();\n\n  // scroll event after no longer watching\n  scroll(container, { x: 190, y: 400 });\n  expect(marshal.updateDroppableScroll).not.toHaveBeenCalled();\n});\n\nit('should stop watching for scroll events when the component is unmounted', () => {\n  jest.spyOn(console, 'warn').mockImplementation(() => {});\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <WithAppContext marshal={marshal} registry={registry}>\n      <ScrollableItem />\n    </WithAppContext>,\n  );\n  const container: ?HTMLElement = wrapper\n    .find('.scroll-container')\n    .getDOMNode();\n  invariant(container);\n  // tell the droppable to watch for scrolling\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n\n  // watch scroll will only be called after the dimension is requested\n  callbacks.getDimensionAndWatchScroll(preset.windowScroll, immediate);\n\n  wrapper.unmount();\n\n  // second event - will not fire any updates\n  scroll(container, { x: 100, y: 300 });\n  expect(marshal.updateDroppableScroll).not.toHaveBeenCalled();\n  // also logs a warning\n  expect(console.warn).toHaveBeenCalled();\n\n  // cleanup\n  // $ExpectError\n  console.warn.mockRestore();\n});\n\nit('should throw an error if asked to watch a scroll when already listening for scroll changes', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <WithAppContext marshal={marshal} registry={registry}>\n      <ScrollableItem />\n    </WithAppContext>,\n  );\n  // tell the droppable to watch for scrolling\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n\n  // watch scroll will only be called after the dimension is requested\n  const request = () =>\n    callbacks.getDimensionAndWatchScroll(preset.windowScroll, immediate);\n  request();\n  expect(request).toThrow();\n\n  // cleanup\n  callbacks.dragStopped();\n  wrapper.unmount();\n});\n\n// if this is not the case then it will break in IE11\nit('should add and remove events with the same event options', () => {\n  const marshal: DimensionMarshal = getMarshalStub();\n  const registry: Registry = createRegistry();\n  const registerSpy = jest.spyOn(registry.droppable, 'register');\n  const wrapper = mount(\n    <WithAppContext marshal={marshal} registry={registry}>\n      <ScrollableItem />\n    </WithAppContext>,\n  );\n  const container: ?HTMLElement = wrapper\n    .find('.scroll-container')\n    .getDOMNode();\n  invariant(container);\n  jest.spyOn(container, 'addEventListener');\n  jest.spyOn(container, 'removeEventListener');\n\n  // tell the droppable to watch for scrolling\n  const callbacks: DroppableCallbacks = registerSpy.mock.calls[0][0].callbacks;\n\n  // watch scroll will only be called after the dimension is requested\n  callbacks.getDimensionAndWatchScroll(preset.windowScroll, scheduled);\n\n  // assertion\n  const expectedOptions = {\n    passive: true,\n  };\n  expect(container.addEventListener).toHaveBeenCalledWith(\n    'scroll',\n    expect.any(Function),\n    expectedOptions,\n  );\n  expect(container.removeEventListener).not.toHaveBeenCalled();\n  container.addEventListener.mockReset();\n\n  // unwatching scroll\n  callbacks.dragStopped();\n\n  // assertion\n  expect(container.removeEventListener).toHaveBeenCalledWith(\n    'scroll',\n    expect.any(Function),\n    expectedOptions,\n  );\n  expect(container.removeEventListener).toHaveBeenCalledTimes(1);\n  expect(container.addEventListener).not.toHaveBeenCalled();\n\n  // cleanup\n  container.addEventListener.mockRestore();\n  container.removeEventListener.mockRestore();\n});\n"
  },
  {
    "path": "test/unit/view/use-droppable-publisher/util/shared.js",
    "content": "// @flow\n/* eslint-disable react/no-multi-comp */\nimport { createBox, type Spacing, type BoxModel } from 'css-box-model';\nimport React, { useMemo, type Node } from 'react';\nimport useDroppablePublisher from '../../../../../src/view/use-droppable-publisher/use-droppable-publisher';\nimport { getComputedSpacing, getPreset } from '../../../../util/dimension';\nimport { type DimensionMarshal } from '../../../../../src/state/dimension-marshal/dimension-marshal-types';\nimport type { Registry } from '../../../../../src/state/registry/registry-types';\nimport type {\n  ScrollOptions,\n  DroppableId,\n  DroppableDescriptor,\n  TypeId,\n} from '../../../../../src/types';\nimport createRef from '../../../../util/create-ref';\nimport AppContext, {\n  type AppContextValue,\n} from '../../../../../src/view/context/app-context';\nimport { noop } from '../../../../../src/empty';\nimport { getMarshalStub } from '../../../../util/dimension-marshal';\n\nexport const scheduled: ScrollOptions = {\n  shouldPublishImmediately: false,\n};\nexport const immediate: ScrollOptions = {\n  shouldPublishImmediately: true,\n};\n\nexport const preset = getPreset();\n\nexport const margin: Spacing = {\n  top: 1,\n  right: 2,\n  bottom: 3,\n  left: 4,\n};\nexport const padding: Spacing = {\n  top: 5,\n  right: 6,\n  bottom: 7,\n  left: 8,\n};\nexport const border: Spacing = {\n  top: 9,\n  right: 10,\n  bottom: 11,\n  left: 12,\n};\nexport const smallFrameClient: BoxModel = createBox({\n  borderBox: {\n    top: 0,\n    left: 0,\n    right: 100,\n    bottom: 100,\n  },\n  margin,\n  padding,\n  border,\n});\n\nexport const bigClient: BoxModel = createBox({\n  borderBox: {\n    top: 0,\n    left: 0,\n    right: 200,\n    bottom: 200,\n  },\n  margin,\n  padding,\n  border,\n});\n\nconst withSpacing = getComputedSpacing({ padding, margin, border });\n\nexport const descriptor: DroppableDescriptor = preset.home.descriptor;\n\ntype WithAppContextProps = {|\n  marshal?: DimensionMarshal,\n  registry: Registry,\n  children: Node,\n|};\n\nconst focusMarshal = {\n  register: () => noop,\n  tryRecordFocus: noop,\n  tryRestoreFocusRecorded: noop,\n  tryShiftRecord: noop,\n};\n\nexport function WithAppContext(props: WithAppContextProps) {\n  const context: AppContextValue = useMemo(\n    () => ({\n      focus: focusMarshal,\n      contextId: 'fake',\n      canLift: () => true,\n      isMovementAllowed: () => true,\n      dragHandleUsageInstructionsId: '1',\n      marshal: props.marshal || getMarshalStub(),\n      registry: props.registry,\n    }),\n    [props.marshal, props.registry],\n  );\n\n  return (\n    <AppContext.Provider value={context}>{props.children}</AppContext.Provider>\n  );\n}\n\ntype ScrollableItemProps = {|\n  type?: TypeId,\n  isScrollable?: boolean,\n  isDropDisabled?: boolean,\n  isCombineEnabled?: boolean,\n  droppableId?: DroppableId,\n|};\n\nexport function ScrollableItem(props: ScrollableItemProps) {\n  const droppableRef = createRef();\n  const placeholderRef = createRef();\n  // originally tests where made with this as the default\n  const isScrollable: boolean = props.isScrollable !== false;\n\n  useDroppablePublisher({\n    droppableId: props.droppableId || descriptor.id,\n    type: props.type || descriptor.type,\n    mode: 'standard',\n    direction: preset.home.axis.direction,\n    isDropDisabled: props.isDropDisabled || false,\n    ignoreContainerClipping: false,\n    getDroppableRef: droppableRef.getRef,\n    isCombineEnabled: props.isCombineEnabled || false,\n  });\n\n  return (\n    <div\n      className=\"scroll-container\"\n      style={{\n        boxSizing: 'border-box',\n        height: bigClient.borderBox.height,\n        width: bigClient.borderBox.width,\n        ...withSpacing,\n        overflowX: isScrollable ? 'scroll' : 'visible',\n        overflowY: isScrollable ? 'scroll' : 'visible',\n      }}\n      ref={droppableRef.setRef}\n    >\n      hi\n      <div className=\"placeholder\" ref={placeholderRef.setRef} />\n    </div>\n  );\n}\n\ntype AppProps = {|\n  droppableIsScrollable?: boolean,\n  parentIsScrollable?: boolean,\n  ignoreContainerClipping?: boolean,\n  showPlaceholder?: boolean,\n|};\n\nexport function App(props: AppProps) {\n  const droppableRef = createRef();\n  const placeholderRef = createRef();\n\n  const {\n    droppableIsScrollable = false,\n    parentIsScrollable = false,\n    ignoreContainerClipping = false,\n    showPlaceholder = false,\n  } = props;\n\n  useDroppablePublisher({\n    droppableId: descriptor.id,\n    direction: 'vertical',\n    mode: 'standard',\n    isDropDisabled: false,\n    isCombineEnabled: false,\n    type: descriptor.type,\n    ignoreContainerClipping,\n    getDroppableRef: droppableRef.getRef,\n  });\n\n  return (\n    <div\n      className=\"scroll-parent\"\n      style={{\n        boxSizing: 'border-box',\n        height: smallFrameClient.borderBox.height,\n        width: smallFrameClient.borderBox.width,\n        ...withSpacing,\n        // setting both manually. This will be done automatically if setting overflow: scroll\n        overflowX: parentIsScrollable ? 'scroll' : 'visible',\n        overflowY: parentIsScrollable ? 'scroll' : 'visible',\n      }}\n    >\n      <div>\n        <div\n          ref={droppableRef.setRef}\n          className=\"droppable\"\n          style={{\n            boxSizing: 'border-box',\n            height: bigClient.borderBox.height,\n            width: bigClient.borderBox.width,\n            ...withSpacing,\n            // setting both manually. This will be done automatically if setting overflow: scroll\n            overflowX: droppableIsScrollable ? 'scroll' : 'visible',\n            overflowY: droppableIsScrollable ? 'scroll' : 'visible',\n          }}\n        >\n          <div>hello world</div>\n          {showPlaceholder ? (\n            <div className=\"placeholder\" ref={placeholderRef.setRef} />\n          ) : null}\n        </div>\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "test/util/after-point.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { Axis } from '../../src/types';\nimport { add, patch } from '../../src/state/position';\n\nexport default function afterPoint(axis: Axis, point: Position): Position {\n  return add(point, patch(axis.line, 1));\n}\n\nexport function afterCrossAxisPoint(axis: Axis, point: Position): Position {\n  return add(point, patch(axis.crossAxisLine, 1));\n}\n"
  },
  {
    "path": "test/util/before-point.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type { Axis } from '../../src/types';\nimport { subtract, patch } from '../../src/state/position';\n\nexport default function beforePoint(axis: Axis, point: Position): Position {\n  return subtract(point, patch(axis.line, 1));\n}\n\nexport function beforeCrossAxisPoint(axis: Axis, point: Position): Position {\n  return subtract(point, patch(axis.crossAxisLine, 1));\n}\n"
  },
  {
    "path": "test/util/cause-runtime-error.js",
    "content": "// @flow\nexport function getRuntimeError(): Event {\n  return new window.ErrorEvent('error', {\n    error: new Error('non-rbd'),\n    cancelable: true,\n  });\n}\n\nexport default function causeRuntimeError() {\n  window.dispatchEvent(getRuntimeError());\n}\n"
  },
  {
    "path": "test/util/clone-impact.js",
    "content": "// @flow\nimport type { DragImpact } from '../../src/types';\n\nexport default (target: DragImpact): DragImpact =>\n  JSON.parse(JSON.stringify(target));\n"
  },
  {
    "path": "test/util/console.js",
    "content": "// @flow\nimport { noop } from '../../src/empty';\n\nfunction withConsole(type: string, fn: () => void, message?: string) {\n  const mock = jest.spyOn(console, type).mockImplementation(noop);\n\n  fn();\n\n  expect(mock).toHaveBeenCalled();\n\n  if (message) {\n    expect(mock).toHaveBeenCalledWith(expect.stringContaining(message));\n  }\n\n  mock.mockReset();\n}\n\nexport const withError = withConsole.bind(null, 'error');\nexport const withWarn = withConsole.bind(null, 'warn');\n\nfunction withoutConsole(type: string, fn: () => void) {\n  const mock = jest.spyOn(console, type).mockImplementation(noop);\n\n  fn();\n\n  expect(mock).not.toHaveBeenCalled();\n  mock.mockReset();\n}\n\nexport const withoutError = withoutConsole.bind(null, 'error');\nexport const withoutWarn = withoutConsole.bind(null, 'warn');\n"
  },
  {
    "path": "test/util/create-ref.js",
    "content": "// @flow\nexport default function createRef() {\n  let ref: ?HTMLElement = null;\n\n  const setRef = (supplied: ?HTMLElement) => {\n    ref = supplied;\n  };\n\n  const getRef = (): ?HTMLElement => ref;\n\n  return { ref, setRef, getRef };\n}\n"
  },
  {
    "path": "test/util/dimension-marshal.js",
    "content": "// @flow\nimport { bindActionCreators } from 'redux';\nimport create from '../../src/state/dimension-marshal/dimension-marshal';\nimport {\n  publishWhileDragging,\n  updateDroppableScroll,\n  updateDroppableIsEnabled,\n  updateDroppableIsCombineEnabled,\n  collectionStarting,\n} from '../../src/state/action-creators';\nimport type {\n  DimensionMarshal,\n  Callbacks,\n} from '../../src/state/dimension-marshal/dimension-marshal-types';\nimport type { Registry } from '../../src/state/registry/registry-types';\n\nexport const createMarshal = (\n  registry: Registry,\n  dispatch: Function,\n): DimensionMarshal => {\n  const callbacks: Callbacks = bindActionCreators(\n    {\n      publishWhileDragging,\n      collectionStarting,\n      updateDroppableScroll,\n      updateDroppableIsEnabled,\n      updateDroppableIsCombineEnabled,\n    },\n    dispatch,\n  );\n\n  return create(registry, callbacks);\n};\n\nexport const getMarshalStub = (): DimensionMarshal => ({\n  updateDroppableScroll: jest.fn(),\n  updateDroppableIsEnabled: jest.fn(),\n  updateDroppableIsCombineEnabled: jest.fn(),\n  scrollDroppable: jest.fn(),\n  startPublishing: jest.fn(),\n  stopPublishing: jest.fn(),\n});\n\nexport const getCallbacksStub = (): Callbacks => ({\n  publishWhileDragging: jest.fn(),\n  updateDroppableScroll: jest.fn(),\n  updateDroppableIsEnabled: jest.fn(),\n  updateDroppableIsCombineEnabled: jest.fn(),\n  collectionStarting: jest.fn(),\n});\n"
  },
  {
    "path": "test/util/dimension.js",
    "content": "// @flow\nimport {\n  createBox,\n  getRect,\n  withScroll,\n  type Rect,\n  type BoxModel,\n  type Spacing,\n  type Position,\n} from 'css-box-model';\nimport { invariant } from '../../src/invariant';\nimport { vertical } from '../../src/state/axis';\nimport { noSpacing, offsetByPosition } from '../../src/state/spacing';\nimport getViewport from '../../src/view/window/get-viewport';\nimport scrollViewport from '../../src/state/scroll-viewport';\nimport getDroppable, {\n  type Closest,\n} from '../../src/state/droppable/get-droppable';\nimport {\n  toDroppableMap,\n  toDroppableList,\n} from '../../src/state/dimension-structures';\nimport type {\n  Axis,\n  Placeholder,\n  DraggableId,\n  Viewport,\n  Scrollable,\n  DraggableDescriptor,\n  DroppableDescriptor,\n  DroppableDimension,\n  DraggableDimension,\n  DraggableDimensionMap,\n  DroppableDimensionMap,\n  DimensionMap,\n  DraggingState,\n  ScrollSize,\n} from '../../src/types';\nimport isTotallyVisibleThroughFrame from '../../src/state/visibility/is-totally-visible-through-frame';\nimport patchDimensionMap from '../../src/state/patch-dimension-map';\n\ntype GetComputedSpacingArgs = {|\n  margin?: Spacing,\n  padding?: Spacing,\n  border?: Spacing,\n  display?: string,\n|};\n\nconst origin: Position = { x: 0, y: 0 };\n\nexport const getFrame = (droppable: DroppableDimension): Scrollable => {\n  invariant(droppable.frame);\n  return droppable.frame;\n};\n\nexport const getComputedSpacing = ({\n  margin = noSpacing,\n  padding = noSpacing,\n  border = noSpacing,\n  display = 'block',\n}: GetComputedSpacingArgs): Object => ({\n  paddingTop: `${padding.top}px`,\n  paddingRight: `${padding.right}px`,\n  paddingBottom: `${padding.bottom}px`,\n  paddingLeft: `${padding.left}px`,\n  marginTop: `${margin.top}px`,\n  marginRight: `${margin.right}px`,\n  marginBottom: `${margin.bottom}px`,\n  marginLeft: `${margin.left}px`,\n  borderTopWidth: `${border.top}px`,\n  borderRightWidth: `${border.right}px`,\n  borderBottomWidth: `${border.bottom}px`,\n  borderLeftWidth: `${border.left}px`,\n  display,\n});\n\nexport const makeScrollable = (\n  droppable: DroppableDimension,\n  amount?: number = 20,\n) => {\n  const axis: Axis = droppable.axis;\n  const borderBox: Rect = droppable.client.borderBox;\n\n  const horizontalGrowth: number = axis === vertical ? 0 : amount;\n  const verticalGrowth: number = axis === vertical ? amount : 0;\n\n  // is 10px smaller than the client on the main axis\n  // this will leave 10px of scrollable area.\n  // only expanding on one axis\n  const newBorderBox: Rect = getRect({\n    top: borderBox.top,\n    left: borderBox.left,\n    // growing the client to account for the scrollable area\n    right: borderBox.right + horizontalGrowth,\n    bottom: borderBox.bottom + verticalGrowth,\n  });\n\n  // add scroll space on the main axis\n  const scrollSize: ScrollSize = {\n    scrollWidth: borderBox.width + horizontalGrowth,\n    scrollHeight: borderBox.height + verticalGrowth,\n  };\n\n  const newClient: BoxModel = createBox({\n    borderBox: newBorderBox,\n    border: droppable.client.border,\n    padding: droppable.client.padding,\n    margin: droppable.client.margin,\n  });\n\n  // eslint-disable-next-line no-use-before-define\n  const preset = getPreset();\n  const newPage: BoxModel = withScroll(newClient, preset.windowScroll);\n\n  return getDroppable({\n    descriptor: droppable.descriptor,\n    isEnabled: droppable.isEnabled,\n    direction: axis.direction,\n    client: newClient,\n    page: newPage,\n    isCombineEnabled: droppable.isCombineEnabled,\n    isFixedOnPage: droppable.isFixedOnPage,\n    closest: {\n      // using old dimensions for frame\n      client: droppable.client,\n      page: droppable.page,\n      scrollSize,\n      scroll: origin,\n      shouldClipSubject: true,\n    },\n  });\n};\n\nexport const makeVirtual = (\n  droppable: DroppableDimension,\n  amount?: number,\n): DroppableDimension =>\n  // a virtual list also needs to be scrollable\n  makeScrollable(\n    {\n      ...droppable,\n      descriptor: {\n        ...droppable.descriptor,\n        mode: 'virtual',\n      },\n    },\n    amount,\n  );\n\nexport const addDroppable = (\n  base: DraggingState,\n  droppable: DroppableDimension,\n): DraggingState => ({\n  ...base,\n  dimensions: patchDimensionMap(base.dimensions, droppable),\n});\n\nexport const addDraggable = (\n  state: DraggingState,\n  draggable: DraggableDimension,\n): DraggingState => ({\n  ...state,\n  dimensions: {\n    ...state.dimensions,\n    draggables: {\n      ...state.dimensions.draggables,\n      [draggable.descriptor.id]: draggable,\n    },\n  },\n});\n\nconst getPlaceholder = (client: BoxModel): Placeholder => ({\n  client,\n  tagName: 'div',\n  display: 'block',\n});\n\ntype GetDraggableArgs = {|\n  descriptor: DraggableDescriptor,\n  borderBox: Spacing,\n  windowScroll?: Position,\n  margin?: Spacing,\n  padding?: Spacing,\n  border?: Spacing,\n|};\n\nexport const getDraggableDimension = ({\n  descriptor,\n  borderBox,\n  windowScroll = origin,\n  margin,\n  border,\n  padding,\n}: GetDraggableArgs): DraggableDimension => {\n  const client: BoxModel = createBox({\n    borderBox,\n    margin,\n    padding,\n    border,\n  });\n  const displaceBy: Position = {\n    x: client.marginBox.width,\n    y: client.marginBox.height,\n  };\n\n  const result: DraggableDimension = {\n    descriptor,\n    client,\n    page: withScroll(client, windowScroll),\n    placeholder: getPlaceholder(client),\n    displaceBy,\n  };\n\n  return result;\n};\n\ntype ClosestMaker = {|\n  borderBox: Spacing,\n  margin?: Spacing,\n  border?: Spacing,\n  padding?: Spacing,\n  scrollSize: ScrollSize,\n  scroll: Position,\n  shouldClipSubject: boolean,\n|};\n\ntype GetDroppableArgs = {|\n  descriptor: DroppableDescriptor,\n  borderBox: Spacing,\n  direction?: 'vertical' | 'horizontal',\n  margin?: Spacing,\n  border?: Spacing,\n  padding?: Spacing,\n  windowScroll?: Position,\n  closest?: ?ClosestMaker,\n  isEnabled?: boolean,\n  isFixedOnPage?: boolean,\n  isCombineEnabled?: boolean,\n|};\n\nexport const getDroppableDimension = ({\n  descriptor,\n  borderBox,\n  margin,\n  padding,\n  border,\n  windowScroll = origin,\n  closest,\n  isEnabled = true,\n  direction = 'vertical',\n  isFixedOnPage = false,\n  isCombineEnabled = false,\n}: GetDroppableArgs): DroppableDimension => {\n  const client: BoxModel = createBox({\n    borderBox,\n    margin,\n    padding,\n    border,\n  });\n  const page: BoxModel = withScroll(client, windowScroll);\n\n  const closestScrollable: ?Closest = (() => {\n    if (!closest) {\n      return null;\n    }\n\n    const frameClient: BoxModel = createBox({\n      borderBox: closest.borderBox,\n      border: closest.border,\n      padding: closest.padding,\n      margin: closest.margin,\n    });\n\n    const framePage: BoxModel = withScroll(frameClient, windowScroll);\n\n    const result: Closest = {\n      client: frameClient,\n      page: framePage,\n      scrollSize: closest.scrollSize,\n      scroll: closest.scroll,\n      shouldClipSubject: closest.shouldClipSubject,\n    };\n\n    return result;\n  })();\n\n  return getDroppable({\n    descriptor,\n    isEnabled,\n    direction,\n    client,\n    page,\n    closest: closestScrollable,\n    isCombineEnabled,\n    isFixedOnPage,\n  });\n};\n\nexport const withAssortedSpacing = () => {\n  const margin: Spacing = { top: 10, left: 10, bottom: 5, right: 5 };\n  const padding: Spacing = { top: 2, left: 2, bottom: 2, right: 2 };\n  const border: Spacing = { top: 1, left: 2, bottom: 3, right: 4 };\n\n  return { margin, padding, border };\n};\n\nconst validateIsInDroppable = (\n  inList: DraggableDimension[],\n  droppable: DroppableDimension,\n) => {\n  inList.forEach((item: DraggableDimension) => {\n    invariant(\n      isTotallyVisibleThroughFrame(droppable.client.borderBox)(\n        item.client.marginBox,\n      ),\n      `\n      draggable: \"${item.descriptor.id}\"\n      margin box must be within\n      droppable: \"${droppable.descriptor.id}\"\n      border box\n    `,\n    );\n  });\n};\n\nconst validateIsStacked = (\n  inList: DraggableDimension[],\n  droppable: DroppableDimension,\n) => {\n  inList.forEach((item: DraggableDimension, index: number) => {\n    // ignore first\n    if (index === 0) {\n      return;\n    }\n    const axis: Axis = droppable.axis;\n    const before: DraggableDimension = inList[index - 1];\n\n    const startOfItem: number = item.client.marginBox[axis.start];\n    const endOfBefore: number = before.client.marginBox[axis.end];\n\n    invariant(\n      startOfItem === endOfBefore,\n      `\n      draggable: \"${item.descriptor.id}\"\n      must be after\n      draggable: \"${before.descriptor.id}\"\n    `,\n    );\n  });\n};\n\nexport const getPreset = (axis?: Axis = vertical) => {\n  const windowScroll: Position = { x: 50, y: 100 };\n  const assortedSpacing = withAssortedSpacing();\n\n  // TODO: cross axis values need to account for margin of assorted spacing\n  const homeBorderBoxCrossAxisStart: number =\n    assortedSpacing.margin[axis.crossAxisStart];\n  const homeBorderBoxCrossAxisEnd: number = homeBorderBoxCrossAxisStart + 100;\n\n  const foreignCrossAxisStart: number = 150;\n  const foreignCrossAxisEnd: number = 250;\n  const emptyForeignCrossAxisStart: number = 250;\n  const emptyForeignCrossAxisEnd: number = 350;\n\n  const droppableBorderBoxSize: number = 200;\n  const droppableBorderBoxStart: number = assortedSpacing.margin[axis.start];\n  const droppableBorderBoxEnd: number =\n    droppableBorderBoxStart + droppableBorderBoxSize;\n\n  type BorderBoxAfterArgs = {|\n    goAfter: DraggableDimension,\n    droppable: DroppableDimension,\n    borderBoxSize: number,\n  |};\n\n  const borderBoxAfter = ({\n    goAfter,\n    droppable,\n    borderBoxSize,\n  }: BorderBoxAfterArgs): Spacing => {\n    // going beneith the margin box, and accounting for own margin\n    const borderBoxStart: number =\n      goAfter.client.marginBox[axis.end] + assortedSpacing.margin[axis.start];\n\n    // sitting inside the droppable, and accounting for own margin\n    const borderBoxCrossAxisStart: number =\n      droppable.client.borderBox[axis.crossAxisStart] +\n      assortedSpacing.margin[axis.crossAxisStart];\n    const borderBoxCrossAxisEnd: number =\n      droppable.client.borderBox[axis.crossAxisEnd] -\n      assortedSpacing.margin[axis.crossAxisEnd];\n\n    return {\n      [axis.start]: borderBoxStart,\n      [axis.crossAxisStart]: borderBoxCrossAxisStart,\n      [axis.crossAxisEnd]: borderBoxCrossAxisEnd,\n      [axis.end]: borderBoxStart + borderBoxSize,\n    };\n  };\n\n  const home: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'home',\n      type: 'TYPE',\n      mode: 'standard',\n    },\n    borderBox: {\n      [axis.start]: droppableBorderBoxStart,\n      [axis.crossAxisStart]: homeBorderBoxCrossAxisStart,\n      [axis.crossAxisEnd]: homeBorderBoxCrossAxisEnd,\n      [axis.end]: droppableBorderBoxEnd,\n    },\n    ...assortedSpacing,\n    windowScroll,\n    direction: axis.direction,\n  });\n\n  const foreign: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'foreign',\n      type: 'TYPE',\n      mode: 'standard',\n    },\n    borderBox: {\n      [axis.start]: droppableBorderBoxStart,\n      [axis.crossAxisStart]: foreignCrossAxisStart,\n      [axis.crossAxisEnd]: foreignCrossAxisEnd,\n      [axis.end]: droppableBorderBoxEnd,\n    },\n    ...assortedSpacing,\n    windowScroll,\n    direction: axis.direction,\n  });\n\n  const emptyForeign: DroppableDimension = getDroppableDimension({\n    descriptor: {\n      id: 'empty-foreign',\n      type: 'TYPE',\n      mode: 'standard',\n    },\n    borderBox: {\n      [axis.start]: droppableBorderBoxStart,\n      [axis.crossAxisStart]: emptyForeignCrossAxisStart,\n      [axis.crossAxisEnd]: emptyForeignCrossAxisEnd,\n      [axis.end]: droppableBorderBoxEnd,\n    },\n    ...assortedSpacing,\n    windowScroll,\n    direction: axis.direction,\n  });\n\n  const inHome1Size: number = 20;\n  const inHome1: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'inhome1',\n      droppableId: home.descriptor.id,\n      type: home.descriptor.type,\n      index: 0,\n    },\n    borderBox: {\n      // starting inside the droppable border box\n      // account for own margin\n      [axis.start]:\n        droppableBorderBoxStart + assortedSpacing.margin[axis.crossAxisStart],\n      [axis.crossAxisStart]:\n        homeBorderBoxCrossAxisStart +\n        assortedSpacing.margin[axis.crossAxisStart],\n      [axis.crossAxisEnd]:\n        homeBorderBoxCrossAxisEnd - assortedSpacing.margin[axis.crossAxisEnd],\n      [axis.end]: droppableBorderBoxStart + inHome1Size,\n    },\n    windowScroll,\n    ...assortedSpacing,\n  });\n\n  // size: 20\n  const inHome2: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'inhome2',\n      droppableId: home.descriptor.id,\n      type: home.descriptor.type,\n      index: 1,\n    },\n    // pushed forward by margin of inHome1\n    borderBox: borderBoxAfter({\n      goAfter: inHome1,\n      droppable: home,\n      borderBoxSize: 20,\n    }),\n    ...assortedSpacing,\n    windowScroll,\n  });\n  // size: 30\n  const inHome3: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'inhome3',\n      droppableId: home.descriptor.id,\n      type: home.descriptor.type,\n      index: 2,\n    },\n    borderBox: borderBoxAfter({\n      goAfter: inHome2,\n      droppable: home,\n      borderBoxSize: 30,\n    }),\n    ...assortedSpacing,\n    windowScroll,\n  });\n  // size: 40\n  const inHome4: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'inhome4',\n      droppableId: home.descriptor.id,\n      type: home.descriptor.type,\n      index: 3,\n    },\n    borderBox: borderBoxAfter({\n      goAfter: inHome3,\n      droppable: home,\n      borderBoxSize: 40,\n    }),\n    ...assortedSpacing,\n    windowScroll,\n  });\n  invariant(\n    inHome4.client.marginBox[axis.end] < droppableBorderBoxEnd,\n    'Expecting items to be in bounds',\n  );\n\n  // size: 10\n  const inForeign1: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'inForeign1',\n      droppableId: foreign.descriptor.id,\n      type: foreign.descriptor.type,\n      index: 0,\n    },\n    borderBox: {\n      [axis.start]: 10,\n      [axis.crossAxisStart]: foreignCrossAxisStart,\n      [axis.crossAxisEnd]: foreignCrossAxisEnd,\n      [axis.end]: 20,\n    },\n    ...assortedSpacing,\n    windowScroll,\n  });\n  // size: 20\n  const inForeign2: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'inForeign2',\n      droppableId: foreign.descriptor.id,\n      type: foreign.descriptor.type,\n      index: 1,\n    },\n    borderBox: {\n      [axis.start]: 30,\n      [axis.crossAxisStart]: foreignCrossAxisStart,\n      [axis.crossAxisEnd]: foreignCrossAxisEnd,\n      [axis.end]: 50,\n    },\n    ...assortedSpacing,\n    windowScroll,\n  });\n  // size: 30\n  const inForeign3: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'inForeign3',\n      droppableId: foreign.descriptor.id,\n      type: foreign.descriptor.type,\n      index: 2,\n    },\n    borderBox: {\n      [axis.start]: 60,\n      [axis.crossAxisStart]: foreignCrossAxisStart,\n      [axis.crossAxisEnd]: foreignCrossAxisEnd,\n      [axis.end]: 90,\n    },\n    ...assortedSpacing,\n    windowScroll,\n  });\n  // size: 40\n  const inForeign4: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      id: 'inForeign4',\n      droppableId: foreign.descriptor.id,\n      type: foreign.descriptor.type,\n      index: 3,\n    },\n    borderBox: {\n      [axis.start]: 100,\n      [axis.crossAxisStart]: foreignCrossAxisStart,\n      [axis.crossAxisEnd]: foreignCrossAxisEnd,\n      [axis.end]: 140,\n    },\n    ...assortedSpacing,\n    windowScroll,\n  });\n\n  const droppables: DroppableDimensionMap = {\n    [home.descriptor.id]: home,\n    [foreign.descriptor.id]: foreign,\n    [emptyForeign.descriptor.id]: emptyForeign,\n  };\n\n  const draggables: DraggableDimensionMap = {\n    [inHome1.descriptor.id]: inHome1,\n    [inHome2.descriptor.id]: inHome2,\n    [inHome3.descriptor.id]: inHome3,\n    [inHome4.descriptor.id]: inHome4,\n    [inForeign1.descriptor.id]: inForeign1,\n    [inForeign2.descriptor.id]: inForeign2,\n    [inForeign3.descriptor.id]: inForeign3,\n    [inForeign4.descriptor.id]: inForeign4,\n  };\n\n  const inHomeList: DraggableDimension[] = [inHome1, inHome2, inHome3, inHome4];\n\n  // validate our setup\n  // only being strict with inHomeList\n  validateIsInDroppable(inHomeList, home);\n  validateIsStacked(inHomeList, home);\n\n  const inForeignList: DraggableDimension[] = [\n    inForeign1,\n    inForeign2,\n    inForeign3,\n    inForeign4,\n  ];\n\n  const dimensions: DimensionMap = {\n    draggables,\n    droppables,\n  };\n\n  const viewport: Viewport = (() => {\n    // scroll the viewport so it has the right frame\n    const base: Viewport = scrollViewport(getViewport(), windowScroll);\n\n    // set the initial and current scroll so that it is the same\n    // we are faking a lift from a scrolled window\n    const result: Viewport = {\n      frame: base.frame,\n      scroll: {\n        initial: windowScroll,\n        current: windowScroll,\n        max: base.scroll.max,\n        diff: {\n          value: origin,\n          displacement: origin,\n        },\n      },\n    };\n    return result;\n  })();\n\n  return {\n    home,\n    inHome1,\n    inHome2,\n    inHome3,\n    inHome4,\n    foreign,\n    inForeign1,\n    inForeign2,\n    inForeign3,\n    inForeign4,\n    emptyForeign,\n    droppables,\n    draggables,\n    dimensions,\n    inHomeList,\n    inForeignList,\n    windowScroll,\n    viewport,\n  };\n};\n\nexport const disableDroppable = (\n  droppable: DroppableDimension,\n): DroppableDimension => ({\n  ...droppable,\n  isEnabled: false,\n});\n\nconst windowScroll: Position = getPreset().windowScroll;\n\ntype ShiftArgs = {|\n  amount: Position,\n  draggables: DraggableDimensionMap,\n  indexChange: number,\n|};\n\n// will not expand the droppable to make room\nexport const shiftDraggables = ({\n  amount,\n  draggables,\n  indexChange,\n}: ShiftArgs): DraggableDimensionMap =>\n  Object.keys(draggables)\n    .map((id: DraggableId) => draggables[id])\n    .map((dimension: DraggableDimension) => {\n      const borderBox: Spacing = offsetByPosition(\n        dimension.client.borderBox,\n        amount,\n      );\n      const client: BoxModel = createBox({\n        borderBox,\n        margin: dimension.client.margin,\n        border: dimension.client.border,\n        padding: dimension.client.padding,\n      });\n      const page: BoxModel = withScroll(client, windowScroll);\n\n      const shifted: DraggableDimension = {\n        descriptor: {\n          ...dimension.descriptor,\n          index: dimension.descriptor.index + indexChange,\n        },\n        displaceBy: dimension.displaceBy,\n        client,\n        page,\n        placeholder: {\n          ...dimension.placeholder,\n          client,\n        },\n      };\n\n      return shifted;\n    })\n    .reduce((previous: DraggableDimensionMap, current: DraggableDimension) => {\n      previous[current.descriptor.id] = current;\n      return previous;\n    }, {});\n\nexport const enableCombining = (\n  droppables: DroppableDimensionMap,\n): DroppableDimensionMap =>\n  toDroppableMap(\n    toDroppableList(droppables).map(\n      (droppable: DroppableDimension): DroppableDimension => ({\n        ...droppable,\n        isCombineEnabled: true,\n      }),\n    ),\n  );\n"
  },
  {
    "path": "test/util/dragging-state.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { add } from '../../src/state/position';\nimport getStatePreset from './get-simple-state-preset';\nimport type {\n  ClientPositions,\n  PagePositions,\n  DraggingState,\n  CollectingState,\n  DropPendingState,\n  DragImpact,\n} from '../../src/types';\n\nconst state = getStatePreset();\n\nexport type IsDraggingState =\n  | DraggingState\n  | CollectingState\n  | DropPendingState;\n\nexport const draggingStates: IsDraggingState[] = [\n  state.dragging(),\n  state.collecting(),\n  state.dropPending(),\n];\n\nexport const withImpact = (\n  current: IsDraggingState,\n  impact: DragImpact,\n): IsDraggingState =>\n  ({\n    ...current,\n    impact,\n  }: any);\n\nexport const move = (\n  previous: IsDraggingState,\n  offset: Position,\n): IsDraggingState => {\n  const client: ClientPositions = {\n    offset,\n    selection: add(previous.initial.client.selection, offset),\n    borderBoxCenter: add(previous.initial.client.borderBoxCenter, offset),\n  };\n  const page: PagePositions = {\n    selection: add(client.selection, previous.viewport.scroll.current),\n    borderBoxCenter: add(\n      client.borderBoxCenter,\n      previous.viewport.scroll.current,\n    ),\n    offset: add(client.offset, previous.viewport.scroll.diff.value),\n  };\n\n  return {\n    // appeasing flow\n    phase: 'DRAGGING',\n    ...previous,\n    // eslint-disable-next-line\n    phase: previous.phase,\n    current: {\n      client,\n      page,\n    },\n  };\n};\n"
  },
  {
    "path": "test/util/force-update.js",
    "content": "// @flow\nimport type { ReactWrapper } from 'enzyme';\n\n// wrapper.update() no longer forces a render\n// instead using wrapper.setProps({});\n// https://github.com/airbnb/enzyme/issues/1245\n\nexport default (wrapper: ReactWrapper<*>) => wrapper.setProps({});\n"
  },
  {
    "path": "test/util/get-simple-state-preset.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\nimport { getPreset } from './dimension';\nimport { vertical } from '../../src/state/axis';\nimport getViewport from '../../src/view/window/get-viewport';\nimport { add } from '../../src/state/position';\nimport getLiftEffect from '../../src/state/get-lift-effect';\nimport getHomeLocation from '../../src/state/get-home-location';\nimport type {\n  Axis,\n  State,\n  IdleState,\n  DraggableDimension,\n  DroppableDimension,\n  DropResult,\n  CompletedDrag,\n  DropReason,\n  DraggableId,\n  DropAnimatingState,\n  Critical,\n  CollectingState,\n  Viewport,\n  ClientPositions,\n  PagePositions,\n  DragPositions,\n  DraggingState,\n  DropPendingState,\n} from '../../src/types';\n\nexport default (axis?: Axis = vertical) => {\n  const preset = getPreset(axis);\n  const critical: Critical = {\n    draggable: preset.inHome1.descriptor,\n    droppable: preset.home.descriptor,\n  };\n\n  const idle: IdleState = {\n    phase: 'IDLE',\n    completed: null,\n    shouldFlush: false,\n  };\n\n  const origin: Position = { x: 0, y: 0 };\n\n  const dragging = (\n    id?: DraggableId = critical.draggable.id,\n    selection?: Position,\n    viewport?: Viewport = preset.viewport,\n  ): DraggingState => {\n    // will populate the dimension state with the initial dimensions\n    const draggable: DraggableDimension = preset.draggables[id];\n    const droppable: DroppableDimension =\n      preset.droppables[draggable.descriptor.droppableId];\n    const clientSelection: Position =\n      selection || draggable.client.borderBox.center;\n    const ourCritical: Critical = {\n      draggable: draggable.descriptor,\n      droppable: droppable.descriptor,\n    };\n\n    const client: ClientPositions = {\n      selection: clientSelection,\n      borderBoxCenter: clientSelection,\n      offset: origin,\n    };\n\n    const page: PagePositions = {\n      selection: add(client.selection, viewport.scroll.initial),\n      borderBoxCenter: add(client.borderBoxCenter, viewport.scroll.initial),\n      offset: add(client.offset, viewport.scroll.diff.value),\n    };\n\n    const initial: DragPositions = {\n      client,\n      page,\n    };\n\n    const { impact, afterCritical } = getLiftEffect({\n      draggable,\n      home: droppable,\n      draggables: preset.dimensions.draggables,\n      viewport,\n    });\n\n    const result: DraggingState = {\n      phase: 'DRAGGING',\n      critical: ourCritical,\n      isDragging: true,\n      movementMode: 'FLUID',\n      dimensions: preset.dimensions,\n      initial,\n      current: initial,\n      impact,\n      afterCritical,\n      onLiftImpact: impact,\n      isWindowScrollAllowed: true,\n      viewport,\n      scrollJumpRequest: null,\n      forceShouldAnimate: null,\n    };\n\n    return result;\n  };\n\n  const collecting = (\n    id?: DraggableId,\n    selection?: Position,\n    viewport?: Viewport,\n  ): CollectingState => ({\n    phase: 'COLLECTING',\n    ...dragging(id, selection, viewport),\n    // eslint-disable-next-line\n    phase: 'COLLECTING',\n  });\n\n  type DropPendingArgs = {\n    reason: DropReason,\n    isWaiting: boolean,\n  };\n\n  const defaultDropPending: DropPendingArgs = {\n    reason: 'DROP',\n    isWaiting: true,\n  };\n\n  const dropPending = (\n    args: ?DropPendingArgs = defaultDropPending,\n  ): DropPendingState => ({\n    phase: 'DROP_PENDING',\n    ...dragging(),\n    // eslint-disable-next-line\n    phase: 'DROP_PENDING',\n    ...args,\n  });\n\n  const scrollJumpRequest = (\n    request: Position,\n    viewport?: Viewport = getViewport(),\n  ): DraggingState => {\n    const state: DraggingState = dragging(undefined, undefined, viewport);\n\n    return {\n      ...state,\n      movementMode: 'SNAP',\n      scrollJumpRequest: request,\n    };\n  };\n\n  const getDropAnimating = (\n    id: DraggableId,\n    reason: DropReason,\n  ): DropAnimatingState => {\n    const draggable: DraggableDimension = preset.draggables[id];\n    const home: DroppableDimension =\n      preset.droppables[draggable.descriptor.droppableId];\n\n    const { impact, afterCritical } = getLiftEffect({\n      draggable,\n      home,\n      draggables: preset.dimensions.draggables,\n      viewport: preset.viewport,\n    });\n\n    const result: DropResult = {\n      draggableId: draggable.descriptor.id,\n      type: draggable.descriptor.type,\n      source: {\n        droppableId: draggable.descriptor.droppableId,\n        index: draggable.descriptor.index,\n      },\n      // no destination when cancelling for result\n      destination:\n        reason === 'DROP' ? getHomeLocation(draggable.descriptor) : null,\n      reason,\n      combine: null,\n      mode: 'FLUID',\n    };\n\n    const ourCritical: Critical = {\n      draggable: draggable.descriptor,\n      droppable: home.descriptor,\n    };\n\n    const completed: CompletedDrag = {\n      critical: ourCritical,\n      afterCritical,\n      impact,\n      result,\n    };\n\n    const state: DropAnimatingState = {\n      phase: 'DROP_ANIMATING',\n      completed,\n      dimensions: preset.dimensions,\n      newHomeClientOffset: { x: 10, y: 20 },\n      dropDuration: 1,\n    };\n    return state;\n  };\n\n  const dropAnimating = (\n    id?: DraggableId = preset.inHome1.descriptor.id,\n  ): DropAnimatingState => getDropAnimating(id, 'DROP');\n\n  const userCancel = (\n    id?: DraggableId = preset.inHome1.descriptor.id,\n  ): DropAnimatingState => getDropAnimating(id, 'CANCEL');\n\n  const allPhases = (\n    id?: DraggableId = preset.inHome1.descriptor.id,\n  ): State[] => [idle, dragging(id), dropAnimating(id), userCancel(id)];\n\n  return {\n    critical,\n    idle,\n    dragging,\n    scrollJumpRequest,\n    dropPending,\n    dropAnimating,\n    userCancel,\n    allPhases,\n    collecting,\n    preset,\n  };\n};\n"
  },
  {
    "path": "test/util/impact.js",
    "content": "// @flow\nimport type {\n  DraggableDimension,\n  DraggableId,\n  DisplacementGroups,\n  DraggableDescriptor,\n  DraggableIdMap,\n  DisplacementMap,\n} from '../../src/types';\n\nexport function getDraggableIds(\n  draggables: DraggableDimension[],\n): DraggableId[] {\n  return draggables.map((d) => d.descriptor.id);\n}\n\nexport function getDraggableIdMap(ids: DraggableId[]): DraggableIdMap {\n  return ids.reduce((map: DraggableIdMap, id: DraggableId) => {\n    map[id] = true;\n    return map;\n  }, {});\n}\n\ntype VisibleEntry = {|\n  dimension: DraggableDimension,\n  shouldAnimate?: boolean,\n|};\n\ntype GetDisplacedArgs = {|\n  visible?: VisibleEntry[],\n  invisible?: DraggableDimension[],\n|};\n\nexport function getForcedDisplacement({\n  visible = [],\n  invisible = [],\n}: GetDisplacedArgs): DisplacementGroups {\n  const all: DraggableId[] = [\n    ...visible.map(\n      (entry: VisibleEntry): DraggableDimension => entry.dimension,\n    ),\n    ...invisible,\n  ]\n    .map((item: DraggableDimension): DraggableDescriptor => item.descriptor)\n    .sort((a, b) => a.index - b.index)\n    .map((descriptor: DraggableDescriptor): DraggableId => descriptor.id);\n\n  const visibleMap: DisplacementMap = visible.reduce(\n    (previous: DisplacementMap, entry: VisibleEntry): DisplacementMap => {\n      const descriptor: DraggableDescriptor = entry.dimension.descriptor;\n      previous[descriptor.id] = {\n        draggableId: descriptor.id,\n        // defaulting to true\n        shouldAnimate:\n          typeof entry.shouldAnimate === 'boolean' ? entry.shouldAnimate : true,\n      };\n      return previous;\n    },\n    {},\n  );\n\n  return {\n    all,\n    visible: visibleMap,\n    invisible: getDraggableIdMap(invisible.map((d) => d.descriptor.id)),\n  };\n}\n"
  },
  {
    "path": "test/util/no-after-critical.js",
    "content": "// @flow\nimport type { LiftEffect } from '../../src/types';\nimport { origin } from '../../src/state/position';\n\nconst noOnLift: LiftEffect = {\n  effected: {},\n  inVirtualList: false,\n  displacedBy: {\n    point: origin,\n    value: 0,\n  },\n};\n\nexport default noOnLift;\n"
  },
  {
    "path": "test/util/pass-through-props.jsx",
    "content": "// @flow\nimport { type Node } from 'react';\n\ntype Props<T> = {|\n  ...T,\n  children: (value: T) => Node,\n|};\n\nexport default function PassThroughProps(props: Props<*>) {\n  const { children, ...rest } = props;\n  return children(rest);\n}\n"
  },
  {
    "path": "test/util/preset-action-args.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Critical,\n  DropReason,\n  DropResult,\n  DragImpact,\n  DragStart,\n  DimensionMap,\n  DraggableDimension,\n  DroppableDimension,\n  Published,\n  CompletedDrag,\n  DraggableLocation,\n} from '../../src/types';\nimport type {\n  DropCompleteArgs,\n  InitialPublishArgs,\n  BeforeInitialCaptureArgs,\n  LiftArgs,\n  AnimateDropArgs,\n} from '../../src/state/action-creators';\nimport { getPreset, getDraggableDimension, makeScrollable } from './dimension';\nimport { offsetByPosition } from '../../src/state/spacing';\nimport getHomeLocation from '../../src/state/get-home-location';\nimport getLiftEffect from '../../src/state/get-lift-effect';\nimport getDropImpact from '../../src/state/middleware/drop/get-drop-impact';\nimport { origin } from '../../src/state/position';\n\n// In case a consumer needs the references\nexport const preset = getPreset();\nconst scrollableHome: DroppableDimension = makeScrollable(preset.home);\nconst scrollableForeign: DroppableDimension = makeScrollable(preset.foreign);\n\nexport const critical: Critical = {\n  draggable: preset.inHome1.descriptor,\n  droppable: preset.home.descriptor,\n};\n\nexport const { afterCritical, impact: homeImpact } = getLiftEffect({\n  draggable: preset.inHome1,\n  draggables: preset.draggables,\n  home: preset.home,\n  viewport: preset.viewport,\n});\n\nconst clientSelection: Position = preset.inHome1.client.borderBox.center;\n\nexport const liftArgs: LiftArgs = {\n  id: critical.draggable.id,\n  clientSelection,\n  movementMode: 'FLUID',\n};\n\nexport const beforeCaptureArgs: BeforeInitialCaptureArgs = {\n  draggableId: critical.draggable.id,\n  movementMode: 'FLUID',\n};\n\nexport const initialPublishArgs: InitialPublishArgs = {\n  critical,\n  dimensions: preset.dimensions,\n  clientSelection,\n  viewport: preset.viewport,\n  movementMode: 'FLUID',\n};\n\nexport const initialPublishWithScrollables: InitialPublishArgs = {\n  ...initialPublishArgs,\n  dimensions: {\n    draggables: preset.dimensions.draggables,\n    droppables: {\n      ...preset.dimensions.droppables,\n      [scrollableHome.descriptor.id]: scrollableHome,\n      [scrollableForeign.descriptor.id]: scrollableForeign,\n    },\n  },\n};\n\nexport const publishAdditionArgs: Published = (() => {\n  // home must be scrollable to publish changes to it\n  const addition: DraggableDimension = getDraggableDimension({\n    descriptor: {\n      ...preset.inHome4.descriptor,\n      // adding to the end of the list\n      index: preset.inHomeList.length,\n      id: 'addition',\n    },\n    borderBox: offsetByPosition(preset.inHome4.client.borderBox, {\n      x: 0,\n      y: preset.inHome4.client.borderBox.height,\n    }),\n    windowScroll: preset.windowScroll,\n  });\n  return {\n    removals: [],\n    additions: [addition],\n    modified: [{ droppableId: scrollableHome.descriptor.id, scroll: origin }],\n  };\n})();\n\nexport const getDragStart = (custom?: Critical = critical): DragStart => ({\n  draggableId: custom.draggable.id,\n  type: custom.droppable.type,\n  source: getHomeLocation(custom.draggable),\n  mode: 'FLUID',\n});\n\nconst result: DropResult = {\n  ...getDragStart(critical),\n  destination: getHomeLocation(critical.draggable),\n  reason: 'DROP',\n  combine: null,\n};\n\n// export const completed: CompletedDrag = {\n//   critical,\n//   result,\n//   impact: homeImpact,\n// };\n\nexport const getDropImpactForReason = (reason: DropReason): DragImpact =>\n  getDropImpact({\n    reason,\n    draggables: preset.draggables,\n    lastImpact: homeImpact,\n    home: preset.home,\n    viewport: preset.viewport,\n    onLiftImpact: homeImpact,\n    afterCritical,\n  }).impact;\n\nexport const getCompletedArgs = (reason: DropReason): DropCompleteArgs => {\n  const destination: ?DraggableLocation =\n    reason === 'CANCEL' ? null : getDragStart().source;\n\n  const customResult: DropResult = {\n    ...getDragStart(),\n    destination,\n    reason,\n    combine: null,\n  };\n\n  const completed: CompletedDrag = {\n    result: customResult,\n    impact: getDropImpactForReason(reason),\n    critical,\n    afterCritical,\n  };\n\n  return { completed };\n};\n\nconst droppedOnHome: CompletedDrag = {\n  result,\n  impact: getDropImpactForReason('DROP'),\n  critical,\n  afterCritical,\n};\n\nexport const animateDropArgs: AnimateDropArgs = {\n  completed: droppedOnHome,\n  dropDuration: 1,\n  newHomeClientOffset: { x: 10, y: 10 },\n};\n\nexport const userCancelArgs: AnimateDropArgs = {\n  ...animateDropArgs,\n  completed: {\n    ...droppedOnHome,\n    result: {\n      ...droppedOnHome.result,\n      reason: 'CANCEL',\n    },\n  },\n};\n\nexport const copy = (dimensions: DimensionMap): DimensionMap => ({\n  droppables: {\n    ...dimensions.droppables,\n  },\n  draggables: {\n    ...dimensions.draggables,\n  },\n});\n"
  },
  {
    "path": "test/util/registry.js",
    "content": "// @flow\nimport type { Position } from 'css-box-model';\nimport type {\n  Id,\n  DraggableId,\n  DroppableId,\n  DraggableDimension,\n  DroppableDimension,\n  DimensionMap,\n  DraggableOptions,\n} from '../../src/types';\nimport type {\n  DroppableCallbacks,\n  Registry,\n  DraggableEntry,\n  DroppableEntry,\n} from '../../src/state/registry/registry-types';\nimport { getPreset } from './dimension';\nimport { origin } from '../../src/state/position';\n\ntype DraggableArgs = {\n  uniqueId?: Id,\n  dimension: DraggableDimension,\n};\n\nconst defaultOptions: DraggableOptions = {\n  canDragInteractiveElements: true,\n  shouldRespectForcePress: false,\n  isEnabled: true,\n};\n\nconst getUniqueId = (() => {\n  let count: number = 0;\n  return function create(): Id {\n    return `unique-id-${count++}`;\n  };\n})();\n\nexport function getDraggableEntry({\n  uniqueId = getUniqueId(),\n  dimension,\n}: DraggableArgs): DraggableEntry {\n  return {\n    uniqueId,\n    descriptor: dimension.descriptor,\n    options: defaultOptions,\n    getDimension: () => dimension,\n  };\n}\n\nexport const getDroppableCallbacks = (\n  dimension: DroppableDimension,\n): DroppableCallbacks => ({\n  getDimensionAndWatchScroll: jest.fn().mockReturnValue(dimension),\n  getScrollWhileDragging: jest.fn().mockReturnValue(origin),\n  scroll: jest.fn(),\n  dragStopped: jest.fn(),\n});\n\ntype DroppableArgs = {|\n  uniqueId?: Id,\n  dimension: DroppableDimension,\n|};\n\nexport function getDroppableEntry({\n  uniqueId = getUniqueId(),\n  dimension,\n}: DroppableArgs): DroppableEntry {\n  return {\n    uniqueId,\n    descriptor: dimension.descriptor,\n    callbacks: getDroppableCallbacks(dimension),\n  };\n}\n\nexport type DimensionWatcher = {|\n  draggable: {|\n    getDimension: Function,\n  |},\n  droppable: {|\n    getDimensionAndWatchScroll: Function,\n    scroll: Function,\n    getScrollWhileDragging: Function,\n    dragStopped: Function,\n  |},\n|};\n\nconst preset = getPreset();\n\nexport const populate = (\n  registry: Registry,\n  dimensions?: DimensionMap = preset.dimensions,\n): DimensionWatcher => {\n  const { draggables, droppables } = dimensions;\n  const watcher: DimensionWatcher = {\n    draggable: {\n      getDimension: jest.fn(),\n    },\n    droppable: {\n      getDimensionAndWatchScroll: jest.fn(),\n      scroll: jest.fn(),\n      getScrollWhileDragging: jest.fn(),\n      dragStopped: jest.fn(),\n    },\n  };\n\n  Object.keys(droppables).forEach((id: DroppableId) => {\n    const droppable: DroppableDimension = droppables[id];\n    const callbacks: DroppableCallbacks = {\n      getDimensionAndWatchScroll: () => {\n        watcher.droppable.getDimensionAndWatchScroll(id);\n        return droppable;\n      },\n      scroll: (change: Position) => {\n        watcher.droppable.scroll(id, change);\n      },\n      getScrollWhileDragging: () => {\n        const scroll: Position = droppable.frame\n          ? droppable.frame.scroll.current\n          : origin;\n\n        watcher.droppable.getScrollWhileDragging(id, scroll);\n        return scroll;\n      },\n      dragStopped: () => {\n        watcher.droppable.dragStopped(id);\n      },\n    };\n\n    const entry: DroppableEntry = {\n      uniqueId: droppable.descriptor.id,\n      descriptor: droppable.descriptor,\n      callbacks,\n    };\n\n    registry.droppable.register(entry);\n  });\n\n  Object.keys(draggables).forEach((id: DraggableId) => {\n    const draggable: DraggableDimension = draggables[id];\n    const getDimension = (): DraggableDimension => {\n      watcher.draggable.getDimension(id);\n      return draggable;\n    };\n\n    const entry: DraggableEntry = {\n      uniqueId: draggable.descriptor.id,\n      descriptor: draggable.descriptor,\n      options: defaultOptions,\n      getDimension,\n    };\n\n    registry.draggable.register(entry);\n  });\n\n  return watcher;\n};\n\nexport const resetWatcher = (watcher: DimensionWatcher) => {\n  watcher.draggable.getDimension.mockReset();\n  Object.keys(watcher.droppable).forEach((key: string) => {\n    watcher.droppable[key].mockReset();\n  });\n};\n"
  },
  {
    "path": "test/util/reorder.js",
    "content": "// @flow\n\n// A little helper function to reorder a list\nexport default (list: any[], startIndex: number, endIndex: number): any[] => {\n  const result = Array.from(list);\n  const [removed] = result.splice(startIndex, 1);\n  result.splice(endIndex, 0, removed);\n\n  return result;\n};\n"
  },
  {
    "path": "test/util/set-window-scroll-size.js",
    "content": "// @flow\n\ntype Args = {|\n  scrollHeight: number,\n  scrollWidth: number,\n|};\n\nconst setWindowScrollSize = ({ scrollHeight, scrollWidth }: Args): void => {\n  const el: ?HTMLElement = document.documentElement;\n\n  if (!el) {\n    throw new Error('Unable to find document element');\n  }\n\n  el.scrollHeight = scrollHeight;\n  el.scrollWidth = scrollWidth;\n};\n\nconst original: Args = (() => {\n  const el: ?HTMLElement = document.documentElement;\n\n  if (!el) {\n    throw new Error('Unable to find document element');\n  }\n\n  return {\n    scrollWidth: el.scrollWidth,\n    scrollHeight: el.scrollHeight,\n  };\n})();\n\nexport const resetWindowScrollSize = () => setWindowScrollSize(original);\n\nexport default setWindowScrollSize;\n"
  },
  {
    "path": "test/util/set-window-scroll.js",
    "content": "// @flow\nimport { type Position } from 'css-box-model';\n\ntype Options = {|\n  shouldPublish: boolean,\n|};\n\nconst defaultOptions: Options = {\n  shouldPublish: true,\n};\n\nconst setWindowScroll = (\n  point: Position,\n  options?: Options = defaultOptions,\n) => {\n  window.pageXOffset = point.x;\n  window.pageYOffset = point.y;\n\n  if (options.shouldPublish) {\n    window.dispatchEvent(new Event('scroll'));\n  }\n};\n\nconst original: Position = {\n  x: window.pageXOffset,\n  y: window.pageYOffset,\n};\n\nexport const resetWindowScroll = () => setWindowScroll(original);\n\nexport default setWindowScroll;\n"
  },
  {
    "path": "test/util/spacing.js",
    "content": "// @flow\nimport type { Spacing } from 'css-box-model';\n\nexport const expandBySpacing = (\n  spacing1: Spacing,\n  spacing2: Spacing,\n): Spacing => ({\n  // pulling back to increase size\n  top: spacing1.top - spacing2.top,\n  left: spacing1.left - spacing2.left,\n  // pushing forward to increase size\n  bottom: spacing1.bottom + spacing2.bottom,\n  right: spacing1.right + spacing2.right,\n});\n\nexport const shrinkBySpacing = (\n  spacing1: Spacing,\n  spacing2: Spacing,\n): Spacing => ({\n  // pushing forward to descrease size\n  top: spacing1.top + spacing2.top,\n  left: spacing1.left + spacing2.left,\n  // pulling backwards to descrease size\n  bottom: spacing1.bottom - spacing2.bottom,\n  right: spacing1.right - spacing2.right,\n});\n"
  },
  {
    "path": "test/util/try-clean-prototype-stubs.js",
    "content": "// @flow\nexport default () => {\n  // clean up any stubs\n  if (Element.prototype.getBoundingClientRect.mockRestore) {\n    Element.prototype.getBoundingClientRect.mockRestore();\n  }\n  if (window.getComputedStyle.mockRestore) {\n    window.getComputedStyle.mockRestore();\n  }\n};\n"
  },
  {
    "path": "test/util/user-input-util.js",
    "content": "// @flow\nimport type { ReactWrapper } from 'enzyme';\nimport { type Position } from 'css-box-model';\n\nconst primaryButton: number = 0;\nconst origin: Position = { x: 0, y: 0 };\n\nconst getTouch = (client: Position, force: number): Object => {\n  // window.Touch not supported in jest yet so just returning an object\n\n  // const touch: Touch = new window.Touch({\n  const touch = {\n    // const touch: Touch = {\n    identifier: Date.now(),\n    // being super generic here\n    target: window,\n    clientX: client.x,\n    clientY: client.y,\n    radiusX: 2.5,\n    radiusY: 2.5,\n    rotationAngle: 0,\n    force,\n  };\n\n  return touch;\n};\n\nexport const dispatchWindowMouseEvent = (\n  eventName: string,\n  client?: Position = origin,\n  button?: number = primaryButton,\n  options?: Object = {},\n): MouseEvent => {\n  const event = new window.MouseEvent(eventName, {\n    bubbles: true,\n    cancelable: true,\n    view: window,\n    clientX: client.x,\n    clientY: client.y,\n    button,\n  });\n\n  // override properties on the event itself\n  Object.assign(event, options);\n\n  window.dispatchEvent(event);\n  return event;\n};\n\nexport const dispatchWindowKeyDownEvent = (keyCode: number): KeyboardEvent => {\n  const event = new window.KeyboardEvent('keydown', {\n    bubbles: true,\n    cancelable: true,\n    keyCode,\n  });\n  window.dispatchEvent(event);\n  return event;\n};\n\nexport const dispatchWindowEvent = (\n  eventName: string,\n  options?: Object = {},\n): Event => {\n  const event: Event = document.createEvent('Event');\n  event.initEvent(eventName, true, true);\n\n  // override properties on the event itself\n  Object.assign(event, options);\n\n  window.dispatchEvent(event);\n\n  return event;\n};\n\nexport const dispatchWindowTouchEvent = (\n  eventName: string,\n  client?: Position = { x: 0, y: 0 },\n  force?: number = 0,\n  options?: Object = {},\n): Event => {\n  const touch = getTouch(client, force);\n  // window.TouchEvent constructor not supported in current version of Jest\n  // So using the old school document.createEvent \\o/\n\n  const touchOptions = {\n    touches: [touch],\n    targetTouches: [],\n    changedTouches: [touch],\n    shiftKey: false,\n  };\n\n  return dispatchWindowEvent(eventName, {\n    ...touchOptions,\n    ...options,\n  });\n};\n\nexport const mouseEvent = (\n  eventName: string,\n  wrapper: ReactWrapper<*>,\n  client?: Position = origin,\n  button?: number = primaryButton,\n  options?: Object = {},\n): void => {\n  wrapper.simulate(eventName, {\n    button,\n    clientX: client.x,\n    clientY: client.y,\n    ...options,\n  });\n};\n\nexport const withKeyboard = (keyCode: number): Function => (\n  wrapper: ReactWrapper<*>,\n  options?: Object = {},\n): void => {\n  wrapper.simulate('keydown', { keyCode, ...options });\n};\n\nexport const touchEvent = (\n  eventName: string,\n  wrapper: ReactWrapper<*>,\n  client?: Position = { x: 0, y: 0 },\n  force?: number = 0,\n  options?: Object = {},\n): void => {\n  const touches: Object[] = [getTouch(client, force)];\n\n  wrapper.simulate(eventName, { touches, ...options });\n};\n"
  },
  {
    "path": "test/util/viewport.js",
    "content": "// @flow\nimport { type Rect, type Position } from 'css-box-model';\nimport type { Viewport } from '../../src/types';\nimport getViewport from '../../src/view/window/get-viewport';\nimport getMaxScroll from '../../src/state/get-max-scroll';\nimport getDocumentElement from '../../src/view/get-document-element';\n\nexport const setWindowScroll = (newScroll: Position) => {\n  window.pageYOffset = newScroll.y;\n  window.pageXOffset = newScroll.x;\n};\n\nexport const setViewport = (viewport: Viewport) => {\n  if (viewport.scroll.current.x !== viewport.frame.left) {\n    throw new Error('scroll x must match left of subject');\n  }\n  if (viewport.scroll.current.y !== viewport.frame.top) {\n    throw new Error('scroll y must match top of subject');\n  }\n\n  setWindowScroll(viewport.scroll.current);\n\n  const doc: HTMLElement = getDocumentElement();\n  doc.clientWidth = viewport.frame.width;\n  doc.clientHeight = viewport.frame.height;\n\n  // reverse engineering these values\n  const scrollHeight: number = viewport.scroll.max.y + viewport.frame.height;\n  const scrollWidth: number = viewport.scroll.max.x + viewport.frame.width;\n\n  doc.scrollHeight = scrollHeight;\n  doc.scrollWidth = scrollWidth;\n};\n\nexport const getCurrent = (): Viewport => getViewport();\n\nconst original: Viewport = getCurrent();\n\nexport const resetViewport = () => setViewport(original);\n\ntype CreateViewportArgs = {|\n  frame: Rect,\n  scroll: Position,\n  scrollHeight: number,\n  scrollWidth: number,\n|};\n\nconst origin: Position = { x: 0, y: 0 };\n\nexport const createViewport = ({\n  frame,\n  scroll,\n  scrollHeight,\n  scrollWidth,\n}: CreateViewportArgs): Viewport => {\n  const viewport: Viewport = {\n    frame,\n    scroll: {\n      initial: scroll,\n      current: scroll,\n      max: getMaxScroll({\n        scrollHeight,\n        scrollWidth,\n        width: frame.width,\n        height: frame.height,\n      }),\n      diff: {\n        value: origin,\n        displacement: origin,\n      },\n    },\n  };\n  return viewport;\n};\n\ntype WithWindowScrollSizeArgs = {|\n  viewport: Viewport,\n  scrollWidth: number,\n  scrollHeight: number,\n|};\n\nexport const withWindowScrollSize = ({\n  viewport,\n  scrollWidth,\n  scrollHeight,\n}: WithWindowScrollSizeArgs): Viewport =>\n  createViewport({\n    frame: viewport.frame,\n    scroll: viewport.scroll.current,\n    scrollHeight,\n    scrollWidth,\n  });\n"
  }
]