[
  {
    "path": ".eslintrc",
    "content": "{\n    \"parser\"  : \"babel-eslint\",\n    \"extends\" : [\n        \"standard\",\n        \"standard-react\"\n     ],\n     \"plugins\": [\n         \"react\"\n     ],\n    \"env\" : {\n        \"browser\" : true,\n        \"es6\": true\n    },\n    \"globals\": {\n        \"__DEV__\": false\n    },\n    \"parserOptions\": {\n        \"ecmaVersion\": 6,\n        \"ecmaFeatures\": {\n            \"jsx\": true\n        }\n    },\n    \"rules\": {\n        \"generator-star-spacing\": 0,\n        \"indent\": [2, 4, { \"ignoredNodes\": [\"JSXAttribute\", \"JSXSpreadAttribute\"], \"SwitchCase\": 1 }],\n        \"no-warning-comments\": [1, {\n            \"terms\": [\"todo\", \"fixme\", \"xxx\"],\n            \"location\": \"start\"\n        }],\n        \"operator-linebreak\": [2, \"after\"],\n        \"padded-blocks\": 0,\n        \"semi\": [2, \"always\"],\n        \"react/jsx-indent-props\": [2, 2],\n        \"react/jsx-boolean-value\": [0, \"never\"],\n        \"react/jsx-curly-spacing\": [0, \"never\"],\n        \"react/jsx-indent\": [2, 4]\n    }\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n\n#LOCK\npackage-lock.json\nyarn.lock"
  },
  {
    "path": ".npmignore",
    "content": "/example\n/node_modules\npackage-lock.json\nyarn.lock\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## v3.9.1\n\n* Fix for `getNode()` deprecation warning with RN `0.62+` (thanks [@r0b0t3d](https://github.com/r0b0t3d))\n\n## v3.9.0\n\n* Fix for incorrect snapToItem (thanks [@Romick2005](https://github.com/Romick2005) & [@sergeyzhukov](https://github.com/sergeyzhukov))\n* Fix issue with tappable pagination dots (thanks [@Creskendoll](https://github.com/Creskendoll))\n* Clear all timeouts when stopping autoplay (thanks [@adrianocola](https://github.com/adrianocola))\n* Add props `animatedDuration`, `animatedFriction`, `animatedTension` and `delayPressInDot` to the `Pagination` component (thanks [@muhlenbrock](https://github.com/muhlenbrock))\n\n## v3.8.4\n\n* Remove TypeScript definitions since they were causing issues (thanks [@radko93](https://github.com/radko93))\n  * If you're using Typescript you should install the type definitions this way: `npm install --save @types/react-native-snap-carousel`\n\n## v3.8.3\n\n* Seems like it's time to remove the `getItemLayout` & `initialScrollIndex` override to properly display the first item when its index is a huge number (thanks [@rontalx](https://github.com/rontalx))\n  * :warning: Make sure to read how these props work together ([link#1](https://facebook.github.io/react-native/docs/flatlist#getitemlayout) & [link #2](https://facebook.github.io/react-native/docs/flatlist#initialscrollindex)), and to understand [why they were disabled in the first place](https://github.com/facebook/react-native/issues/15734#issuecomment-330616697)!\n* Fix `snapToItem` not working when `enableMomentum` is set to `true` on Android (thanks [@daaashleywch](https://github.com/daaashleywch))\n* Add basic TypeScript support (thanks [@facuacostag](https://github.com/facuacostag))\n* Stack layout's peaking items will remain opaque if `inactiveSlideOpacity` is set to `1`\n\n\n## v3.8.2\n\n* Fix autoplay stop after user interaction (thanks [@HelloCore](https://github.com/HelloCore))\n* Allow using a custom animated image component with `ParallaxImage` (thanks [@DanielMarkiel](https://github.com/DanielMarkiel))\n\n## v3.8.1\n\n* Migrate from deprecated `componentWillReceiveProps` to `componentDidUpdate` (thanks [@kiarashws](https://github.com/kiarashws))\n* Use `console.error` instead of `console.warn` for critical warnings (thanks [@bardiarastin](https://github.com/bardiarastin))\n* Update parallax doc (thanks [@bardiarastin](https://github.com/bardiarastin))\n\n## v3.8.0\n\n* Set [`removeClippedSubviews`](https://facebook.github.io/react-native/docs/scrollview#removeclippedsubviews) to `false` by default for 'tinder' and 'stack' layouts, or when `useScrollView` is set to `true`. This aims at preventing a bunch of rendering issues.\n* Make sure that autoplay is properly restarted after a `touchStart` event\n* Allow serialized animated event as `onScroll`. See [#439](https://github.com/meliorence/react-native-snap-carousel/pull/439) for more info (thanks [@Jberivera](https://github.com/Jberivera))\n* Allow using a custom scroll component. See [#498](https://github.com/meliorence/react-native-snap-carousel/pull/498) for more info (thanks [@martinezguillaume](https://github.com/martinezguillaume))\n* Prevent loop animation from being played when reaching the end of the dataset. See [#443](https://github.com/meliorence/react-native-snap-carousel/pull/443) for more info (thanks [@suhanmoon](https://github.com/suhanmoon))\n* Fire the `onTouchStart` prop. See [#464](https://github.com/meliorence/react-native-snap-carousel/pull/464) for more info (thanks [@sangle7](https://github.com/sangle7))\n* Add accessibilityLabel to `Pagination`. See [#438](https://github.com/meliorence/react-native-snap-carousel/pull/438) for more info (thanks [@thymikee](https://github.com/thymikee))\n* Allow `contentContainerCustomStyle` to override default paddings. See [#482](https://github.com/meliorence/react-native-snap-carousel/pull/482) for more info (thanks [@yamov](https://github.com/yamov))\n\n## v3.7.5\n* Fix issue with `scrollEnabled` introduced in version `3.7.3`... again! (thanks [@ifsnow](https://github.com/ifsnow))\n\n## v3.7.4\n* Fix issue with `scrollEnabled` introduced in version `3.7.3` (thanks [@JakeRawr](https://github.com/JakeRawr))\n\n## v3.7.3\n* Fix faulty animated value and make sure to always check for `data` before checking for `data.length`\n* Fix `scrollEnabled` override when it was initially set to `false` (thanks [@JakeRawr](https://github.com/JakeRawr))\n\n## v3.7.2\n* Fix `ParallaxImage` not being rendered (thanks [@louiszawadzki](https://github.com/louiszawadzki))\n\n## v3.7.1\n* Fix a potential crash in release mode (thanks [@hanpanpan200](https://github.com/hanpanpan200))\n* Do not round scroll offset's number in order to prevent potential issues with scroll repositioning\n\n## v3.7.0\n### New features and enhancements\n* Add a new callback method: [`onBeforeSnapToItem()`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#methods)\n* Add prop `lockScrollTimeoutDuration`\n* Add the ability to enable/disable callback's execution when snaping programmatically\n* Add the ability to change `scrollEnabled` to `true` from initially `false` (thanks [@tomauty](https://github.com/tomauty))\n### Bugfixes\n* Fix random errors when accessing wrapped component's reference\n* Fix errors triggered when calling `setState()` while the component has already been unmounted\n### Other\n* Support `keyExtractor` on `ScrollView` (thanks [@hadimhd](https://github.com/hadimhd))\n\n## v3.6.0\n* Add a `layout` prop to let users choose between 3 different carousel layouts (see [the documentation](https://github.com/meliorence/react-native-snap-carousel#layouts-and-custom-interpolations))\n![react-native-snap-carousel default layout](https://i.imgur.com/e1WbZcu.gif)\n![react-native-snap-carousel stack layout](https://i.imgur.com/foMIGM2.gif)\n![react-native-snap-carousel tinder layout](https://i.imgur.com/R7OpEFs.gif)\n* Add the ability to define dynamic styles based on scroll position with props `scrollInterpolator` and `slideInterpolatedStyle`. This allows implementing custom animations and layouts (see [the dedicated documentation](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/CUSTOM_INTERPOLATIONS.md)).\n* Rename props `customAnimationType` and `customAnimationOptions` to `activeAnimationType` and `activeAnimationOptions`\n\n## v3.5.0\n* Add the ability to render either a `ScrollView` component or a `FlatList` one (default) ([see prop `useScrollView`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#behavior))\n* Add support for versions of React Native < `0.43` (see [this note](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/KNOWN_ISSUES.md#react-native-version))\n* Add support for custom animations ([see props `customAnimationType` and `customAnimationOptions`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#style-and-animation))\n* Add method [`triggerRenderingHack()`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#available-methods) to work around [a random `FlatList` bug](https://github.com/facebook/react-native/issues/1831) that keeps content hidden until the carousel is scrolled\n* Hack around `ScrollView`/`FlatList` image rendering issues on Android\n* Fix issue with tappable dots when loop is enabled\n\n## v3.4.0\n* Fix `snapToItem` call that results in snapping to the wrong item when `loop` is enabled\n* Fix issue that, in some use cases, prevents every items but the initial ones to be rendered\n* On Android, prevent loop and callback issues because scroll offset's value doesn't return an integer\n* Add prop `inactiveSlideShift` (see #204)\n* Expose `FlatList`'s prop `inverted` (**use at your own risk since it will mess with the current handling of RTL layouts**)\n* Set `removeClippedSubviews` to `true` by default\n\n## v3.3.4\n* Fix issue with possible faulty index when `loopClonesPerSide` is greater than data length\n* Guard against `setNativeProps()` being `undefined`\n* On Android, make sure that the first item has the proper active style after init\n* On iOS, remove the feature \"snap as soon as the previous/next item becomes active when `lockScrollWhileSnapping` is enabled\" since it messes with direct calls to `snapToItem()`\n\n## v3.3.3\n* Prevent issue on iOS when `enableSnap` is set to `false` while `lockScrollWhileSnapping` is set to `true`\n\n## v3.3.2\n* Fix issue with `lockScrollWhileSnapping` when no callback was provided\n* `Pagination` component: add props `activeOpacity` and `dotContainerStyle`\n\n## v3.3.1\n* Fix issue when initializing the carousel with empty data\n* Make tappable `PaginationDot` snaps to the right item when loop is enabled\n\n## v3.3.0\n* Bring in the most wanted 'infinite loop' feature :tada: (see [the 'Loop' section](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#loop) for more info about the new props `loop` and `loopClonesPerSide`)\n* Improve Android behavior when momentum is disabled\n* Guard against potential errors when component is unmounted\n* Add prop `lockScrollWhileSnapping` to improve behavior when momentum is disabled\n\n## v3.2.3\n* Fix issue with callback not fired when doing a long swipe\n\n## v3.2.2\n* Fix RTL issues\n* Fix issue with active item when `enableMomentum` was set to `true`\n* Fix issue with overlapping items (thanks [@henninghall](https://github.com/henninghall))\n* `ParallaxImage` component: allow overriding default styles\n* `Pagination` component: adapt to RTL layouts\n\n## v3.2.1\n* Fix issue with active item when no callback has been specified (introduced in version `3.2.0`)\n\n## v3.2.0\n* Refactor callback handling. **Make sure to use the new prop `callbackOffsetMargin` if you experience missed callbacks.**\n* Make item's scale and opacity animations follow scroll value (thanks [@hammadj](https://github.com/hammadj))\n* `Pagination` component: make dots tappable with new props `tappableDots` and `carouselRef` (see the [example](https://github.com/meliorence/react-native-snap-carousel/blob/master/example/src/index.js))\n* Fix issue when carousel has been unmounted but parent container requires to re-render\n* Fix state and scroll issues when the currently active item is being dynamically removed\n* Improve snap feeling when momentum is disabled (default)\n* Add prop `callbackOffsetMargin`\n* Remove props `animationFunc`, `animationOptions`, `scrollEndDragDebounceValue`, `snapOnAndroid`, and `useNativeOnScroll`\n\n## v3.1.0\n* `Pagination` component: add new props for advanced customization\n\n## v3.0.0\n### WARNING\n* **Do not use this version as some temporary code was pushed to `npm` by mistake. Make sure to use version `3.1.0` instead.**\n### Breaking changes\n* Plugin is now built on top of `FlatList`, which allows for huge performance optimizations. From now on, items must be rendered using props `data` and `renderItem`.\n### General\n* Add `ParallaxImage` component (see the specific documentation [here](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PARALLAX_IMAGE.md))\n* Add prop `activeSlideAlignment`\n* Fix issue with autoplay when setting `scrollEnabled` to `false`\n* Prevent going back to the first item when overscrolling the last one\n* Prevent callback from being called at the wrong time in some specific scenarios\n\n## v2.4.0\n* Add `Pagination` component (see the specific documentation [here](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PAGINATION.md))\n* Allow `firstItem` to be changed dynamically\n* Allow `0` value for `carouselHorizontalPadding` and `carouselVerticalPadding` (thanks [@bonbonez](https://github.com/bonbonez))\n* Keep the easing of slide's opacity animation linear\n* Use native driver for slide's animation (can be overridden via `animationOptions`)\n\n## v2.3.1\n* Fix issue when snap is disabled\n\n## v2.3.0\n* Refactor callback handling to provide a more reliable solution when momentum is disabled\n* Fix issue with parallel animations (thanks [@jnbt](https://github.com/jnbt))\n* Prevent calls to `undefined` interpolators when working with dynamic slides (thanks [@cskaynar](https://github.com/cskaynar))\n* Improve vertical mode\n* Add prop `scrollEndDragDebounceValue`\n* Expose current scroll position with `this.currentScrollPosition`\n* Remove props `scrollEndDragThrottleValue` and `snapCallbackDebounceValue` (use `scrollEndDragDebounceValue` instead)\n\n## v2.2.2\n* Fix issue that prevented inactive styles of first and last items to be applied when using `snapToPrev` and `snapToNext` methods\n\n## v2.2.1\n* Do not mark `sliderWidth` and `sliderHeight` as required\n* Add warnings when properties specific to carousel's orientation haven't been set\n\n## v2.2.0\n* Implement vertical mode (prop `vertical`)\n* Make sure that current active item is properly updated when snapping\n* Prevent issues when 'sliderWidth' is smaller than viewport's width\n* Recalculate card positions on layout to handle rotation (thanks [@andrewpope](https://github.com/andrewpope)); make sure to read [this note](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/TIPS_AND_TRICKS.md#handling-device-rotation)\n* Refresh card positions if slider and/or item's dimensions are updated (thanks [@hoangnm](https://github.com/hoangnm))\n* Add props `scrollEndDragThrottleValue` and `snapCallbackDebounceValue`\n* Expose `View`'s `onLayout` prop\n* Deprecate prop `onScrollViewScroll`\n\n## v2.1.4\n* Add prop `onScrollViewScroll`\n\n## v2.1.3\n* Default value for `showsHorizontalScrollIndicator` is now `false`\n* Expose `ScrollView`'s `onSscroll` prop (thanks [@radko93](https://github.com/radko93))\n\n## v2.1.2\n* Do not trigger `onSnapToItem` when snapping back to the same slide (thanks [@rgabs](https://github.com/rgabs))\n* Add prop `carouselHorizontalPadding` to override container's inner padding (thanks [@skeie](https://github.com/skeie))\n\n## v2.1.1\n* Ensure compatibility with RN 0.43 (previous version of plugin's dependency `react-addons-shallow-compare` was breaking with React 16)\n* Fix issue with padding on iOS that could cause the carousel to snap back when its last item was clicked\n\n## v2.1.0\n* Add RTL support\n* Keep current active item when adding slides dynamically\n* Prevent invalid `firstItem` number\n* Add prop `activeSlideOffset`\n\n## v2.0.3\n\n* Prevent error when carousel has only one child (thanks [@kevinvandijk](https://github.com/kevinvandijk))\n* Fix issue when appending dynamic slides (the first one was ignored)\n* Fix edge case that prevented the first slide from being focused when swiping back with momentum enabled\n* Bump example's RN version to 0.42.3\n\n## v2.0.2\n\n* Make sure that scroll indicator is hidden by default\n\n## v2.0.1\n\n* Fix un-handled exception with interpolators (thanks [@chitezh](https://github.com/chitezh))\n\n## v2.0.0\n\n* Items are now direct children of the `<Carousel />` component, which makes it easier to use (thanks [@Jonarod](https://github.com/Jonarod))\n* Props `items` and `renderItem` have been removed\n\n## v1.6.1\n\n* Due to some touch events being buggy, rework methods so the children will receive touch events on Android\n\n## v1.6.0\n\n* Add prop `enableMomentum`\n* Fix an infinite-loop on iOS with momentum enabled\n* Fix the snapping effect when releasing touch without interia on iOS with momentum enabled\n* Fix autoplay on Android, it should start and stop properly and stop being triggered while swiping\n* Use `View.propTypes.style` instead of `PropTypes.number` in styles validation (thanks [@pesakitan22](https://github.com/pesakitan22))\n\n## v1.5.0\n\n* Items length can now be changed on-the-fly (thanks [@superical](https://github.com/superical))\n* Now handling momentum (thanks [@FakeYou](https://github.com/FakeYou))\n\n## v1.4.0\n\n* Better update strategy with shallowCompare\n* Add `snapToNext()`, `snapToPrev()`, `currentIndex` methods and properties\n\n## v1.3.1\n\n* Properly center on first item when mounting component on Android (potentially iOS too)\n\n## v1.3.0\n\n* Pass the item data as the 2nd param of `onSnapToItem` callback\n\n## v1.2.1\n\n* Fix reference call when the component has been unmounted\n\n## v1.2.0\n\n* Add prop `onSnapToItem`\n\n## v1.1.0\n\n* Center slides properly\n* Handle one slide only\n* Add props `inactiveSlideScale`, `inactiveSlideOpacity`, `containerCustomStyle` and `contentContainerCustomStyle`"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": ":warning: **From now on, users that don't adhere to the following guidelines when submitting an issue will see it closed without warning.**\n\n> This project is the result of countless hours of work and is maintained for free on our spare time. Show some love and respect by making it easier for us to help you!\n\nIf you would like to report a problem, take a look around and see if someone already opened an issue about it. If you are certain this is a new, unreported bug, you can submit a bug report by [opening a new issue](https://github.com/meliorence/react-native-snap-carousel/issues/new).\n\n:warning: When doing so, you need to fill out [the issue template](https://raw.githubusercontent.com/meliorence/react-native-snap-carousel/master/ISSUE_TEMPLATE.md) completely. **This step is mandatory!** Not doing so will result in your issue getting closed. Don't take this personally if this happens, and feel free to open a new issue once you've gathered all the information required by the template.\n\n* **One issue, one bug:** Please report a single bug per issue.\n* **Provide a [Snack example]((https://snack.expo.io/)):** To demonstrate the issue, you need to provide a reduced test case using [Snack](https://snack.expo.io/) and follow [the guidelines for providing a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). More often than not, providing a screencast will also be of tremendous help to understand the matter at stake (a screenshot might sometimes be enough).\n* **Provide reproduction steps:** List all the steps necessary to reproduce the issue. Provide a Snack, share the relevant source code or upload a sample project to GitHub. We should be able to follow these steps to reproduce your issue with minimal effort.\n* **Try out the latest version:** Verify that the issue can be reproduced locally by updating your project to use [the latest commit from `master`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/TIPS_AND_TRICKS.md#using-a-specific-commit). The bug may have already been fixed! Also make sure to test the latest stable release of React Native as your issue could be linked to RN's core."
  },
  {
    "path": "ISSUE_TEMPLATE.md",
    "content": "<!--\n  MAKE SURE TO READ AND FOLLOW THIS TEMPLATE CLOSELY OR YOUR ISSUE WILL BE CLOSED WITHOUT NOTICE\n-->\n\n### Is this a bug report, a feature request, or a question?\n\n(Write your answer here.)\n\n<!--\n  If you answered \"Bug report\":\n\n    We expect you to produce a high-quality bug report since putting care into your report helps us fix the issue faster.\n    For bug reports, it is REQUIRED to fill the rest of this template, or the issue will be closed.\n\n  If you answered \"Feature request\" or \"Question\":\n\n    Make sure to describe as precisely as possible the feature you'd like to see implemented or the question you'd like to see answered.\n    When relevant, provide visual examples (screenshots, screencasts, diagrams...).\n    You can ignore the next steps as long as you've made sure that your description is as clear, thorough and illustrated as possible.\n-->\n\n### Have you followed the required steps before opening a bug report?\n\n(Check the step you've followed - put an `x` character between the square brackets (`[]`).)\n\n- [] I have read [the guidelines regarding bug report](https://github.com/meliorence/react-native-snap-carousel/blob/master/CONTRIBUTING.md).\n- [] I have reviewed [the documentation](https://github.com/meliorence/react-native-snap-carousel/blob/master/README.md) in its entirety, including the dedicated documentations :books:.\n- [] I have searched for [existing issues](https://github.com/meliorence/react-native-snap-carousel/issues) and made sure that the problem hasn't already been reported.\n- [] I am using [the latest plugin version](https://github.com/meliorence/react-native-snap-carousel/releases).\n- [] I am following [the issue template](https://raw.githubusercontent.com/meliorence/react-native-snap-carousel/master/ISSUE_TEMPLATE.md) closely in order to produce a useful bug report.\n\n<!--\n  Please DO NOT go futher if you've not followed ALL of the above steps.\n  Failing to do so will result in your issue getting closed without warning.\n-->\n\n### Have you made sure that it wasn't a [React Native bug](https://github.com/meliorence/react-native-snap-carousel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22react-native+bug%22+)?\n\n(Write your answer here.)\n\n<!--\n  Steps you should take:\n\n    1. Take a look at plugin's issues that are [labelled `react-native bug`](https://github.com/meliorence/react-native-snap-carousel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22react-native+bug%22+)\n\n    2. Search [React Native issues](https://github.com/facebook/react-native/issues)\n\n    3. Read the following sections of the doc again: [\"Known issues\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/KNOWN_ISSUES.md), [\"Important note regarding Android\"](https://github.com/meliorence/react-native-snap-carousel#important-note-regarding-android), and [\"Custom interpolations caveats\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/CUSTOM_INTERPOLATIONS.md#caveats).\n -->\n\n### Is the bug specific to iOS or Android? Or can it be reproduced on both platforms?\n\n(Write your answer here and specify the iOS/Android versions on which you've been able to reproduce the issue.)\n\n### Is the bug reproductible in a production environment (not a debug one)?\n\n(Write your answer here.)\n\n<!--\n  If you haven't been able to reproduce the bug in production mode, it probably has to do with React Native's limitations (see [\"Known issues\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/KNOWN_ISSUES.md)). Chances are we won't be able to do anything about it.\n-->\n\n### Environment\n\n<!--\n  Provide information about your current environment. At the very least, it should include the following:\n\n  Environment:\n    React: 16.0.0-beta.5\n    React native: 0.49.2\n    react-native-snap-carousel: 3.3.4\n\n  Target Platform:\n    Android (6.0)\n    iOS (10.3)\n-->\n\n(Write your answer here.)\n\n### Expected Behavior\n\n<!--\n  How did you expect your project to behave?\n  It’s fine if you’re not sure your understanding is correct.\n  Just write down what you thought would happen.\n-->\n\n(Write what you thought would happen.)\n\n### Actual Behavior\n\n<!--\n  Did something go wrong?\n  Is something broken, or not behaving as you expected?\n  Describe this section in detail, and attach screencasts (or screenshots) if possible.\n  Don't just say \"it doesn't work\"!\n-->\n\n(Write what happened. Add screencasts/screenshots!)\n\n### Reproducible Demo\n\n(Paste the link to a [Snack example](https://snack.expo.io/) in which the issue can be reproduced. Please follow [the guidelines](https://stackoverflow.com/help/mcve) for providing a Minimal, Complete, and Verifiable example.)\n\n<!--\n  This step is MANDATORY:\n\n    * It shows that you value and respect the time of the people that are willing to help you; no one wishes to waste his spare time trying to recreate someone else's problem.\n    * Issues without reproducible demos have an extremely low priority and will probably be closed without notice.\n    * You might figure out the issues yourself as you work on extracting it.\n-->\n\n### Steps to Reproduce\n\n<!--\n  How would you describe your issue to someone who doesn’t know you or your project?\n  Write a sequence of steps that anybody can repeat to see the issue.\n  Be specific! If the bug cannot be reproduced, your issue will be closed.\n-->\n\n(Write your steps so that anyone can reproduce the issue in the Snack demo you provided.)\n\n1.\n2.\n3.\n\n<!--\n  Thanks for helping us help you!\n-->\n"
  },
  {
    "path": "LICENSE",
    "content": "BSD 3-Clause License\n\nCopyright (c) 2021, Meliorence\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "PULL_REQUEST_TEMPLATE.md",
    "content": "### Platforms affected\n\n\n### What does this PR do?\n\n\n### What testing has been done on this change?\n\n\n### Tested features checklist\n<!--\nIMPORTANT: Please make sure that none of these features have been broken by your changes.\nIt's easy to overlook something you didn't use yet.\n-->\n- [ ] Default setup ([example](https://github.com/meliorence/react-native-snap-carousel/blob/master/example/src/index.js#L46-L87))\n- [ ] Carousels with and without momentum enabled ([prop `enableMomentum`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#behavior))\n- [ ] Vertical carousels ([prop `vertical`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#behavior))\n- [ ] Slide alignment ([prop `activeSlideAlignment`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#style-and-animation))\n- [ ] Autoplay ([prop `autoplay`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#autoplay))\n- [ ] Loop mode ([prop `loop`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#loop))\n- [ ] `ScrollView`/`FlatList` carousels ([prop `useScrollView`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#behavior))\n- [ ] [Callback methods](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#callbacks)\n- [ ] [`ParallaxImage` component](https://github.com/meliorence/react-native-snap-carousel#parallaximage-component)\n- [ ] [`Pagination` component](https://github.com/meliorence/react-native-snap-carousel#pagination-component)\n- [ ] [Layouts and custom interpolations](https://github.com/meliorence/react-native-snap-carousel#layouts-and-custom-interpolations)\n"
  },
  {
    "path": "README.md",
    "content": "# react-native-snap-carousel\n\n![platforms](https://img.shields.io/badge/platforms-Android%20%7C%20iOS-brightgreen.svg?style=flat-square&colorB=191A17)\n[![npm](https://img.shields.io/npm/v/react-native-snap-carousel.svg?style=flat-square)](https://www.npmjs.com/package/react-native-snap-carousel)\n[![npm](https://img.shields.io/npm/dm/react-native-snap-carousel.svg?style=flat-square&colorB=007ec6)](https://www.npmjs.com/package/react-native-snap-carousel)\n<!-- [![github release](https://img.shields.io/github/release/meliorence/react-native-snap-carousel.svg?style=flat-square)](https://github.com/meliorence/react-native-snap-carousel/releases) -->\n[![github issues](https://img.shields.io/github/issues/meliorence/react-native-snap-carousel.svg?style=flat-square)](https://github.com/meliorence/react-native-snap-carousel/issues)\n[![github closed issues](https://img.shields.io/github/issues-closed/meliorence/react-native-snap-carousel.svg?style=flat-square&colorB=44cc11)](https://github.com/meliorence/react-native-snap-carousel/issues?q=is%3Aissue+is%3Aclosed)\n[![Issue Stats](https://img.shields.io/issuestats/i/github/meliorence/react-native-snap-carousel.svg?style=flat-square&colorB=44cc11)](http://github.com/meliorence/react-native-snap-carousel/issues)\n\n-----\n-----\n\n## ✨ Some great news for you, fellow plugin user!\n\n### 💡 **[Head over there now](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/VERSION_4.md)** to learn more about all the goodness that's coming your way.\n\n-----\n-----\n\n## Table of contents\n\n1. [Showcase](#showcase)\n1. [Usage](#usage)\n1. [Example](#example)\n1. [Props, methods and getters](#props-methods-and-getters)\n1. [Layouts and custom interpolations](#layouts-and-custom-interpolations)\n1. [`ParallaxImage` component](#parallaximage-component)\n1. [`Pagination` component](#pagination-component)\n1. [Tips and tricks](#tips-and-tricks)\n1. [Known issues](#known-issues)\n1. [Important note regarding Android](#important-note-regarding-android)\n1. [Important note regarding iOS](#important-note-regarding-ios)\n1. [Roadmap](#roadmap)\n1. [Credits](#credits)\n\n## Showcase\n\n### :raised_hands: New feature: layouts\n\n[Do you want to find out more?](#layouts-and-custom-interpolations)\n\n![react-native-snap-carousel default layout](https://i.imgur.com/e1WbZcu.gif)\n![react-native-snap-carousel tinder layout](https://i.imgur.com/R7OpEFs.gif)\n![react-native-snap-carousel stack layout](https://i.imgur.com/foMIGM2.gif)\n\n### Real-world examples\n\nThese are live apps we've created that make heavy use of the plugin. Don't be shy, share yours if you've done something awesome with it!\n\n![react-native-snap-carousel aix](https://i.imgur.com/pPm0csc.gif)\n![react-native-snap-carousel aix](https://i.imgur.com/UFsPlz2.gif)\n\n![react-native-snap-carousel](https://i.imgur.com/Fope3uj.gif)\n![react-native-snap-carousel](https://i.imgur.com/WNOBYfl.gif)\n![react-native-snap-carousel](https://i.imgur.com/sK5DKaG.gif)\n\n---\n\n## :handshake: Maintainers wanted\n\nHey there,\n\nCreating and maintaining this plugin has been a fun ride that started in 2016. We thank you all for your appreciation and for making the most out of it! You've motivated us to spend countless hours improving the plugin, and made us happy to give back to the Open Source community.\n\nPut simply, we love this project. However we currently aren't able to give it the love it deserves and the care it requires. **If you have enough time and knowledge, and want to become a maintainer, please let us know**.\n\n### 💡 **[Just head there if you're interested](https://github.com/meliorence/react-native-snap-carousel/issues/632).**\n\nWe're not abandoning the ship, but we need more people to help us keep it alive and well!\n\n---\n\n## Usage\n\n```bash\n$ npm install --save react-native-snap-carousel\n```\n\nIf you're using Typescript you should also install type definitions:\n```bash\n$ npm install --save @types/react-native-snap-carousel\n```\n\n\n```javascript\nimport Carousel from 'react-native-snap-carousel';\n\nexport class MyCarousel extends Component {\n\n    _renderItem = ({item, index}) => {\n        return (\n            <View style={styles.slide}>\n                <Text style={styles.title}>{ item.title }</Text>\n            </View>\n        );\n    }\n\n    render () {\n        return (\n            <Carousel\n              ref={(c) => { this._carousel = c; }}\n              data={this.state.entries}\n              renderItem={this._renderItem}\n              sliderWidth={sliderWidth}\n              itemWidth={itemWidth}\n            />\n        );\n    }\n}\n```\n\n## Example\n\nHere are simple examples that can be edited in real time in your browser:\n\n- https://snack.expo.io/@vitkor/carousel-simple-example\n- https://snack.expo.io/@bd-arc/react-native-snap-carousel-%7C-example-with-custom-interpolations\n\nYou can also find a more in-depth (read \"complex\") one in the [`/example` folder](https://github.com/meliorence/react-native-snap-carousel/tree/master/example).\n\n![react-native-snap-carousel](https://i.imgur.com/pZincya.gif)\n\n## Props, methods and getters\n\nIn order to let you to create mighty carousels and to keep up with your requests, we add new features on a regular basis. Consequently, the list of available props has become really huge and deserves a documentation of its own.\n\n### :books: [Documentation for \"Props, methods and getters\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md)\n\n## Layouts and custom interpolations\n\n### Built-in layouts\n\nIn version `3.6.0`, we've added two new layouts on top of the original one: the first one is called 'stack' since it mimics a stack of cards, and the other one is called 'tinder' since it provides a Tinder-like animation.\n\nYou can choose between the three of them using [the new prop `layout`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#style-and-animation) and you can modify the default card offset in the 'stack' and 'tinder' layouts with [prop `layoutCardOffset`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#style-and-animation).\n\n![react-native-snap-carousel default layout](https://i.imgur.com/e1WbZcu.gif)\n```javascript\n<Carousel layout={'default'} />\n```\n\n![react-native-snap-carousel stack layout ios](https://i.imgur.com/c7pU4rT.gif)\n![react-native-snap-carousel stack layout android](https://i.imgur.com/AnruacR.gif)\n```javascript\n<Carousel layout={'stack'} layoutCardOffset={`18`} />\n```\n\n![react-native-snap-carousel tinder layout ios](https://i.imgur.com/D9QyTzb.gif)\n![react-native-snap-carousel tinder layout android](https://i.imgur.com/ab1TI4e.gif)\n```javascript\n<Carousel layout={'tinder'} layoutCardOffset={`9`} />\n```\n\nA few things worth noting:\n* As you can see, the effect had to be inverted on Android. This has to do with [a really annoying Android-specific bug](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/CUSTOM_INTERPOLATIONS.md#android).\n* Even though the new layouts have been created with horizontal carousels in mind, they will also work with vertical ones \\o/\n* :warning: **You should NOT use `stack` or `tinder` layouts if you have a large data set to display.** In order to avoid rendering issues, the carousel will use a `ScrollView` component rather than a `FlatList` one for those layouts (see [prop `useScrollView`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#behavior)). The tradeof is that you won't benefit from any of `FlatList`'s advanced optimizations. See [this issue](https://github.com/meliorence/react-native-snap-carousel/issues/262) for workarounds; or you may want to implement your own [custom interpolation](#custom-interpolations).\n\n### Custom interpolations\n\nOn top of the new layouts, we've exposed the logic we used so that users can create their own awesome layouts! If you're interested, take a deep breath and dive into the dedicated documentation.\n\n### :books: [Documentation for \"Custom interpolations\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/CUSTOM_INTERPOLATIONS.md)\n\nHere are a few examples of what can easily be achieved (you can explore [the source code](https://github.com/meliorence/react-native-snap-carousel/blob/master/example/src/utils/animations.js) and try it live in [the provided example](https://github.com/meliorence/react-native-snap-carousel/tree/master/example)):\n\n![react-native-snap-carousel custom layout](https://i.imgur.com/OrdLsCM.gif)\n![react-native-snap-carousel custom layout](https://i.imgur.com/slnTbyG.gif)\n![react-native-snap-carousel custom layout](https://i.imgur.com/kDx3xTc.gif)\n\n## `ParallaxImage` component\n\nVersion `3.0.0` introduced a `<ParallaxImage />` component, an image component aware of carousel's current scroll position and therefore able to display a nice parallax effect (powered by the native driver to ensure top-notch performance).\n\n### :books: [Documentation for \"`ParallaxImage` component\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PARALLAX_IMAGE.md)\n\n![react-native-snap-carousel parallax image](https://i.imgur.com/6iIb4SR.gif)\n\n## `Pagination` component\n\nStarting with version `2.4.0`, a customizable `<Pagination />` component has been added. You can see below how it looks like with its default configuration.\n\n### :books: [Documentation for \"`Pagination` component\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PAGINATION.md)\n\n![react-native-snap-carousel pagination](https://i.imgur.com/FLQcGGL.gif)\n\n## Tips and tricks\n\nWe've gathered together all the useful tips and tricks. There is a bunch of them, which makes **this section a must-read!**\n\n### :books: [Documentation for \"Tips and tricks\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/TIPS_AND_TRICKS.md)\n\n## Known issues\n\n**Make sure to read about the known issues before opening a new one**; you may find something useful.\n\n### :books: [Documentation for \"Known issues\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/KNOWN_ISSUES.md)\n\n## Important note regarding Android\n\n![react-native-snap-carousel android](https://i.imgur.com/03iuB2Um.jpg)\n\nAndroid's debug mode is a mess: timeouts regularly desynchronize and scroll events are fired with some lag, which completely alters the inner logic of the carousel. **On Android, you *will* experience issues with carousel's behavior when JS Dev Mode is enabled, and you *might* have trouble with unreliable callbacks and loop mode when it isn't**. This is unfortunate, but it's rooted in various flaws of `ScrollView`/`FlatList`'s implementation and the miscellaneous workarounds we had to implement to compensate for it.\n\n:warning: **Therefore you should always check if the issue you experience also happens in a production environment. This is, sadly, the only way to test the real performance and behavior of the carousel.**\n\n> For more information, you can read the following notes: [\"Android performance\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/KNOWN_ISSUES.md#android-performance) and [\"Unreliable callbacks\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/KNOWN_ISSUES.md#unreliable-callbacks).\n\n## Important note regarding iOS\n\n![react-native-snap-carousel ios](https://i.imgur.com/npuiUSbh.png)\n\n:warning: When debugging with the iOS simulator, **you're only one \"Cmd + T\" away from toggling \"Slow Animations\"**. If carousel's animations seem painfully slow, make sure that you haven't enabled this setting by mistake.\n\n## Roadmap\n\n- [ ] Add [more examples](https://github.com/meliorence/react-native-snap-carousel/issues/257)\n- [ ] Base the plugin on a component less buggy than `FlatList`\n- [X] Implement different layouts and allow using custom interpolations\n- [X] Implement both `FlatList` and `ScrollView` handling\n- [X] Add the ability to provide custom items animation\n- [X] Implement 'loop' mode\n- [X] Improve Android's behavior\n- [x] Add parallax image component\n- [x] Base the plugin on `FlatList` instead of `ScrollView`\n- [x] Add alignment option\n- [x] Add pagination component\n- [x] Add vertical implementation\n- [x] Handle device orientation event (see [this note](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/TIPS_AND_TRICKS.md#handling-device-rotation))\n- [x] Add RTL support\n- [x] Improve momemtum handling\n- [x] Improve snap on Android\n- [x] Handle passing 1 item only\n- [x] Fix centering\n\n## Credits\n\nWritten by [Benoît Delmaire](https://fr.linkedin.com/in/benoitdelmaire) ([bd-arc](https://github.com/bd-arc)) and [Maxime Bertonnier](https://fr.linkedin.com/in/maxime-bertonnier-744351aa) ([Exilz](https://github.com/Exilz)) at\n[Meliorence](https://www.meliorence.com/).\n"
  },
  {
    "path": "doc/CUSTOM_INTERPOLATIONS.md",
    "content": "# Implementing custom interpolations\n\n> :warning: **This guide describes an advanced feature that is not intended for the faint-hearted**. Your sanity will be seriously challenged by the two most-feared enemies of this plugin: Android and React Native's `FlatList`. You **will** discover bugs that will drive you mad and, as a result, your aging process will accelerate drastically. Consider yourself warned and make sure to read [the caveats](#caveats) first and foremost!\n\n## Table of contents\n\n1. [Preview](#preview)\n1. [Usage](#usage)\n1. [Step-by-step example](#step-by-step-example)\n1. [Caveats](#caveats)\n\n## Preview\n\nVersion `3.6.0` introduced a new cool feature: layouts. On top of the default one, we've implemented two other ways of stacking and animating items in the carousel. You can choose between these with [prop `layout`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#style-and-animation). Here how each one looks like (the reason why iOS and Android are differents [will be explained later](#caveats)):\n\n![react-native-snap-carousel default layout](https://i.imgur.com/e1WbZcu.gif)\n```javascript\n<Carousel layout={'default'} />\n```\n\n![react-native-snap-carousel stack layout ios](https://i.imgur.com/c7pU4rT.gif)\n![react-native-snap-carousel stack layout android](https://i.imgur.com/AnruacR.gif)\n```javascript\n<Carousel layout={'stack'} />\n```\n\n![react-native-snap-carousel tinder layout ios](https://i.imgur.com/D9QyTzb.gif)\n![react-native-snap-carousel tinder layout android](https://i.imgur.com/ab1TI4e.gif)\n```javascript\n<Carousel layout={'tinder'} />\n```\n\nWe are able to do all this thanks to React Native's great [Animated API](https://facebook.github.io/react-native/docs/animations.html). Basically, we interpolate the current scroll position and provide to each item a set of animations based on this value. But those new layouts are just the tip of the iceberg. You can easily create others like these ones:\n\n![react-native-snap-carousel custom layout](https://i.imgur.com/slnTbyG.gif)\n![react-native-snap-carousel custom layout](https://i.imgur.com/OrdLsCM.gif)\n![react-native-snap-carousel custom layout](https://i.imgur.com/Nht4w9D.gif)\n![react-native-snap-carousel custom layout](https://i.imgur.com/kDx3xTc.gif)\n\nWe've decided to expose a way for users to provide their own interpolators, customize their carousels and create awesome animations! Note that you can find the source code of the built-in layouts [here](https://github.com/meliorence/react-native-snap-carousel/blob/master/src/utils/animations.js) and the source code of the custom examples [here](https://github.com/meliorence/react-native-snap-carousel/blob/master/example/src/utils/animations.js). Taking a look at these is a very good way to understand how it works.\n\n## Usage\n\n### Prerequisites\n\n- You have some experience with React Native's [Animated API](https://facebook.github.io/react-native/docs/animations.html).\n- You have a good understanding of [Animated's interpolations](https://github.com/browniefed/react-native-animation-book/blob/master/INTERPOLATION.md).\n- You've read and understood [the caveats](#caveats).\n- You are known for both your mental toughness and the peace of your mind.\n\n### Summary\n\nAdding a custom interpolation is done by providing either one of these props (but most likely both): `scrollInterpolator` and `slideInterpolatedStyle`.\n\n:bulb: You cannot use prop `activeAnimationOptions` in conjunction with custom interpolations. Make sure it isn't set since the scroll position will simply not be interpolated otherwise.\n\n### Prop `scrollInterpolator`\n\nThis prop will be used to interpolate the scroll position. Particularly, this means associating a specific scroll position to a specific value that is going to be used in `slideInterpolatedStyle` in order to animate styles.\n\n`scrollInterpolator` **has to be a function**. It will be called for every item in the data set on carousel's initialization and **it will receive two arguments: `index` and `carouselProps`**. The first one is the item index and the second one contains every carousel props since you might need them to define your interpolation. **The function must return an object of the following shape:**\n\n```javascript\n{\n    inputRange: [scroll value 1, scroll value 2, ...],\n    outputRange: [value associated with 1, value associated with 2, ...],\n}\n```\n\n> :warning: **Both arrays must have the same length**, otherwise you'll get an error.\n\nSince it can be pretty difficult to determine the adequate `inputRange` we've created a helper for you: [`getInputRangeFromIndexes(range, index, carouselProps)`](https://github.com/meliorence/react-native-snap-carousel/blob/master/src/utils/animations.js#L5:L24). You only need to determine the range of items **relative to the active one** you'd like to animate at the same time. The current item will be zero-indexed in this function. For example, using a range of `[1, 0, -1]` means that you will be able to animate the current active item (`0`), the previous one (`-1)` and the next one (`1`).\n\n> :warning: As you might have noticed, **when using `getInputRangeFromIndexes()` you need to declare your range in a reverse order**. While this is pretty counter-intuitive, you'll otherwise get an error because `\"inputRange must be monotonically increasing\"`.\n\n### Prop `slideInterpolatedStyle`\n\nThis prop is where the magic happens and where you're finally able to bend item's animation to your will. **`slideInterpolatedStyle` must be a function that returns a style object. It will receive three arguments: `index`, `animatedValue` and `carouselProps`.** The first and the last one are the same as the ones passed in `scrollInterpolator`, while `animatedValue` correspond with the animated value of carousel's scroll position.\n\nBased on the range you declared in `scrollInterpolator`, you can now interpolate values and do whatever you want.\n\n> :bulb: Unlike what you need to do in `scrollInterpolator`, the `inputRange` you declare in `slideInterpolatedStyle` has to be in a regular order.\n\nConsider the following:\n\n```javascript\nfunction animatedStyle = (index, animatedValue, carouselProps) => {\n    return {\n        opacity: animatedValue.interpolate({\n            inputRange: [-1, 0, 1],\n            outputRange: [0, 1, 0.5],\n            extrapolate: 'clamp'\n        })\n    }\n}\n```\n\nIt will translate into:\n- item `-1` (the previous one) will have an opacity of `0`\n- item `0` (the active one) will have an opacity of `1`\n- item `1` (the next one) will have an opacity of `0.5`.\n\nWhen you scroll, items' opacity will progressively animate from one value to the next, following the scroll position.\n\n: bulb: Using `extrapolate: 'clamp'` will prevent your interpolation to exceed `outputRange`'s values, the \"clamping\" being desirable with most use cases. From [the RN doc](https://facebook.github.io/react-native/docs/animations.html#interpolation): *\"By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value.\"*\n\n## Step-by-step example\n\nIt is recommended to take a look at [the source code of the built-in layouts](https://github.com/meliorence/react-native-snap-carousel/blob/master/src/utils/animations.js) and at [the source code the custom examples](https://github.com/meliorence/react-native-snap-carousel/blob/master/example/src/utils/animations.js); you'll learn a lot!\n\nFor those who want to follow through a step-by-step tutorial, the following is for you.\n\n### Defining the scroll interpolator\n\nLet's say we want to create a photo album effect: when swiping, the active item will move away and the next ones will appear from underneath. Of course, these items are going to be slightly rotated.\n\nFirst things first: for which items do we need to create a custom animation?\n- Item `-1`: the item that has been moved away.\n- Item `0`: the active item.\n- Items `1` and `2`: underneath rotated items.\n- Item `3`: invisible item that will make item `2` appear with an opacity transition.\n\nWith this clarified, declaring the scroll interpolator is as simple as :\n\n```javascript\nimport { getInputRangeFromIndexes } from 'react-native-snap-carousel';\n\nfunction scrollInterpolator (index, carouselProps) {\n    const range = [3, 2, 1, 0, -1]; // <- Remember that this has to be declared in a reverse order\n    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);\n    const outputRange = range;\n\n    return { inputRange, outputRange };\n}\n```\n\n### Creating the animations\n\nThis is where the fun begins!\n\nThe first trick is **to ensure that the active item will always sit on top of the next ones**. By default, an item with a higher index will also have a higher `zIndex`. To counteract this, you can use the following. :warning: **Currently, this can lead to swipe/click events being missed!** See [this issue](https://github.com/meliorence/react-native-snap-carousel/issues/262) for more info.\n\n```javascript\n{\n    zIndex: carouselProps.data.length - index\n}\n```\n\nThen we can define the `opacity` animation. Since we only need a transition between the second and third items, declaring it is pretty straightforward:\n\n```javascript\nopacity: animatedValue.interpolate({\n    inputRange: [2, 3],\n    outputRange: [1, 0]\n})\n```\n\nNow for the `rotate` animation. The active item and the third one won't be rotated at all, while the previous one will be in order to add a nice visual effect when swiping. Read [this](https://facebook.github.io/react-native/docs/animations.html#interpolation) if you need an explanation of the `extrapolate` property.\n\n```javascript\ntransform: [{\n    rotate: animatedValue.interpolate({\n        inputRange: [-1, 0, 1, 2, 3], // <- Unlike with `scrollInterpolator()`, this is declared in a regular order\n        outputRange: ['-25deg', '0deg', '-3deg', '1.8deg', '0deg'],\n        extrapolate: 'clamp'\n    })\n}]\n```\n\nThe tricky part is the `transform` animation. First, we need to ensure that our animated items are all centered in the carousel. To do that, we need to apply a translation equals to: **`-itemWidth` (or `-itemHeight` for vertical sliders) * relative index**. Then, we want item `-1` to move a bit more quickly than the others, which means negatively translating it. Finally, it's a good idea to make our animations compatible with both horizontal and vertical carousels. Hence the following:\n\n```javascript\nconst sizeRef = carouselProps.vertical ? carouselProps.itemHeight : carouselProps.itemWidth;\nconst translateProp = carouselProps.vertical ? 'translateY' : 'translateX';\n\nreturn {\n    transform: [{\n        [translateProp]: animatedValue.interpolate({\n            inputRange: [-1, 0, 1, 2, 3],\n            outputRange: [\n                -sizeRef * 0.5,\n                0,\n                -sizeRef, // centered\n                -sizeRef * 2, // centered\n                -sizeRef * 3 // centered\n            ],\n            extrapolate: 'clamp'\n        })\n    }]\n};\n```\n\nLet's put it all together:\n\n```javascript\nimport React, { PureComponent } from 'react';\nimport Carousel, { getInputRangeFromIndexes } from 'react-native-snap-carousel';\n\nexport default class MyCustomCarousel extends PureComponent {\n\n    _scrollInterpolator (index, carouselProps) {\n        const range = [3, 2, 1, 0, -1];\n        const inputRange = getInputRangeFromIndexes(range, index, carouselProps);\n        const outputRange = range;\n\n        return { inputRange, outputRange };\n    }\n\n    _animatedStyles (index, animatedValue, carouselProps) {\n        const sizeRef = carouselProps.vertical ? carouselProps.itemHeight : carouselProps.itemWidth;\n        const translateProp = carouselProps.vertical ? 'translateY' : 'translateX';\n\n        return {\n            zIndex: carouselProps.data.length - index,\n            opacity: animatedValue.interpolate({\n                inputRange: [2, 3],\n                outputRange: [1, 0]\n            }),\n            transform: [{\n                rotate: animatedValue.interpolate({\n                    inputRange: [-1, 0, 1, 2, 3],\n                    outputRange: ['-25deg', '0deg', '-3deg', '1.8deg', '0deg'],\n                    extrapolate: 'clamp'\n                })\n            }, {\n                [translateProp]: animatedValue.interpolate({\n                    inputRange: [-1, 0, 1, 2, 3],\n                    outputRange: [\n                        -sizeRef * 0.5,\n                        0,\n                        -sizeRef, // centered\n                        -sizeRef * 2, // centered\n                        -sizeRef * 3 // centered\n                    ],\n                    extrapolate: 'clamp'\n                })\n            }]\n        };\n    }\n\n    render () {\n        return (\n            <Carousel\n              // other props\n              scrollInterpolator={this._scrollInterpolator}\n              slideInterpolatedStyle={this._animatedStyles}\n              useScrollView={true}\n            />\n        );\n    }\n}\n```\n\nHere is the result, which you can try live in [the provided example](https://github.com/meliorence/react-native-snap-carousel/tree/master/example):\n\n![react-native-snap-carousel custom layout](https://i.imgur.com/slnTbyG.gif)\n\n:pill: Now for the bad news: **as is, this example won't be properly rendered on Android**. Continue reading to find out why and to discover ways to make it work.\n\n## Caveats\n\n### Android\n\nIf you have any kind of experience with React Native, you already know that Android is always there to punch you in the face when you make the mistake of thinking that everything is fine.\n\nThe issue here is pretty simple but very sad: [Android doesn't honor the `zIndex` property for `ScrollView`'s items](https://github.com/facebook/react-native/issues/16878). In concrete terms, this means that all items **after** the current active one will visually sit on top of it. Usually, you won't want that to happen.\n\nFor most layouts, you will probably use the following trick to render the active item on top of the next ones (as seen in the 'stack' layout, the 'tinder' layout, the step-by-step example, and more):\n\n```javascript\n{ zIndex: carouselProps.data.length - index }\n```\n\nWell, do not bother doing so on Android since it just won't work... As far as we know, you have three ways of dealing with this matter:\n- **Use Android-specific prop `elevation`** -> `{ elevation: carouselProps.data.length - index }`. While this will work from a visual point of view, it has two major drawbacks: you will generate shadows (which you can \"cut\" with a container) and, more importantly, it has no effect over the rendering hierarchy. This means that **the item receving the tap event is not going to be the active one**. Pretty bothersome, right? Still, if you don't provide user interaction, this solution can be enough.\n- **Invert the effect**. This is what has been done for the built-in layouts. Since the active item will always sits on top of the previous one on Android, background cards are made of the previous items instead of the next ones.\n- **Use `FlatList`'s prop `inverted` with a reverse data set**. This provides the perfect transition to our second main problem...\n\n\n### The `FlatList` component\n\n`FlatList` is buggy as hell, period.\n\nWith custom interpolations, what you're most likely to experience is... nothing! Your incredible animations are not going to be played because the next and previous items are going to show up too late to the party.\n\nTwo solutions:\n- **Play with the following `FlatList` props** until you find something that suits your needs (or not): `initialNumToRender`, `maxToRenderPerBatch`, `windowSize` and `updateCellsBatchingPeriod`.\n- **Set `useScrollView` to `true` and/or `removeClippedSubviews` to `false`**. End of the bugs. :warning: This is a trade-off: you will have to forget about the performance optimizations that *are supposed* to come with `FlatList`, but your sanity will be preserved. We've chosen this solution for the 'stack' and 'tinder' layouts. **Bear in mind that this solution is not suited for large data sets.**\n\n### Others\n\nWe use the native driver to ensure smooth animations and prevent performance issues. As stated [in RN doc](https://facebook.github.io/react-native/docs/animations.html#caveats): *\"Not everything you can do with Animated is currently supported by the native driver. The main limitation is that **you can only animate non-layout properties: things like `transform` and `opacity` will work, but flexbox and position properties will not**.\"*.\n\n## What's next?\n\nWe hope that you find this feature as awesome and useful as we are. Now go create awesome animations!\n\nWe only ask for one thing in return: **please share with us your most interesting interpolations!**"
  },
  {
    "path": "doc/KNOWN_ISSUES.md",
    "content": "# Known issues\n\n## Table of contents\n\n1. [`FlatList` and `ScrollView`'s limitations](#flatlist-and-scrollviews-limitations)\n1. [React Native version](#react-native-version)\n1. [Android performance](#android-performance)\n1. [Unreliable callbacks](#unreliable-callbacks)\n1. [Unreliable first item](#unreliable-first-item)\n1. [Error with Jest](#error-with-jest)\n1. [RTL support (experimental)](#rtl-support-experimental)\n1. [Carousel is not visible until you start swiping](#carousel-initially-not-visible)\n\n## `FlatList` and `ScrollView`'s limitations\n\nNote that this plugin is built on top of React Native's `FlatList` which, in turn, is based on `VirtualizedList` and `ScrollView`. Unfortunately, their implementations have flaws that affect the plugin, the most problematic ones being the following:\n- there is no `scrollEnd` event\n- `scrollTo` method doesn't accept any callback\n- Android's `scrollTo` animation is quite brutal\n- it is not possible to specify a scroll duration\n- there are rendering and performance issues with the `FlatList` component.\n\nOn top of that, `FlatList` has [its own set of bugs and buggy behaviors](https://github.com/facebook/react-native/issues?utf8=%E2%9C%93&q=flatlist).\n\nWe're trying to work around these issues, but the result is not always as smooth as we'd want it to be. **You can help by letting the React Native team know how badly we need those features!** React Native has [a dedicated canny](https://react-native.canny.io/feature-requests) for feature requests; here are the ones that need your vote the most:\n- [[ScrollView] Add completion callback to scrollTo](https://react-native.canny.io/feature-requests/p/scrollview-add-completion-callback-to-scrollto)\n- [snapToInterval for Android](https://react-native.canny.io/feature-requests/p/snaptointerval-for-android)\n- [Add speed attribute to scrollTo](https://react-native.canny.io/feature-requests/p/add-speed-attribute-to-scrollto)\n- [Bring ios only methods to Android ScrollView](https://react-native.canny.io/feature-requests/p/bring-ios-only-methods-to-android-scrollview)\n- [ScrollView Animation Events (e.g. onScrollAnimationEnd)](https://react-native.canny.io/feature-requests/p/scrollview-animation-events-eg-onscrollanimationend)\n\nRemember that every vote counts and take a look at [#203](https://github.com/meliorence/react-native-snap-carousel/issues/203) for more info!\n\n## React Native version\n\n:warning: **RN 0.43.x is the minimum recommended version for plugin releases `>= 3.0.0` since it was the first version to introduce the `FlatList` component.** Since version `3.5.0`, the component will fall back to rendering a `ScrollView` if you're using an older version of React Native (mirroring the effect of setting prop `useScrollView` to `true`). **But keep in mind that the `ScrollView` component is not suited to render a huge number of items.** If you experience performance issues, consider updating your React Native version and using the default `FlatList` version.\n\nBear in mind that we follow RN evolutions closely, which means newer versions of the plugin might break when used in conjunction with a version of RN that is not the latest stable one.\n\n## Android performance\n\n:warning: **Make sure to test carousel's performance and behavior without JS Dev Mode enabled, ideally with a production build.**.\n\nIt can take user experience from \"crappy and sluggish\" to \"pretty good\" - it's Android though, so nothing like \"perfect\" or \"incredibly smooth\"...\n\nAlso, make sure to implement all the recommendations listed [here](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/TIPS_AND_TRICKS.md#optimizing-performance).\n\n## Unreliable callbacks\n\nWhen `enableMomentum` is disabled (default behavior), providing a reliable callback is really tricky since no `scrollEnd` event has been exposed yet for the `ScrollView` component. We can only rely on the `scrollEndDrag` event, which comes with a huge bunch of issues. See [#34](https://github.com/meliorence/react-native-snap-carousel/issues/34) for more information.\n\nVersion 2.3.0 tackled these issues with all sorts of flags and hacks. But you could still be facing the following one: **when you build a debug version of your app without enabling JS remote debugging, timers may desynchronize and cause a complete callback mess**. Try to either enable remote debugging or build a production version of your app, and everything should get back to normal.\n\nCallback handling has been completely revamped in version 3.2.0, in a less hacky and more reliable way. There is one issue though: callbacks now rely on scroll events. Usually, this is not a problem since the plugin features a native-powered scroll. **But there has been [a regression in React Native 0.46.x](https://github.com/facebook/react-native/issues/15769), that has been fixed in version 0.48.2.**\n\nIf you're using an in-between version, you're in for some trouble since events won't be fired frequently enough (particularly on Android). **We've added a prop `callbackOffsetMargin` to help with this situation.**\n\n## Unreliable first item\n\nBy design, **the `FlatList` component only renders a small chunk if items initially**.\n\nThis means **you may need to rely on inherited props [`getItemLayout`](https://facebook.github.io/react-native/docs/flatlist#getitemlayout) & [`initialScrollIndex`](https://facebook.github.io/react-native/docs/flatlist#initialscrollindex) to get the `firstItem` prop to work properly** (usable from version `3.8.3` on).\n\n## Error with Jest\n\nYou might encounter the following error when using the plugin in conjonction with Jest: `TypeError: Cannot read property 'style' of undefined at Object.<anonymous>`.\n\nAs you can see [here](https://github.com/facebook/react-native/blob/master/jest/setup.js), this is because React Native mocks `ScrollView` for you when you write unit tests with Jest.\n\nThe easiest workaround is to add `jest.unmock('ScrollView')` before importing the component in your test file (thanks [@hoangnm](https://github.com/hoangnm) for the tip!).\n\n## RTL support (experimental)\n\nSince version 2.1.0, the plugin is compatible with RTL layouts. Our implementation relies on miscellaneous hacks that work around a [React Native bug](https://github.com/facebook/react-native/issues/11960) with horizontal `ScrollView`. As such, this feature should be considered experimental since it might break with newer versions of React Native.\n\nNote that you may want to reverse the order of your data array for your items to be displayed in the proper RTL order. We've tried implementing it internally, but this led to numerous and unnecessary issues. You'll just have to do something as simple as `myCustomData.reverse()`.\n\n## Carousel is not visible until you start swiping\n\nThere's a known issue where the Carousel will not be visible on the screen and will only show up after you start swiping. [This issue has been reported a few times](https://github.com/meliorence/react-native-snap-carousel/issues/238#issuecomment-354536859) and is caused by a [known React Native bug in the FlatList component](https://github.com/facebook/react-native/issues/1831). \n\nIt may be solved using one these three possible workarounds:\n\n- [Adding removeClippedSubviews={false} to the Carousel element](https://github.com/meliorence/react-native-snap-carousel/issues/238#issuecomment-354528113): Note that this will disable all optimizations from the FlatList Component.\n- [Adding useScrollView to the Carousel element](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md): Similar solution to the one provided above. Replaces FlatList component with ScrollView, only recommended for small sets of data.\n- [As of version 3.5.0, you may use the triggerRenderingHack() method](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#available-methods): This hacky solution was specifically implemented for this bug, allowing you to keep the FlatList component). [Note: This is recommended if you need the performance optimizations that FlatList provides).\n\n\n\n"
  },
  {
    "path": "doc/PAGINATION.md",
    "content": "# `<Pagination />` component\n\nStarting with version `2.4.0`, a customizable `<Pagination />` component has been added. This is how it looks like with its default configuration:\n\n![react-native-snap-carousel pagination](https://i.imgur.com/FLQcGGL.gif)\n\n## Table of contents\n\n1. [Props](#props)\n1. [Note on dots' colors](#note-on-dots-colors)\n1. [Usage](#usage)\n\n## Props\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n**`activeDotIndex`** | Index of the currently active dot | Number | **Required**\n**`dotsLength`** | Number of dots to display | Number | **Required**\n`activeOpacity` | Opacity of the dot when tapped. The prop has no effect if `tappableDots` hasn't been set to `true`. | Number | 1\n`carouselRef` | Reference to the `Carousel` component to which pagination is linked. Needed only when setting `tappableDots` to `true`. | Object | `undefined`\n`containerStyle` | Style for dots' container that will be merged with the default one | View Style Object | `{}`\n`dotColor` | Background color of the active dot. **Use this if you want to animate the change between active and inactive colors**, and always in conjunction with `inactiveDotColor` (see [notes](#dots-colors)). | String | `undefined`\n`dotContainerStyle` | Style of each dot's container. Use this if you need to specify styles that wouldn't have any effect when defined with `dotStyle` (such as `flex`). | View Style Object | `{}`\n`dotElement` | Optional custom active dot element that will replace the default one. The element will receive a prop `active` set to `true` as well as a prop `index`. | React element | `undefined`\n`dotStyle` | Dots' style that will be merged with the default one | View Style Object | `{}`\n`inactiveDotColor` | Background color of the inactive dots. **Use this if you want to animate the change between active and inactive colors**, and always in conjunction with `dotColor` (see [notes](#dots-colors)). | String | `undefined`\n`inactiveDotElement` | Optional custom inactive dot element that will replace the default one. The element will receive a prop `active` set to `false` as well as a prop `index` | React element | `undefined`\n`inactiveDotOpacity` | Value of the opacity effect applied to inactive dots | Number | `0.5`\n`inactiveDotScale` | Value of the 'scale' transform applied to inactive dots | Number | `0.5`\n`inactiveDotStyle` | Dots' style that will be applied to inactive elements | View Style Object | `{}`\n`renderDots` | Function that gives you complete control over pagination's rendering. It will receive three parameters : `(activeIndex, total, context)`. This can be especially useful in order to replace dots with numbers. **:warning: You will need to provide your own logic to handle taps. See [this comment](https://github.com/meliorence/react-native-snap-carousel/issues/273#issuecomment-368295203) for more info.** | Function | `undefined`\n`tappableDots` | Make default dots tappable, e.g. your carousel will slide to the corresponding item. Note that `carouselRef` must be specified for this to work. | Boolean | `false`\n`vertical` | Whether to layout dots vertically or horizontally | Boolean | `false`\n`animatedDuration` | Length of dot animation (milliseconds) | Number | `250`\n`animatedFriction` | Controls \"bounciness\"/overshoot on dot animation | Number | `4`\n`animatedTension` | Controls speed dot animation | Number | `50`\n`delayPressInDot` | Delay in ms, from the start of the touch, before onPressIn is called on dot | Number | `0`\n\n## Note on dots' colors\nIf your active and inactive dots aren't of the same color, you have a choice to make:\n1. either animate the color transition by specifying both `dotColor` and `inactiveDotColor`\n1. or setting `{ backgroundColor }` in both `dotStyle` and `inactiveDotStyle`.\n\n**When animating the color transition, the dot component will no longer be able to use the native driver for scale and opacity transitions.** As stated in [React Native's doc](https://facebook.github.io/react-native/docs/animations.html#caveats), color animations aren't supported by the native driver. And, unfortunately, it doesn't seem currently possible to run native-powered and js-powered animations at the same time on the same element.\n\nBasically, this is a tradeoff between color transition and optimal smoothness. We recommended you to try the first version and, if you experiment performance drops, to settle for the second one.\n\n## Usage\n\nSince `<Pagination />` is, purposely, a separated component, you need to connect it to your `<Carousel />` component manually. This is pretty straightforward, but here is an example to get you started.\n\n```javascript\nimport Carousel, { Pagination } from 'react-native-snap-carousel';\n\nexport default class MyCarousel extends Component {\n\n    _renderItem ({item, index}) {\n        return <MySlideComponent data={item} />\n    }\n\n    get pagination () {\n        const { entries, activeSlide } = this.state;\n        return (\n            <Pagination\n              dotsLength={entries.length}\n              activeDotIndex={activeSlide}\n              containerStyle={{ backgroundColor: 'rgba(0, 0, 0, 0.75)' }}\n              dotStyle={{\n                  width: 10,\n                  height: 10,\n                  borderRadius: 5,\n                  marginHorizontal: 8,\n                  backgroundColor: 'rgba(255, 255, 255, 0.92)'\n              }}\n              inactiveDotStyle={{\n                  // Define styles for inactive dots here\n              }}\n              inactiveDotOpacity={0.4}\n              inactiveDotScale={0.6}\n            />\n        );\n    }\n\n    render () {\n        return (\n            <View>\n                <Carousel\n                  data={this.state.entries}\n                  renderItem={this._renderItem}\n                  onSnapToItem={(index) => this.setState({ activeSlide: index }) }\n                />\n                { this.pagination }\n            </View>\n        );\n    }\n```\n"
  },
  {
    "path": "doc/PARALLAX_IMAGE.md",
    "content": "# `<ParallaxImage />` component\n\nVersion `3.0.0` introduced a `<ParallaxImage />` component, an image component aware of carousel's current scroll position and therefore able to display a nice parallax effect (powered by the native driver to ensure top-notch performance).\n\n![react-native-snap-carousel parallax image](https://i.imgur.com/6iIb4SR.gif)\n\n## Props\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n`containerStyle` | Optional style for image's container | View Style Object | `{}`\n`dimensions` | Optional on-screen dimensions of the image, as measured with [native methods](https://facebook.github.io/react-native/docs/direct-manipulation.html#other-native-methods). This allows for a bit of optimization, but it's sometimes tricky to get these in responsive layouts. | `{ width: number, height: number }` | `undefined`\n`fadeDuration` | Duration of the fade-in effect when image is loaded | Number | `500`\n`parallaxFactor` | Speed of the parallax effect. Be aware that the bigger the value, the more image will appear \"zoomed in\". | Number | `0.3`\n`showSpinner` | Whether to display a spinner while image is loading or not | Boolean | `true`\n`spinnerColor` | Color of the spinner | String | 'rgba(0, 0, 0, 0.4)'\n`AnimatedImageComponent` | Custom animated image component | Function Object | `Animated.Image`\n\nAll [`<Image />` props](https://facebook.github.io/react-native/docs/image.html#props) are also inherited, **particularly `source` which is required**.\n\n## Usage\n\nThe first thing you need to do is to **set `hasParallaxImages` to `true` for your `<Carousel />`**. This will make a new argument available in your `renderItem()` function, which must then be passed to the `<ParallaxImage />`.\n\nHere is an example that shows how to connect images to your carousel (note the `parallaxProps` argument).\n\n```javascript\nimport Carousel, { ParallaxImage } from 'react-native-snap-carousel';\nimport { Dimensions, StyleSheet } from 'react-native';\n\nconst { width: screenWidth } = Dimensions.get('window')\n\nexport default class MyCarousel extends Component {\n\n    _renderItem ({item, index}, parallaxProps) {\n        return (\n            <View style={styles.item}>\n                <ParallaxImage\n                    source={{ uri: item.thumbnail }}\n                    containerStyle={styles.imageContainer}\n                    style={styles.image}\n                    parallaxFactor={0.4}\n                    {...parallaxProps}\n                />\n                <Text style={styles.title} numberOfLines={2}>\n                    { item.title }\n                </Text>\n            </View>\n        );\n    }\n\n    render () {\n        return (\n            <Carousel\n                sliderWidth={screenWidth}\n                sliderHeight={screenWidth}\n                itemWidth={screenWidth - 60}\n                data={this.state.entries}\n                renderItem={this._renderItem}\n                hasParallaxImages={true}\n            />\n        );\n    }\n}\n\nconst styles = StyleSheet.create({\n  item: {\n    width: screenWidth - 60,\n    height: screenWidth - 60,\n  },\n  imageContainer: {\n    flex: 1,\n    marginBottom: Platform.select({ ios: 0, android: 1 }), // Prevent a random Android rendering issue\n    backgroundColor: 'white',\n    borderRadius: 8,\n  },\n  image: {\n    ...StyleSheet.absoluteFillObject,\n    resizeMode: 'cover',\n  },\n})\n```\n\n## Example to use with React Hooks\n\n```javascript\nimport React, {useRef, useState, useEffect} from 'react';\nimport Carousel, {ParallaxImage} from 'react-native-snap-carousel';\nimport {\n  View,\n  Text,\n  Dimensions,\n  StyleSheet,\n  TouchableOpacity,\n  Platform,\n} from 'react-native';\n\nconst ENTRIES1 = [\n  {\n    title: 'Beautiful and dramatic Antelope Canyon',\n    subtitle: 'Lorem ipsum dolor sit amet et nuncat mergitur',\n    illustration: 'https://i.imgur.com/UYiroysl.jpg',\n  },\n  {\n    title: 'Earlier this morning, NYC',\n    subtitle: 'Lorem ipsum dolor sit amet',\n    illustration: 'https://i.imgur.com/UPrs1EWl.jpg',\n  },\n  {\n    title: 'White Pocket Sunset',\n    subtitle: 'Lorem ipsum dolor sit amet et nuncat ',\n    illustration: 'https://i.imgur.com/MABUbpDl.jpg',\n  },\n  {\n    title: 'Acrocorinth, Greece',\n    subtitle: 'Lorem ipsum dolor sit amet et nuncat mergitur',\n    illustration: 'https://i.imgur.com/KZsmUi2l.jpg',\n  },\n  {\n    title: 'The lone tree, majestic landscape of New Zealand',\n    subtitle: 'Lorem ipsum dolor sit amet',\n    illustration: 'https://i.imgur.com/2nCt3Sbl.jpg',\n  },\n];\nconst {width: screenWidth} = Dimensions.get('window');\n\nconst MyCarousel = props => {\n  const [entries, setEntries] = useState([]);\n  const carouselRef = useRef(null);\n\n  const goForward = () => {\n    carouselRef.current.snapToNext();\n  };\n\n  useEffect(() => {\n    setEntries(ENTRIES1);\n  }, []);\n\n  const renderItem = ({item, index}, parallaxProps) => {\n    return (\n      <View style={styles.item}>\n        <ParallaxImage\n          source={{uri: item.illustration}}\n          containerStyle={styles.imageContainer}\n          style={styles.image}\n          parallaxFactor={0.4}\n          {...parallaxProps}\n        />\n        <Text style={styles.title} numberOfLines={2}>\n          {item.title}\n        </Text>\n      </View>\n    );\n  };\n\n  return (\n    <View style={styles.container}>\n      <TouchableOpacity onPress={goForward}>\n        <Text>go to next slide</Text>\n      </TouchableOpacity>\n      <Carousel\n        ref={carouselRef}\n        sliderWidth={screenWidth}\n        sliderHeight={screenWidth}\n        itemWidth={screenWidth - 60}\n        data={entries}\n        renderItem={renderItem}\n        hasParallaxImages={true}\n      />\n    </View>\n  );\n};\n\nexport default MyCarousel;\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n  },\n  item: {\n    width: screenWidth - 60,\n    height: screenWidth - 60,\n  },\n  imageContainer: {\n    flex: 1,\n    marginBottom: Platform.select({ios: 0, android: 1}), // Prevent a random Android rendering issue\n    backgroundColor: 'white',\n    borderRadius: 8,\n  },\n  image: {\n    ...StyleSheet.absoluteFillObject,\n    resizeMode: 'cover',\n  },\n});\n\n```\n"
  },
  {
    "path": "doc/PROPS_METHODS_AND_GETTERS.md",
    "content": "# Props, methods and getters\n\n## Table of contents\n\n1. [Props](#props)\n    * [Required](#required)\n    * [Behavior](#behavior)\n    * [Loop](#loop)\n    * [Autoplay](#autoplay)\n    * [Style and animation](#style-and-animation)\n    * [Callbacks](#callbacks)\n    * [Inherited props](#inherited-props)\n1. [Methods](#methods)\n1. [Getters](#getters)\n\n## Props\n\n### Required\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n**`data`** | Array of items to loop on | Array | **Required**\n**`renderItem`** | Takes an item from data and renders it into the list. The function receives one argument `{item, index}` (see [Usage](https://github.com/meliorence/react-native-snap-carousel#usage)) and must return a React element. | Function | **Required**\n**`itemWidth`** | Width in pixels of carousel's items, **must be the same for all of them** | Number | **Required for __horizontal__ carousel**\n**`sliderWidth`** | Width in pixels of the carousel itself | Number | **Required for __horizontal__ carousel**\n**`itemHeight`** | Height in pixels of carousel's items, **must be the same for all of them** | Number | **Required for __vertical__ carousel**\n**`sliderHeight`** | Height in pixels of the carousel itself | Number | **Required for __vertical__ carousel**\n\n### Behavior\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n`activeSlideOffset` | From slider's center, minimum slide distance to be scrolled before being set to active. | Number | `20`\n`apparitionDelay` | `FlatList`'s init is a real mess, with lots of unneeded flickers and slides movement. This prop controls the delay during which the carousel will be hidden when mounted. **WARNING: on Android, using it may lead to [rendering issues](https://github.com/meliorence/react-native-snap-carousel/issues/236) (i.e. images not showing up)**. Make sure to test thoroughly if you decide on using it. | Number | `0`\n`callbackOffsetMargin` | Scroll events might not be triggered often enough to get a precise measure and, therefore, to provide a reliable callback. This usually is an Android issue, which might be linked to the version of React Native you're using (see [\"Unreliable callbacks\"](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/KNOWN_ISSUES.md#unreliable-callbacks)). To work around this, you can define a small margin that will increase the \"sweet spot\"'s width. The default value should cover most cases, but **you will want to increase it if you experience missed callbacks**. | Number | `5`\n`enableMomentum` | See [momentum](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/TIPS_AND_TRICKS.md#momentum) | Boolean | `false`\n`enableSnap` | If enabled, releasing the touch will scroll to the center of the nearest/active item | Boolean | `true`\n`firstItem` | Index of the first item to display. :warning: **Make sure to use inherited props [`getItemLayout`](https://facebook.github.io/react-native/docs/flatlist#getitemlayout) & [`initialScrollIndex`](https://facebook.github.io/react-native/docs/flatlist#initialscrollindex) if the prop doesn't seem to work**. | Number | `0`\n`hasParallaxImages` | Whether the carousel contains `<ParallaxImage />` components or not. Required for specific data to be passed to children. | Boolean | `false`\n`lockScrollTimeoutDuration` | This prop works in conjunction with `lockScrollWhileSnapping`. When scroll is locked, a timer is created in order to release the scroll if something goes wrong with the regular callback handling. **Normally, you shouldn't have to use this prop.** | Number | `1000`\n`lockScrollWhileSnapping` | Prevent the user from swiping again while the carousel is snapping to a position. This prevents miscellaneous minor issues (inadvertently tapping an item while scrolling, stopping the scrolling animation if the carousel is tapped in the middle of a snap, clunky behavior on Android when short snapping quickly in opposite directions). The only drawback is that enabling the prop hinders the ability to swipe quickly between items as a little pause between swipes is needed. **Note that the prop won't have any effect if `enableMomentum` is set to `true`, since it would otherwise impede the natural and expected behavior.** | Boolean | `false`\n`scrollEnabled` | When `false`, the view cannot be scrolled via touch interaction ([inherited prop](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md#inherited-props)) | Boolean | `true`\n`shouldOptimizeUpdates` | Whether to implement a `shouldComponentUpdate` strategy to minimize updates | Boolean | `true`\n`swipeThreshold` | Delta x when swiping to trigger the snap | Number | `20`\n`useScrollView` | Whether to use a `ScrollView` component instead of the default `FlatList` one. The advantages are to avoid rendering issues that can arise with `FlatList` and to provide compatibility with React Native pre- `0.43`. The major drawbacks are that you won't benefit from any of `FlatList`'s advanced optimizations and that you won't be able to use either `VirtualizedList` or `FlatList`'s specific props. **We recommend activating it only with a small set of slides and to test performance thoroughly in production mode.** Since version `3.7.6`, this prop also accepts a custom scroll component (see #498 for more info). | Boolean | `false` for `default` layout, `true` for `stack` and `tinder` layouts\n`vertical` | Layout slides vertically instead of horizontally | Boolean | `false`\n\n### Loop\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n`loop` | Enable infinite loop mode. **:warning: It won't work if `enableSnap` has been set to `false`.** | Boolean | `false`\n`loopClonesPerSide` | Number of clones to append to each side of the original items. **When swiping very quickly**, the user will eventually need to pause for a quick second before the scroll is repositioned (this occurs when the end of the set is reached). By increasing this number, the user will be able to scroll more slides before having to stop; but you'll also load more items in memory. This is a trade-off between optimal user experience and performance. | Number | `3`\n\n### Autoplay\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n`autoplay` | Trigger autoplay on mount. If you enable autoplay, we recommend you to set `enableMomentum` to `false` (default) and `lockScrollWhileSnapping` to `true`; this will enhance user experience a bit. | Boolean | `false`\n`autoplayDelay` | Delay before enabling autoplay on startup & after releasing the touch | Number | `1000`\n`autoplayInterval` | Delay in ms until navigating to the next item | Number |  `3000`\n\n### Style and animation\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n`activeAnimationOptions` | Custom animation options. Note that `useNativeDriver` will be enabled by default and that opacity's easing will always be kept linear. **Setting this prop to something other than `null` will trigger custom animations and will completely change the way items are animated**: rather than having their opacity and scale interpolated based the scroll value (default behavior), they will now play the custom animation you provide as soon as they become active. **This means you cannot use props `layout`, `scrollInterpolator` or `slideInterpolatedStyle` in conjunction with `activeAnimationOptions`.** | Object | `null`\n`activeAnimationType` | Custom [animation type](https://facebook.github.io/react-native/docs/animated.html#configuring-animations): either `'decay`, `'spring'` or `'timing'`. Note that it will only be applied to the scale animation since opacity's animation type will always be set to `timing` (no one wants the opacity to 'bounce' around). | String | `'timing'`\n`activeSlideAlignment` | Determine active slide's alignment relative to the carousel. Possible values are: `'start'`, `'center'` and `'end'`. **It is not recommended to use this prop in conjunction with the `layout` one.** | String | `'center'`\n`containerCustomStyle` | Optional styles for Scrollview's global wrapper | View Style Object | `{}`\n`contentContainerCustomStyle` | Optional styles for Scrollview's items container | View Style Object | `{}`\n`inactiveSlideOpacity` | Value of the opacity effect applied to inactive slides | Number | `0.7`\n`inactiveSlideScale` | Value of the 'scale' transform applied to inactive slides | Number | `0.9`\n`inactiveSlideShift` | Value of the 'translate' transform applied to inactive slides (see [#204](https://github.com/meliorence/react-native-snap-carousel/issues/204) or [the \"custom interpolations\" doc](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/CUSTOM_INTERPOLATIONS.md) for an example usage). This prop will have no effect with layouts others than the default one. | Number | `0`\n`layout` | Define the way items are rendered and animated. Possible values are `'default'`, `'stack'` and `'tinder'`. See [this](https://github.com/meliorence/react-native-snap-carousel#layouts-and-custom-interpolations) for more info and visual examples. :warning: **Setting this prop to either `'stack'` or `'tinder'` will activate `useScrollView` [to prevent rendering bugs with `FlatList`](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/CUSTOM_INTERPOLATIONS.md#caveats). Therefore, those layouts won't be suited if you have a large data set since all items are going to be rendered upfront.** | String | `'default'`\n`layoutCardOffset` | Use to increase or decrease the default card offset in both 'stack' and 'tinder' layouts. | Number | `18` for the 'stack' layout, `9` for the 'tinder' one\n`scrollInterpolator` | Used to define custom interpolations. See [the dedicated doc](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/CUSTOM_INTERPOLATIONS.md#summary). | Function | `undefined`\n`slideInterpolatedStyle` | Used to define custom interpolations. See [the dedicated doc](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/CUSTOM_INTERPOLATIONS.md#summary). | Function | `undefined`\n`slideStyle` | Optional style for each item's container (the one whose scale and opacity are animated) | Animated View Style Object | `{}`\n\n### Callbacks\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n`onLayout(event)` | Exposed `View` callback; invoked on mount and layout changes | Function | `undefined`\n`onScroll(event)` | Exposed `ScrollView` callback; fired while scrolling | Function | `undefined`\n`onBeforeSnapToItem(slideIndex)` | Callback fired when the new active item has been determined, before snapping to it | Function | `undefined`\n`onSnapToItem(slideIndex)` | Callback fired after snapping to an item | Function | `undefined`\n\n### Inherited props\n\nThe component is built on top of the `FlatList` component, meaning it inherits from [`FlatList`](https://facebook.github.io/react-native/docs/flatlist.html), [`VirtualizedList`](https://facebook.github.io/react-native/docs/virtualizedlist.html), and [`ScrollView`](https://facebook.github.io/react-native/docs/scrollview.html).\n\nYou can use almost all props from this three components, but some of them can't be overriden because it would mess with our implementation's logic.\n\nHere are a few useful props regarding carousel's **style and \"feeling\"**: `scrollEnabled` (if you want to disable user scrolling while still being able to use `Carousel`'s methods), `showsHorizontalScrollIndicator`, `overScrollMode` (android), `bounces` (ios), `decelerationRate` (ios), `scrollEventThrottle` (ios).\n\nAnd here are some useful ones for **performance optimizations and rendering**: `initialNumToRender`, `maxToRenderPerBatch`, `windowSize`, `updateCellsBatchingPeriod`, `extraData`, `removeClippedSubviews` (the latter may have bugs, as stated in [RN's doc](https://facebook.github.io/react-native/docs/flatlist.html#removeclippedsubviews)). The first three are already implemented with default parameters, but you can override them if they don't suit your needs.\n\n## Methods\n\n### Reference to the component\n\nIn order to use the following methods, you need to create a reference to the carousel's instance. There are two ways of doing it.\n\n#### ref as a callback attribute (**recommended**)\n```javascript\n<Carousel\n  // other props\n  ref={(c) => { this._carousel = c; }}\n/>\n\n// methods can then be called this way\nonPress={() => { this._carousel.snapToNext(); }}\n```\n\n#### ref as a string attribute ([legacy](http://stackoverflow.com/questions/37468913/why-ref-string-is-legacy))\n```javascript\n<Carousel\n  // other props\n  ref={'carousel'}\n/>\n\n// methods can then be called this way\nonPress={() => { this.refs.carousel.snapToNext(); }}\n```\n\n### Available methods\n\nMethod | Description\n------ | ------\n`startAutoplay (instantly = false)` | Start the autoplay programmatically\n`stopAutoplay ()` | Stop the autoplay programmatically\n`snapToItem (index, animated = true, fireCallback = true)` | Snap to an item programmatically\n`snapToNext (animated = true, fireCallback = true)` | Snap to next item programmatically\n`snapToPrev (animated = true, fireCallback = true)` | Snap to previous item programmatically\n`triggerRenderingHack (offset)` | Call this when needed to work around [a random `FlatList` bug](https://github.com/facebook/react-native/issues/1831) that keeps content hidden until the carousel is scrolled (see [#238](https://github.com/meliorence/react-native-snap-carousel/issues/238)). Note that the `offset` parameter is not required and will default to either `1` or `-1` depending on the current scroll position.\n\n## Getters\n\n> You need a reference to the carousel's instance (see [above](#reference-to-the-component) if needed).\n\nProperty | Description\n------ | ------\n`currentIndex` | Current active item (`int`, starts at 0)\n`currentScrollPosition` | Underlying `ScrollView`'s current content offset (`int`, starts at `0` if `activeSlideAlignment` is set to `start`, negative value otherwise)\n"
  },
  {
    "path": "doc/TIPS_AND_TRICKS.md",
    "content": "# Tips and tricks\n\n## Table of contents\n\n1. [Optimizing performance](#optimizing-performance)\n1. [Momentum](#momentum)\n1. [Margin between slides](#margin-between-slides)\n1. [Carousel's stretched height](#carousels-stretched-height)\n1. [Items' dynamic height](#items-dynamic-height)\n1. [Fullscreen slides](#fullscreen-slides)\n1. [Viewport wide slides / no preview effect](#viewport-wide-slides--no-preview-effect)\n1. [Handling device rotation](#handling-device-rotation)\n1. [Native-powered animations](#native-powered-animations)\n1. [Implementing navigation](#implementing-navigation)\n1. [Implementing zooming feature](#implementing-zooming-feature)\n1. [Using a specific commit](#using-a-specific-commit)\n1. [Useful threads](#useful-threads)\n1. [Understanding styles](#understanding-styles)\n1. [Migration from version 2.x](#migration-from-version-2x)\n\n## Optimizing performance\n\nHere are a few good practices to keep in mind when dealing with the component (or any React Native list for that matter):\n\n* **Implement `shouldComponentUpdate`** (see [the `shallowCompare` addon](https://www.npmjs.com/package/react-addons-shallow-compare`)) for every carousel children (in `renderItem()`) or **make it a `PureComponent`** (some users report that `shouldComponentUpdate` is faster, but you should try both and decide for yourself).\n* Make sure the carousel **isn't a child of a `ScrollView`** (this includes `FlatList`, `VirtualizedList` and many plugins). Apparently, it would render all child components, even those currently off-screen.\n* If your data set is huge, **consider loading additional chunks of data only when the user has reached the end of the current set**. In order to do this, you'll have to play with `VirtualizedList`'s props `onEndReached` and `onEndReachedThreshold`\n* **Add [prop `removeClippedSubviews`](https://facebook.github.io/react-native/docs/scrollview.html#removeclippedsubviews)** and set it to `true` so that out-of-view items are removed from memory.\n\nHere are a few other tips given by [@pcooney10](https://github.com/pcooney10) in [this thread](https://github.com/meliorence/react-native-snap-carousel/issues/247#issuecomment-360276562):\n\n- Make sure there aren't any excessive calls to `this.setState` in the component that renders the carousels and their parents.\n- Properly leverage the `initialNumToRender` and `maxToRenderPerBatch` props inherited from `FlatList`, and `windowSize` inherited from `VirtualizedList`.\n- Utilize [`InteractionManager`](https://facebook.github.io/react-native/docs/interactionmanager.html) to render the Carousels that are \"below the fold\".\n- Avoid using functions and object literals for props declared on components - this apparently results in \"new props\" during a re-render.\n\nLastly, make sure to read [this note](https://github.com/meliorence/react-native-snap-carousel#important-note-regarding-android) regarding Android and [this one](https://github.com/meliorence/react-native-snap-carousel#important-note-regarding-ios) regarding iOS.\n\n## Momentum\n\nSince version `1.5.0`, the snapping effect can be based on momentum (by setting `enableMomentum` to `true`) instead of when you're releasing your finger. It means that the component will wait until the `ScrollView` isn't moving anymore to snap.\n\nBy default, the inertia isn't too high on Android. However, we had to tweak the default iOS value a bit to make sure the snapping isn't delayed for too long. You can adjust this value to your needs thanks to [this prop](https://facebook.github.io/react-native/docs/scrollview.html#decelerationrate).\n\nIf momentum is disabled (default behavior), make sure to play with prop `scrollEndDragDebounceValue` since it can help achieving a better snap feeling.\n\n> **We recommend setting `enableMomentum` to `false` (default) and `decelerationRate` to `'fast'` when you are displaying only one main slide** (as in the showcase above), and to use `true` and `0.9` otherwise.\n\n## Margin between slides\nIf you need some **extra horizontal margin** between slides (besides the one resulting from the scale effect), you should add it as `paddingHorizontal` on slide's container.\n\n:warning: **The value of `itemWidth` must include this extra margin.**\n\n```javascript\nconst horizontalMargin = 20;\nconst slideWidth = 280;\n\nconst sliderWidth = Dimensions.get('window').width;\nconst itemWidth = slideWidth + horizontalMargin * 2;\nconst itemHeight = 200;\n\nconst styles = StyleSheet.create({\n    slide: {\n        width: itemWidth,\n        height: itemHeight,\n        paddingHorizontal: horizontalMargin\n        // other styles for the item container\n    },\n    slideInnerContainer: {\n        width: slideWidth,\n        flex: 1\n        // other styles for the inner container\n    }\n};\n```\n```javascript\n    _renderItem ({item, index}) {\n        return (\n            <View style={styles.slide}>\n                <View style={styles.slideInnerContainer} />\n            </View>\n        );\n    }\n\n    render () {\n        return (\n            <Carousel\n              renderItem={this._renderItem}\n              sliderWidth={sliderWidth}\n              itemWidth={itemWidth}\n            />\n        );\n    }\n```\n\n## Carousel's stretched height\n\nSince `<Carousel />` is, ultimately, based on `<ScrollView />`, it inherits [its default styles](https://github.com/facebook/react-native/blob/c38f167019a3c481847d4abc80a458f7784f1336/Libraries/Components/ScrollView/ScrollView.js#L1153-L1169) and particularly `{ flexGrow: 1 }`. This means that, by default, **the carousel container will stretch to fill up all available space**.\n\nIf this is not what you're after, you can prevent this behavior by passing `{ flexGrow: 0 }` to prop `containerCustomStyle`.\n\nAlternatively, you can either use this prop to pass a custom height to the container, or wrap the carousel in a `<View />` with a fixed height.\n\n## Items' dynamic height\n\nIf you want your slides to have dynamic height (e.g. to fill up the entirety of the available space), you need to transfer `{ flex: 1 }` to all the relevant wrappers. Here is a minimal example:\n\n```javascript\n_renderItem ({item, index}) {\n    return (\n        <View style={{ flex: 1 }} />\n    );\n}\n\nrender () {\n    return (\n        <Carousel\n          data={this.state.data}\n          renderItem={this._renderItem}\n          containerCustomStyle={{ flex: 1 }}\n          slideStyle={{ flex: 1 }}\n        />\n    );\n}\n```\n\n## Fullscreen slides\n\nWhile the plugin hasn't been designed with this use case in mind, you can easily implement fullscreen slides. The following code can serve as a good starting point.\n\n```javascript\nconst { width: viewportWidth, height: viewportHeight } = Dimensions.get('window');\n\nexport class MyCarousel extends Component {\n\n    _renderItem ({item, index}) {\n        return (\n            <View style={{ height: viewportHeight }} /> // or { flex: 1 } for responsive height\n        );\n    }\n\n    render () {\n        return (\n            <Carousel\n              data={this.state.entries}\n              renderItem={this._renderItem}\n              sliderWidth={viewportWidth}\n              itemWidth={viewportWidth}\n              slideStyle={{ width: viewportWidth }}\n              inactiveSlideOpacity={1}\n              inactiveSlideScale={1}\n            />\n        );\n    }\n}\n```\n\n[This plugin](https://github.com/shichongrui/react-native-on-layout) can also prove useful.\n\n## Viewport wide slides / no preview effect\n\n**If you are using the plugin without the preview effect (meaning that your slides, as well as your slider, are viewport wide), we do not recommend using this plugin.**\n\nYou'll be better off with [`react-native-swiper`](https://github.com/leecade/react-native-swiper) for the simple reason that it implements the `ViewPagerAndroid` component, which provides a way better overall feeling on Android, whereas we must hack our way around [the frustrating limitations of the `ScrollView` component](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/KNOWN_ISSUES.md#flatlist-and-scrollviews-limitations).\n\n## Handling device rotation\n\nSince version 2.2.0, slides will re-center properly if you update slider and/or items' dimensions when `onLayout` is fired.\n\nHere is an example of a working implementation (thanks [@andrewpope](https://github.com/meliorence/react-native-snap-carousel/pull/76#issuecomment-306187425)):\n\n```\nconstructor(props) {\n    super(props);\n    this.state = {\n        viewport: {\n            width: Dimensions.get('window').width,\n            height: Dimensions.get('window').height\n        }\n    };\n}\n\nrender() {\n    return (\n        <View\n            onLayout={() => {\n                this.setState({\n                    viewport: {\n                        width: Dimensions.get('window').width,\n                        height: Dimensions.get('window').height\n                    }\n                });\n            }}\n        >\n            <Carousel\n                ref={c => { this.carousel = c; } }\n                sliderWidth={this.state.viewport.width}\n                itemWidth={this.state.viewport.width}\n                ...\n            />\n        </View>\n    );\n}\n```\n\n## Native-powered animations\n\nSlides' animations are based on scroll events and have been moved to the native thread in order to prevent the tiny lag associated with React Native's JavaScript bridge. This is really useful when displaying a `transform` and/or `opacity` animation that needs to follow carousel's scroll position closely. You can find more info in [this post from Facebook](https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html) or in [this one on Medium](https://medium.com/xebia/linking-animations-to-scroll-position-in-react-native-5c55995f5a6e).\n\n## Implementing navigation\n\nSome users had trouble implementing navigation with the carousel (see [#83](https://github.com/meliorence/react-native-snap-carousel/issues/83), [#146](https://github.com/meliorence/react-native-snap-carousel/issues/146) and [#212](https://github.com/meliorence/react-native-snap-carousel/issues/212)) because they weren't aware of methods' context.\n\n[jordangrant](https://github.com/jordangrant) was kind enough to share [a comprehensive walkthrough](https://github.com/meliorence/react-native-snap-carousel/issues/146#issuecomment-343933652) which is reproduced below. Kuddos to him!\n\nIn your Carousel:\n\n```\n<Carousel\n    data={image1}\n    renderItem={this._renderItem.bind(this)}   //<------\n    sliderWidth={equalWidth2}\n    itemWidth={equalWidth5}\n  />\n```\n\nAdding the bind allows the `_renderItem` function to understand what `this` is (in `this.props.navigation`).\n\nIn `_renderItem()`:\n\n```\n_renderItem ({item, index}) {\n        return (\n            <SliderEntry\n              data={item}\n              navigation={this.props.navigation}   //<-------\n            />\n        );\n    }\n```\n\nAnd inside `SliderEntry.js`:\n\n```\nexport default class SliderEntry extends Component {\n\n    static propTypes = {\n        data: PropTypes.object.isRequired,\n    };\n\n    render () {\n        const { data: { title, subtitle, illustration}, navigation } = this.props;    //<------\n\n        return (\n          <TouchableOpacity\n            activeOpacity={1}\n            style={styles.slideInnerContainer}\n            onPress={() => navigation.navigate('Feed')}  //<------- now you can use navigation\n          >\n    }\n}\n```\n\n## Implementing zooming feature\n\nSee https://github.com/meliorence/react-native-snap-carousel/issues/264#issuecomment-366473756\n\n## Using a specific commit\n\nThis plugin is regularly updated, and new versions are frequently pushed to `npm`. But you may want to use a specific commit, not yet merged or published.\n\nThis is pretty easy: in your `package.json` file, use the GitHub link instead of a version number, and point to the specific commit using `#`. For example, if the commit reference is `fbdb671`, you would write:\n```javascript\n\"react-native-snap-carousel\": \"https://github.com/meliorence/react-native-snap-carousel#fbdb671\"\n```\n\n## Useful threads\n\nSome issues stand above the others because a lot of useful information has been shared.\n\nIn order to make it easier for everyone to find them, they are [tagged with an asterisk](https://github.com/meliorence/react-native-snap-carousel/issues?q=is%3Aissue+label%3A%2A).\n\n## Understanding styles\n\nHere is a screenshot that should help you understand how each of the required variables is used.\n\n![react-native-snap-carousel info](https://i.imgur.com/PMi6aBd.jpg)\n\n## Migration from version 2.x\n\nSlides are no longer appended as direct children of the component since the plugin is now based on `FlatList` instead of `ScrollView`. There are two new props that takes care of their rendering: `data` and `renderItem` (both are inherited from `FlatList`).\n\n> :warning: **Make sure to read about [the recommended React Native version](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/KNOWN_ISSUES.md#react-native-version) before migrating.**\n\nIf you were already looping throught an array of data to populate the carousel, the migration is pretty straightforward. Just pass your slides' data to the `data` prop, convert your slides' getter to a function and pass it to the `renderItem` prop: you're good to go!\n\n**From**\n```javascript\n    get slides () {\n        return this.state.entries.map((entry, index) => {\n            return (\n                <View key={`entry-${index}`} style={styles.slide}>\n                    <Text style={styles.title}>{ entry.title }</Text>\n                </View>\n            );\n        });\n    }\n\n    render () {\n        return (\n            <Carousel\n              sliderWidth={sliderWidth}\n              itemWidth={itemWidth}\n            >\n                { this.slides }\n            </Carousel>\n        );\n    }\n```\n\n**To**\n```javascript\n    _renderItem ({item, index}) {\n        return (\n            <View style={styles.slide}>\n                <Text style={styles.title}>{ item.title }</Text>\n            </View>\n        );\n    }\n\n    render () {\n        return (\n            <Carousel\n              data={this.state.entries}\n              renderItem={this._renderItem}\n              sliderWidth={sliderWidth}\n              itemWidth={itemWidth}\n            />\n        );\n    }\n```\n\n> Note that the `key` prop is no longer needed for carousel's items. If you want to provide a custom key, you should pass your own [`keyExtractor`](https://facebook.github.io/react-native/docs/flatlist.html#keyextractor) to the `<Carousel />`.\n\nIf you were previously appending random types of children, you will need to rely on a specific bit of data to return the proper element from your `renderItem` function.\n\n**Example**\n```javascript\n    _renderItem ({item, index}) {\n        if (item.type === 'text') {\n            return <Text style={styles.textSlide} />;\n        } else if (item.type === 'image') {\n            return <Image style={styles.imageSlide} />;\n        } else {\n            return <View style={styles.viewSlide} />;\n        }\n    }\n```\n"
  },
  {
    "path": "doc/VERSION_4.md",
    "content": "# A shiny new version is on its way!\n\n![react-native-snap-carousel mind blown](https://i.imgur.com/gdaKtSm.gif)\n\n## 💡 Why?\n\nSo far, and because of [numerous React Native limitations](https://github.com/meliorence/react-native-snap-carousel/issues/203), the entire plugin has basically been based on a pile of hacks and workarounds...\n\nWith the most recent versions of React Native, a few interesting props have appeared and made me consider the possibility of finally rewriting the inner logic of the carousel.\n\nDon't get me wrong: we'll still have to rely on a few hacks to account for, well, Android particularly. But it was possible to get rid of most of them, and that is for the best!\n\n## ✨ Wonderful benefits\n\nMost of the heavy work is done, and here's what you can enjoy out-of-the-box:\n\n- **(Very) Smooth scrolling.** Put simply, this is night and day. Just try it for yourself and you'll see that there's just no going back!\n- **Reliable callback logic.**\n- **Optimized custom interpolations ('stack' and 'tinder' layouts for example) that can be used with a huge number of items.** Previously, you couldn't use those with a big data set as this would create performance issues. :warning: **This one is iOS-only for now** (but, given a few recent tests, we might find a way to make it work on Android).\n- **An experimental snap feature** that is promising but not yet complete (see below).\n\n## 📍 Next steps\n\nBefore making it widely available, **I now need your help** 🙌\n\nThe first thing you can do is test this new version and let me know how it works for you and you particular setup. For example, vertical carousels, pagination and parallax images haven't been tested yet — they are expected to work properly though.\n\n### How to test?\n\n- You can find the already published beta versions by running: `npm view react-native-snap-carousel versions --json`\n- [Follow this PR closely](https://github.com/meliorence/react-native-snap-carousel/pull/678). **This is where the discussion will take place.**\n- And if you like to live on the edge, [try the latest commits](https://stackoverflow.com/a/27630247/) of that same PR ;-)\n\n### 🦸‍♀️🦸‍♂️ Get your hands dirty!\n\nThen, **if you want to jump in**, I'd be glad if you could help me with the following:\n\n1. **Reducing the number of rerenders** (see [#478](https://github.com/meliorence/react-native-snap-carousel/issues/478)). [`why-did-you-render`](https://github.com/welldone-software/why-did-you-render) is going to prove really helpful for that.\n2. **Finding a way to make the experimental snap feature work even with the last items** (see \"New props\" below for more details on this feature).\n\nLet's finish that together and make sure this plugin remains absolutely awesome!\n\nCheers,\n[bd-arc](https://github.com/bd-arc)\n\n---\n\n## 📚 New, updated and removed props\n\n### New props\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n✅ **`useExperimentalSnap`** | By default, items will always be centered according to the `activeSlideAlignment` prop. A sometimes unwanted result of this is the addition of empty spaces at the end/beginning of the carousel. Since version 4, it is possible to use another centering option that will avoid white spaces. :warning: **If you set it to `true`, some items might not be \"reachable\" — i.e. for the last item(s), the snap callbacks won't be triggered and the animations won't be complete.** We recommend activate it only if you don't rely on `onSnapToItem` and if both `inactiveSlideScale` and `inactiveSlideOpacity` are set to `1`. A side benefit of activating it is **the ability to slide only one item at a time** when setting the inherited prop `disableIntervalMomentum` to `true`. | Boolean | `false`\n✅ **`onScrollIndexChanged(slideIndex)`** | Executed as soon as the active index changes during scroll (whereas `onSnapToItem` is executed only for the last active item). :warning: **Avoid doing heavy calculations or rendering here!** | Function | `undefined`\n\n### Updated props\n\nProp | Description | Type | Default\n------ | ------ | ------ | ------\n✅ **`renderItem({ item, index, dataIndex })`** | `renderItem()` now receives a **`dataIndex` param** that will represent the index based on your data set and not on the actual number of items — the two numbers won't match for looped carousels. This is useful if you need to pass to the item something based on your data rather than on the inner index. | Function | **Required**\n\n### Removed props\n\n- ❌ `activeAnimationOptions`\n- ❌ `activeAnimationType`\n- ❌ `enableMomentum`\n- ❌ `lockScrollTimeoutDuration`\n- ❌ `lockScrollWhileSnapping`\n- ❌ `onBeforeSnapToItem`\n- ❌ `swipeThreshold`"
  },
  {
    "path": "example/.buckconfig",
    "content": "\n[android]\n  target = Google Inc.:Google APIs:23\n\n[maven_repositories]\n  central = https://repo1.maven.org/maven2\n"
  },
  {
    "path": "example/.flowconfig",
    "content": "[ignore]\n; We fork some components by platform\n.*/*[.]android.js\n\n; Ignore \"BUCK\" generated dirs\n<PROJECT_ROOT>/\\.buckd/\n\n; Ignore polyfills\nnode_modules/react-native/Libraries/polyfills/.*\n\n; These should not be required directly\n; require from fbjs/lib instead: require('fbjs/lib/warning')\nnode_modules/warning/.*\n\n; Flow doesn't support platforms\n.*/Libraries/Utilities/LoadingView.js\n\n[untyped]\n.*/node_modules/@react-native-community/cli/.*/.*\n\n[include]\n\n[libs]\nnode_modules/react-native/Libraries/react-native/react-native-interface.js\nnode_modules/react-native/flow/\n\n[options]\nemoji=true\n\nesproposal.optional_chaining=enable\nesproposal.nullish_coalescing=enable\n\nmodule.file_ext=.js\nmodule.file_ext=.json\nmodule.file_ext=.ios.js\n\nmunge_underscores=true\n\nmodule.name_mapper='^react-native$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/react-native/react-native-implementation'\nmodule.name_mapper='^react-native/\\(.*\\)$' -> '<PROJECT_ROOT>/node_modules/react-native/\\1'\nmodule.name_mapper='^[./a-zA-Z0-9$_-]+\\.\\(bmp\\|gif\\|jpg\\|jpeg\\|png\\|psd\\|svg\\|webp\\|m4v\\|mov\\|mp4\\|mpeg\\|mpg\\|webm\\|aac\\|aiff\\|caf\\|m4a\\|mp3\\|wav\\|html\\|pdf\\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub'\n\nsuppress_type=$FlowIssue\nsuppress_type=$FlowFixMe\nsuppress_type=$FlowFixMeProps\nsuppress_type=$FlowFixMeState\n\nsuppress_comment=\\\\(.\\\\|\\n\\\\)*\\\\$FlowFixMe\\\\($\\\\|[^(]\\\\|(\\\\(<VERSION>\\\\)? *\\\\(site=[a-z,_]*react_native\\\\(_ios\\\\)?_\\\\(oss\\\\|fb\\\\)[a-z,_]*\\\\)?)\\\\)\nsuppress_comment=\\\\(.\\\\|\\n\\\\)*\\\\$FlowIssue\\\\((\\\\(<VERSION>\\\\)? *\\\\(site=[a-z,_]*react_native\\\\(_ios\\\\)?_\\\\(oss\\\\|fb\\\\)[a-z,_]*\\\\)?)\\\\)?:? #[0-9]+\nsuppress_comment=\\\\(.\\\\|\\n\\\\)*\\\\$FlowExpectedError\n\n[lints]\nsketchy-null-number=warn\nsketchy-null-mixed=warn\nsketchy-number=warn\nuntyped-type-import=warn\nnonstrict-import=warn\ndeprecated-type=warn\nunsafe-getters-setters=warn\ninexact-spread=warn\nunnecessary-invariant=warn\nsignature-verification-failure=warn\ndeprecated-utility=error\n\n[strict]\ndeprecated-type\nnonstrict-import\nsketchy-null\nunclear-type\nunsafe-getters-setters\nuntyped-import\nuntyped-type-import\n\n[version]\n^0.105.0\n"
  },
  {
    "path": "example/.gitattributes",
    "content": "*.pbxproj -text\n"
  },
  {
    "path": "example/.gitignore",
    "content": "# OSX\n#\n.DS_Store\n\n# Xcode\n#\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata\n*.xccheckout\n*.moved-aside\nDerivedData\n*.hmap\n*.ipa\n*.xcuserstate\n\n# Android/IntelliJ\n#\nbuild/\n.idea\n.gradle\nlocal.properties\n*.iml\n\n# node.js\n#\nnode_modules/\nnpm-debug.log\nyarn-error.log\n\n# BUCK\nbuck-out/\n\\.buckd/\n*.keystore\n!debug.keystore\n\n# fastlane\n#\n# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the\n# screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://docs.fastlane.tools/best-practices/source-control/\n\n*/fastlane/report.xml\n*/fastlane/Preview.html\n*/fastlane/screenshots\n\n# Bundle artifact\n*.jsbundle\n\n# CocoaPods\n/ios/Pods/\n"
  },
  {
    "path": "example/.prettierrc.js",
    "content": "module.exports = {\n  bracketSpacing: false,\n  jsxBracketSameLine: true,\n  singleQuote: true,\n  trailingComma: 'all',\n};\n"
  },
  {
    "path": "example/.watchmanconfig",
    "content": "{}"
  },
  {
    "path": "example/__tests__/index.js",
    "content": "/**\n * @format\n */\n\nimport 'react-native';\nimport React from 'react';\nimport Root from '../src/index';\n\n// Note: test renderer must be required after react-native.\nimport renderer from 'react-test-renderer';\n\nit('renders correctly', () => {\n  renderer.create(<Root />);\n});\n"
  },
  {
    "path": "example/android/.project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>android</name>\n\t<comment>Project android created by Buildship.</comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.buildship.core.gradleprojectbuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>org.eclipse.buildship.core.gradleprojectnature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "example/android/.settings/org.eclipse.buildship.core.prefs",
    "content": "connection.project.dir=\neclipse.preferences.version=1\n"
  },
  {
    "path": "example/android/app/_BUCK",
    "content": "# To learn about Buck see [Docs](https://buckbuild.com/).\n# To run your application with Buck:\n# - install Buck\n# - `npm start` - to start the packager\n# - `cd android`\n# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname \"CN=Android Debug,O=Android,C=US\"`\n# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck\n# - `buck install -r android/app` - compile, install and run application\n#\n\nload(\":build_defs.bzl\", \"create_aar_targets\", \"create_jar_targets\")\n\nlib_deps = []\n\ncreate_aar_targets(glob([\"libs/*.aar\"]))\n\ncreate_jar_targets(glob([\"libs/*.jar\"]))\n\nandroid_library(\n    name = \"all-libs\",\n    exported_deps = lib_deps,\n)\n\nandroid_library(\n    name = \"app-code\",\n    srcs = glob([\n        \"src/main/java/**/*.java\",\n    ]),\n    deps = [\n        \":all-libs\",\n        \":build_config\",\n        \":res\",\n    ],\n)\n\nandroid_build_config(\n    name = \"build_config\",\n    package = \"com.example\",\n)\n\nandroid_resource(\n    name = \"res\",\n    package = \"com.example\",\n    res = \"src/main/res\",\n)\n\nandroid_binary(\n    name = \"app\",\n    keystore = \"//android/keystores:debug\",\n    manifest = \"src/main/AndroidManifest.xml\",\n    package_type = \"debug\",\n    deps = [\n        \":app-code\",\n    ],\n)\n"
  },
  {
    "path": "example/android/app/build.gradle",
    "content": "apply plugin: \"com.android.application\"\n\nimport com.android.build.OutputFile\n\n/**\n * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets\n * and bundleReleaseJsAndAssets).\n * These basically call `react-native bundle` with the correct arguments during the Android build\n * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the\n * bundle directly from the development server. Below you can see all the possible configurations\n * and their defaults. If you decide to add a configuration block, make sure to add it before the\n * `apply from: \"../../node_modules/react-native/react.gradle\"` line.\n *\n * project.ext.react = [\n *   // the name of the generated asset file containing your JS bundle\n *   bundleAssetName: \"index.android.bundle\",\n *\n *   // the entry file for bundle generation\n *   entryFile: \"index.android.js\",\n *\n *   // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format\n *   bundleCommand: \"ram-bundle\",\n *\n *   // whether to bundle JS and assets in debug mode\n *   bundleInDebug: false,\n *\n *   // whether to bundle JS and assets in release mode\n *   bundleInRelease: true,\n *\n *   // whether to bundle JS and assets in another build variant (if configured).\n *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants\n *   // The configuration property can be in the following formats\n *   //         'bundleIn${productFlavor}${buildType}'\n *   //         'bundleIn${buildType}'\n *   // bundleInFreeDebug: true,\n *   // bundleInPaidRelease: true,\n *   // bundleInBeta: true,\n *\n *   // whether to disable dev mode in custom build variants (by default only disabled in release)\n *   // for example: to disable dev mode in the staging build type (if configured)\n *   devDisabledInStaging: true,\n *   // The configuration property can be in the following formats\n *   //         'devDisabledIn${productFlavor}${buildType}'\n *   //         'devDisabledIn${buildType}'\n *\n *   // the root of your project, i.e. where \"package.json\" lives\n *   root: \"../../\",\n *\n *   // where to put the JS bundle asset in debug mode\n *   jsBundleDirDebug: \"$buildDir/intermediates/assets/debug\",\n *\n *   // where to put the JS bundle asset in release mode\n *   jsBundleDirRelease: \"$buildDir/intermediates/assets/release\",\n *\n *   // where to put drawable resources / React Native assets, e.g. the ones you use via\n *   // require('./image.png')), in debug mode\n *   resourcesDirDebug: \"$buildDir/intermediates/res/merged/debug\",\n *\n *   // where to put drawable resources / React Native assets, e.g. the ones you use via\n *   // require('./image.png')), in release mode\n *   resourcesDirRelease: \"$buildDir/intermediates/res/merged/release\",\n *\n *   // by default the gradle tasks are skipped if none of the JS files or assets change; this means\n *   // that we don't look at files in android/ or ios/ to determine whether the tasks are up to\n *   // date; if you have any other folders that you want to ignore for performance reasons (gradle\n *   // indexes the entire tree), add them here. Alternatively, if you have JS files in android/\n *   // for example, you might want to remove it from here.\n *   inputExcludes: [\"android/**\", \"ios/**\"],\n *\n *   // override which node gets called and with what additional arguments\n *   nodeExecutableAndArgs: [\"node\"],\n *\n *   // supply additional arguments to the packager\n *   extraPackagerArgs: []\n * ]\n */\n\nproject.ext.react = [\n    entryFile: \"index.js\",\n    enableHermes: false,  // clean and rebuild if changing\n]\n\napply from: \"../../node_modules/react-native/react.gradle\"\n\n/**\n * Set this to true to create two separate APKs instead of one:\n *   - An APK that only works on ARM devices\n *   - An APK that only works on x86 devices\n * The advantage is the size of the APK is reduced by about 4MB.\n * Upload all the APKs to the Play Store and people will download\n * the correct one based on the CPU architecture of their device.\n */\ndef enableSeparateBuildPerCPUArchitecture = false\n\n/**\n * Run Proguard to shrink the Java bytecode in release builds.\n */\ndef enableProguardInReleaseBuilds = false\n\n/**\n * The preferred build flavor of JavaScriptCore.\n *\n * For example, to use the international variant, you can use:\n * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`\n *\n * The international variant includes ICU i18n library and necessary data\n * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that\n * give correct results when using with locales other than en-US.  Note that\n * this variant is about 6MiB larger per architecture than default.\n */\ndef jscFlavor = 'org.webkit:android-jsc:+'\n\n/**\n * Whether to enable the Hermes VM.\n *\n * This should be set on project.ext.react and mirrored here.  If it is not set\n * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode\n * and the benefits of using Hermes will therefore be sharply reduced.\n */\ndef enableHermes = project.ext.react.get(\"enableHermes\", false);\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n\n    defaultConfig {\n        applicationId \"com.example\"\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n    }\n    splits {\n        abi {\n            reset()\n            enable enableSeparateBuildPerCPUArchitecture\n            universalApk false  // If true, also generate a universal APK\n            include \"armeabi-v7a\", \"x86\", \"arm64-v8a\", \"x86_64\"\n        }\n    }\n    signingConfigs {\n        debug {\n            storeFile file('debug.keystore')\n            storePassword 'android'\n            keyAlias 'androiddebugkey'\n            keyPassword 'android'\n        }\n    }\n    buildTypes {\n        debug {\n            signingConfig signingConfigs.debug\n        }\n        release {\n            // Caution! In production, you need to generate your own keystore file.\n            // see https://facebook.github.io/react-native/docs/signed-apk-android.\n            signingConfig signingConfigs.debug\n            minifyEnabled enableProguardInReleaseBuilds\n            proguardFiles getDefaultProguardFile(\"proguard-android.txt\"), \"proguard-rules.pro\"\n        }\n    }\n    // applicationVariants are e.g. debug, release\n    applicationVariants.all { variant ->\n        variant.outputs.each { output ->\n            // For each separate APK per architecture, set a unique version code as described here:\n            // https://developer.android.com/studio/build/configure-apk-splits.html\n            def versionCodes = [\"armeabi-v7a\": 1, \"x86\": 2, \"arm64-v8a\": 3, \"x86_64\": 4]\n            def abi = output.getFilter(OutputFile.ABI)\n            if (abi != null) {  // null for the universal-debug, universal-release variants\n                output.versionCodeOverride =\n                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode\n            }\n\n        }\n    }\n}\n\ndependencies {\n    implementation fileTree(dir: \"libs\", include: [\"*.jar\"])\n    implementation \"com.facebook.react:react-native:+\"  // From node_modules\n\n    if (enableHermes) {\n        def hermesPath = \"../../node_modules/hermes-engine/android/\";\n        debugImplementation files(hermesPath + \"hermes-debug.aar\")\n        releaseImplementation files(hermesPath + \"hermes-release.aar\")\n    } else {\n        implementation jscFlavor\n    }\n}\n\n// Run this once to be able to run the application with BUCK\n// puts all compile dependencies into folder libs for BUCK to use\ntask copyDownloadableDepsToLibs(type: Copy) {\n    from configurations.compile\n    into 'libs'\n}\n\napply from: file(\"../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle\"); applyNativeModulesAppBuildGradle(project)\n"
  },
  {
    "path": "example/android/app/build_defs.bzl",
    "content": "\"\"\"Helper definitions to glob .aar and .jar targets\"\"\"\n\ndef create_aar_targets(aarfiles):\n    for aarfile in aarfiles:\n        name = \"aars__\" + aarfile[aarfile.rindex(\"/\") + 1:aarfile.rindex(\".aar\")]\n        lib_deps.append(\":\" + name)\n        android_prebuilt_aar(\n            name = name,\n            aar = aarfile,\n        )\n\ndef create_jar_targets(jarfiles):\n    for jarfile in jarfiles:\n        name = \"jars__\" + jarfile[jarfile.rindex(\"/\") + 1:jarfile.rindex(\".jar\")]\n        lib_deps.append(\":\" + name)\n        prebuilt_jar(\n            name = name,\n            binary_jar = jarfile,\n        )\n"
  },
  {
    "path": "example/android/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n"
  },
  {
    "path": "example/android/app/src/debug/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>\n\n    <application android:usesCleartextTraffic=\"true\" tools:targetApi=\"28\" tools:ignore=\"GoogleAppIndexingWarning\" />\n</manifest>\n"
  },
  {
    "path": "example/android/app/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  package=\"com.example\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n\n    <application\n      android:name=\".MainApplication\"\n      android:label=\"@string/app_name\"\n      android:icon=\"@mipmap/ic_launcher\"\n      android:roundIcon=\"@mipmap/ic_launcher_round\"\n      android:allowBackup=\"false\"\n      android:theme=\"@style/AppTheme\">\n      <activity\n        android:name=\".MainActivity\"\n        android:label=\"@string/app_name\"\n        android:configChanges=\"keyboard|keyboardHidden|orientation|screenSize\"\n        android:windowSoftInputMode=\"adjustResize\">\n        <intent-filter>\n            <action android:name=\"android.intent.action.MAIN\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n      </activity>\n      <activity android:name=\"com.facebook.react.devsupport.DevSettingsActivity\" />\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "example/android/app/src/main/java/com/example/MainActivity.java",
    "content": "package com.example;\n\nimport com.facebook.react.ReactActivity;\n\npublic class MainActivity extends ReactActivity {\n\n  /**\n   * Returns the name of the main component registered from JavaScript. This is used to schedule\n   * rendering of the component.\n   */\n  @Override\n  protected String getMainComponentName() {\n    return \"example\";\n  }\n}\n"
  },
  {
    "path": "example/android/app/src/main/java/com/example/MainApplication.java",
    "content": "package com.example;\n\nimport android.app.Application;\nimport android.content.Context;\nimport com.facebook.react.PackageList;\nimport com.facebook.react.ReactApplication;\nimport com.facebook.react.ReactNativeHost;\nimport com.facebook.react.ReactPackage;\nimport com.facebook.soloader.SoLoader;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.List;\n\npublic class MainApplication extends Application implements ReactApplication {\n\n  private final ReactNativeHost mReactNativeHost =\n      new ReactNativeHost(this) {\n        @Override\n        public boolean getUseDeveloperSupport() {\n          return BuildConfig.DEBUG;\n        }\n\n        @Override\n        protected List<ReactPackage> getPackages() {\n          @SuppressWarnings(\"UnnecessaryLocalVariable\")\n          List<ReactPackage> packages = new PackageList(this).getPackages();\n          // Packages that cannot be autolinked yet can be added manually here, for example:\n          // packages.add(new MyReactNativePackage());\n          return packages;\n        }\n\n        @Override\n        protected String getJSMainModuleName() {\n          return \"index\";\n        }\n      };\n\n  @Override\n  public ReactNativeHost getReactNativeHost() {\n    return mReactNativeHost;\n  }\n\n  @Override\n  public void onCreate() {\n    super.onCreate();\n    SoLoader.init(this, /* native exopackage */ false);\n    initializeFlipper(this); // Remove this line if you don't want Flipper enabled\n  }\n\n  /**\n   * Loads Flipper in React Native templates.\n   *\n   * @param context\n   */\n  private static void initializeFlipper(Context context) {\n    if (BuildConfig.DEBUG) {\n      try {\n        /*\n         We use reflection here to pick up the class that initializes Flipper,\n        since Flipper library is not available in release mode\n        */\n        Class<?> aClass = Class.forName(\"com.facebook.flipper.ReactNativeFlipper\");\n        aClass.getMethod(\"initializeFlipper\", Context.class).invoke(null, context);\n      } catch (ClassNotFoundException e) {\n        e.printStackTrace();\n      } catch (NoSuchMethodException e) {\n        e.printStackTrace();\n      } catch (IllegalAccessException e) {\n        e.printStackTrace();\n      } catch (InvocationTargetException e) {\n        e.printStackTrace();\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "example/android/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">example</string>\n</resources>\n"
  },
  {
    "path": "example/android/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"android:textColor\">#000000</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "example/android/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    ext {\n        buildToolsVersion = \"28.0.3\"\n        minSdkVersion = 16\n        compileSdkVersion = 28\n        targetSdkVersion = 28\n    }\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath(\"com.android.tools.build:gradle:3.4.2\")\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        mavenLocal()\n        maven {\n            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm\n            url(\"$rootDir/../node_modules/react-native/android\")\n        }\n        maven {\n            // Android JSC is installed from npm\n            url(\"$rootDir/../node_modules/jsc-android/dist\")\n        }\n\n        google()\n        jcenter()\n        maven { url 'https://jitpack.io' }\n    }\n}\n"
  },
  {
    "path": "example/android/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-5.5-all.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "example/android/gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n\nandroid.useAndroidX=true\nandroid.enableJetifier=true\n"
  },
  {
    "path": "example/android/gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "example/android/gradlew.bat",
    "content": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\r\n@rem you may not use this file except in compliance with the License.\r\n@rem You may obtain a copy of the License at\r\n@rem\r\n@rem      http://www.apache.org/licenses/LICENSE-2.0\r\n@rem\r\n@rem Unless required by applicable law or agreed to in writing, software\r\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\r\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n@rem See the License for the specific language governing permissions and\r\n@rem limitations under the License.\r\n@rem\r\n\r\n@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "example/android/settings.gradle",
    "content": "rootProject.name = 'example'\napply from: file(\"../node_modules/@react-native-community/cli-platform-android/native_modules.gradle\"); applyNativeModulesSettingsGradle(settings)\ninclude ':app'\n"
  },
  {
    "path": "example/app.json",
    "content": "{\n  \"name\": \"example\",\n  \"displayName\": \"example\"\n}"
  },
  {
    "path": "example/babel.config.js",
    "content": "module.exports = {\n  presets: ['module:metro-react-native-babel-preset'],\n};\n"
  },
  {
    "path": "example/index.js",
    "content": "/**\n * @format\n */\n\nimport {AppRegistry} from 'react-native';\nimport App from './src';\nimport {name as appName} from './app.json';\n\nAppRegistry.registerComponent(appName, () => App);\n"
  },
  {
    "path": "example/ios/Podfile",
    "content": "platform :ios, '9.0'\nrequire_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'\n\ntarget 'example' do\n  # Pods for example\n  pod 'FBLazyVector', :path => \"../node_modules/react-native/Libraries/FBLazyVector\"\n  pod 'FBReactNativeSpec', :path => \"../node_modules/react-native/Libraries/FBReactNativeSpec\"\n  pod 'RCTRequired', :path => \"../node_modules/react-native/Libraries/RCTRequired\"\n  pod 'RCTTypeSafety', :path => \"../node_modules/react-native/Libraries/TypeSafety\"\n  pod 'React', :path => '../node_modules/react-native/'\n  pod 'React-Core', :path => '../node_modules/react-native/'\n  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'\n  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'\n  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'\n  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'\n  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'\n  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'\n  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'\n  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'\n  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'\n  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'\n  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'\n  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'\n\n  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'\n  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'\n  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'\n  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'\n  pod 'ReactCommon/jscallinvoker', :path => \"../node_modules/react-native/ReactCommon\"\n  pod 'ReactCommon/turbomodule/core', :path => \"../node_modules/react-native/ReactCommon\"\n  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'\n\n  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'\n  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'\n  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'\n\n  target 'exampleTests' do\n    inherit! :search_paths\n    # Pods for testing\n  end\n\n  use_native_modules!\nend\n\ntarget 'example-tvOS' do\n  # Pods for example-tvOS\n\n  target 'example-tvOSTests' do\n    inherit! :search_paths\n    # Pods for testing\n  end\n\nend\n"
  },
  {
    "path": "example/ios/example/AppDelegate.h",
    "content": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n#import <React/RCTBridgeDelegate.h>\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>\n\n@property (nonatomic, strong) UIWindow *window;\n\n@end\n"
  },
  {
    "path": "example/ios/example/AppDelegate.m",
    "content": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n#import \"AppDelegate.h\"\n\n#import <React/RCTBridge.h>\n#import <React/RCTBundleURLProvider.h>\n#import <React/RCTRootView.h>\n\n@implementation AppDelegate\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\n{\n  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];\n  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge\n                                                   moduleName:@\"example\"\n                                            initialProperties:nil];\n\n  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];\n\n  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];\n  UIViewController *rootViewController = [UIViewController new];\n  rootViewController.view = rootView;\n  self.window.rootViewController = rootViewController;\n  [self.window makeKeyAndVisible];\n  return YES;\n}\n\n- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge\n{\n#if DEBUG\n  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@\"index\" fallbackResource:nil];\n#else\n  return [[NSBundle mainBundle] URLForResource:@\"main\" withExtension:@\"jsbundle\"];\n#endif\n}\n\n@end\n"
  },
  {
    "path": "example/ios/example/Base.lproj/LaunchScreen.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"7702\" systemVersion=\"14D136\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"7701\"/>\n        <capability name=\"Constraints with non-1.0 multipliers\" minToolsVersion=\"5.1\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view contentMode=\"scaleToFill\" id=\"iN0-l3-epB\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"480\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <subviews>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Powered by React Native\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"9\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"8ie-xW-0ye\">\n                    <rect key=\"frame\" x=\"20\" y=\"439\" width=\"441\" height=\"21\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"example\" textAlignment=\"center\" lineBreakMode=\"middleTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"18\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"kId-c2-rCX\">\n                    <rect key=\"frame\" x=\"20\" y=\"140\" width=\"441\" height=\"43\"/>\n                    <fontDescription key=\"fontDescription\" type=\"boldSystem\" pointSize=\"36\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n            </subviews>\n            <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\n            <constraints>\n                <constraint firstItem=\"kId-c2-rCX\" firstAttribute=\"centerY\" secondItem=\"iN0-l3-epB\" secondAttribute=\"bottom\" multiplier=\"1/3\" constant=\"1\" id=\"5cJ-9S-tgC\"/>\n                <constraint firstAttribute=\"centerX\" secondItem=\"kId-c2-rCX\" secondAttribute=\"centerX\" id=\"Koa-jz-hwk\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"8ie-xW-0ye\" secondAttribute=\"bottom\" constant=\"20\" id=\"Kzo-t9-V3l\"/>\n                <constraint firstItem=\"8ie-xW-0ye\" firstAttribute=\"leading\" secondItem=\"iN0-l3-epB\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"MfP-vx-nX0\"/>\n                <constraint firstAttribute=\"centerX\" secondItem=\"8ie-xW-0ye\" secondAttribute=\"centerX\" id=\"ZEH-qu-HZ9\"/>\n                <constraint firstItem=\"kId-c2-rCX\" firstAttribute=\"leading\" secondItem=\"iN0-l3-epB\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"fvb-Df-36g\"/>\n            </constraints>\n            <nil key=\"simulatedStatusBarMetrics\"/>\n            <freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>\n            <point key=\"canvasLocation\" x=\"548\" y=\"455\"/>\n        </view>\n    </objects>\n</document>\n"
  },
  {
    "path": "example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "example/ios/example/Images.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}\n"
  },
  {
    "path": "example/ios/example/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>Snap carousel</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSAppTransportSecurity</key>\n\t<dict>\n\t\t<key>NSAllowsArbitraryLoads</key>\n\t\t<true/>\n\t\t<key>NSExceptionDomains</key>\n\t\t<dict>\n\t\t\t<key>localhost</key>\n\t\t\t<dict>\n\t\t\t\t<key>NSExceptionAllowsInsecureHTTPLoads</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t</dict>\n\t</dict>\n\t<key>NSLocationWhenInUseUsageDescription</key>\n\t<string></string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UIViewControllerBasedStatusBarAppearance</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/example/main.m",
    "content": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n#import <UIKit/UIKit.h>\n\n#import \"AppDelegate.h\"\n\nint main(int argc, char * argv[]) {\n  @autoreleasepool {\n    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n  }\n}\n"
  },
  {
    "path": "example/ios/example-tvOS/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSAppTransportSecurity</key>\n\t<dict>\n\t\t<key>NSExceptionDomains</key>\n\t\t<dict>\n\t\t\t<key>localhost</key>\n\t\t\t<dict>\n\t\t\t\t<key>NSExceptionAllowsInsecureHTTPLoads</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t</dict>\n\t</dict>\n\t<key>NSLocationWhenInUseUsageDescription</key>\n\t<string></string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UIViewControllerBasedStatusBarAppearance</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/example-tvOSTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/example.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t00E356F31AD99517003FC87E /* exampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* exampleTests.m */; };\n\t\t13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };\n\t\t13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };\n\t\t13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };\n\t\t13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };\n\t\t29C871C0741732DA80D4A28B /* libPods-exampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E829CA22C7590836F0BDC89 /* libPods-exampleTests.a */; };\n\t\t2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };\n\t\t2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };\n\t\t2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };\n\t\t2DCD954D1E0B4F2C00145EB5 /* exampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* exampleTests.m */; };\n\t\t871938999323E775E1A601AA /* libPods-example-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D7EE427033EF6DE8A18138AF /* libPods-example-tvOS.a */; };\n\t\tB4AC6785CB63F44B1476B739 /* libPods-example-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D322FB106C50427D6E424A6B /* libPods-example-tvOSTests.a */; };\n\t\tF272BF3BCAF6E9F45485CA12 /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A1084C799FFD8DE81B1B05A /* libPods-example.a */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 13B07F861A680F5B00A75B9A;\n\t\t\tremoteInfo = example;\n\t\t};\n\t\t2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 2D02E47A1E0B4A5D006451C7;\n\t\t\tremoteInfo = \"example-tvOS\";\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\t008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = \"<group>\"; };\n\t\t00E356EE1AD99517003FC87E /* exampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = exampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t00E356F21AD99517003FC87E /* exampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = exampleTests.m; sourceTree = \"<group>\"; };\n\t\t0685F86383145C5CB4CDA68E /* Pods-exampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-exampleTests.release.xcconfig\"; path = \"Target Support Files/Pods-exampleTests/Pods-exampleTests.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t11B0F93180450FD943C626DD /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-example.release.xcconfig\"; path = \"Target Support Files/Pods-example/Pods-example.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t13B07F961A680F5B00A75B9A /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = example/AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = example/AppDelegate.m; sourceTree = \"<group>\"; };\n\t\t13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = \"<group>\"; };\n\t\t13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = \"<group>\"; };\n\t\t13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = \"<group>\"; };\n\t\t13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = example/main.m; sourceTree = \"<group>\"; };\n\t\t2848D7646158208FFC51959F /* Pods-example-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-example-tvOS.release.xcconfig\"; path = \"Target Support Files/Pods-example-tvOS/Pods-example-tvOS.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t2A1084C799FFD8DE81B1B05A /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = \"libPods-example.a\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t2D02E47B1E0B4A5D006451C7 /* example-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"example-tvOS.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t2D02E4901E0B4A5D006451C7 /* example-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = \"example-tvOSTests.xctest\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t4E829CA22C7590836F0BDC89 /* libPods-exampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = \"libPods-exampleTests.a\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t641D414720AFDDEC3EA337EC /* Pods-example-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-example-tvOSTests.debug.xcconfig\"; path = \"Target Support Files/Pods-example-tvOSTests/Pods-example-tvOSTests.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t66247520A490D5DB33BCE5DA /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-example.debug.xcconfig\"; path = \"Target Support Files/Pods-example/Pods-example.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t81EBEEC75A4C26459B97B278 /* Pods-example-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-example-tvOS.debug.xcconfig\"; path = \"Target Support Files/Pods-example-tvOS/Pods-example-tvOS.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tC67ED4B3CF798134625BA09B /* Pods-example-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-example-tvOSTests.release.xcconfig\"; path = \"Target Support Files/Pods-example-tvOSTests/Pods-example-tvOSTests.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tC903D82C7E072C46D3D68139 /* Pods-exampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-exampleTests.debug.xcconfig\"; path = \"Target Support Files/Pods-exampleTests/Pods-exampleTests.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tD322FB106C50427D6E424A6B /* libPods-example-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = \"libPods-example-tvOSTests.a\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tD7EE427033EF6DE8A18138AF /* libPods-example-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = \"libPods-example-tvOS.a\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };\n\t\tED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t00E356EB1AD99517003FC87E /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t29C871C0741732DA80D4A28B /* libPods-exampleTests.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t13B07F8C1A680F5B00A75B9A /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF272BF3BCAF6E9F45485CA12 /* libPods-example.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E4781E0B4A5D006451C7 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t871938999323E775E1A601AA /* libPods-example-tvOS.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E48D1E0B4A5D006451C7 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tB4AC6785CB63F44B1476B739 /* libPods-example-tvOSTests.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t00E356EF1AD99517003FC87E /* exampleTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t00E356F21AD99517003FC87E /* exampleTests.m */,\n\t\t\t\t00E356F01AD99517003FC87E /* Supporting Files */,\n\t\t\t);\n\t\t\tpath = exampleTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t00E356F01AD99517003FC87E /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t00E356F11AD99517003FC87E /* Info.plist */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t13B07FAE1A68108700A75B9A /* example */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t008F07F21AC5B25A0029DE68 /* main.jsbundle */,\n\t\t\t\t13B07FAF1A68108700A75B9A /* AppDelegate.h */,\n\t\t\t\t13B07FB01A68108700A75B9A /* AppDelegate.m */,\n\t\t\t\t13B07FB51A68108700A75B9A /* Images.xcassets */,\n\t\t\t\t13B07FB61A68108700A75B9A /* Info.plist */,\n\t\t\t\t13B07FB11A68108700A75B9A /* LaunchScreen.xib */,\n\t\t\t\t13B07FB71A68108700A75B9A /* main.m */,\n\t\t\t);\n\t\t\tname = example;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t13F9C63D4CAF75CDA2D4380F /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t66247520A490D5DB33BCE5DA /* Pods-example.debug.xcconfig */,\n\t\t\t\t11B0F93180450FD943C626DD /* Pods-example.release.xcconfig */,\n\t\t\t\t81EBEEC75A4C26459B97B278 /* Pods-example-tvOS.debug.xcconfig */,\n\t\t\t\t2848D7646158208FFC51959F /* Pods-example-tvOS.release.xcconfig */,\n\t\t\t\t641D414720AFDDEC3EA337EC /* Pods-example-tvOSTests.debug.xcconfig */,\n\t\t\t\tC67ED4B3CF798134625BA09B /* Pods-example-tvOSTests.release.xcconfig */,\n\t\t\t\tC903D82C7E072C46D3D68139 /* Pods-exampleTests.debug.xcconfig */,\n\t\t\t\t0685F86383145C5CB4CDA68E /* Pods-exampleTests.release.xcconfig */,\n\t\t\t);\n\t\t\tname = Pods;\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2D16E6871FA4F8E400B85C8A /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tED297162215061F000B7C4FE /* JavaScriptCore.framework */,\n\t\t\t\tED2971642150620600B7C4FE /* JavaScriptCore.framework */,\n\t\t\t\t2A1084C799FFD8DE81B1B05A /* libPods-example.a */,\n\t\t\t\tD7EE427033EF6DE8A18138AF /* libPods-example-tvOS.a */,\n\t\t\t\tD322FB106C50427D6E424A6B /* libPods-example-tvOSTests.a */,\n\t\t\t\t4E829CA22C7590836F0BDC89 /* libPods-exampleTests.a */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t832341AE1AAA6A7D00B99B32 /* Libraries */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = Libraries;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83CBB9F61A601CBA00E9B192 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t13B07FAE1A68108700A75B9A /* example */,\n\t\t\t\t832341AE1AAA6A7D00B99B32 /* Libraries */,\n\t\t\t\t00E356EF1AD99517003FC87E /* exampleTests */,\n\t\t\t\t83CBBA001A601CBA00E9B192 /* Products */,\n\t\t\t\t2D16E6871FA4F8E400B85C8A /* Frameworks */,\n\t\t\t\t13F9C63D4CAF75CDA2D4380F /* Pods */,\n\t\t\t);\n\t\t\tindentWidth = 2;\n\t\t\tsourceTree = \"<group>\";\n\t\t\ttabWidth = 2;\n\t\t\tusesTabs = 0;\n\t\t};\n\t\t83CBBA001A601CBA00E9B192 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t13B07F961A680F5B00A75B9A /* example.app */,\n\t\t\t\t00E356EE1AD99517003FC87E /* exampleTests.xctest */,\n\t\t\t\t2D02E47B1E0B4A5D006451C7 /* example-tvOS.app */,\n\t\t\t\t2D02E4901E0B4A5D006451C7 /* example-tvOSTests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t00E356ED1AD99517003FC87E /* exampleTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget \"exampleTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t21B1CB7811DC630A464E9976 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t00E356EA1AD99517003FC87E /* Sources */,\n\t\t\t\t00E356EB1AD99517003FC87E /* Frameworks */,\n\t\t\t\t00E356EC1AD99517003FC87E /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t00E356F51AD99517003FC87E /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = exampleTests;\n\t\t\tproductName = exampleTests;\n\t\t\tproductReference = 00E356EE1AD99517003FC87E /* exampleTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t13B07F861A680F5B00A75B9A /* example */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget \"example\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t7B3F63962D923B5AC2EBFF6A /* [CP] Check Pods Manifest.lock */,\n\t\t\t\tFD10A7F022414F080027D42C /* Start Packager */,\n\t\t\t\t13B07F871A680F5B00A75B9A /* Sources */,\n\t\t\t\t13B07F8C1A680F5B00A75B9A /* Frameworks */,\n\t\t\t\t13B07F8E1A680F5B00A75B9A /* Resources */,\n\t\t\t\t00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = example;\n\t\t\tproductName = example;\n\t\t\tproductReference = 13B07F961A680F5B00A75B9A /* example.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t2D02E47A1E0B4A5D006451C7 /* example-tvOS */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget \"example-tvOS\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t71AFCCE0B3908DB29062379D /* [CP] Check Pods Manifest.lock */,\n\t\t\t\tFD10A7F122414F3F0027D42C /* Start Packager */,\n\t\t\t\t2D02E4771E0B4A5D006451C7 /* Sources */,\n\t\t\t\t2D02E4781E0B4A5D006451C7 /* Frameworks */,\n\t\t\t\t2D02E4791E0B4A5D006451C7 /* Resources */,\n\t\t\t\t2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"example-tvOS\";\n\t\t\tproductName = \"example-tvOS\";\n\t\t\tproductReference = 2D02E47B1E0B4A5D006451C7 /* example-tvOS.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t2D02E48F1E0B4A5D006451C7 /* example-tvOSTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget \"example-tvOSTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t6C1FB4F89E984853D9133472 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t2D02E48C1E0B4A5D006451C7 /* Sources */,\n\t\t\t\t2D02E48D1E0B4A5D006451C7 /* Frameworks */,\n\t\t\t\t2D02E48E1E0B4A5D006451C7 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"example-tvOSTests\";\n\t\t\tproductName = \"example-tvOSTests\";\n\t\t\tproductReference = 2D02E4901E0B4A5D006451C7 /* example-tvOSTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t83CBB9F71A601CBA00E9B192 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0940;\n\t\t\t\tORGANIZATIONNAME = Facebook;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t00E356ED1AD99517003FC87E = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 6.2;\n\t\t\t\t\t\tTestTargetID = 13B07F861A680F5B00A75B9A;\n\t\t\t\t\t};\n\t\t\t\t\t2D02E47A1E0B4A5D006451C7 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2.1;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t\t2D02E48F1E0B4A5D006451C7 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2.1;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t\tTestTargetID = 2D02E47A1E0B4A5D006451C7;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject \"example\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 83CBB9F61A601CBA00E9B192;\n\t\t\tproductRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t13B07F861A680F5B00A75B9A /* example */,\n\t\t\t\t00E356ED1AD99517003FC87E /* exampleTests */,\n\t\t\t\t2D02E47A1E0B4A5D006451C7 /* example-tvOS */,\n\t\t\t\t2D02E48F1E0B4A5D006451C7 /* example-tvOSTests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t00E356EC1AD99517003FC87E /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t13B07F8E1A680F5B00A75B9A /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,\n\t\t\t\t13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E4791E0B4A5D006451C7 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E48E1E0B4A5D006451C7 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Bundle React Native code and images\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"export NODE_BINARY=node\\n../node_modules/react-native/scripts/react-native-xcode.sh\";\n\t\t};\n\t\t21B1CB7811DC630A464E9976 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-exampleTests-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Bundle React Native Code And Images\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"export NODE_BINARY=node\\n../node_modules/react-native/scripts/react-native-xcode.sh\";\n\t\t};\n\t\t6C1FB4F89E984853D9133472 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-example-tvOSTests-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t71AFCCE0B3908DB29062379D /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-example-tvOS-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t7B3F63962D923B5AC2EBFF6A /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tFD10A7F022414F080027D42C /* Start Packager */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Start Packager\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"export RCT_METRO_PORT=\\\"${RCT_METRO_PORT:=8081}\\\"\\necho \\\"export RCT_METRO_PORT=${RCT_METRO_PORT}\\\" > \\\"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\\\"\\nif [ -z \\\"${RCT_NO_LAUNCH_PACKAGER+xxx}\\\" ] ; then\\n  if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\\n    if ! curl -s \\\"http://localhost:${RCT_METRO_PORT}/status\\\" | grep -q \\\"packager-status:running\\\" ; then\\n      echo \\\"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\\\"\\n      exit 2\\n    fi\\n  else\\n    open \\\"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\\\" || echo \\\"Can't start packager automatically\\\"\\n  fi\\nfi\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tFD10A7F122414F3F0027D42C /* Start Packager */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Start Packager\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"export RCT_METRO_PORT=\\\"${RCT_METRO_PORT:=8081}\\\"\\necho \\\"export RCT_METRO_PORT=${RCT_METRO_PORT}\\\" > \\\"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\\\"\\nif [ -z \\\"${RCT_NO_LAUNCH_PACKAGER+xxx}\\\" ] ; then\\n  if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\\n    if ! curl -s \\\"http://localhost:${RCT_METRO_PORT}/status\\\" | grep -q \\\"packager-status:running\\\" ; then\\n      echo \\\"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\\\"\\n      exit 2\\n    fi\\n  else\\n    open \\\"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\\\" || echo \\\"Can't start packager automatically\\\"\\n  fi\\nfi\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t00E356EA1AD99517003FC87E /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t00E356F31AD99517003FC87E /* exampleTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t13B07F871A680F5B00A75B9A /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,\n\t\t\t\t13B07FC11A68108700A75B9A /* main.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E4771E0B4A5D006451C7 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */,\n\t\t\t\t2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E48C1E0B4A5D006451C7 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2DCD954D1E0B4F2C00145EB5 /* exampleTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t00E356F51AD99517003FC87E /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 13B07F861A680F5B00A75B9A /* example */;\n\t\t\ttargetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;\n\t\t};\n\t\t2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 2D02E47A1E0B4A5D006451C7 /* example-tvOS */;\n\t\t\ttargetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\t13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t13B07FB21A68108700A75B9A /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.xib;\n\t\t\tpath = example;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t00E356F61AD99517003FC87E /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = C903D82C7E072C46D3D68139 /* Pods-exampleTests.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = exampleTests/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/example.app/example\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t00E356F71AD99517003FC87E /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 0685F86383145C5CB4CDA68E /* Pods-exampleTests.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tINFOPLIST_FILE = exampleTests/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/example.app/example\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t13B07F941A680F5B00A75B9A /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 66247520A490D5DB33BCE5DA /* Pods-example.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEAD_CODE_STRIPPING = NO;\n\t\t\t\tINFOPLIST_FILE = example/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = example;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t13B07F951A680F5B00A75B9A /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 11B0F93180450FD943C626DD /* Pods-example.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tINFOPLIST_FILE = example/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = example;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t2D02E4971E0B4A5E006451C7 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 81EBEEC75A4C26459B97B278 /* Pods-example-tvOS.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = \"App Icon & Top Shelf Image\";\n\t\t\t\tASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tINFOPLIST_FILE = \"example-tvOS/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.facebook.REACT.example-tvOS\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.2;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2D02E4981E0B4A5E006451C7 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 2848D7646158208FFC51959F /* Pods-example-tvOS.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = \"App Icon & Top Shelf Image\";\n\t\t\t\tASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tINFOPLIST_FILE = \"example-tvOS/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.facebook.REACT.example-tvOS\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.2;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t2D02E4991E0B4A5E006451C7 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 641D414720AFDDEC3EA337EC /* Pods-example-tvOSTests.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tINFOPLIST_FILE = \"example-tvOSTests/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.facebook.REACT.example-tvOSTests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/example-tvOS.app/example-tvOS\";\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 10.1;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2D02E49A1E0B4A5E006451C7 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = C67ED4B3CF798134625BA09B /* Pods-example-tvOSTests.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tINFOPLIST_FILE = \"example-tvOSTests/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.facebook.REACT.example-tvOSTests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/example-tvOS.app/example-tvOS\";\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 10.1;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t83CBBA201A601CBA00E9B192 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83CBBA211A601CBA00E9B192 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget \"exampleTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t00E356F61AD99517003FC87E /* Debug */,\n\t\t\t\t00E356F71AD99517003FC87E /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget \"example\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t13B07F941A680F5B00A75B9A /* Debug */,\n\t\t\t\t13B07F951A680F5B00A75B9A /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget \"example-tvOS\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2D02E4971E0B4A5E006451C7 /* Debug */,\n\t\t\t\t2D02E4981E0B4A5E006451C7 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget \"example-tvOSTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2D02E4991E0B4A5E006451C7 /* Debug */,\n\t\t\t\t2D02E49A1E0B4A5E006451C7 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject \"example\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83CBBA201A601CBA00E9B192 /* Debug */,\n\t\t\t\t83CBBA211A601CBA00E9B192 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;\n}\n"
  },
  {
    "path": "example/ios/example.xcodeproj/xcshareddata/xcschemes/example-tvOS.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0940\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"NO\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2D2A28121D9B038B00D4039D\"\n               BuildableName = \"libReact.a\"\n               BlueprintName = \"React-tvOS\"\n               ReferencedContainer = \"container:../node_modules/react-native/React/React.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2D02E47A1E0B4A5D006451C7\"\n               BuildableName = \"example-tvOS.app\"\n               BlueprintName = \"example-tvOS\"\n               ReferencedContainer = \"container:example.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"NO\"\n            buildForArchiving = \"NO\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2D02E48F1E0B4A5D006451C7\"\n               BuildableName = \"example-tvOSTests.xctest\"\n               BlueprintName = \"example-tvOSTests\"\n               ReferencedContainer = \"container:example.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"2D02E48F1E0B4A5D006451C7\"\n               BuildableName = \"example-tvOSTests.xctest\"\n               BlueprintName = \"example-tvOSTests\"\n               ReferencedContainer = \"container:example.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"2D02E47A1E0B4A5D006451C7\"\n            BuildableName = \"example-tvOS.app\"\n            BlueprintName = \"example-tvOS\"\n            ReferencedContainer = \"container:example.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"2D02E47A1E0B4A5D006451C7\"\n            BuildableName = \"example-tvOS.app\"\n            BlueprintName = \"example-tvOS\"\n            ReferencedContainer = \"container:example.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"2D02E47A1E0B4A5D006451C7\"\n            BuildableName = \"example-tvOS.app\"\n            BlueprintName = \"example-tvOS\"\n            ReferencedContainer = \"container:example.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "example/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0940\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"NO\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"83CBBA2D1A601D0E00E9B192\"\n               BuildableName = \"libReact.a\"\n               BlueprintName = \"React\"\n               ReferencedContainer = \"container:../node_modules/react-native/React/React.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"13B07F861A680F5B00A75B9A\"\n               BuildableName = \"example.app\"\n               BlueprintName = \"example\"\n               ReferencedContainer = \"container:example.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"NO\"\n            buildForArchiving = \"NO\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"00E356ED1AD99517003FC87E\"\n               BuildableName = \"exampleTests.xctest\"\n               BlueprintName = \"exampleTests\"\n               ReferencedContainer = \"container:example.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"00E356ED1AD99517003FC87E\"\n               BuildableName = \"exampleTests.xctest\"\n               BlueprintName = \"exampleTests\"\n               ReferencedContainer = \"container:example.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"13B07F861A680F5B00A75B9A\"\n            BuildableName = \"example.app\"\n            BlueprintName = \"example\"\n            ReferencedContainer = \"container:example.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"13B07F861A680F5B00A75B9A\"\n            BuildableName = \"example.app\"\n            BlueprintName = \"example\"\n            ReferencedContainer = \"container:example.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"13B07F861A680F5B00A75B9A\"\n            BuildableName = \"example.app\"\n            BlueprintName = \"example\"\n            ReferencedContainer = \"container:example.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "example/ios/example.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:example.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:Pods/Pods.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "example/ios/exampleTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "example/ios/exampleTests/exampleTests.m",
    "content": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n#import <UIKit/UIKit.h>\n#import <XCTest/XCTest.h>\n\n#import <React/RCTLog.h>\n#import <React/RCTRootView.h>\n\n#define TIMEOUT_SECONDS 600\n#define TEXT_TO_LOOK_FOR @\"Welcome to React\"\n\n@interface exampleTests : XCTestCase\n\n@end\n\n@implementation exampleTests\n\n- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test\n{\n  if (test(view)) {\n    return YES;\n  }\n  for (UIView *subview in [view subviews]) {\n    if ([self findSubviewInView:subview matching:test]) {\n      return YES;\n    }\n  }\n  return NO;\n}\n\n- (void)testRendersWelcomeScreen\n{\n  UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];\n  NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];\n  BOOL foundElement = NO;\n\n  __block NSString *redboxError = nil;\n#ifdef DEBUG\n  RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {\n    if (level >= RCTLogLevelError) {\n      redboxError = message;\n    }\n  });\n#endif\n\n  while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {\n    [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];\n    [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];\n\n    foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {\n      if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {\n        return YES;\n      }\n      return NO;\n    }];\n  }\n  \n#ifdef DEBUG\n  RCTSetLogFunction(RCTDefaultLogFunction);\n#endif\n\n  XCTAssertNil(redboxError, @\"RedBox error: %@\", redboxError);\n  XCTAssertTrue(foundElement, @\"Couldn't find element with text '%@' in %d seconds\", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);\n}\n\n\n@end\n"
  },
  {
    "path": "example/metro.config.js",
    "content": "/**\n * Metro configuration for React Native\n * https://github.com/facebook/react-native\n *\n * @format\n */\n\nmodule.exports = {\n  transformer: {\n    getTransformOptions: async () => ({\n      transform: {\n        experimentalImportSupport: false,\n        inlineRequires: false,\n      },\n    }),\n  },\n};\n"
  },
  {
    "path": "example/package.json",
    "content": "{\n  \"name\": \"example\",\n  \"version\": \"0.61.5\",\n  \"private\": true,\n  \"scripts\": {\n    \"android\": \"react-native run-android\",\n    \"ios\": \"react-native run-ios\",\n    \"start\": \"react-native start\",\n    \"test\": \"jest\"\n  },\n  \"dependencies\": {\n    \"react\": \"16.9.0\",\n    \"react-native\": \"0.61.5\",\n    \"react-native-linear-gradient\": \"2.5.6\",\n    \"react-native-snap-carousel\": \"file:../\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.6.2\",\n    \"@babel/runtime\": \"^7.6.2\",\n    \"babel-jest\": \"^24.9.0\",\n    \"jest\": \"^24.9.0\",\n    \"metro-react-native-babel-preset\": \"^0.56.0\",\n    \"react-test-renderer\": \"16.9.0\"\n  },\n  \"jest\": {\n    \"preset\": \"react-native\"\n  }\n}\n"
  },
  {
    "path": "example/src/components/SliderEntry.js",
    "content": "import React, { Component } from 'react';\nimport { View, Text, Image, TouchableOpacity } from 'react-native';\nimport PropTypes from 'prop-types';\nimport { ParallaxImage } from 'react-native-snap-carousel';\nimport styles from '../styles/SliderEntry.style';\n\nexport default class SliderEntry extends Component {\n\n    static propTypes = {\n        data: PropTypes.object.isRequired,\n        even: PropTypes.bool,\n        parallax: PropTypes.bool,\n        parallaxProps: PropTypes.object\n    };\n\n    get image () {\n        const { data: { illustration }, parallax, parallaxProps, even } = this.props;\n\n        return parallax ? (\n            <ParallaxImage\n              source={{ uri: illustration }}\n              containerStyle={[styles.imageContainer, even ? styles.imageContainerEven : {}]}\n              style={styles.image}\n              parallaxFactor={0.35}\n              showSpinner={true}\n              spinnerColor={even ? 'rgba(255, 255, 255, 0.4)' : 'rgba(0, 0, 0, 0.25)'}\n              {...parallaxProps}\n            />\n        ) : (\n            <Image\n              source={{ uri: illustration }}\n              style={styles.image}\n            />\n        );\n    }\n\n    render () {\n        const { data: { title, subtitle }, even } = this.props;\n\n        const uppercaseTitle = title ? (\n            <Text\n              style={[styles.title, even ? styles.titleEven : {}]}\n              numberOfLines={2}\n            >\n                { title.toUpperCase() }\n            </Text>\n        ) : false;\n\n        return (\n            <TouchableOpacity\n              activeOpacity={1}\n              style={styles.slideInnerContainer}\n              onPress={() => { alert(`You've clicked '${title}'`); }}\n              >\n                <View style={styles.shadow} />\n                <View style={[styles.imageContainer, even ? styles.imageContainerEven : {}]}>\n                    { this.image }\n                    <View style={[styles.radiusMask, even ? styles.radiusMaskEven : {}]} />\n                </View>\n                <View style={[styles.textContainer, even ? styles.textContainerEven : {}]}>\n                    { uppercaseTitle }\n                    <Text\n                      style={[styles.subtitle, even ? styles.subtitleEven : {}]}\n                      numberOfLines={2}\n                    >\n                        { subtitle }\n                    </Text>\n                </View>\n            </TouchableOpacity>\n        );\n    }\n}\n"
  },
  {
    "path": "example/src/index.js",
    "content": "import React, { Component } from 'react';\nimport { Platform, View, ScrollView, Text, StatusBar, SafeAreaView } from 'react-native';\nimport LinearGradient from 'react-native-linear-gradient';\nimport Carousel, { Pagination } from 'react-native-snap-carousel';\nimport { sliderWidth, itemWidth } from './styles/SliderEntry.style';\nimport SliderEntry from './components/SliderEntry';\nimport styles, { colors } from './styles/index.style';\nimport { ENTRIES1, ENTRIES2 } from './static/entries';\nimport { scrollInterpolators, animatedStyles } from './utils/animations';\n\nconst IS_ANDROID = Platform.OS === 'android';\nconst SLIDER_1_FIRST_ITEM = 1;\n\nexport default class example extends Component {\n\n    constructor (props) {\n        super(props);\n        this.state = {\n            slider1ActiveSlide: SLIDER_1_FIRST_ITEM\n        };\n    }\n\n    _renderItem ({item, index}) {\n        return <SliderEntry data={item} even={(index + 1) % 2 === 0} />;\n    }\n\n    _renderItemWithParallax ({item, index}, parallaxProps) {\n        return (\n            <SliderEntry\n              data={item}\n              even={(index + 1) % 2 === 0}\n              parallax={true}\n              parallaxProps={parallaxProps}\n            />\n        );\n    }\n\n    _renderLightItem ({item, index}) {\n        return <SliderEntry data={item} even={false} />;\n    }\n\n    _renderDarkItem ({item, index}) {\n        return <SliderEntry data={item} even={true} />;\n    }\n\n    mainExample (number, title) {\n        const { slider1ActiveSlide } = this.state;\n\n        return (\n            <View style={styles.exampleContainer}>\n                <Text style={styles.title}>{`Example ${number}`}</Text>\n                <Text style={styles.subtitle}>{title}</Text>\n                <Carousel\n                  ref={c => this._slider1Ref = c}\n                  data={ENTRIES1}\n                  renderItem={this._renderItemWithParallax}\n                  sliderWidth={sliderWidth}\n                  itemWidth={itemWidth}\n                  hasParallaxImages={true}\n                  firstItem={SLIDER_1_FIRST_ITEM}\n                  inactiveSlideScale={0.94}\n                  inactiveSlideOpacity={0.7}\n                  // inactiveSlideShift={20}\n                  containerCustomStyle={styles.slider}\n                  contentContainerCustomStyle={styles.sliderContentContainer}\n                  loop={true}\n                  loopClonesPerSide={2}\n                  autoplay={true}\n                  autoplayDelay={500}\n                  autoplayInterval={3000}\n                  onSnapToItem={(index) => this.setState({ slider1ActiveSlide: index }) }\n                />\n                <Pagination\n                  dotsLength={ENTRIES1.length}\n                  activeDotIndex={slider1ActiveSlide}\n                  containerStyle={styles.paginationContainer}\n                  dotColor={'rgba(255, 255, 255, 0.92)'}\n                  dotStyle={styles.paginationDot}\n                  inactiveDotColor={colors.black}\n                  inactiveDotOpacity={0.4}\n                  inactiveDotScale={0.6}\n                  carouselRef={this._slider1Ref}\n                  tappableDots={!!this._slider1Ref}\n                />\n            </View>\n        );\n    }\n\n    momentumExample (number, title) {\n        return (\n            <View style={styles.exampleContainer}>\n                <Text style={styles.title}>{`Example ${number}`}</Text>\n                <Text style={styles.subtitle}>{title}</Text>\n                <Carousel\n                  data={ENTRIES2}\n                  renderItem={this._renderItem}\n                  sliderWidth={sliderWidth}\n                  itemWidth={itemWidth}\n                  inactiveSlideScale={0.95}\n                  inactiveSlideOpacity={1}\n                  enableMomentum={true}\n                  activeSlideAlignment={'start'}\n                  containerCustomStyle={styles.slider}\n                  contentContainerCustomStyle={styles.sliderContentContainer}\n                  activeAnimationType={'spring'}\n                  activeAnimationOptions={{\n                      friction: 4,\n                      tension: 40\n                  }}\n                />\n            </View>\n        );\n    }\n\n    layoutExample (number, title, type) {\n        const isTinder = type === 'tinder';\n        return (\n            <View style={[styles.exampleContainer, isTinder ? styles.exampleContainerDark : styles.exampleContainerLight]}>\n                <Text style={[styles.title, isTinder ? {} : styles.titleDark]}>{`Example ${number}`}</Text>\n                <Text style={[styles.subtitle, isTinder ? {} : styles.titleDark]}>{title}</Text>\n                <Carousel\n                  data={isTinder ? ENTRIES2 : ENTRIES1}\n                  renderItem={isTinder ? this._renderLightItem : this._renderItem}\n                  sliderWidth={sliderWidth}\n                  itemWidth={itemWidth}\n                  containerCustomStyle={styles.slider}\n                  contentContainerCustomStyle={styles.sliderContentContainer}\n                  layout={type}\n                  loop={true}\n                />\n            </View>\n        );\n    }\n\n    customExample (number, title, refNumber, renderItemFunc) {\n        const isEven = refNumber % 2 === 0;\n\n        // Do not render examples on Android; because of the zIndex bug, they won't work as is\n        return !IS_ANDROID ? (\n            <View style={[styles.exampleContainer, isEven ? styles.exampleContainerDark : styles.exampleContainerLight]}>\n                <Text style={[styles.title, isEven ? {} : styles.titleDark]}>{`Example ${number}`}</Text>\n                <Text style={[styles.subtitle, isEven ? {} : styles.titleDark]}>{title}</Text>\n                <Carousel\n                  data={isEven ? ENTRIES2 : ENTRIES1}\n                  renderItem={renderItemFunc}\n                  sliderWidth={sliderWidth}\n                  itemWidth={itemWidth}\n                  containerCustomStyle={styles.slider}\n                  contentContainerCustomStyle={styles.sliderContentContainer}\n                  scrollInterpolator={scrollInterpolators[`scrollInterpolator${refNumber}`]}\n                  slideInterpolatedStyle={animatedStyles[`animatedStyles${refNumber}`]}\n                  useScrollView={true}\n                />\n            </View>\n        ) : false;\n    }\n\n    get gradient () {\n        return (\n            <LinearGradient\n              colors={[colors.background1, colors.background2]}\n              startPoint={{ x: 1, y: 0 }}\n              endPoint={{ x: 0, y: 1 }}\n              style={styles.gradient}\n            />\n        );\n    }\n\n    render () {\n        const example1 = this.mainExample(1, 'Default layout | Loop | Autoplay | Parallax | Scale | Opacity | Pagination with tappable dots');\n        const example2 = this.momentumExample(2, 'Momentum | Left-aligned | Active animation');\n        const example3 = this.layoutExample(3, '\"Stack of cards\" layout | Loop', 'stack');\n        const example4 = this.layoutExample(4, '\"Tinder-like\" layout | Loop', 'tinder');\n        const example5 = this.customExample(5, 'Custom animation 1', 1, this._renderItem);\n        const example6 = this.customExample(6, 'Custom animation 2', 2, this._renderLightItem);\n        const example7 = this.customExample(7, 'Custom animation 3', 3, this._renderDarkItem);\n        const example8 = this.customExample(8, 'Custom animation 4', 4, this._renderLightItem);\n\n        return (\n            <SafeAreaView style={styles.safeArea}>\n                <View style={styles.container}>\n                    <StatusBar\n                      translucent={true}\n                      backgroundColor={'rgba(0, 0, 0, 0.3)'}\n                      barStyle={'light-content'}\n                    />\n                    { this.gradient }\n                    <ScrollView\n                      style={styles.scrollview}\n                      scrollEventThrottle={200}\n                      directionalLockEnabled={true}\n                    >\n                        { example1 }\n                        { example2 }\n                        { example3 }\n                        { example4 }\n                        { example5 }\n                        { example6 }\n                        { example7 }\n                        { example8 }\n                    </ScrollView>\n                </View>\n            </SafeAreaView>\n        );\n    }\n}\n"
  },
  {
    "path": "example/src/static/entries.js",
    "content": "export const ENTRIES1 = [\n    {\n        title: 'Beautiful and dramatic Antelope Canyon',\n        subtitle: 'Lorem ipsum dolor sit amet et nuncat mergitur',\n        illustration: 'https://i.imgur.com/UYiroysl.jpg'\n    },\n    {\n        title: 'Earlier this morning, NYC',\n        subtitle: 'Lorem ipsum dolor sit amet',\n        illustration: 'https://i.imgur.com/UPrs1EWl.jpg'\n    },\n    {\n        title: 'White Pocket Sunset',\n        subtitle: 'Lorem ipsum dolor sit amet et nuncat ',\n        illustration: 'https://i.imgur.com/MABUbpDl.jpg'\n    },\n    {\n        title: 'Acrocorinth, Greece',\n        subtitle: 'Lorem ipsum dolor sit amet et nuncat mergitur',\n        illustration: 'https://i.imgur.com/KZsmUi2l.jpg'\n    },\n    {\n        title: 'The lone tree, majestic landscape of New Zealand',\n        subtitle: 'Lorem ipsum dolor sit amet',\n        illustration: 'https://i.imgur.com/2nCt3Sbl.jpg'\n    },\n    {\n        title: 'Middle Earth, Germany',\n        subtitle: 'Lorem ipsum dolor sit amet',\n        illustration: 'https://i.imgur.com/lceHsT6l.jpg'\n    }\n];\n\nexport const ENTRIES2 = [\n    {\n        title: 'Favourites landscapes 1',\n        subtitle: 'Lorem ipsum dolor sit amet',\n        illustration: 'https://i.imgur.com/SsJmZ9jl.jpg'\n    },\n    {\n        title: 'Favourites landscapes 2',\n        subtitle: 'Lorem ipsum dolor sit amet et nuncat mergitur',\n        illustration: 'https://i.imgur.com/5tj6S7Ol.jpg'\n    },\n    {\n        title: 'Favourites landscapes 3',\n        subtitle: 'Lorem ipsum dolor sit amet et nuncat',\n        illustration: 'https://i.imgur.com/pmSqIFZl.jpg'\n    },\n    {\n        title: 'Favourites landscapes 4',\n        subtitle: 'Lorem ipsum dolor sit amet et nuncat mergitur',\n        illustration: 'https://i.imgur.com/cA8zoGel.jpg'\n    },\n    {\n        title: 'Favourites landscapes 5',\n        subtitle: 'Lorem ipsum dolor sit amet',\n        illustration: 'https://i.imgur.com/pewusMzl.jpg'\n    },\n    {\n        title: 'Favourites landscapes 6',\n        subtitle: 'Lorem ipsum dolor sit amet et nuncat',\n        illustration: 'https://i.imgur.com/l49aYS3l.jpg'\n    }\n];\n"
  },
  {
    "path": "example/src/styles/SliderEntry.style.js",
    "content": "import { StyleSheet, Dimensions, Platform } from 'react-native';\nimport { colors } from './index.style';\n\nconst IS_IOS = Platform.OS === 'ios';\nconst { width: viewportWidth, height: viewportHeight } = Dimensions.get('window');\n\nfunction wp (percentage) {\n    const value = (percentage * viewportWidth) / 100;\n    return Math.round(value);\n}\n\nconst slideHeight = viewportHeight * 0.36;\nconst slideWidth = wp(75);\nconst itemHorizontalMargin = wp(2);\n\nexport const sliderWidth = viewportWidth;\nexport const itemWidth = slideWidth + itemHorizontalMargin * 2;\n\nconst entryBorderRadius = 8;\n\nexport default StyleSheet.create({\n    slideInnerContainer: {\n        width: itemWidth,\n        height: slideHeight,\n        paddingHorizontal: itemHorizontalMargin,\n        paddingBottom: 18 // needed for shadow\n    },\n    shadow: {\n        position: 'absolute',\n        top: 0,\n        left: itemHorizontalMargin,\n        right: itemHorizontalMargin,\n        bottom: 18,\n        shadowColor: colors.black,\n        shadowOpacity: 0.25,\n        shadowOffset: { width: 0, height: 10 },\n        shadowRadius: 10,\n        borderRadius: entryBorderRadius\n    },\n    imageContainer: {\n        flex: 1,\n        marginBottom: IS_IOS ? 0 : -1, // Prevent a random Android rendering issue\n        backgroundColor: 'white',\n        borderTopLeftRadius: entryBorderRadius,\n        borderTopRightRadius: entryBorderRadius\n    },\n    imageContainerEven: {\n        backgroundColor: colors.black\n    },\n    image: {\n        ...StyleSheet.absoluteFillObject,\n        resizeMode: 'cover',\n        borderRadius: IS_IOS ? entryBorderRadius : 0,\n        borderTopLeftRadius: entryBorderRadius,\n        borderTopRightRadius: entryBorderRadius\n    },\n    // image's border radius is buggy on iOS; let's hack it!\n    radiusMask: {\n        position: 'absolute',\n        bottom: 0,\n        left: 0,\n        right: 0,\n        height: entryBorderRadius,\n        backgroundColor: 'white'\n    },\n    radiusMaskEven: {\n        backgroundColor: colors.black\n    },\n    textContainer: {\n        justifyContent: 'center',\n        paddingTop: 20 - entryBorderRadius,\n        paddingBottom: 20,\n        paddingHorizontal: 16,\n        backgroundColor: 'white',\n        borderBottomLeftRadius: entryBorderRadius,\n        borderBottomRightRadius: entryBorderRadius\n    },\n    textContainerEven: {\n        backgroundColor: colors.black\n    },\n    title: {\n        color: colors.black,\n        fontSize: 13,\n        fontWeight: 'bold',\n        letterSpacing: 0.5\n    },\n    titleEven: {\n        color: 'white'\n    },\n    subtitle: {\n        marginTop: 6,\n        color: colors.gray,\n        fontSize: 12,\n        fontStyle: 'italic'\n    },\n    subtitleEven: {\n        color: 'rgba(255, 255, 255, 0.7)'\n    }\n});\n"
  },
  {
    "path": "example/src/styles/index.style.js",
    "content": "import { StyleSheet } from 'react-native';\n\nexport const colors = {\n    black: '#1a1917',\n    gray: '#888888',\n    background1: '#B721FF',\n    background2: '#21D4FD'\n};\n\nexport default StyleSheet.create({\n    safeArea: {\n        flex: 1,\n        backgroundColor: colors.black\n    },\n    container: {\n        flex: 1,\n        backgroundColor: colors.background1\n    },\n    gradient: {\n        ...StyleSheet.absoluteFillObject\n    },\n    scrollview: {\n        flex: 1\n    },\n    exampleContainer: {\n        paddingVertical: 30\n    },\n    exampleContainerDark: {\n        backgroundColor: colors.black\n    },\n    exampleContainerLight: {\n        backgroundColor: 'white'\n    },\n    title: {\n        paddingHorizontal: 30,\n        backgroundColor: 'transparent',\n        color: 'rgba(255, 255, 255, 0.9)',\n        fontSize: 20,\n        fontWeight: 'bold',\n        textAlign: 'center'\n    },\n    titleDark: {\n        color: colors.black\n    },\n    subtitle: {\n        marginTop: 5,\n        paddingHorizontal: 30,\n        backgroundColor: 'transparent',\n        color: 'rgba(255, 255, 255, 0.75)',\n        fontSize: 13,\n        fontStyle: 'italic',\n        textAlign: 'center'\n    },\n    slider: {\n        marginTop: 15,\n        overflow: 'visible' // for custom animations\n    },\n    sliderContentContainer: {\n        paddingVertical: 10 // for custom animation\n    },\n    paginationContainer: {\n        paddingVertical: 8\n    },\n    paginationDot: {\n        width: 8,\n        height: 8,\n        borderRadius: 4,\n        marginHorizontal: 8\n    }\n});\n"
  },
  {
    "path": "example/src/utils/animations.js",
    "content": "import { getInputRangeFromIndexes } from 'react-native-snap-carousel';\n\n// Photo album effect\nfunction scrollInterpolator1 (index, carouselProps) {\n    const range = [3, 2, 1, 0, -1];\n    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);\n    const outputRange = range;\n\n    return { inputRange, outputRange };\n}\nfunction animatedStyles1 (index, animatedValue, carouselProps) {\n    const sizeRef = carouselProps.vertical ? carouselProps.itemHeight : carouselProps.itemWidth;\n    const translateProp = carouselProps.vertical ? 'translateY' : 'translateX';\n\n    return {\n        zIndex: carouselProps.data.length - index,\n        opacity: animatedValue.interpolate({\n            inputRange: [2, 3],\n            outputRange: [1, 0],\n            extrapolate: 'clamp'\n        }),\n        transform: [{\n            rotate: animatedValue.interpolate({\n                inputRange: [-1, 0, 1, 2, 3],\n                outputRange: ['-25deg', '0deg', '-3deg', '1.8deg', '0deg'],\n                extrapolate: 'clamp'\n            })\n        }, {\n            [translateProp]: animatedValue.interpolate({\n                inputRange: [-1, 0, 1, 2, 3],\n                outputRange: [\n                    -sizeRef * 0.5,\n                    0,\n                    -sizeRef, // centered\n                    -sizeRef * 2, // centered\n                    -sizeRef * 3 // centered\n                ],\n                extrapolate: 'clamp'\n            })\n        }]\n    };\n}\n\n// Perspective effect\nfunction scrollInterpolator2 (index, carouselProps) {\n    const range = [2, 1, 0, -1];\n    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);\n    const outputRange = range;\n\n    return { inputRange, outputRange };\n}\nfunction animatedStyles2 (index, animatedValue, carouselProps) {\n    const sizeRef = carouselProps.vertical ? carouselProps.itemHeight : carouselProps.itemWidth;\n    const translateProp = carouselProps.vertical ? 'translateY' : 'translateX';\n\n    return {\n        zIndex: carouselProps.data.length - index,\n        opacity: animatedValue.interpolate({\n            inputRange: [-1, 0, 1, 2],\n            outputRange: [0.75, 1, 0.6, 0.4]\n        }),\n        transform: [{\n            rotate: animatedValue.interpolate({\n                inputRange: [-1, 0, 1, 2],\n                outputRange: ['0deg', '0deg', '5deg', '8deg'],\n                extrapolate: 'clamp'\n            })\n        }, {\n            scale: animatedValue.interpolate({\n                inputRange: [-1, 0, 1, 2],\n                outputRange: [0.96, 1, 0.85, 0.7]\n            })\n        }, {\n            [translateProp]: animatedValue.interpolate({\n                inputRange: [-1, 0, 1, 2],\n                outputRange: [\n                    0,\n                    0,\n                    -sizeRef + 30,\n                    -sizeRef * 2 + 45\n                ],\n                extrapolate: 'clamp'\n            })\n        }]\n    };\n}\n\n// Left/right translate effect\nfunction scrollInterpolator3 (index, carouselProps) {\n    const range = [2, 1, 0, -1];\n    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);\n    const outputRange = range;\n\n    return { inputRange, outputRange };\n}\nfunction animatedStyles3 (index, animatedValue, carouselProps) {\n    const sizeRef = carouselProps.vertical ? carouselProps.itemHeight : carouselProps.itemWidth;\n    const translateProp = carouselProps.vertical ? 'translateY' : 'translateX';\n\n    return {\n        zIndex: carouselProps.data.length - index,\n        opacity: animatedValue.interpolate({\n            inputRange: [-1, 0, 1, 2],\n            outputRange: [1, 1, 0.75, 0.5],\n            extrapolate: 'clamp'\n        }),\n        transform: [{\n            [translateProp]: animatedValue.interpolate({\n                inputRange: [-1, 0, 1, 2],\n                outputRange: [\n                    0,\n                    0,\n                    -sizeRef * 2,\n                    -sizeRef\n                ],\n                extrapolate: 'clamp'\n            })\n        }]\n    };\n}\n\n// From https://codeburst.io/horizontal-scroll-animations-in-react-native-18dac6e9c720\nfunction scrollInterpolator4 (index, carouselProps) {\n    const range = [1, 0, -1];\n    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);\n    const outputRange = range;\n\n    return { inputRange, outputRange };\n}\nfunction animatedStyles4 (index, animatedValue, carouselProps) {\n    return {\n        zIndex: carouselProps.data.length - index,\n        opacity: animatedValue.interpolate({\n            inputRange: [-1, 0, 1],\n            outputRange: [0.75, 1, 0.75],\n            extrapolate: 'clamp'\n        }),\n        transform: [\n            {\n                perspective: 1000\n            },\n            {\n                scale: animatedValue.interpolate({\n                    inputRange: [-1, 0, 1],\n                    outputRange: [0.65, 1, 0.65],\n                    extrapolate: 'clamp'\n                })\n            },\n            {\n                rotateX: animatedValue.interpolate({\n                    inputRange: [-1, 0, 1],\n                    outputRange: ['30deg', '0deg', '30deg'],\n                    extrapolate: 'clamp'\n                })\n            },\n            {\n                rotateY: animatedValue.interpolate({\n                    inputRange: [-1, 0, 1],\n                    outputRange: ['-30deg', '0deg', '30deg'],\n                    extrapolate: 'clamp'\n                })\n            }\n        ]\n    };\n}\n\n// Exports\nexport const scrollInterpolators = {\n    scrollInterpolator1,\n    scrollInterpolator2,\n    scrollInterpolator3,\n    scrollInterpolator4\n};\n\nexport const animatedStyles = {\n    animatedStyles1,\n    animatedStyles2,\n    animatedStyles3,\n    animatedStyles4\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n    \"name\": \"react-native-snap-carousel\",\n    \"version\": \"3.9.1\",\n    \"description\": \"Swiper/carousel component for React Native with previews, multiple layouts, parallax images, performant handling of huge numbers of items, and RTL support. Compatible with Android & iOS.\",\n    \"main\": \"src/index.js\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"github.com/meliorence/react-native-snap-carousel\"\n    },\n    \"keywords\": [\n        \"react\",\n        \"native\",\n        \"carousel\",\n        \"slider\",\n        \"swiper\",\n        \"flatlist\",\n        \"scrollview\",\n        \"parallax\",\n        \"images\",\n        \"infinite\",\n        \"scroll\",\n        \"scrolling\",\n        \"items\",\n        \"edge\",\n        \"snap\",\n        \"card\",\n        \"cards\",\n        \"stack\",\n        \"deck\",\n        \"tinder\",\n        \"android\",\n        \"ios\",\n        \"snapping\",\n        \"component\",\n        \"rtl\"\n    ],\n    \"author\": \"Meliorence <contact@meliorence.com> (github.com/meliorence)\",\n    \"license\": \"BSD-3-Clause\",\n    \"dependencies\": {\n        \"prop-types\": \"^15.6.1\",\n        \"react-addons-shallow-compare\": \"15.6.2\"\n    },\n    \"peerDependencies\": {\n        \"react\": \">=15.0.0\",\n        \"react-native\": \"*\"\n    },\n    \"devDependencies\": {\n        \"babel-eslint\": \"^8.2.2\",\n        \"eslint\": \"^4.19.1\",\n        \"eslint-config-standard\": \"^10.2.1\",\n        \"eslint-config-standard-react\": \"^5.0.0\",\n        \"eslint-plugin-import\": \"^2.11.0\",\n        \"eslint-plugin-node\": \"^5.2.1\",\n        \"eslint-plugin-promise\": \"^3.7.0\",\n        \"eslint-plugin-react\": \"^7.7.0\",\n        \"eslint-plugin-standard\": \"^3.0.1\"\n    },\n    \"homepage\": \"https://github.com/meliorence/react-native-snap-carousel\",\n    \"bugs\": {\n        \"url\": \"https://github.com/meliorence/react-native-snap-carousel/issues\"\n    },\n    \"readmeFilename\": \"README.md\"\n}\n"
  },
  {
    "path": "src/carousel/Carousel.js",
    "content": "import React, { Component } from 'react';\nimport { Animated, Easing, FlatList, I18nManager, Platform, ScrollView, View, ViewPropTypes } from 'react-native';\nimport PropTypes from 'prop-types';\nimport shallowCompare from 'react-addons-shallow-compare';\nimport {\n    defaultScrollInterpolator,\n    stackScrollInterpolator,\n    tinderScrollInterpolator,\n    defaultAnimatedStyles,\n    shiftAnimatedStyles,\n    stackAnimatedStyles,\n    tinderAnimatedStyles\n} from '../utils/animations';\n\nconst IS_IOS = Platform.OS === 'ios';\n\n// Native driver for scroll events\n// See: https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html\nconst AnimatedFlatList = FlatList ? Animated.createAnimatedComponent(FlatList) : null;\nconst AnimatedScrollView = Animated.createAnimatedComponent(ScrollView);\n\n// React Native automatically handles RTL layouts; unfortunately, it's buggy with horizontal ScrollView\n// See https://github.com/facebook/react-native/issues/11960\n// NOTE: the following variable is not declared in the constructor\n// otherwise it is undefined at init, which messes with custom indexes\nconst IS_RTL = I18nManager.isRTL;\n\nexport default class Carousel extends Component {\n\n    static propTypes = {\n        data: PropTypes.array.isRequired,\n        renderItem: PropTypes.func.isRequired,\n        itemWidth: PropTypes.number, // required for horizontal carousel\n        itemHeight: PropTypes.number, // required for vertical carousel\n        sliderWidth: PropTypes.number, // required for horizontal carousel\n        sliderHeight: PropTypes.number, // required for vertical carousel\n        activeAnimationType: PropTypes.string,\n        activeAnimationOptions: PropTypes.object,\n        activeSlideAlignment: PropTypes.oneOf(['center', 'end', 'start']),\n        activeSlideOffset: PropTypes.number,\n        apparitionDelay: PropTypes.number,\n        autoplay: PropTypes.bool,\n        autoplayDelay: PropTypes.number,\n        autoplayInterval: PropTypes.number,\n        callbackOffsetMargin: PropTypes.number,\n        containerCustomStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        contentContainerCustomStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        enableMomentum: PropTypes.bool,\n        enableSnap: PropTypes.bool,\n        firstItem: PropTypes.number,\n        hasParallaxImages: PropTypes.bool,\n        inactiveSlideOpacity: PropTypes.number,\n        inactiveSlideScale: PropTypes.number,\n        inactiveSlideShift: PropTypes.number,\n        layout: PropTypes.oneOf(['default', 'stack', 'tinder']),\n        layoutCardOffset: PropTypes.number,\n        lockScrollTimeoutDuration: PropTypes.number,\n        lockScrollWhileSnapping: PropTypes.bool,\n        loop: PropTypes.bool,\n        loopClonesPerSide: PropTypes.number,\n        scrollEnabled: PropTypes.bool,\n        scrollInterpolator: PropTypes.func,\n        slideInterpolatedStyle: PropTypes.func,\n        slideStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        shouldOptimizeUpdates: PropTypes.bool,\n        swipeThreshold: PropTypes.number,\n        useScrollView: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),\n        vertical: PropTypes.bool,\n        onBeforeSnapToItem: PropTypes.func,\n        onSnapToItem: PropTypes.func\n    };\n\n    static defaultProps = {\n        activeAnimationType: 'timing',\n        activeAnimationOptions: null,\n        activeSlideAlignment: 'center',\n        activeSlideOffset: 20,\n        apparitionDelay: 0,\n        autoplay: false,\n        autoplayDelay: 1000,\n        autoplayInterval: 3000,\n        callbackOffsetMargin: 5,\n        containerCustomStyle: {},\n        contentContainerCustomStyle: {},\n        enableMomentum: false,\n        enableSnap: true,\n        firstItem: 0,\n        hasParallaxImages: false,\n        inactiveSlideOpacity: 0.7,\n        inactiveSlideScale: 0.9,\n        inactiveSlideShift: 0,\n        layout: 'default',\n        lockScrollTimeoutDuration: 1000,\n        lockScrollWhileSnapping: false,\n        loop: false,\n        loopClonesPerSide: 3,\n        scrollEnabled: true,\n        slideStyle: {},\n        shouldOptimizeUpdates: true,\n        swipeThreshold: 20,\n        useScrollView: !AnimatedFlatList,\n        vertical: false\n    }\n\n    constructor (props) {\n        super(props);\n\n        this.state = {\n            hideCarousel: true,\n            interpolators: []\n        };\n\n        // The following values are not stored in the state because 'setState()' is asynchronous\n        // and this results in an absolutely crappy behavior on Android while swiping (see #156)\n        const initialActiveItem = this._getFirstItem(props.firstItem);\n        this._activeItem = initialActiveItem;\n        this._previousActiveItem = initialActiveItem;\n        this._previousFirstItem = initialActiveItem;\n        this._previousItemsLength = initialActiveItem;\n\n        this._mounted = false;\n        this._positions = [];\n        this._currentContentOffset = 0; // store ScrollView's scroll position\n        this._canFireBeforeCallback = false;\n        this._canFireCallback = false;\n        this._scrollOffsetRef = null;\n        this._onScrollTriggered = true; // used when momentum is enabled to prevent an issue with edges items\n        this._lastScrollDate = 0; // used to work around a FlatList bug\n        this._scrollEnabled = props.scrollEnabled !== false;\n\n        this._initPositionsAndInterpolators = this._initPositionsAndInterpolators.bind(this);\n        this._renderItem = this._renderItem.bind(this);\n        this._onSnap = this._onSnap.bind(this);\n\n        this._onLayout = this._onLayout.bind(this);\n        this._onScroll = this._onScroll.bind(this);\n        this._onScrollBeginDrag = props.enableSnap ? this._onScrollBeginDrag.bind(this) : undefined;\n        this._onScrollEnd = props.enableSnap || props.autoplay ? this._onScrollEnd.bind(this) : undefined;\n        this._onScrollEndDrag = !props.enableMomentum ? this._onScrollEndDrag.bind(this) : undefined;\n        this._onMomentumScrollEnd = props.enableMomentum ? this._onMomentumScrollEnd.bind(this) : undefined;\n        this._onTouchStart = this._onTouchStart.bind(this);\n        this._onTouchEnd = this._onTouchEnd.bind(this);\n        this._onTouchRelease = this._onTouchRelease.bind(this);\n\n        this._getKeyExtractor = this._getKeyExtractor.bind(this);\n\n        this._setScrollHandler(props);\n\n        // This bool aims at fixing an iOS bug due to scrollTo that triggers onMomentumScrollEnd.\n        // onMomentumScrollEnd fires this._snapScroll, thus creating an infinite loop.\n        this._ignoreNextMomentum = false;\n\n        // Warnings\n        if (!ViewPropTypes) {\n            console.warn('react-native-snap-carousel: It is recommended to use at least version 0.44 of React Native with the plugin');\n        }\n        if (!props.vertical && (!props.sliderWidth || !props.itemWidth)) {\n            console.error('react-native-snap-carousel: You need to specify both `sliderWidth` and `itemWidth` for horizontal carousels');\n        }\n        if (props.vertical && (!props.sliderHeight || !props.itemHeight)) {\n            console.error('react-native-snap-carousel: You need to specify both `sliderHeight` and `itemHeight` for vertical carousels');\n        }\n        if (props.apparitionDelay && !IS_IOS && !props.useScrollView) {\n            console.warn('react-native-snap-carousel: Using `apparitionDelay` on Android is not recommended since it can lead to rendering issues');\n        }\n        if (props.customAnimationType || props.customAnimationOptions) {\n            console.warn('react-native-snap-carousel: Props `customAnimationType` and `customAnimationOptions` have been renamed to `activeAnimationType` and `activeAnimationOptions`');\n        }\n        if (props.onScrollViewScroll) {\n            console.error('react-native-snap-carousel: Prop `onScrollViewScroll` has been removed. Use `onScroll` instead');\n        }\n    }\n\n    componentDidMount () {\n        const { apparitionDelay, autoplay, firstItem } = this.props;\n        const _firstItem = this._getFirstItem(firstItem);\n        const apparitionCallback = () => {\n            this.setState({ hideCarousel: false });\n            if (autoplay) {\n                this.startAutoplay();\n            }\n        };\n\n        this._mounted = true;\n        this._initPositionsAndInterpolators();\n\n        // Without 'requestAnimationFrame' or a `0` timeout, images will randomly not be rendered on Android...\n        requestAnimationFrame(() => {\n            if (!this._mounted) {\n                return;\n            }\n\n            this._snapToItem(_firstItem, false, false, true, false);\n            this._hackActiveSlideAnimation(_firstItem, 'start', true);\n\n            if (apparitionDelay) {\n                this._apparitionTimeout = setTimeout(() => {\n                    apparitionCallback();\n                }, apparitionDelay);\n            } else {\n                apparitionCallback();\n            }\n        });\n    }\n\n    shouldComponentUpdate (nextProps, nextState) {\n        if (this.props.shouldOptimizeUpdates === false) {\n            return true;\n        } else {\n            return shallowCompare(this, nextProps, nextState);\n        }\n    }\n\n    componentDidUpdate (prevProps) {\n        const { interpolators } = this.state;\n        const { firstItem, itemHeight, itemWidth, scrollEnabled, sliderHeight, sliderWidth } = this.props;\n        const itemsLength = this._getCustomDataLength(this.props);\n\n        if (!itemsLength) {\n            return;\n        }\n\n        const nextFirstItem = this._getFirstItem(firstItem, this.props);\n        let nextActiveItem = this._activeItem || this._activeItem === 0 ? this._activeItem : nextFirstItem;\n\n        const hasNewSliderWidth = sliderWidth && sliderWidth !== prevProps.sliderWidth;\n        const hasNewSliderHeight = sliderHeight && sliderHeight !== prevProps.sliderHeight;\n        const hasNewItemWidth = itemWidth && itemWidth !== prevProps.itemWidth;\n        const hasNewItemHeight = itemHeight && itemHeight !== prevProps.itemHeight;\n        const hasNewScrollEnabled = scrollEnabled !== prevProps.scrollEnabled;\n\n        // Prevent issues with dynamically removed items\n        if (nextActiveItem > itemsLength - 1) {\n            nextActiveItem = itemsLength - 1;\n        }\n\n        // Handle changing scrollEnabled independent of user -> carousel interaction\n        if (hasNewScrollEnabled) {\n            this._setScrollEnabled(scrollEnabled);\n        }\n\n        if (interpolators.length !== itemsLength || hasNewSliderWidth ||\n            hasNewSliderHeight || hasNewItemWidth || hasNewItemHeight) {\n            this._activeItem = nextActiveItem;\n            this._previousItemsLength = itemsLength;\n\n            this._initPositionsAndInterpolators(this.props);\n\n            // Handle scroll issue when dynamically removing items (see #133)\n            // This also fixes first item's active state on Android\n            // Because 'initialScrollIndex' apparently doesn't trigger scroll\n            if (this._previousItemsLength > itemsLength) {\n                this._hackActiveSlideAnimation(nextActiveItem, null, true);\n            }\n\n            if (hasNewSliderWidth || hasNewSliderHeight || hasNewItemWidth || hasNewItemHeight) {\n                this._snapToItem(nextActiveItem, false, false, false, false);\n            }\n        } else if (nextFirstItem !== this._previousFirstItem && nextFirstItem !== this._activeItem) {\n            this._activeItem = nextFirstItem;\n            this._previousFirstItem = nextFirstItem;\n            this._snapToItem(nextFirstItem, false, true, false, false);\n        }\n\n        if (this.props.onScroll !== prevProps.onScroll) {\n          this._setScrollHandler(this.props);\n        }\n    }\n\n    componentWillUnmount () {\n        this._mounted = false;\n        this.stopAutoplay();\n        clearTimeout(this._apparitionTimeout);\n        clearTimeout(this._hackSlideAnimationTimeout);\n        clearTimeout(this._enableAutoplayTimeout);\n        clearTimeout(this._autoplayTimeout);\n        clearTimeout(this._snapNoMomentumTimeout);\n        clearTimeout(this._edgeItemTimeout);\n        clearTimeout(this._lockScrollTimeout);\n    }\n\n    get realIndex () {\n        return this._activeItem;\n    }\n\n    get currentIndex () {\n        return this._getDataIndex(this._activeItem);\n    }\n\n    get currentScrollPosition () {\n        return this._currentContentOffset;\n    }\n\n    _setScrollHandler(props) {\n      // Native driver for scroll events\n      const scrollEventConfig = {\n        listener: this._onScroll,\n        useNativeDriver: true,\n      };\n      this._scrollPos = new Animated.Value(0);\n      const argMapping = props.vertical\n        ? [{ nativeEvent: { contentOffset: { y: this._scrollPos } } }]\n        : [{ nativeEvent: { contentOffset: { x: this._scrollPos } } }];\n\n      if (props.onScroll && Array.isArray(props.onScroll._argMapping)) {\n        // Because of a react-native issue https://github.com/facebook/react-native/issues/13294\n        argMapping.pop();\n        const [ argMap ] = props.onScroll._argMapping;\n        if (argMap && argMap.nativeEvent && argMap.nativeEvent.contentOffset) {\n          // Shares the same animated value passed in props\n          this._scrollPos =\n            argMap.nativeEvent.contentOffset.x ||\n            argMap.nativeEvent.contentOffset.y ||\n            this._scrollPos;\n        }\n        argMapping.push(...props.onScroll._argMapping);\n      }\n      this._onScrollHandler = Animated.event(\n        argMapping,\n        scrollEventConfig\n      );\n    }\n\n    _needsScrollView () {\n        const { useScrollView } = this.props;\n        return useScrollView || !AnimatedFlatList || this._shouldUseStackLayout() || this._shouldUseTinderLayout();\n    }\n\n    _needsRTLAdaptations () {\n        const { vertical } = this.props;\n        return IS_RTL && !IS_IOS && !vertical;\n    }\n\n    _canLockScroll () {\n        const { scrollEnabled, enableMomentum, lockScrollWhileSnapping } = this.props;\n        return scrollEnabled && !enableMomentum && lockScrollWhileSnapping;\n    }\n\n    _enableLoop () {\n        const { data, enableSnap, loop } = this.props;\n        return enableSnap && loop && data && data.length && data.length > 1;\n    }\n\n    _shouldAnimateSlides (props = this.props) {\n        const { inactiveSlideOpacity, inactiveSlideScale, scrollInterpolator, slideInterpolatedStyle } = props;\n        return inactiveSlideOpacity < 1 ||\n            inactiveSlideScale < 1 ||\n            !!scrollInterpolator ||\n            !!slideInterpolatedStyle ||\n            this._shouldUseShiftLayout() ||\n            this._shouldUseStackLayout() ||\n            this._shouldUseTinderLayout();\n    }\n\n    _shouldUseCustomAnimation () {\n        const { activeAnimationOptions } = this.props;\n        return !!activeAnimationOptions && !this._shouldUseStackLayout() && !this._shouldUseTinderLayout();\n    }\n\n    _shouldUseShiftLayout () {\n        const { inactiveSlideShift, layout } = this.props;\n        return layout === 'default' && inactiveSlideShift !== 0;\n    }\n\n    _shouldUseStackLayout () {\n        return this.props.layout === 'stack';\n    }\n\n    _shouldUseTinderLayout () {\n        return this.props.layout === 'tinder';\n    }\n\n    _getCustomData (props = this.props) {\n        const { data, loopClonesPerSide } = props;\n        const dataLength = data && data.length;\n\n        if (!dataLength) {\n            return [];\n        }\n\n        if (!this._enableLoop()) {\n            return data;\n        }\n\n        let previousItems = [];\n        let nextItems = [];\n\n        if (loopClonesPerSide > dataLength) {\n            const dataMultiplier = Math.floor(loopClonesPerSide / dataLength);\n            const remainder = loopClonesPerSide % dataLength;\n\n            for (let i = 0; i < dataMultiplier; i++) {\n                previousItems.push(...data);\n                nextItems.push(...data);\n            }\n\n            previousItems.unshift(...data.slice(-remainder));\n            nextItems.push(...data.slice(0, remainder));\n        } else {\n            previousItems = data.slice(-loopClonesPerSide);\n            nextItems = data.slice(0, loopClonesPerSide);\n        }\n\n        return previousItems.concat(data, nextItems);\n    }\n\n    _getCustomDataLength (props = this.props) {\n        const { data, loopClonesPerSide } = props;\n        const dataLength = data && data.length;\n\n        if (!dataLength) {\n            return 0;\n        }\n\n        return this._enableLoop() ? dataLength + (2 * loopClonesPerSide) : dataLength;\n    }\n\n    _getCustomIndex (index, props = this.props) {\n        const itemsLength = this._getCustomDataLength(props);\n\n        if (!itemsLength || (!index && index !== 0)) {\n            return 0;\n        }\n\n        return this._needsRTLAdaptations() ? itemsLength - index - 1 : index;\n    }\n\n    _getDataIndex (index) {\n        const { data, loopClonesPerSide } = this.props;\n        const dataLength = data && data.length;\n\n        if (!this._enableLoop() || !dataLength) {\n            return index;\n        }\n\n        if (index >= dataLength + loopClonesPerSide) {\n            return loopClonesPerSide > dataLength ?\n                (index - loopClonesPerSide) % dataLength :\n                index - dataLength - loopClonesPerSide;\n        } else if (index < loopClonesPerSide) {\n            // TODO: is there a simpler way of determining the interpolated index?\n            if (loopClonesPerSide > dataLength) {\n                const baseDataIndexes = [];\n                const dataIndexes = [];\n                const dataMultiplier = Math.floor(loopClonesPerSide / dataLength);\n                const remainder = loopClonesPerSide % dataLength;\n\n                for (let i = 0; i < dataLength; i++) {\n                    baseDataIndexes.push(i);\n                }\n\n                for (let j = 0; j < dataMultiplier; j++) {\n                    dataIndexes.push(...baseDataIndexes);\n                }\n\n                dataIndexes.unshift(...baseDataIndexes.slice(-remainder));\n                return dataIndexes[index];\n            } else {\n                return index + dataLength - loopClonesPerSide;\n            }\n        } else {\n            return index - loopClonesPerSide;\n        }\n    }\n\n    // Used with `snapToItem()` and 'PaginationDot'\n    _getPositionIndex (index) {\n        const { loop, loopClonesPerSide } = this.props;\n        return loop ? index + loopClonesPerSide : index;\n    }\n\n    _getFirstItem (index, props = this.props) {\n        const { loopClonesPerSide } = props;\n        const itemsLength = this._getCustomDataLength(props);\n\n        if (!itemsLength || index > itemsLength - 1 || index < 0) {\n            return 0;\n        }\n\n        return this._enableLoop() ? index + loopClonesPerSide : index;\n    }\n\n    _getWrappedRef () {\n        if (this._carouselRef && (\n            (this._needsScrollView() && this._carouselRef.scrollTo) ||\n            (!this._needsScrollView() && this._carouselRef.scrollToOffset)\n        )) {\n            return this._carouselRef;\n        }\n        // https://github.com/facebook/react-native/issues/10635\n        // https://stackoverflow.com/a/48786374/8412141\n        return this._carouselRef && this._carouselRef.getNode && this._carouselRef.getNode();\n    }\n\n    _getScrollEnabled () {\n        return this._scrollEnabled;\n    }\n\n    _setScrollEnabled (scrollEnabled = true) {\n        const wrappedRef = this._getWrappedRef();\n\n        if (!wrappedRef || !wrappedRef.setNativeProps) {\n            return;\n        }\n\n        // 'setNativeProps()' is used instead of 'setState()' because the latter\n        // really takes a toll on Android behavior when momentum is disabled\n        wrappedRef.setNativeProps({ scrollEnabled });\n        this._scrollEnabled = scrollEnabled;\n    }\n\n    _getKeyExtractor (item, index) {\n        return this._needsScrollView() ? `scrollview-item-${index}` : `flatlist-item-${index}`;\n    }\n\n    _getScrollOffset (event) {\n        const { vertical } = this.props;\n        return (event && event.nativeEvent && event.nativeEvent.contentOffset &&\n            event.nativeEvent.contentOffset[vertical ? 'y' : 'x']) || 0;\n    }\n\n    _getContainerInnerMargin (opposite = false) {\n        const { sliderWidth, sliderHeight, itemWidth, itemHeight, vertical, activeSlideAlignment } = this.props;\n\n        if ((activeSlideAlignment === 'start' && !opposite) ||\n            (activeSlideAlignment === 'end' && opposite)) {\n            return 0;\n        } else if ((activeSlideAlignment === 'end' && !opposite) ||\n            (activeSlideAlignment === 'start' && opposite)) {\n            return vertical ? sliderHeight - itemHeight : sliderWidth - itemWidth;\n        } else {\n            return vertical ? (sliderHeight - itemHeight) / 2 : (sliderWidth - itemWidth) / 2;\n        }\n    }\n\n    _getViewportOffset () {\n        const { sliderWidth, sliderHeight, itemWidth, itemHeight, vertical, activeSlideAlignment } = this.props;\n\n        if (activeSlideAlignment === 'start') {\n            return vertical ? itemHeight / 2 : itemWidth / 2;\n        } else if (activeSlideAlignment === 'end') {\n            return vertical ?\n                sliderHeight - (itemHeight / 2) :\n                sliderWidth - (itemWidth / 2);\n        } else {\n            return vertical ? sliderHeight / 2 : sliderWidth / 2;\n        }\n    }\n\n    _getCenter (offset) {\n        return offset + this._getViewportOffset() - this._getContainerInnerMargin();\n    }\n\n    _getActiveItem (offset) {\n        const { activeSlideOffset, swipeThreshold } = this.props;\n        const center = this._getCenter(offset);\n        const centerOffset = activeSlideOffset || swipeThreshold;\n\n        for (let i = 0; i < this._positions.length; i++) {\n            const { start, end } = this._positions[i];\n            if (center + centerOffset >= start && center - centerOffset <= end) {\n                return i;\n            }\n        }\n\n        const lastIndex = this._positions.length - 1;\n        if (this._positions[lastIndex] && center - centerOffset > this._positions[lastIndex].end) {\n            return lastIndex;\n        }\n\n        return 0;\n    }\n\n    _initPositionsAndInterpolators (props = this.props) {\n        const { data, itemWidth, itemHeight, scrollInterpolator, vertical } = props;\n        const sizeRef = vertical ? itemHeight : itemWidth;\n\n        if (!data || !data.length) {\n            return;\n        }\n\n        let interpolators = [];\n        this._positions = [];\n\n        this._getCustomData(props).forEach((itemData, index) => {\n            const _index = this._getCustomIndex(index, props);\n            let animatedValue;\n\n            this._positions[index] = {\n                start: index * sizeRef,\n                end: index * sizeRef + sizeRef\n            };\n\n            if (!this._shouldAnimateSlides(props)) {\n                animatedValue = new Animated.Value(1);\n            } else if (this._shouldUseCustomAnimation()) {\n                animatedValue = new Animated.Value(_index === this._activeItem ? 1 : 0);\n            } else {\n                let interpolator;\n\n                if (scrollInterpolator) {\n                    interpolator = scrollInterpolator(_index, props);\n                } else if (this._shouldUseStackLayout()) {\n                    interpolator = stackScrollInterpolator(_index, props);\n                } else if (this._shouldUseTinderLayout()) {\n                    interpolator = tinderScrollInterpolator(_index, props);\n                }\n\n                if (!interpolator || !interpolator.inputRange || !interpolator.outputRange) {\n                    interpolator = defaultScrollInterpolator(_index, props);\n                }\n\n                animatedValue = this._scrollPos.interpolate({\n                    ...interpolator,\n                    extrapolate: 'clamp'\n                });\n            }\n\n            interpolators.push(animatedValue);\n        });\n\n        this.setState({ interpolators });\n    }\n\n    _getSlideAnimation (index, toValue) {\n        const { interpolators } = this.state;\n        const { activeAnimationType, activeAnimationOptions } = this.props;\n\n        const animatedValue = interpolators && interpolators[index];\n\n        if (!animatedValue && animatedValue !== 0) {\n            return null;\n        }\n\n        const animationCommonOptions = {\n            isInteraction: false,\n            useNativeDriver: true,\n            ...activeAnimationOptions,\n            toValue: toValue\n        };\n\n        return Animated.parallel([\n            Animated['timing'](\n                animatedValue,\n                { ...animationCommonOptions, easing: Easing.linear }\n            ),\n            Animated[activeAnimationType](\n                animatedValue,\n                { ...animationCommonOptions }\n            )\n        ]);\n    }\n\n    _playCustomSlideAnimation (current, next) {\n        const { interpolators } = this.state;\n        const itemsLength = this._getCustomDataLength();\n        const _currentIndex = this._getCustomIndex(current);\n        const _currentDataIndex = this._getDataIndex(_currentIndex);\n        const _nextIndex = this._getCustomIndex(next);\n        const _nextDataIndex = this._getDataIndex(_nextIndex);\n        let animations = [];\n\n        // Keep animations in sync when looping\n        if (this._enableLoop()) {\n            for (let i = 0; i < itemsLength; i++) {\n                if (this._getDataIndex(i) === _currentDataIndex && interpolators[i]) {\n                    animations.push(this._getSlideAnimation(i, 0));\n                } else if (this._getDataIndex(i) === _nextDataIndex && interpolators[i]) {\n                    animations.push(this._getSlideAnimation(i, 1));\n                }\n            }\n        } else {\n            if (interpolators[current]) {\n                animations.push(this._getSlideAnimation(current, 0));\n            }\n            if (interpolators[next]) {\n                animations.push(this._getSlideAnimation(next, 1));\n            }\n        }\n\n        Animated.parallel(animations, { stopTogether: false }).start();\n    }\n\n    _hackActiveSlideAnimation (index, goTo, force = false) {\n        const { data } = this.props;\n\n        if (!this._mounted || !this._carouselRef || !this._positions[index] || (!force && this._enableLoop())) {\n            return;\n        }\n\n        const offset = this._positions[index] && this._positions[index].start;\n\n        if (!offset && offset !== 0) {\n            return;\n        }\n\n        const itemsLength = data && data.length;\n        const direction = goTo || itemsLength === 1 ? 'start' : 'end';\n\n        this._scrollTo(offset + (direction === 'start' ? -1 : 1), false);\n\n        clearTimeout(this._hackSlideAnimationTimeout);\n        this._hackSlideAnimationTimeout = setTimeout(() => {\n            this._scrollTo(offset, false);\n        }, 50); // works randomly when set to '0'\n    }\n\n    _lockScroll () {\n        const { lockScrollTimeoutDuration } = this.props;\n        clearTimeout(this._lockScrollTimeout);\n        this._lockScrollTimeout = setTimeout(() => {\n            this._releaseScroll();\n        }, lockScrollTimeoutDuration);\n        this._setScrollEnabled(false);\n    }\n\n    _releaseScroll () {\n        clearTimeout(this._lockScrollTimeout);\n        this._setScrollEnabled(true);\n    }\n\n    _repositionScroll (index) {\n        const { data, loopClonesPerSide } = this.props;\n        const dataLength = data && data.length;\n\n        if (!this._enableLoop() || !dataLength ||\n            (index >= loopClonesPerSide && index < dataLength + loopClonesPerSide)) {\n            return;\n        }\n\n        let repositionTo = index;\n\n        if (index >= dataLength + loopClonesPerSide) {\n            repositionTo = index - dataLength;\n        } else if (index < loopClonesPerSide) {\n            repositionTo = index + dataLength;\n        }\n\n        this._snapToItem(repositionTo, false, false, false, false);\n    }\n\n    _scrollTo (offset, animated = true) {\n        const { vertical } = this.props;\n        const wrappedRef = this._getWrappedRef();\n\n        if (!this._mounted || !wrappedRef) {\n            return;\n        }\n\n        const specificOptions = this._needsScrollView() ? {\n            x: vertical ? 0 : offset,\n            y: vertical ? offset : 0\n        } : {\n            offset\n        };\n        const options = {\n            ...specificOptions,\n            animated\n        };\n\n        if (this._needsScrollView()) {\n            wrappedRef.scrollTo(options);\n        } else {\n            wrappedRef.scrollToOffset(options);\n        }\n    }\n\n    _onScroll (event) {\n        const { callbackOffsetMargin, enableMomentum, onScroll } = this.props;\n\n        const scrollOffset = event ? this._getScrollOffset(event) : this._currentContentOffset;\n        const nextActiveItem = this._getActiveItem(scrollOffset);\n        const itemReached = nextActiveItem === this._itemToSnapTo;\n        const scrollConditions =\n            scrollOffset >= this._scrollOffsetRef - callbackOffsetMargin &&\n            scrollOffset <= this._scrollOffsetRef + callbackOffsetMargin;\n\n        this._currentContentOffset = scrollOffset;\n        this._onScrollTriggered = true;\n        this._lastScrollDate = Date.now();\n\n        if (this._activeItem !== nextActiveItem && this._shouldUseCustomAnimation()) {\n            this._playCustomSlideAnimation(this._activeItem, nextActiveItem);\n        }\n\n        if (enableMomentum) {\n            clearTimeout(this._snapNoMomentumTimeout);\n\n            if (this._activeItem !== nextActiveItem) {\n                this._activeItem = nextActiveItem;\n            }\n\n            if (itemReached) {\n                if (this._canFireBeforeCallback) {\n                    this._onBeforeSnap(this._getDataIndex(nextActiveItem));\n                }\n\n                if (scrollConditions && this._canFireCallback) {\n                    this._onSnap(this._getDataIndex(nextActiveItem));\n                }\n            }\n        } else if (this._activeItem !== nextActiveItem && itemReached) {\n            if (this._canFireBeforeCallback) {\n                this._onBeforeSnap(this._getDataIndex(nextActiveItem));\n            }\n\n            if (scrollConditions) {\n                this._activeItem = nextActiveItem;\n\n                if (this._canLockScroll()) {\n                    this._releaseScroll();\n                }\n\n                if (this._canFireCallback) {\n                    this._onSnap(this._getDataIndex(nextActiveItem));\n                }\n            }\n        }\n\n        if (nextActiveItem === this._itemToSnapTo &&\n            scrollOffset === this._scrollOffsetRef) {\n            this._repositionScroll(nextActiveItem);\n        }\n\n        if (typeof onScroll === \"function\" && event) {\n            onScroll(event);\n        }\n    }\n\n    _onStartShouldSetResponderCapture (event) {\n        const { onStartShouldSetResponderCapture } = this.props;\n\n        if (onStartShouldSetResponderCapture) {\n            onStartShouldSetResponderCapture(event);\n        }\n\n        return this._getScrollEnabled();\n    }\n\n    _onTouchStart () {\n        const { onTouchStart } = this.props\n\n        // `onTouchStart` is fired even when `scrollEnabled` is set to `false`\n        if (this._getScrollEnabled() !== false && this._autoplaying) {\n            this.pauseAutoPlay();\n        }\n\n        if (onTouchStart) {\n            onTouchStart()\n        }\n    }\n\n    _onTouchEnd () {\n        const { onTouchEnd } = this.props\n\n        if (this._getScrollEnabled() !== false && this._autoplay && !this._autoplaying) {\n            // This event is buggy on Android, so a fallback is provided in _onScrollEnd()\n            this.startAutoplay();\n        }\n\n        if (onTouchEnd) {\n            onTouchEnd()\n        }\n    }\n\n    // Used when `enableSnap` is ENABLED\n    _onScrollBeginDrag (event) {\n        const { onScrollBeginDrag } = this.props;\n\n        if (!this._getScrollEnabled()) {\n            return;\n        }\n\n        this._scrollStartOffset = this._getScrollOffset(event);\n        this._scrollStartActive = this._getActiveItem(this._scrollStartOffset);\n        this._ignoreNextMomentum = false;\n        // this._canFireCallback = false;\n\n        if (onScrollBeginDrag) {\n            onScrollBeginDrag(event);\n        }\n    }\n\n    // Used when `enableMomentum` is DISABLED\n    _onScrollEndDrag (event) {\n        const { onScrollEndDrag } = this.props;\n\n        if (this._carouselRef) {\n            this._onScrollEnd && this._onScrollEnd();\n        }\n\n        if (onScrollEndDrag) {\n            onScrollEndDrag(event);\n        }\n    }\n\n    // Used when `enableMomentum` is ENABLED\n    _onMomentumScrollEnd (event) {\n        const { onMomentumScrollEnd } = this.props;\n\n        if (this._carouselRef) {\n            this._onScrollEnd && this._onScrollEnd();\n        }\n\n        if (onMomentumScrollEnd) {\n            onMomentumScrollEnd(event);\n        }\n    }\n\n    _onScrollEnd (event) {\n        const { autoplayDelay, enableSnap } = this.props;\n\n        if (this._ignoreNextMomentum) {\n            // iOS fix\n            this._ignoreNextMomentum = false;\n            return;\n        }\n\n        if (this._currentContentOffset === this._scrollEndOffset) {\n            return;\n        }\n\n        this._scrollEndOffset = this._currentContentOffset;\n        this._scrollEndActive = this._getActiveItem(this._scrollEndOffset);\n\n        if (enableSnap) {\n            this._snapScroll(this._scrollEndOffset - this._scrollStartOffset);\n        }\n\n        // The touchEnd event is buggy on Android, so this will serve as a fallback whenever needed\n        // https://github.com/facebook/react-native/issues/9439\n        if (this._autoplay && !this._autoplaying) {\n            clearTimeout(this._enableAutoplayTimeout);\n            this._enableAutoplayTimeout = setTimeout(() => {\n                this.startAutoplay();\n            }, autoplayDelay + 50);\n        }\n    }\n\n    // Due to a bug, this event is only fired on iOS\n    // https://github.com/facebook/react-native/issues/6791\n    // it's fine since we're only fixing an iOS bug in it, so ...\n    _onTouchRelease (event) {\n        const { enableMomentum } = this.props;\n\n        if (enableMomentum && IS_IOS) {\n            clearTimeout(this._snapNoMomentumTimeout);\n            this._snapNoMomentumTimeout = setTimeout(() => {\n                this._snapToItem(this._activeItem);\n            }, 100);\n        }\n    }\n\n    _onLayout (event) {\n        const { onLayout } = this.props;\n\n        // Prevent unneeded actions during the first 'onLayout' (triggered on init)\n        if (this._onLayoutInitDone) {\n            this._initPositionsAndInterpolators();\n            this._snapToItem(this._activeItem, false, false, false, false);\n        } else {\n            this._onLayoutInitDone = true;\n        }\n\n        if (onLayout) {\n            onLayout(event);\n        }\n    }\n\n    _snapScroll (delta) {\n        const { swipeThreshold } = this.props;\n\n        // When using momentum and releasing the touch with\n        // no velocity, scrollEndActive will be undefined (iOS)\n        if (!this._scrollEndActive && this._scrollEndActive !== 0 && IS_IOS) {\n            this._scrollEndActive = this._scrollStartActive;\n        }\n\n        if (this._scrollStartActive !== this._scrollEndActive) {\n            // Snap to the new active item\n            this._snapToItem(this._scrollEndActive);\n        } else {\n            // Snap depending on delta\n            if (delta > 0) {\n                if (delta > swipeThreshold) {\n                    this._snapToItem(this._scrollStartActive + 1);\n                } else {\n                    this._snapToItem(this._scrollEndActive);\n                }\n            } else if (delta < 0) {\n                if (delta < -swipeThreshold) {\n                    this._snapToItem(this._scrollStartActive - 1);\n                } else {\n                    this._snapToItem(this._scrollEndActive);\n                }\n            } else {\n                // Snap to current\n                this._snapToItem(this._scrollEndActive);\n            }\n        }\n    }\n\n    _snapToItem (index, animated = true, fireCallback = true, initial = false, lockScroll = true) {\n        const { enableMomentum, onSnapToItem, onBeforeSnapToItem } = this.props;\n        const itemsLength = this._getCustomDataLength();\n        const wrappedRef = this._getWrappedRef();\n\n        if (!itemsLength || !wrappedRef) {\n            return;\n        }\n\n        if (!index || index < 0) {\n            index = 0;\n        } else if (itemsLength > 0 && index >= itemsLength) {\n            index = itemsLength - 1;\n        }\n\n        if (index !== this._previousActiveItem) {\n            this._previousActiveItem = index;\n\n            // Placed here to allow overscrolling for edges items\n            if (lockScroll && this._canLockScroll()) {\n                this._lockScroll();\n            }\n\n            if (fireCallback) {\n                if (onBeforeSnapToItem) {\n                    this._canFireBeforeCallback = true;\n                }\n\n                if (onSnapToItem) {\n                    this._canFireCallback = true;\n                }\n            }\n        }\n\n        this._itemToSnapTo = index;\n        this._scrollOffsetRef = this._positions[index] && this._positions[index].start;\n        this._onScrollTriggered = false;\n\n        if (!this._scrollOffsetRef && this._scrollOffsetRef !== 0) {\n            return;\n        }\n\n        this._scrollTo(this._scrollOffsetRef, animated);\n\n        this._scrollEndOffset = this._currentContentOffset;\n\n        if (enableMomentum) {\n            // iOS fix, check the note in the constructor\n            if (!initial) {\n                this._ignoreNextMomentum = true;\n            }\n\n            // When momentum is enabled and the user is overscrolling or swiping very quickly,\n            // 'onScroll' is not going to be triggered for edge items. Then callback won't be\n            // fired and loop won't work since the scrollview is not going to be repositioned.\n            // As a workaround, '_onScroll()' will be called manually for these items if a given\n            // condition hasn't been met after a small delay.\n            // WARNING: this is ok only when relying on 'momentumScrollEnd', not with 'scrollEndDrag'\n            if (index === 0 || index === itemsLength - 1) {\n                clearTimeout(this._edgeItemTimeout);\n                this._edgeItemTimeout = setTimeout(() => {\n                    if (!initial && index === this._activeItem && !this._onScrollTriggered) {\n                        this._onScroll();\n                    }\n                }, 250);\n            }\n        }\n    }\n\n    _onBeforeSnap (index) {\n        const { onBeforeSnapToItem } = this.props;\n\n        if (!this._carouselRef) {\n            return;\n        }\n\n        this._canFireBeforeCallback = false;\n        onBeforeSnapToItem && onBeforeSnapToItem(index);\n    }\n\n    _onSnap (index) {\n        const { onSnapToItem } = this.props;\n\n        if (!this._carouselRef) {\n            return;\n        }\n\n        this._canFireCallback = false;\n        onSnapToItem && onSnapToItem(index);\n    }\n\n    startAutoplay () {\n        const { autoplayInterval, autoplayDelay } = this.props;\n        this._autoplay = true;\n\n        if (this._autoplaying) {\n            return;\n        }\n\n        clearTimeout(this._autoplayTimeout);\n        this._autoplayTimeout = setTimeout(() => {\n            this._autoplaying = true;\n            this._autoplayInterval = setInterval(() => {\n                if (this._autoplaying) {\n                    this.snapToNext();\n                }\n            }, autoplayInterval);\n        }, autoplayDelay);\n    }\n\n    pauseAutoPlay () {\n        this._autoplaying = false;\n        clearTimeout(this._autoplayTimeout);\n        clearTimeout(this._enableAutoplayTimeout);\n        clearInterval(this._autoplayInterval);\n    }\n\n    stopAutoplay () {\n        this._autoplay = false;\n        this.pauseAutoPlay();\n    }\n\n    snapToItem (index, animated = true, fireCallback = true) {\n        if (!index || index < 0) {\n            index = 0;\n        }\n\n        const positionIndex = this._getPositionIndex(index);\n\n        if (positionIndex === this._activeItem) {\n            return;\n        }\n\n        this._snapToItem(positionIndex, animated, fireCallback);\n    }\n\n    snapToNext (animated = true, fireCallback = true) {\n        const itemsLength = this._getCustomDataLength();\n\n        let newIndex = this._activeItem + 1;\n        if (newIndex > itemsLength - 1) {\n            if (!this._enableLoop()) {\n                return;\n            }\n            newIndex = 0;\n        }\n        this._snapToItem(newIndex, animated, fireCallback);\n    }\n\n    snapToPrev (animated = true, fireCallback = true) {\n        const itemsLength = this._getCustomDataLength();\n\n        let newIndex = this._activeItem - 1;\n        if (newIndex < 0) {\n            if (!this._enableLoop()) {\n                return;\n            }\n            newIndex = itemsLength - 1;\n        }\n        this._snapToItem(newIndex, animated, fireCallback);\n    }\n\n    // https://github.com/facebook/react-native/issues/1831#issuecomment-231069668\n    triggerRenderingHack (offset) {\n        // Avoid messing with user scroll\n        if (Date.now() - this._lastScrollDate < 500) {\n            return;\n        }\n\n        const scrollPosition = this._currentContentOffset;\n        if (!scrollPosition && scrollPosition !== 0) {\n            return;\n        }\n\n        const scrollOffset = offset || (scrollPosition === 0 ? 1 : -1);\n        this._scrollTo(scrollPosition + scrollOffset, false);\n    }\n\n    _getSlideInterpolatedStyle (index, animatedValue) {\n        const { layoutCardOffset, slideInterpolatedStyle } = this.props;\n\n        if (slideInterpolatedStyle) {\n            return slideInterpolatedStyle(index, animatedValue, this.props);\n        } else if (this._shouldUseTinderLayout()) {\n            return tinderAnimatedStyles(index, animatedValue, this.props, layoutCardOffset);\n        } else if (this._shouldUseStackLayout()) {\n            return stackAnimatedStyles(index, animatedValue, this.props, layoutCardOffset);\n        } else if (this._shouldUseShiftLayout()) {\n            return shiftAnimatedStyles(index, animatedValue, this.props);\n        } else {\n            return defaultAnimatedStyles(index, animatedValue, this.props);\n        }\n    }\n\n    _renderItem ({ item, index }) {\n        const { interpolators } = this.state;\n        const {\n            hasParallaxImages,\n            itemWidth,\n            itemHeight,\n            keyExtractor,\n            renderItem,\n            sliderHeight,\n            sliderWidth,\n            slideStyle,\n            vertical\n        } = this.props;\n\n        const animatedValue = interpolators && interpolators[index];\n\n        if (!animatedValue && animatedValue !== 0) {\n            return null;\n        }\n\n        const animate = this._shouldAnimateSlides();\n        const Component = animate ? Animated.View : View;\n        const animatedStyle = animate ? this._getSlideInterpolatedStyle(index, animatedValue) : {};\n\n        const parallaxProps = hasParallaxImages ? {\n            scrollPosition: this._scrollPos,\n            carouselRef: this._carouselRef,\n            vertical,\n            sliderWidth,\n            sliderHeight,\n            itemWidth,\n            itemHeight\n        } : undefined;\n\n        const mainDimension = vertical ? { height: itemHeight } : { width: itemWidth };\n        const specificProps = this._needsScrollView() ? {\n            key: keyExtractor ? keyExtractor(item, index) : this._getKeyExtractor(item, index)\n        } : {};\n\n        return (\n            <Component style={[mainDimension, slideStyle, animatedStyle]} pointerEvents={'box-none'} {...specificProps}>\n                { renderItem({ item, index }, parallaxProps) }\n            </Component>\n        );\n    }\n\n    _getComponentOverridableProps () {\n        const {\n            enableMomentum,\n            itemWidth,\n            itemHeight,\n            loopClonesPerSide,\n            sliderWidth,\n            sliderHeight,\n            vertical\n        } = this.props;\n\n        const visibleItems = Math.ceil(vertical ?\n            sliderHeight / itemHeight :\n            sliderWidth / itemWidth) + 1;\n        const initialNumPerSide = this._enableLoop() ? loopClonesPerSide : 2;\n        const initialNumToRender = visibleItems + (initialNumPerSide * 2);\n        const maxToRenderPerBatch = 1 + (initialNumToRender * 2);\n        const windowSize = maxToRenderPerBatch;\n\n        const specificProps = !this._needsScrollView() ? {\n            initialNumToRender: initialNumToRender,\n            maxToRenderPerBatch: maxToRenderPerBatch,\n            windowSize: windowSize\n            // updateCellsBatchingPeriod\n        } : {};\n\n        return {\n            decelerationRate: enableMomentum ? 0.9 : 'fast',\n            showsHorizontalScrollIndicator: false,\n            showsVerticalScrollIndicator: false,\n            overScrollMode: 'never',\n            automaticallyAdjustContentInsets: false,\n            directionalLockEnabled: true,\n            pinchGestureEnabled: false,\n            scrollsToTop: false,\n            removeClippedSubviews: !this._needsScrollView(),\n            inverted: this._needsRTLAdaptations(),\n            // renderToHardwareTextureAndroid: true,\n            ...specificProps\n        };\n    }\n\n    _getComponentStaticProps () {\n        const { hideCarousel } = this.state;\n        const {\n            containerCustomStyle,\n            contentContainerCustomStyle,\n            keyExtractor,\n            sliderWidth,\n            sliderHeight,\n            style,\n            vertical\n        } = this.props;\n\n        const containerStyle = [\n            containerCustomStyle || style || {},\n            hideCarousel ? { opacity: 0 } : {},\n            vertical ?\n                { height: sliderHeight, flexDirection: 'column' } :\n                // LTR hack; see https://github.com/facebook/react-native/issues/11960\n                // and https://github.com/facebook/react-native/issues/13100#issuecomment-328986423\n                { width: sliderWidth, flexDirection: this._needsRTLAdaptations() ? 'row-reverse' : 'row' }\n        ];\n        const contentContainerStyle = [\n            vertical ? {\n                paddingTop: this._getContainerInnerMargin(),\n                paddingBottom: this._getContainerInnerMargin(true)\n            } : {\n                paddingLeft: this._getContainerInnerMargin(),\n                paddingRight: this._getContainerInnerMargin(true)\n            },\n            contentContainerCustomStyle || {}\n        ];\n\n        const specificProps = !this._needsScrollView() ? {\n            // extraData: this.state,\n            renderItem: this._renderItem,\n            numColumns: 1,\n            keyExtractor: keyExtractor || this._getKeyExtractor\n        } : {};\n\n        return {\n            ref: c => this._carouselRef = c,\n            data: this._getCustomData(),\n            style: containerStyle,\n            contentContainerStyle: contentContainerStyle,\n            horizontal: !vertical,\n            scrollEventThrottle: 1,\n            onScroll: this._onScrollHandler,\n            onScrollBeginDrag: this._onScrollBeginDrag,\n            onScrollEndDrag: this._onScrollEndDrag,\n            onMomentumScrollEnd: this._onMomentumScrollEnd,\n            onResponderRelease: this._onTouchRelease,\n            onStartShouldSetResponderCapture: this._onStartShouldSetResponderCapture,\n            onTouchStart: this._onTouchStart,\n            onTouchEnd: this._onScrollEnd,\n            onLayout: this._onLayout,\n            ...specificProps\n        };\n    }\n\n    render () {\n        const { data, renderItem, useScrollView } = this.props;\n\n        if (!data || !renderItem) {\n            return null;\n        }\n\n        const props = {\n            ...this._getComponentOverridableProps(),\n            ...this.props,\n            ...this._getComponentStaticProps()\n        };\n\n        const ScrollViewComponent = typeof useScrollView === 'function' ? useScrollView : AnimatedScrollView\n\n        return this._needsScrollView() ? (\n            <ScrollViewComponent {...props}>\n                {\n                    this._getCustomData().map((item, index) => {\n                        return this._renderItem({ item, index });\n                    })\n                }\n            </ScrollViewComponent>\n        ) : (\n            <AnimatedFlatList {...props} />\n        );\n    }\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "import Carousel from './carousel/Carousel';\nimport Pagination from './pagination/Pagination';\nimport ParallaxImage from './parallaximage/ParallaxImage';\nimport { getInputRangeFromIndexes } from './utils/animations';\n\nexport { Carousel as default, Pagination, ParallaxImage, getInputRangeFromIndexes };\n"
  },
  {
    "path": "src/pagination/Pagination.js",
    "content": "import React, { PureComponent } from 'react';\nimport { I18nManager, Platform, View, ViewPropTypes } from 'react-native';\nimport PropTypes from 'prop-types';\nimport PaginationDot from './PaginationDot';\nimport styles from './Pagination.style';\n\nconst IS_IOS = Platform.OS === 'ios';\nconst IS_RTL = I18nManager.isRTL;\n\nexport default class Pagination extends PureComponent {\n\n    static propTypes = {\n        activeDotIndex: PropTypes.number.isRequired,\n        dotsLength: PropTypes.number.isRequired,\n        activeOpacity: PropTypes.number,\n        carouselRef: PropTypes.object,\n        containerStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        dotColor: PropTypes.string,\n        dotContainerStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        dotElement: PropTypes.element,\n        dotStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        inactiveDotColor: PropTypes.string,\n        inactiveDotElement: PropTypes.element,\n        inactiveDotOpacity: PropTypes.number,\n        inactiveDotScale: PropTypes.number,\n        inactiveDotStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        renderDots: PropTypes.func,\n        tappableDots: PropTypes.bool,\n        vertical: PropTypes.bool,\n        accessibilityLabel: PropTypes.string,\n        animatedDuration: PropTypes.number,\n        animatedFriction: PropTypes.number,\n        animatedTension: PropTypes.number,\n        delayPressInDot: PropTypes.number,\n    };\n\n    static defaultProps = {\n        inactiveDotOpacity: 0.5,\n        inactiveDotScale: 0.5,\n        tappableDots: false,\n        vertical: false,\n        animatedDuration: 250,\n        animatedFriction: 4,\n        animatedTension: 50,\n        delayPressInDot: 0,\n    }\n\n    constructor (props) {\n        super(props);\n\n        // Warnings\n        if ((props.dotColor && !props.inactiveDotColor) || (!props.dotColor && props.inactiveDotColor)) {\n            console.warn(\n                'react-native-snap-carousel | Pagination: ' +\n                'You need to specify both `dotColor` and `inactiveDotColor`'\n            );\n        }\n        if ((props.dotElement && !props.inactiveDotElement) || (!props.dotElement && props.inactiveDotElement)) {\n            console.warn(\n                'react-native-snap-carousel | Pagination: ' +\n                'You need to specify both `dotElement` and `inactiveDotElement`'\n            );\n        }\n        if (props.tappableDots && props.carouselRef === undefined) {\n            console.warn(\n                'react-native-snap-carousel | Pagination: ' +\n                'You must specify prop `carouselRef` when setting `tappableDots` to `true`'\n            );\n        }\n    }\n\n    _needsRTLAdaptations () {\n        const { vertical } = this.props;\n        return IS_RTL && !IS_IOS && !vertical;\n    }\n\n    get _activeDotIndex () {\n        const { activeDotIndex, dotsLength } = this.props;\n        return this._needsRTLAdaptations() ? dotsLength - activeDotIndex - 1 : activeDotIndex;\n    }\n\n    get dots () {\n        const {\n            activeOpacity,\n            carouselRef,\n            dotsLength,\n            dotColor,\n            dotContainerStyle,\n            dotElement,\n            dotStyle,\n            inactiveDotColor,\n            inactiveDotElement,\n            inactiveDotOpacity,\n            inactiveDotScale,\n            inactiveDotStyle,\n            renderDots,\n            tappableDots,\n            animatedDuration,\n            animatedFriction,\n            animatedTension,\n            delayPressInDot,\n        } = this.props;\n\n        if (renderDots) {\n            return renderDots(this._activeDotIndex, dotsLength, this);\n        }\n\n        const DefaultDot = <PaginationDot\n          carouselRef={carouselRef}\n          tappable={tappableDots && typeof carouselRef !== 'undefined'}\n          activeOpacity={activeOpacity}\n          color={dotColor}\n          containerStyle={dotContainerStyle}\n          style={dotStyle}\n          inactiveColor={inactiveDotColor}\n          inactiveOpacity={inactiveDotOpacity}\n          inactiveScale={inactiveDotScale}\n          inactiveStyle={inactiveDotStyle}\n          animatedDuration={animatedDuration}\n          animatedFriction={animatedFriction}\n          animatedTension={animatedTension}\n          delayPressInDot={delayPressInDot}\n        />;\n\n        const dots = [...Array(dotsLength).keys()].map(i => {\n            const isActive = i === this._activeDotIndex;\n            return React.cloneElement(\n                (isActive ? dotElement : inactiveDotElement) || DefaultDot,\n                {\n                    key: `pagination-dot-${i}`,\n                    active: isActive,\n                    index: i\n                }\n            );\n        });\n\n        return dots;\n    }\n\n    render () {\n        const { dotsLength, containerStyle, vertical, accessibilityLabel } = this.props;\n\n        if (!dotsLength || dotsLength < 2) {\n            return false;\n        }\n\n        const style = [\n            styles.sliderPagination,\n            { flexDirection: vertical ?\n                'column' :\n                (this._needsRTLAdaptations() ? 'row-reverse' : 'row')\n            },\n            containerStyle || {}\n        ];\n\n        return (\n            <View\n              pointerEvents={'box-none'}\n              style={style}\n              accessible={!!accessibilityLabel}\n              accessibilityLabel={accessibilityLabel}\n            >\n                { this.dots }\n            </View>\n        );\n    }\n}\n"
  },
  {
    "path": "src/pagination/Pagination.style.js",
    "content": "import { StyleSheet } from 'react-native';\n\nconst DEFAULT_DOT_SIZE = 7;\nconst DEFAULT_DOT_COLOR = 'rgba(0, 0, 0, 0.75)';\n\nexport default StyleSheet.create({\n    sliderPagination: {\n        alignItems: 'center',\n        justifyContent: 'center',\n        paddingHorizontal: 20,\n        paddingVertical: 30\n    },\n    sliderPaginationDotContainer: {\n        alignItems: 'center',\n        justifyContent: 'center',\n        marginHorizontal: 8\n    },\n    sliderPaginationDot: {\n        width: DEFAULT_DOT_SIZE,\n        height: DEFAULT_DOT_SIZE,\n        borderRadius: DEFAULT_DOT_SIZE / 2,\n        backgroundColor: DEFAULT_DOT_COLOR\n    }\n});\n"
  },
  {
    "path": "src/pagination/PaginationDot.js",
    "content": "import React, { PureComponent } from 'react';\nimport { View, Animated, Easing, TouchableOpacity, ViewPropTypes } from 'react-native';\nimport PropTypes from 'prop-types';\nimport styles from './Pagination.style';\n\nexport default class PaginationDot extends PureComponent {\n\n    static propTypes = {\n        inactiveOpacity: PropTypes.number.isRequired,\n        inactiveScale: PropTypes.number.isRequired,\n        active: PropTypes.bool,\n        activeOpacity: PropTypes.number,\n        carouselRef: PropTypes.object,\n        color: PropTypes.string,\n        containerStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        inactiveColor: PropTypes.string,\n        inactiveStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        index: PropTypes.number,\n        style: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        tappable: PropTypes.bool\n    };\n\n    constructor (props) {\n        super(props);\n        this.state = {\n            animColor: new Animated.Value(0),\n            animOpacity: new Animated.Value(0),\n            animTransform: new Animated.Value(0)\n        };\n    }\n\n    componentDidMount () {\n        if (this.props.active) {\n            this._animate(1);\n        }\n    }\n\n    componentDidUpdate (prevProps) {\n        if (prevProps.active !== this.props.active) {\n            this._animate(this.props.active ? 1 : 0);\n        }\n    }\n\n    _animate (toValue = 0) {\n        const { animColor, animOpacity, animTransform } = this.state;\n        const { animatedDuration, animatedFriction, animatedTension } = this.props\n\n        const commonProperties = {\n            toValue,\n            duration: animatedDuration,\n            isInteraction: false,\n            useNativeDriver: !this._shouldAnimateColor\n        };\n\n        let animations = [\n            Animated.timing(animOpacity, {\n                easing: Easing.linear,\n                ...commonProperties\n            }),\n            Animated.spring(animTransform, {\n                friction: animatedFriction,\n                tension: animatedTension,\n                ...commonProperties\n            })\n        ];\n\n        if (this._shouldAnimateColor) {\n            animations.push(Animated.timing(animColor, {\n                easing: Easing.linear,\n                ...commonProperties\n            }));\n        }\n\n        Animated.parallel(animations).start();\n    }\n\n    get _shouldAnimateColor () {\n        const { color, inactiveColor } = this.props;\n        return color && inactiveColor;\n    }\n\n    render () {\n        const { animColor, animOpacity, animTransform } = this.state;\n        const {\n            active,\n            activeOpacity,\n            carouselRef,\n            color,\n            containerStyle,\n            inactiveColor,\n            inactiveStyle,\n            inactiveOpacity,\n            inactiveScale,\n            index,\n            style,\n            tappable,\n            delayPressInDot\n        } = this.props;\n\n        const animatedStyle = {\n            opacity: animOpacity.interpolate({\n                inputRange: [0, 1],\n                outputRange: [inactiveOpacity, 1]\n            }),\n            transform: [{\n                scale: animTransform.interpolate({\n                    inputRange: [0, 1],\n                    outputRange: [inactiveScale, 1]\n                })\n            }]\n        };\n        const animatedColor = this._shouldAnimateColor ? {\n            backgroundColor: animColor.interpolate({\n                inputRange: [0, 1],\n                outputRange: [inactiveColor, color]\n            })\n        } : {};\n\n        const dotContainerStyle = [\n            styles.sliderPaginationDotContainer,\n            containerStyle || {}\n        ];\n\n        const dotStyle = [\n            styles.sliderPaginationDot,\n            style || {},\n            (!active && inactiveStyle) || {},\n            animatedStyle,\n            animatedColor\n        ];\n\n        const onPress = tappable ? () => {\n            try {\n                const currentRef = carouselRef.current || carouselRef;\n                currentRef._snapToItem(currentRef._getPositionIndex(index));\n            } catch (error) {\n                console.warn(\n                    'react-native-snap-carousel | Pagination: ' +\n                    '`carouselRef` has to be a Carousel ref.\\n' + error\n                );\n            }\n        } : undefined;\n\n        return (\n            <TouchableOpacity\n              accessible={false}\n              style={dotContainerStyle}\n              activeOpacity={tappable ? activeOpacity : 1}\n              onPress={onPress}\n              delayPressIn={delayPressInDot}\n            >\n                <Animated.View style={dotStyle} />\n            </TouchableOpacity>\n        );\n    }\n}\n"
  },
  {
    "path": "src/parallaximage/ParallaxImage.js",
    "content": "// Parallax effect inspired by https://github.com/oblador/react-native-parallax/\n\nimport React, { Component } from 'react';\nimport { View, ViewPropTypes, Image, Animated, Easing, ActivityIndicator, findNodeHandle } from 'react-native';\nimport PropTypes from 'prop-types';\nimport styles from './ParallaxImage.style';\n\nexport default class ParallaxImage extends Component {\n\n    static propTypes = {\n        ...Image.propTypes,\n        carouselRef: PropTypes.object, // passed from <Carousel />\n        itemHeight: PropTypes.number, // passed from <Carousel />\n        itemWidth: PropTypes.number, // passed from <Carousel />\n        scrollPosition: PropTypes.object, // passed from <Carousel />\n        sliderHeight: PropTypes.number, // passed from <Carousel />\n        sliderWidth: PropTypes.number, // passed from <Carousel />\n        vertical: PropTypes.bool, // passed from <Carousel />\n        containerStyle: ViewPropTypes ? ViewPropTypes.style : View.propTypes.style,\n        dimensions: PropTypes.shape({\n            width: PropTypes.number,\n            height: PropTypes.number\n        }),\n        fadeDuration: PropTypes.number,\n        parallaxFactor: PropTypes.number,\n        showSpinner: PropTypes.bool,\n        spinnerColor: PropTypes.string,\n        AnimatedImageComponent: PropTypes.oneOfType([\n            PropTypes.func,\n            PropTypes.object\n        ])\n    };\n\n    static defaultProps = {\n        containerStyle: {},\n        fadeDuration: 500,\n        parallaxFactor: 0.3,\n        showSpinner: true,\n        spinnerColor: 'rgba(0, 0, 0, 0.4)',\n        AnimatedImageComponent: Animated.Image\n    }\n\n    constructor (props) {\n        super(props);\n        this.state = {\n            offset: 0,\n            width: 0,\n            height: 0,\n            status: 1, // 1 -> loading; 2 -> loaded // 3 -> transition finished; 4 -> error\n            animOpacity: new Animated.Value(0)\n        };\n        this._onLoad = this._onLoad.bind(this);\n        this._onError = this._onError.bind(this);\n        this._measureLayout = this._measureLayout.bind(this);\n    }\n\n    setNativeProps (nativeProps) {\n        this._container.setNativeProps(nativeProps);\n    }\n\n    componentDidMount () {\n        this._mounted = true;\n\n        setTimeout(() => {\n            this._measureLayout();\n        }, 0);\n    }\n\n    componentWillUnmount () {\n        this._mounted = false;\n    }\n\n    _measureLayout () {\n        if (this._container) {\n            const {\n                dimensions,\n                vertical,\n                carouselRef,\n                sliderWidth,\n                sliderHeight,\n                itemWidth,\n                itemHeight\n            } = this.props;\n\n            if (carouselRef) {\n                this._container.measureLayout(\n                    findNodeHandle(carouselRef),\n                    (x, y, width, height, pageX, pageY) => {\n                        const offset = vertical ?\n                            y - ((sliderHeight - itemHeight) / 2) :\n                            x - ((sliderWidth - itemWidth) / 2);\n\n                        this.setState({\n                            offset: offset,\n                            width: dimensions && dimensions.width ?\n                                dimensions.width :\n                                Math.ceil(width),\n                            height: dimensions && dimensions.height ?\n                                dimensions.height :\n                                Math.ceil(height)\n                        });\n                    }\n                );\n            }\n        }\n    }\n\n    _onLoad (event) {\n        const { animOpacity } = this.state;\n        const { fadeDuration, onLoad } = this.props;\n\n        if (!this._mounted) {\n            return;\n        }\n\n        this.setState({ status: 2 });\n\n        if (onLoad) {\n            onLoad(event);\n        }\n\n        Animated.timing(animOpacity, {\n            toValue: 1,\n            duration: fadeDuration,\n            easing: Easing.out(Easing.quad),\n            isInteraction: false,\n            useNativeDriver: true\n        }).start(() => {\n            this.setState({ status: 3 });\n        });\n    }\n\n    // If arg is missing from method signature, it just won't be called\n    _onError (event) {\n        const { onError } = this.props;\n\n        this.setState({ status: 4 });\n\n        if (onError) {\n            onError(event);\n        }\n    }\n\n    get image () {\n        const { status, animOpacity, offset, width, height } = this.state;\n        const {\n            scrollPosition,\n            dimensions,\n            vertical,\n            sliderWidth,\n            sliderHeight,\n            parallaxFactor,\n            style,\n            AnimatedImageComponent,\n            ...other\n        } = this.props;\n\n        const parallaxPadding = (vertical ? height : width) * parallaxFactor;\n        const requiredStyles = { position: 'relative' };\n        const dynamicStyles = {\n            width: vertical ? width : width + parallaxPadding * 2,\n            height: vertical ? height + parallaxPadding * 2 : height,\n            opacity: animOpacity,\n            transform: scrollPosition ? [\n                {\n                    translateX: !vertical ? scrollPosition.interpolate({\n                        inputRange: [offset - sliderWidth, offset + sliderWidth],\n                        outputRange: [-parallaxPadding, parallaxPadding],\n                        extrapolate: 'clamp'\n                    }) : 0\n                },\n                {\n                    translateY: vertical ? scrollPosition.interpolate({\n                        inputRange: [offset - sliderHeight, offset + sliderHeight],\n                        outputRange: [-parallaxPadding, parallaxPadding],\n                        extrapolate: 'clamp'\n                    }) : 0\n                }\n            ] : []\n        };\n\n        return (\n            <AnimatedImageComponent\n              {...other}\n              style={[styles.image, style, requiredStyles, dynamicStyles]}\n              onLoad={this._onLoad}\n              onError={status !== 3 ? this._onError : undefined} // prevent infinite-loop bug\n            />\n        );\n    }\n\n    get spinner () {\n        const { status } = this.state;\n        const { showSpinner, spinnerColor } = this.props;\n\n        return status === 1 && showSpinner ? (\n            <View style={styles.loaderContainer}>\n                <ActivityIndicator\n                  size={'small'}\n                  color={spinnerColor}\n                  animating={true}\n                />\n            </View>\n        ) : false;\n    }\n\n    render () {\n        const { containerStyle } = this.props;\n\n        return (\n            <View\n              ref={(c) => { this._container = c; }}\n              pointerEvents={'none'}\n              style={[containerStyle, styles.container]}\n              onLayout={this._measureLayout}\n            >\n                { this.image }\n                { this.spinner }\n            </View>\n        );\n    }\n}\n"
  },
  {
    "path": "src/parallaximage/ParallaxImage.style.js",
    "content": "import { StyleSheet } from 'react-native';\n\nexport default StyleSheet.create({\n    container: {\n        overflow: 'hidden',\n        alignItems: 'center',\n        justifyContent: 'center'\n    },\n    image: {\n        position: 'relative',\n        resizeMode: 'cover',\n        width: null,\n        height: null\n    },\n    loaderContainer: {\n        ...StyleSheet.absoluteFillObject,\n        alignItems: 'center',\n        justifyContent: 'center'\n    }\n});\n"
  },
  {
    "path": "src/utils/animations.js",
    "content": "import { Platform } from 'react-native';\n\nconst IS_ANDROID = Platform.OS === 'android';\n\n// Get scroll interpolator's input range from an array of slide indexes\n// Indexes are relative to the current active slide (index 0)\n// For example, using [3, 2, 1, 0, -1] will return:\n// [\n//     (index - 3) * sizeRef, // active + 3\n//     (index - 2) * sizeRef, // active + 2\n//     (index - 1) * sizeRef, // active + 1\n//     index * sizeRef, // active\n//     (index + 1) * sizeRef // active - 1\n// ]\nexport function getInputRangeFromIndexes (range, index, carouselProps) {\n    const sizeRef = carouselProps.vertical ? carouselProps.itemHeight : carouselProps.itemWidth;\n    let inputRange = [];\n\n    for (let i = 0; i < range.length; i++) {\n        inputRange.push((index - range[i]) * sizeRef);\n    }\n\n    return inputRange;\n}\n\n// Default behavior\n// Scale and/or opacity effect\n// Based on props 'inactiveSlideOpacity' and 'inactiveSlideScale'\nexport function defaultScrollInterpolator (index, carouselProps) {\n    const range = [1, 0, -1];\n    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);\n    const outputRange = [0, 1, 0];\n\n    return { inputRange, outputRange };\n}\nexport function defaultAnimatedStyles (index, animatedValue, carouselProps) {\n    let animatedOpacity = {};\n    let animatedScale = {};\n\n    if (carouselProps.inactiveSlideOpacity < 1) {\n        animatedOpacity = {\n            opacity: animatedValue.interpolate({\n                inputRange: [0, 1],\n                outputRange: [carouselProps.inactiveSlideOpacity, 1]\n            })\n        };\n    }\n\n    if (carouselProps.inactiveSlideScale < 1) {\n        animatedScale = {\n            transform: [{\n                scale: animatedValue.interpolate({\n                    inputRange: [0, 1],\n                    outputRange: [carouselProps.inactiveSlideScale, 1]\n                })\n            }]\n        };\n    }\n\n    return {\n        ...animatedOpacity,\n        ...animatedScale\n    };\n}\n\n// Shift animation\n// Same as the default one, but the active slide is also shifted up or down\n// Based on prop 'inactiveSlideShift'\nexport function shiftAnimatedStyles (index, animatedValue, carouselProps) {\n    let animatedOpacity = {};\n    let animatedScale = {};\n    let animatedTranslate = {};\n\n    if (carouselProps.inactiveSlideOpacity < 1) {\n        animatedOpacity = {\n            opacity: animatedValue.interpolate({\n                inputRange: [0, 1],\n                outputRange: [carouselProps.inactiveSlideOpacity, 1]\n            })\n        };\n    }\n\n    if (carouselProps.inactiveSlideScale < 1) {\n        animatedScale = {\n            scale: animatedValue.interpolate({\n                inputRange: [0, 1],\n                outputRange: [carouselProps.inactiveSlideScale, 1]\n            })\n        };\n    }\n\n    if (carouselProps.inactiveSlideShift !== 0) {\n        const translateProp = carouselProps.vertical ? 'translateX' : 'translateY';\n        animatedTranslate = {\n            [translateProp]: animatedValue.interpolate({\n                inputRange: [0, 1],\n                outputRange: [carouselProps.inactiveSlideShift, 0]\n            })\n        };\n    }\n\n    return {\n        ...animatedOpacity,\n        transform: [\n            { ...animatedScale },\n            { ...animatedTranslate }\n        ]\n    };\n}\n\n// Stack animation\n// Imitate a deck/stack of cards (see #195)\n// WARNING: The effect had to be visually inverted on Android because this OS doesn't honor the `zIndex`property\n// This means that the item with the higher zIndex (and therefore the tap receiver) remains the one AFTER the currently active item\n// The `elevation` property compensates for that only visually, which is not good enough\nexport function stackScrollInterpolator (index, carouselProps) {\n    const range = IS_ANDROID ?\n        [1, 0, -1, -2, -3] :\n        [3, 2, 1, 0, -1];\n    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);\n    const outputRange = range;\n\n    return { inputRange, outputRange };\n}\nexport function stackAnimatedStyles (index, animatedValue, carouselProps, cardOffset) {\n    const sizeRef = carouselProps.vertical ? carouselProps.itemHeight : carouselProps.itemWidth;\n    const translateProp = carouselProps.vertical ? 'translateY' : 'translateX';\n\n    const card1Scale = 0.9;\n    const card2Scale = 0.8;\n\n    cardOffset = !cardOffset && cardOffset !== 0 ? 18 : cardOffset;\n\n    const getTranslateFromScale = (cardIndex, scale) => {\n        const centerFactor = 1 / scale * cardIndex;\n        const centeredPosition = -Math.round(sizeRef * centerFactor);\n        const edgeAlignment = Math.round((sizeRef - (sizeRef * scale)) / 2);\n        const offset = Math.round(cardOffset * Math.abs(cardIndex) / scale);\n\n        return IS_ANDROID ?\n            centeredPosition - edgeAlignment - offset :\n            centeredPosition + edgeAlignment + offset;\n    };\n\n    const opacityOutputRange = carouselProps.inactiveSlideOpacity === 1 ? [1, 1, 1, 0] : [1, 0.75, 0.5, 0];\n\n    return IS_ANDROID ? {\n        // elevation: carouselProps.data.length - index, // fix zIndex bug visually, but not from a logic point of view\n        opacity: animatedValue.interpolate({\n            inputRange: [-3, -2, -1, 0],\n            outputRange: opacityOutputRange.reverse(),\n            extrapolate: 'clamp'\n        }),\n        transform: [{\n            scale: animatedValue.interpolate({\n                inputRange: [-2, -1, 0, 1],\n                outputRange: [card2Scale, card1Scale, 1, card1Scale],\n                extrapolate: 'clamp'\n            })\n        }, {\n            [translateProp]: animatedValue.interpolate({\n                inputRange: [-3, -2, -1, 0, 1],\n                outputRange: [\n                    getTranslateFromScale(-3, card2Scale),\n                    getTranslateFromScale(-2, card2Scale),\n                    getTranslateFromScale(-1, card1Scale),\n                    0,\n                    sizeRef * 0.5\n                ],\n                extrapolate: 'clamp'\n            })\n        }]\n    } : {\n        zIndex: carouselProps.data.length - index,\n        opacity: animatedValue.interpolate({\n            inputRange: [0, 1, 2, 3],\n            outputRange: opacityOutputRange,\n            extrapolate: 'clamp'\n        }),\n        transform: [{\n            scale: animatedValue.interpolate({\n                inputRange: [-1, 0, 1, 2],\n                outputRange: [card1Scale, 1, card1Scale, card2Scale],\n                extrapolate: 'clamp'\n            })\n        }, {\n            [translateProp]: animatedValue.interpolate({\n                inputRange: [-1, 0, 1, 2, 3],\n                outputRange: [\n                    -sizeRef * 0.5,\n                    0,\n                    getTranslateFromScale(1, card1Scale),\n                    getTranslateFromScale(2, card2Scale),\n                    getTranslateFromScale(3, card2Scale)\n                ],\n                extrapolate: 'clamp'\n            })\n        }]\n    };\n}\n\n// Tinder animation\n// Imitate the popular Tinder layout\n// WARNING: The effect had to be visually inverted on Android because this OS doesn't honor the `zIndex`property\n// This means that the item with the higher zIndex (and therefore the tap receiver) remains the one AFTER the currently active item\n// The `elevation` property compensates for that only visually, which is not good enough\nexport function tinderScrollInterpolator (index, carouselProps) {\n    const range = IS_ANDROID ?\n        [1, 0, -1, -2, -3] :\n        [3, 2, 1, 0, -1];\n    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);\n    const outputRange = range;\n\n    return { inputRange, outputRange };\n}\nexport function tinderAnimatedStyles (index, animatedValue, carouselProps, cardOffset) {\n    const sizeRef = carouselProps.vertical ? carouselProps.itemHeight : carouselProps.itemWidth;\n    const mainTranslateProp = carouselProps.vertical ? 'translateY' : 'translateX';\n    const secondaryTranslateProp = carouselProps.vertical ? 'translateX' : 'translateY';\n\n    const card1Scale = 0.96;\n    const card2Scale = 0.92;\n    const card3Scale = 0.88;\n\n    const peekingCardsOpacity = IS_ANDROID ? 0.92 : 1;\n\n    cardOffset = !cardOffset && cardOffset !== 0 ? 9 : cardOffset;\n\n    const getMainTranslateFromScale = (cardIndex, scale) => {\n        const centerFactor = 1 / scale * cardIndex;\n        return -Math.round(sizeRef * centerFactor);\n    };\n\n    const getSecondaryTranslateFromScale = (cardIndex, scale) => {\n        return Math.round(cardOffset * Math.abs(cardIndex) / scale);\n    };\n\n    return IS_ANDROID ? {\n        // elevation: carouselProps.data.length - index, // fix zIndex bug visually, but not from a logic point of view\n        opacity: animatedValue.interpolate({\n            inputRange: [-3, -2, -1, 0, 1],\n            outputRange: [0, peekingCardsOpacity, peekingCardsOpacity, 1, 0],\n            extrapolate: 'clamp'\n        }),\n        transform: [{\n            scale: animatedValue.interpolate({\n                inputRange: [-3, -2, -1, 0],\n                outputRange: [card3Scale, card2Scale, card1Scale, 1],\n                extrapolate: 'clamp'\n            })\n        }, {\n            rotate: animatedValue.interpolate({\n                inputRange: [0, 1],\n                outputRange: ['0deg', '22deg'],\n                extrapolate: 'clamp'\n            })\n        }, {\n            [mainTranslateProp]: animatedValue.interpolate({\n                inputRange: [-3, -2, -1, 0, 1],\n                outputRange: [\n                    getMainTranslateFromScale(-3, card3Scale),\n                    getMainTranslateFromScale(-2, card2Scale),\n                    getMainTranslateFromScale(-1, card1Scale),\n                    0,\n                    sizeRef * 1.1\n                ],\n                extrapolate: 'clamp'\n            })\n        }, {\n            [secondaryTranslateProp]: animatedValue.interpolate({\n                inputRange: [-3, -2, -1, 0],\n                outputRange: [\n                    getSecondaryTranslateFromScale(-3, card3Scale),\n                    getSecondaryTranslateFromScale(-2, card2Scale),\n                    getSecondaryTranslateFromScale(-1, card1Scale),\n                    0\n                ],\n                extrapolate: 'clamp'\n            })\n        }]\n    } : {\n        zIndex: carouselProps.data.length - index,\n        opacity: animatedValue.interpolate({\n            inputRange: [-1, 0, 1, 2, 3],\n            outputRange: [0, 1, peekingCardsOpacity, peekingCardsOpacity, 0],\n            extrapolate: 'clamp'\n        }),\n        transform: [{\n            scale: animatedValue.interpolate({\n                inputRange: [0, 1, 2, 3],\n                outputRange: [1, card1Scale, card2Scale, card3Scale],\n                extrapolate: 'clamp'\n            })\n        }, {\n            rotate: animatedValue.interpolate({\n                inputRange: [-1, 0],\n                outputRange: ['-22deg', '0deg'],\n                extrapolate: 'clamp'\n            })\n        }, {\n            [mainTranslateProp]: animatedValue.interpolate({\n                inputRange: [-1, 0, 1, 2, 3],\n                outputRange: [\n                    -sizeRef * 1.1,\n                    0,\n                    getMainTranslateFromScale(1, card1Scale),\n                    getMainTranslateFromScale(2, card2Scale),\n                    getMainTranslateFromScale(3, card3Scale)\n                ],\n                extrapolate: 'clamp'\n            })\n        }, {\n            [secondaryTranslateProp]: animatedValue.interpolate({\n                inputRange: [0, 1, 2, 3],\n                outputRange: [\n                    0,\n                    getSecondaryTranslateFromScale(1, card1Scale),\n                    getSecondaryTranslateFromScale(2, card2Scale),\n                    getSecondaryTranslateFromScale(3, card3Scale)\n                ],\n                extrapolate: 'clamp'\n            })\n        }]\n    };\n}\n"
  }
]