diff --git a/.bundle/config b/.bundle/config index 6712438927..f7382bd2cb 100644 --- a/.bundle/config +++ b/.bundle/config @@ -1,2 +1,2 @@ --- -BUNDLE_BIN: "./examples/ios" +BUNDLE_PATH: "./example/ios/bundles" diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..2d56161cc1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,111 @@ + + +### Is this a bug report? + +(write your answer here) + + + +### Have you read the [Installation Instructions](https://github.com/react-community/react-native-maps/blob/master/docs/installation.md)? + +(Write your answer here.) + +### Environment + + + +### Steps to Reproduce + + + +(Write your steps here:) + +1. 2. 3. + +### Expected Behavior + + + +(Write what you thought would happen.) + +### Actual Behavior + + + +(Write what happened. Add screenshots!) + +### Reproducible Demo + + + +(Paste the link to an example project and exact instructions to reproduce the issue.) + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..040aaebf4a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,53 @@ + + +### Does any other open PR do the same thing? + + + +(please answer here) + +### What issue is this PR fixing? + +(please link the issue here) + +### How did you test this PR? + + + +(please answer here) + + diff --git a/.gitignore b/.gitignore index dc4d6bb16b..f8943c908f 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,8 @@ DerivedData *.ipa *.xcuserstate project.xcworkspace +Pods/ +AirMapsExplorer.xcworkspace/ # Android/IJ # @@ -28,12 +30,15 @@ project.xcworkspace *.iml .gradle local.properties +lib/android/src/main/gen +example/android/app/src/main/gen # node.js # node_modules/ npm-debug.log -Pods/ -AirMapsExplorer.xcworkspace/ -lib/android/src/main/gen -example/android/app/src/main/gen +yarn-error.log + +# Rubygem bundles +# +bundles/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 5678d80526..4793ed145d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,78 @@ # Change Log +## 0.21.0 (March 31, 2018) +* Common: [#2030](https://github.com/react-community/react-native-maps/pull/2030) Broadened peer-dependency support +* Common: [#2035](https://github.com/react-community/react-native-maps/pull/2035), [#2113](https://github.com/react-community/react-native-maps/pull/2113), & [#2141](https://github.com/react-community/react-native-maps/pull/2141) Typescript improvements and fixes +* Common: [#2011](https://github.com/react-community/react-native-maps/pull/2011) Add suport for KML file (Only Markers) +* Common: [#2053](https://github.com/react-community/react-native-maps/pull/2053) Fix 'module undefined' for React Native >= 0.54 +* Common: [#2131](https://github.com/react-community/react-native-maps/pull/2131) Fix initialRegion for React Native >= 0.54 +* Common: [#2115](https://github.com/react-community/react-native-maps/pull/2115) Upgrade React Native peer dependency to 0.54 +* Common: [#2032](https://github.com/react-community/react-native-maps/pull/2032) Add onMyLocationChange event +* Common: [#2039](https://github.com/react-community/react-native-maps/pull/2039) Fixed problem with pointForCoordinate and coordinateForPoint methods +* Common: [#2050](https://github.com/react-community/react-native-maps/pull/2050) Add support for onPoiClick +* iOS: [#2022](https://github.com/react-community/react-native-maps/pull/2022) Add support for Map.Overlay +* iOS: [#2068](https://github.com/react-community/react-native-maps/pull/2068) Prevent marker press from calling MapView onPress +* iOS: [#2057](https://github.com/react-community/react-native-maps/pull/2057) Fixed polygon and polyline not re-rendering when changing tile URL (AirMaps) +* iOS: [#2101](https://github.com/react-community/react-native-maps/pull/2101) Fixed re-render not updating MapView.Circle component in UI when radius or center coordinates change (AirMaps) +* Android: [#2111](https://github.com/react-community/react-native-maps/pull/2111) Allow vector drawables to be used as markers +* Android: [#2132](https://github.com/react-community/react-native-maps/pull/2132) Add mock-provider boolean on each location update +* Android: [#2047](https://github.com/react-community/react-native-maps/pull/2047) Check for presence of project-wide (ext) Gradle configuration properties `compileSdkVersion`, `targetSdkVersion`, `buildToolsVersion`, `supportLibVersion`, `googlePlayServicesVersion`, and `androidMapsUtilsVersion`. This provides a better mechanism for aligning the requirements of the module with that of the host project. +* Android: [#2096](https://github.com/react-community/react-native-maps/pull/2096) Updated gradle configuration for gradle 3.0.0+ + +## 0.20.1 (February 13, 2018) +* Common: [hotfix PROVIDER_GOOGLE](https://github.com/react-community/react-native-maps/commit/cd868ea7b33a04c8bdd5e909cf134a133b2cb316) +* iOS: [#2019](https://github.com/airbnb/react-native-maps/pull/2019) Exposing the maximumZ property to AIRMapUrlTile + + +## 0.20.0 (February 9, 2018) +* Common: [#1889](https://github.com/airbnb/react-native-maps/pull/1889) Fix for 'Animated.Region undefined constructor' in recent react-native version. +* iOS: [#1853](https://github.com/airbnb/react-native-maps/pull/1853) Fixed onMapReady no longer getting called on iOS +* Android: [#1906](https://github.com/airbnb/react-native-maps/pull/1906) Manage Zoom Controls visibility on the map +* iOS: [#1911](https://github.com/airbnb/react-native-maps/pull/1911) Add gradient/multi-color polyline support for iOS (MapKit) +* Android: [#1918](https://github.com/airbnb/react-native-maps/pull/1918) Ground Overlay Support +* Common: [#1851](https://github.com/airbnb/react-native-maps/pull/1851) New methods to convert between LatLng and Point +* iOS: [#1846](https://github.com/airbnb/react-native-maps/pull/1846) Fix callouts appearing behind markers +* iOS: [#1969](https://github.com/airbnb/react-native-maps/pull/1969) Added tracksInfoWindowChanges property to iOS Google Maps +* iOS: [#1960](https://github.com/airbnb/react-native-maps/pull/1960) Fixed gradient polyline not always fully drawn + stability issues +* iOS: [#1953](https://github.com/airbnb/react-native-maps/pull/1953) Fix onMapReady not getting called after first time, initialRegion lat/lng delta not setting properly, setRegion method getting called even when map is not ready and prevent onRegionChange/ onRegionChangeComplete event until initialRegion or region is set. +* Android: [#1781](https://github.com/airbnb/react-native-maps/pull/1781) Polygon holes support +* Android: [#1976](https://github.com/airbnb/react-native-maps/pull/1976) Add native animation for Markers on Android + +## 0.19.0 (December 14, 2017) +* Common: [#1715](https://github.com/airbnb/react-native-maps/pull/1715) Fixed region/initialRegion null overrides of this.props +* Common: [#1876](https://github.com/airbnb/react-native-maps/pull/1876) Added support for locally stored tile overlay +* iOS: [#1854](https://github.com/airbnb/react-native-maps/pull/1854) Update GoogleMaps dependency to 2.5.0 + +## 0.18.3 (November 30, 2017) +* Android: [#1839](https://github.com/airbnb/react-native-maps/pull/1839) [AirGoogleMapManager] Use RCTDirectEventBlock for onMarkerPress + +## 0.18.2 (November 29, 2017) +* Android: [#1835](https://github.com/airbnb/react-native-maps/pull/1835) [AirMapView] Null check map instance on view methods + +## 0.18.1 (November 28, 2017) +* Android: [#1828](https://github.com/airbnb/react-native-maps/pull/1828) [AirMapManager] Update MapBuilder for getCommandsMap to support all entires + +## 0.18.0 (November 28, 2017) +* Android/iOS: [#1587](https://github.com/airbnb/react-native-maps/pull/1750) Add support to set map boundaries +* Android/iOS: [#1750](https://github.com/airbnb/react-native-maps/pull/1750) Add mapPadding property +* Common: [#1792](https://github.com/airbnb/react-native-maps/pull/1792) Make all components use ViewPropTypes || View.propTypes +* iOS: [#1774](https://github.com/airbnb/react-native-maps/pull/1774) Added missing parameters to google map screenshot +* iOS: [#1824](https://github.com/airbnb/react-native-maps/pull/1824) Add new iOS `mutedStandard` map-type +* iOS: [#1705](https://github.com/airbnb/react-native-maps/pull/1705) Enable control of Google Maps Marker tracksViewChanges property. +* Android: [#1710](https://github.com/airbnb/react-native-maps/pull/1710) Added support for new Android camera movement APIs +* iOS: [#1741](https://github.com/airbnb/react-native-maps/pull/1741) Fixed iOS google MapView.onMarkerPress not receiving the marker identifier +* iOS: [#1816](https://github.com/airbnb/react-native-maps/pull/1816) Fix The name of the given podspec ‘yoga' doesn't match the expected one ‘Yoga' +* iOS: [#1797](https://github.com/airbnb/react-native-maps/pull/1797) Fixed onMapReady event on iOS to resemble onMapReady on Android +* Common: [#1817](https://github.com/airbnb/react-native-maps/pull/1817) Allow fitToCoordinates to be called without options parameter + +## 0.17.1 (October 18, 2017) +* Common: [#1687](https://github.com/airbnb/react-native-maps/pull/1687) Fixed TypeScript definitions ## 0.17.0 (October 11, 2017) * iOS: [#1527](https://github.com/airbnb/react-native-maps/pull/1527) Added [iOS / Google Maps] support for showsIndoorLevelPicker * iOS/Android: [#1544](https://github.com/airbnb/react-native-maps/pull/1544) Adds support to animateToBearing and animateToViewingAngle ( IOS + Android ) * JS: [#1503](https://github.com/airbnb/react-native-maps/pull/1503) Remove caret from "react": "^16.0.0-alpha.12 * Android: [#1521](https://github.com/airbnb/react-native-maps/pull/1521) Fix rare android crashes when map size is 0 -* Common: [#1610](https://github.com/airbnb/react-native-maps/pull/1610) Added Typescript Definitions +* Common: [#1601](https://github.com/airbnb/react-native-maps/pull/1610) Added Typescript Definitions * Android: [#1612](https://github.com/airbnb/react-native-maps/pull/1612) Remove legalNotice from android AirMapModule ## 0.16.4 (September 13, 2017) diff --git a/Gemfile b/Gemfile index e696ba58e5..8308684860 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,2 @@ source 'https://rubygems.org' -ruby '2.2.4' -gem 'cocoapods', '1.2.0' +gem 'cocoapods' diff --git a/Gemfile.lock b/Gemfile.lock index 9265653cd6..af24b61695 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,76 +1,76 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (2.3.5) - activesupport (4.2.8) + CFPropertyList (2.3.6) + activesupport (4.2.10) i18n (~> 0.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - claide (1.0.1) - cocoapods (1.2.0) + atomos (0.1.2) + claide (1.0.2) + cocoapods (1.4.0) activesupport (>= 4.0.2, < 5) - claide (>= 1.0.1, < 2.0) - cocoapods-core (= 1.2.0) - cocoapods-deintegrate (>= 1.0.1, < 2.0) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.4.0) + cocoapods-deintegrate (>= 1.0.2, < 2.0) cocoapods-downloader (>= 1.1.3, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.1.2, < 2.0) + cocoapods-trunk (>= 1.3.0, < 2.0) cocoapods-try (>= 1.1.0, < 2.0) - colored (~> 1.2) + colored2 (~> 3.1) escape (~> 0.0.4) fourflusher (~> 2.0.1) gh_inspector (~> 1.0) - molinillo (~> 0.5.5) + molinillo (~> 0.6.4) nap (~> 1.0) - ruby-macho (~> 0.2.5) - xcodeproj (>= 1.4.1, < 2.0) - cocoapods-core (1.2.0) - activesupport (>= 4.0.2, < 5) + ruby-macho (~> 1.1) + xcodeproj (>= 1.5.4, < 2.0) + cocoapods-core (1.4.0) + activesupport (>= 4.0.2, < 6) fuzzy_match (~> 2.0.4) nap (~> 1.0) - cocoapods-deintegrate (1.0.1) + cocoapods-deintegrate (1.0.2) cocoapods-downloader (1.1.3) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.0) cocoapods-stats (1.0.0) - cocoapods-trunk (1.1.2) + cocoapods-trunk (1.3.0) nap (>= 0.8, < 2.0) - netrc (= 0.7.8) + netrc (~> 0.11) cocoapods-try (1.1.0) - colored (1.2) + colored2 (3.1.2) + concurrent-ruby (1.0.5) escape (0.0.4) fourflusher (2.0.1) fuzzy_match (2.0.4) - gh_inspector (1.0.3) - i18n (0.8.1) - minitest (5.10.1) - molinillo (0.5.7) + gh_inspector (1.1.3) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + minitest (5.11.3) + molinillo (0.6.4) nanaimo (0.2.3) nap (1.1.0) - netrc (0.7.8) - ruby-macho (0.2.6) + netrc (0.11.0) + ruby-macho (1.1.0) thread_safe (0.3.6) - tzinfo (1.2.3) + tzinfo (1.2.5) thread_safe (~> 0.1) - xcodeproj (1.4.2) + xcodeproj (1.5.6) CFPropertyList (~> 2.3.3) - activesupport (>= 3) - claide (>= 1.0.1, < 2.0) - colored (~> 1.2) + atomos (~> 0.1.2) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) nanaimo (~> 0.2.3) PLATFORMS ruby DEPENDENCIES - cocoapods (= 1.2.0) - -RUBY VERSION - ruby 2.2.4p230 + cocoapods BUNDLED WITH - 1.14.6 + 1.16.1 diff --git a/README.md b/README.md index 91b22377be..089b310730 100644 --- a/README.md +++ b/README.md @@ -26,15 +26,17 @@ versions you should add `react` as a dependency in your `package.json`. [`` Component API](docs/mapview.md) -[`` Component API](docs/marker.md) +[`` Component API](docs/marker.md) -[`` Component API](docs/callout.md) +[`` Component API](docs/callout.md) -[`` Component API](docs/polygon.md) +[`` Component API](docs/polygon.md) -[`` Component API](docs/polyline.md) +[`` Component API](docs/polyline.md) -[`` Component API](docs/circle.md) +[`` Component API](docs/circle.md) + +[`` Component API](docs/overlay.md) ## General Usage @@ -96,12 +98,14 @@ render() { ### Rendering a list of markers on a map ```jsx +import { Marker } from 'react-native-maps'; + {this.state.markers.map(marker => ( - + - + ``` ### Rendering a Marker with a custom image ```jsx - @@ -130,19 +134,21 @@ render() { ### Rendering a custom Marker with a custom Callout ```jsx - +import { Callout } from 'react-native-maps'; + + - + - - + + ``` ### Draggable Markers ```jsx - this.setState({ x: e.nativeEvent.coordinate })} /> @@ -151,17 +157,26 @@ render() { ### Using a custom Tile Overlay +#### Tile Overlay using tile server + ```jsx - - ``` @@ -172,6 +187,57 @@ For Android: add the following line in your AndroidManifest.xml ``` For IOS: configure [App Transport Security](https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33) in your app +#### Tile Overlay using local tiles + +Tiles can be stored locally within device using xyz tiling scheme and displayed as tile overlay as well. This is usefull especially for offline map usage when tiles are available for selected map region within device storage. + +```jsx +import { LocalTile } from 'react-native-maps'; + + + + +``` + +For Android: LocalTile is still just overlay over original map tiles. It means that if device is online, underlying tiles will be still downloaded. If original tiles download/display is not desirable set mapType to 'none'. For example: +``` + +``` + +See [OSM Wiki](https://wiki.openstreetmap.org/wiki/Category:Tile_downloading) for how to download tiles for offline usage. + +### Overlaying other components on the map + +Place components you that wish to overlay `MapView` underneath the `MapView` closing tag. Absolutely position these elements. + +```jsx +render() { + return ( + + + ); +} +``` + ### Customizing the map style Create the json object, or download a generated one from the [google style generator](https://mapstyle.withgoogle.com/). @@ -211,6 +277,20 @@ An unofficial step-by-step guide is also available at https://gist.github.com/he ## Examples +To run examples: + +```bash +npm i +npm start + +#Android +npm run run:android + +#iOS +npm run build:ios +npm run run:ios +``` + ### MapView Events The `` component and its child components have several events that you can subscribe to. @@ -282,6 +362,14 @@ So far, ``, ``, and `` are available to pass in +### Gradient Polylines (iOS MapKit only) + +Gradient polylines can be created using the `strokeColors` prop of the `` component. + +![](https://i.imgur.com/P7UeqAm.png?1) + + + ### Default Markers Default markers will be rendered unless a custom marker is specified. One can optionally adjust the @@ -326,16 +414,22 @@ Enable lite mode on Android with `liteMode` prop. Ideal when having multiple map ![](http://i.giphy.com/qZ2lAf18s89na.gif) +### On Poi Click (Google Maps Only) + +Poi are clickable, you can catch the event to get its information (usually to get the full detail from Google Place using the placeId). + +![](https://media.giphy.com/media/3480VsCKnHr31uCLU3/giphy.gif) + ### Animated Region -The MapView can accept an `MapView.AnimatedRegion` value as its `region` prop. This allows you to utilize the Animated API to control the map's center and zoom. +The MapView can accept an `AnimatedRegion` value as its `region` prop. This allows you to utilize the Animated API to control the map's center and zoom. ```jsx -import MapView from 'react-native-maps'; +import MapView, { AnimatedRegion, Animated } from 'react-native-maps'; getInitialState() { return { - region: new MapView.AnimatedRegion({ + region: new AnimatedRegion({ latitude: LATITUDE, longitude: LONGITUDE, latitudeDelta: LATITUDE_DELTA, @@ -350,7 +444,7 @@ onRegionChange(region) { render() { return ( - @@ -363,9 +457,11 @@ render() { Markers can also accept an `AnimatedRegion` value as a coordinate. ```jsx +import Mapview, { AnimatedRegion, Marker } from 'react-native-maps'; + getInitialState() { return { - coordinate: new MapView.AnimatedRegion({ + coordinate: new AnimatedRegion({ latitude: LATITUDE, longitude: LONGITUDE, }), @@ -373,18 +469,69 @@ getInitialState() { } componentWillReceiveProps(nextProps) { + const duration = 500 + if (this.props.coordinate !== nextProps.coordinate) { - this.state.coordinate.timing({ - ...nextProps.coordinate, - duration: 500 - }).start(); + if (Platform.OS === 'android') { + if (this.marker) { + this.marker._component.animateMarkerToCoordinate( + nextProps.coordinate, + duration + ); + } + } else { + this.state.coordinate.timing({ + ...nextProps.coordinate, + duration + }).start(); + } } } render() { return ( - + { this.marker = marker }} + coordinate={this.state.coordinate} + /> + + ); +} +``` + +If you need a smoother animation to move the marker on Android, you can modify the previous example: + +```jsx +// ... + +componentWillReceiveProps(nextProps) { + const duration = 500 + + if (this.props.coordinate !== nextProps.coordinate) { + if (Platform.OS === 'android') { + if (this.marker) { + this.marker._component.animateMarkerToCoordinate( + nextProps.coordinate, + duration + ); + } + } else { + this.state.coordinate.timing({ + ...nextProps.coordinate, + duration + }).start(); + } + } +} + +render() { + return ( + + { this.marker = marker }} + coordinate={this.state.coordinate} + /> ); } @@ -393,6 +540,8 @@ render() { ### Take Snapshot of map ```jsx +import MapView, { Marker } from 'react-native-maps'; + getInitialState() { return { coordinate: { @@ -422,7 +571,7 @@ render() { return ( { this.map = map }}> - + @@ -452,6 +601,7 @@ Pass an array of coordinates to focus a map region on said coordinates. * Make sure that you have [properly installed](docs/installation.md) react-native-maps. * Check in the logs if there is more informations about the issue. * Try setting the style of the MapView to an absolute position with top, left, right and bottom values set. +* Make sure you have enabled Google Maps API in ![Google developer console](https://console.developers.google.com/apis/library) ```javascript const styles = StyleSheet.create({ diff --git a/docs/callout.md b/docs/callout.md index 58b59a6bd5..9a3eb55439 100644 --- a/docs/callout.md +++ b/docs/callout.md @@ -1,4 +1,4 @@ -# `` Component API +# `` Component API ## Props diff --git a/docs/circle.md b/docs/circle.md index 992ac4567d..d00d6f4d9c 100644 --- a/docs/circle.md +++ b/docs/circle.md @@ -1,4 +1,4 @@ -# `` Component API +# `` Component API ## Props diff --git a/docs/examples-setup.md b/docs/examples-setup.md index 048dd46e7c..89dfc3362a 100644 --- a/docs/examples-setup.md +++ b/docs/examples-setup.md @@ -11,23 +11,33 @@ gem install bundler 2. Install dependencies and open the workspace: ``` -cd example npm install -cd ios -bundle install -bundle exec pod install -open AirMapsExplorer.xcworkspace +npm run build:ios +npm run run:ios ``` -3. Make sure the `AirMapsExplorer` target is selected and click `Run` +or + +``` +yarn install +yarn build:ios +yarn run:ios +``` ## android 1. Start your emulator -2. Install via gradle: +2. Install dependencies and run the example: + +``` +npm install +npm run run:android +``` + +or ``` -# from the example/ dir: -react-native run-android +yarn install +yarn run:android ``` diff --git a/docs/installation.md b/docs/installation.md index ad9d4b3833..acfbb2875d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -6,218 +6,302 @@ First, download the library from npm: npm install react-native-maps --save ``` -Second, install the native dependencies: You can use `rnpm` (now part of `react-native` core via `link`) to -add native dependencies automatically then continue the directions below depending on your target OS. -``` -react-native link react-native-maps -``` +## Get a Google Maps API key + +Go to https://developers.google.com/maps/documentation/ios-sdk/get-api-key and https://developers.google.com/maps/documentation/android-api/signup to get your keys for both iOS and Android. + +Make sure that Google Maps Android API and Google Maps SDK for iOS are enabled for the current project. +https://console.developers.google.com/apis/library/maps-android-backend.googleapis.com/ +https://console.developers.google.com/apis/library/maps-ios-backend.googleapis.com + +Without an API key the Google Maps map won't render anything. + - >This installation should work in physical devices. For Genymotion, be sure to check Android installation about Google Play Services +## iOS - CocoaPods -## iOS +Setup your `Podfile` (found at `/ios/Podfile` as below, replace all references to `_YOUR_PROJECT_TARGET_` with your project target (it's the same as project name by default), and then run `pod install` while in the `ios` folder. -> These options may not be necessary if you ran "react-native link" +Please make sure to use `.xcworkspace`, not `.xcproject` after that. -### Option 1: CocoaPods - Same as the included AirMapsExplorer example +~~~ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' -1. Setup your `Podfile` like the included [example/ios/Podfile](../example/ios/Podfile), replace all references to `AirMapsExplorer` with your project name, and then run `pod install`. - (If you do not need `GoogleMaps` support for iOS, then you can probably completely skip this step.) -1. Open your project in Xcode workspace -1. If you need `GoogleMaps` support also - - Drag this folder `node_modules/react-native-maps/lib/ios/AirGoogleMaps/` into your project, and choose `Create groups` in the popup window. - - In `AppDelegate.m`, add `@import GoogleMaps;` before `@implementation AppDelegate`. In `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`, add `[GMSServices provideAPIKey:@"YOUR_GOOGLE_MAP_API_KEY"];` - - In your project's `Build Settings` > `Header Search Paths`, double click the value field. In the popup, add `$(SRCROOT)/../node_modules/react-native-maps/lib/ios/AirMaps` and change `non-recursive` to `recursive`. (Dragging the folder `node_modules/react-native-maps/lib/ios/AirMaps/` into your project introduces duplicate symbols. We should not do it.) - -Note: We recommend using a version of React Native >= .40. Newer versions (>= .40) require `package.json` to be set to `"react-native-maps": "^0.13.0"`, while older versions require `"react-native-maps": "^0.12.4"`. +target '_YOUR_PROJECT_TARGET_' do + rn_path = '../node_modules/react-native' + rn_maps_path = '../node_modules/react-native-maps' -### Option 2: CocoaPods -This is now considered the **old way** because it will only work if you **don't** have -`use_frameworks!` in your `Podfile`. + # See http://facebook.github.io/react-native/docs/integration-with-existing-apps.html#configuring-cocoapods-dependencies + pod 'yoga', path: "#{rn_path}/ReactCommon/yoga/yoga.podspec" + pod 'React', path: rn_path, subspecs: [ + 'Core', + 'CxxBridge', + 'DevSupport', + 'RCTActionSheet', + 'RCTAnimation', + 'RCTGeolocation', + 'RCTImage', + 'RCTLinkingIOS', + 'RCTNetwork', + 'RCTSettings', + 'RCTText', + 'RCTVibration', + 'RCTWebSocket', + ] -To install using Cocoapods, simply insert the following line into your `Podfile`: + # React Native third party dependencies podspecs + pod 'DoubleConversion', :podspec => "#{rn_path}/third-party-podspecs/DoubleConversion.podspec" + pod 'glog', :podspec => "#{rn_path}/third-party-podspecs/glog.podspec" + # If you are using React Native <0.54, you will get the following error: + # "The name of the given podspec `GLog` doesn't match the expected one `glog`" + # Use the following line instead: + #pod 'GLog', :podspec => "#{rn_path}/third-party-podspecs/GLog.podspec" + pod 'Folly', :podspec => "#{rn_path}/third-party-podspecs/Folly.podspec" - pod 'react-native-maps', :path => '../node_modules/react-native-maps' + # react-native-maps dependencies + pod 'react-native-maps', path: rn_maps_path + pod 'react-native-google-maps', path: rn_maps_path # Remove this line if you don't want to support GoogleMaps on iOS + pod 'GoogleMaps' # Remove this line if you don't want to support GoogleMaps on iOS + pod 'Google-Maps-iOS-Utils' # Remove this line if you don't want to support GoogleMaps on iOS +end -If you need `GoogleMaps` support in iOS also add this line: +post_install do |installer| + installer.pods_project.targets.each do |target| + if target.name == 'react-native-google-maps' + target.build_configurations.each do |config| + config.build_settings['CLANG_ENABLE_MODULES'] = 'No' + end + end + if target.name == "React" + target.remove_from_project + end + end +end +~~~ - pod 'react-native-google-maps', :path => '../node_modules/react-native-maps' -Now if you need `GoogleMaps` support you will also have to add a bunch of other stuff to your -`Podfile`. See the **comments* in the included [example/ios/Podfile](../example/ios/Podfile) which explain the rest. +## IMPORTANT!! -After your `Podfile` is setup properly, run `pod install`. +**!! DO NOT USE !!** `react-native link` -### Option 3: Manually - >This was already done for you if you ran "react-native link" +Have ran it already? Read [this](#on-ios). + +## If you want to use Google maps + + +Add to `ios/_YOUR_PROJECT_NAME_/AppDelegate.m: + +```objc ++ @import GoogleMaps; //add this line if you want to use Google Maps + +@implementation AppDelegate +... + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ ++ [GMSServices provideAPIKey:@"_YOUR_API_KEY_"]; // add this line using the api key obtained from Google Console +... +``` + +This should be the **first line** of the method. + +## Notes on running on a real ios device + +The steps are as described in https://facebook.github.io/react-native/docs/running-on-device.html , however instead of opening the .xcodeproj file you should open .xcworkspace file. -1. Open your project in Xcode, right click on `Libraries` and click `Add - Files to "Your Project Name"` Look under `node_modules/react-native-maps/lib/ios` and add `AIRMaps.xcodeproj`. -1. Add `libAIRMaps.a` to `Build Phases -> Link Binary With Libraries. -1. Click on `AIRMaps.xcodeproj` in `Libraries` and go the `Build - Settings` tab. Double click the text to the right of `Header Search - Paths` and verify that it has `$(SRCROOT)/../../react-native/React` as well as `$(SRCROOT)/../../react-native/Libraries/Image` - if they - aren't, then add them. This is so Xcode is able to find the headers that - the `AIRMaps` source files are referring to by pointing to the - header files installed within the `react-native` `node_modules` - directory. -1. Whenever you want to use it within React code now you can: `var MapView = - require('react-native-maps');` ## Android 1. In your `android/app/build.gradle` add: - >This step is not necessary if you ran "react-native link react-native-maps" - ```groovy - ... - dependencies { - ... - compile project(':react-native-maps') - } - ``` +```groovy +... +dependencies { + ... + implementation project(':react-native-maps') +} +``` + +If you've defined *[project-wide properties](https://developer.android.com/studio/build/gradle-tips.html)* (**recommended**) in your root `build.gradle`, this library will detect the presence of the following properties: + +```groovy +buildscript {...} +allprojects {...} + +/** + + Project-wide Gradle configuration properties + */ +ext { + compileSdkVersion = 26 + targetSdkVersion = 26 + buildToolsVersion = "26.0.2" + supportLibVersion = "26.1.0" + googlePlayServicesVersion = "11.8.0" + androidMapsUtilsVersion = "0.5+" +} +``` - If you have a different play services than the one included in this library, use the following instead (switch 10.0.1 for the desired version): + If you do **not** have *project-wide properties* defined and have a different play-services version than the one included in this library, use the following instead (switch 10.0.1 for the desired version): - ```groovy +```groovy +... +dependencies { ... - dependencies { - ... - compile(project(':react-native-maps')){ - exclude group: 'com.google.android.gms', module: 'play-services-base' - exclude group: 'com.google.android.gms', module: 'play-services-maps' - } - compile 'com.google.android.gms:play-services-base:10.0.1' - compile 'com.google.android.gms:play-services-maps:10.0.1' + implementation(project(':react-native-maps')){ + exclude group: 'com.google.android.gms', module: 'play-services-base' + exclude group: 'com.google.android.gms', module: 'play-services-maps' } - ``` + implementation 'com.google.android.gms:play-services-base:10.0.1' + implementation 'com.google.android.gms:play-services-maps:10.0.1' +} +``` -1. In your `android/settings.gradle` add: - >This step is not necessary if you ran "react-native link" +2. In your `android/settings.gradle` add: - ```groovy - ... - include ':react-native-maps' - project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/lib/android') - ``` - -1. Specify your Google Maps API Key: - > For development, you need to get a ***API Key***. Go to https://console.developers.google.com/apis/credentials to check your credentials. - - Add your API key to your manifest file (`android\app\src\main\AndroidManifest.xml`): - - ```xml - - - - - ``` +```groovy +... +include ':react-native-maps' +project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/lib/android') +``` + +3. Specify your Google Maps API Key: + + Add your API key to your manifest file (`android/app/src/main/AndroidManifest.xml`): + +```xml + + + + +``` > Note: As shown above, com.google.android.geo.API_KEY is the recommended metadata name for the API key. A key with this name can be used to authenticate to multiple Google Maps-based APIs on the Android platform, including the Google Maps Android API. For backwards compatibility, the API also supports the name com.google.android.maps.v2.API_KEY. This legacy name allows authentication to the Android Maps API v2 only. An application can specify only one of the API key metadata names. If both are specified, the API throws an exception. Source: https://developers.google.com/maps/documentation/android-api/signup -1. Ensure that you have Google Play Services installed: + +4. Add `import com.airbnb.android.react.maps.MapsPackage;` and `new MapsPackage()` in your `MainApplication.java` : + +```java +import com.airbnb.android.react.maps.MapsPackage; +... + @Override + protected List getPackages() { + return Arrays.asList( + new MainReactPackage(), + new MapsPackage() + ); + } +``` + + +5. Ensure that you have Google Play Services installed: * For Genymotion you can follow [these instructions](https://www.genymotion.com/help/desktop/faq/#google-play-services). * For a physical device you need to search on Google for 'Google Play Services'. There will be a link that takes you to the Play Store and from there you will see a button to update it (do not search within the Play Store). ## Troubleshooting -If you get the error `duplicate symbols for architecture x86_64` when building for iOS, you may need to reconfigure your linking and Podfile as [described in detail in this comment on issue #718](https://github.com/airbnb/react-native-maps/issues/718#issuecomment-295585410) - If you have a blank map issue, ([#118](https://github.com/airbnb/react-native-maps/issues/118), [#176](https://github.com/airbnb/react-native-maps/issues/176), [#684](https://github.com/airbnb/react-native-maps/issues/684)), try the following lines : ### On iOS: -You have to link dependencies with rnpm and re-run the build: +If google logo/markers/polylines etc are displayed, this is likely an API key issue. Verify your API keys and their restrictions. Ensure the native `provideAPIKey` call is the first line of `didFinishLaunchingWithOptions`. -1. `react-native link react-native-maps` -1. `react-native run-ios` +If you have ran 'react-native link` by mistake: + +1. delete node_modules +2. delete ios/Pods +3. delete ios/Podfile.lock +4. open Xcode and delete `AIRMaps.xcodeproj` from Libraries if it exists +5. in Build Phases -> Link Binary With Libraries delete `libAIRMaps.a` if it exists +6. delete ios/build folder +7. start again with the installation steps + +If you use Xcode with version less than 9 you may get `use of undeclared identifier 'MKMapTypeMutedStandard'` or `Entry, ":CFBundleIdentifier", Does Not Exist` errors. In this case you have to update your Xcode. ### On Android: 1. Be sure to have `new MapsPackage()` in your `MainApplication.java` : - >This step is not necessary if you ran "react-native link react-native-maps" - ``` - import com.airbnb.android.react.maps.MapsPackage; - ... - @Override - protected List getPackages() { - return Arrays.asList( - new MainReactPackage(), - new MapsPackage() - ); - } - ``` +```java +import com.airbnb.android.react.maps.MapsPackage; +... + @Override + protected List getPackages() { + return Arrays.asList( + new MainReactPackage(), + new MapsPackage() + ); + } +``` 1. Set this Stylesheet in your map component - ``` - import MapView from 'react-native-maps'; - ... - const styles = StyleSheet.create({ - container: { - ...StyleSheet.absoluteFillObject, - height: 400, - width: 400, - justifyContent: 'flex-end', - alignItems: 'center', - }, - map: { - ...StyleSheet.absoluteFillObject, - }, - }); - - module.exports = class MyApp extends React.Component { - render() { - const { region } = this.props; - console.log(region); - - return ( - - - - - ); - } - } - ``` +```jsx +import MapView from 'react-native-maps'; +... +const styles = StyleSheet.create({ + container: { + ...StyleSheet.absoluteFillObject, + height: 400, + width: 400, + justifyContent: 'flex-end', + alignItems: 'center', + }, + map: { + ...StyleSheet.absoluteFillObject, + }, +}); + +export default class MyApp extends React.Component { + render() { + const { region } = this.props; + console.log(region); + + return ( + + + + + ); + } +} +``` 1. Run "android" and make sure all packages are up-to-date. 1. If not installed yet, you have to install the following packages : - Extras / Google Play services - Extras / Google Repository - Android 6.0 (API 23) / Google APIs Intel x86 Atom System Image Rev. 19 - - Android SDK Build-tools 23.0.3 -1. Check manual installation steps if you didn't run "react-native link react-native-maps" + - Android SDK Build-tools 23.0.3 1. Go to [Google API Console](https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend) and select your project, or create one. Then, once enabled, select `Go to credentials`. Select `Google Maps Android API` and create a new key. Enter the name of the API key and create it. 1. Clean the cache : - ``` - watchman watch-del-all - npm cache clean - ``` +``` +watchman watch-del-all +npm cache clean +``` 1. When starting emulator, make sure you have enabled `Wipe user data`. 1. Run `react-native run-android` 1. If you encounter `com.android.dex.DexException: Multiple dex files define Landroid/support/v7/appcompat/R$anim`, then clear build folder. - ``` - cd android - ./gradlew clean - cd .. - ``` +``` +cd android +./gradlew clean +cd .. +``` 1. If you are using Android Virtual Devices (AVD), ensure that `Use Host GPU` is checked in the settings for your virtual device. diff --git a/docs/mapview.md b/docs/mapview.md index 2aa6a7086f..edbe23a850 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -7,10 +7,12 @@ | `provider` | `string` | | The map framework to use.

Either `"google"` for GoogleMaps, otherwise `null` or `undefined` to use the native map framework (`MapKit` in iOS and `GoogleMaps` in android). | `region` | `Region` | | The region to be displayed by the map.

The region is defined by the center coordinates and the span of coordinates to display. | `initialRegion` | `Region` | | The initial region to be displayed by the map. Use this prop instead of `region` only if you don't want to control the viewport of the map besides the initial region.

Changing this prop after the component has mounted will not result in a region change.

This is similar to the `initialValue` prop of a text input. +| `mapPadding` | `EdgePadding` | | Adds custom padding to each side of the map. Useful when map elements/markers are obscured. **Note** Google Maps only. +| `paddingAdjustmentBehavior` | 'always'\|'automatic'\|'never' | 'never' | Indicates how/when to affect padding with safe area insets (`GoogleMaps` in iOS only) | `liteMode` | `Boolean` | `false` | Enable lite mode. **Note**: Android only. -| `mapType` | `String` | `"standard"` | The map type to be displayed.

- standard: standard road map (default)
- satellite: satellite view
- hybrid: satellite view with roads and points of interest overlayed
- terrain: (Android only) topographic view +| `mapType` | `String` | `"standard"` | The map type to be displayed.

- standard: standard road map (default)
- none: no map
- satellite: satellite view
- hybrid: satellite view with roads and points of interest overlayed
- terrain: (Android only) topographic view
- mutedStandard: more subtle, makes markers/lines pop more (iOS 11.0+ only) | `customMapStyle` | `Array` | | Adds custom styling to the map component. See [README](https://github.com/airbnb/react-native-maps#customizing-the-map-style) for more information. -| `showsUserLocation` | `Boolean` | `false` | If `true` the app will ask for the user's location. **NOTE**: You need to add `NSLocationWhenInUseUsageDescription` key in Info.plist to enable geolocation, otherwise it is going to *fail silently*! +| `showsUserLocation` | `Boolean` | `false` | If `true` the app will ask for the user's location. **NOTE**: You need to add `NSLocationWhenInUseUsageDescription` key in Info.plist to enable geolocation, otherwise it is going to *fail silently*! You will also need to add an explanation for why you need the users location against `NSLocationWhenInUseUsageDescription` in Info.plist. Otherwise Apple may reject your app submission. | `userLocationAnnotationTitle` | `String` | | The title of the annotation for current user location. This only works if `showsUserLocation` is true. There is a default value `My Location` set by MapView. **Note**: iOS only. | `followsUserLocation` | `Boolean` | `false` | If `true` the map will focus on the user's location. This only works if `showsUserLocation` is true and the user has shared their location. **Note**: iOS only. | `showsMyLocationButton` | `Boolean` | `true` | If `false` hide the button to move map to the current user's location. @@ -22,6 +24,7 @@ | `showsIndoors` | `Boolean` | `true` | A Boolean indicating whether indoor maps should be enabled. | `showsIndoorLevelPicker` | `Boolean` | `false` | A Boolean indicating whether indoor level picker should be enabled. **Note:** Google Maps only (either Android or iOS with `PROVIDER_GOOGLE`). | `zoomEnabled` | `Boolean` | `true` | If `false` the user won't be able to pinch/zoom the map. +| `zoomControlEnabled` | `Boolean` | `true` | If `false` the zoom control at the bottom right of the map won't be visible **Note:** Android only. | `minZoomLevel` | `Number` | `0` | Minimum zoom value for the map, must be between 0 and 20 | `maxZoomLevel` | `Number` | `20` | Maximum zoom value for the map, must be between 0 and 20 | `rotateEnabled` | `Boolean` | `true` | If `false` the user won't be able to pinch/rotate the map. @@ -34,6 +37,7 @@ | `loadingBackgroundColor` | `Color` | `#FFFFFF` | Sets loading background color, default to `#FFFFFF`. | `moveOnMarkerPress` | `Boolean` | `true` | `Android only` If `false` the map won't move when a marker is pressed. | `legalLabelInsets` | `EdgeInsets` | | If set, changes the position of the "Legal" label link from the OS default. **Note:** iOS only. +| `kmlSrc` | `string` | | The URL from KML file. **Note:** Google Maps and Markers only (either Android or iOS with `PROVIDER_GOOGLE`). ## Events @@ -43,10 +47,13 @@ To access event data, you will need to use `e.nativeEvent`. For example, `onPres | Event Name | Returns | Notes |---|---|---| | `onMapReady` | | Callback that is called once the map is fully loaded. +| `onKmlReady` | `KmlContainer` | Callback that is called once the kml is fully loaded. | `onRegionChange` | `Region` | Callback that is called continuously when the region changes, such as when a user is dragging the map. | `onRegionChangeComplete` | `Region` | Callback that is called once when the region changes, such as when the user is done moving the map. +| `onUserLocationChange` | `{ coordinate: Location }` | Callback that is called when the underlying map figures our users current location (coordinate also includes isFromMockProvider value for Android API 18 and above). Make sure **showsUserLocation** is set to *true* and that the provider is `"google"`. | `onPress` | `{ coordinate: LatLng, position: Point }` | Callback that is called when user taps on the map. | `onPanDrag` | `{ coordinate: LatLng, position: Point }` | Callback that is called when user presses and drags the map. **NOTE**: for iOS `scrollEnabled` should be set to false to trigger the event +| `onPoiClick` | `{ coordinate: LatLng, position: Point, placeId: string, name: string }` | Callback that is called when user click on a POI. | `onLongPress` | `{ coordinate: LatLng, position: Point }` | Callback that is called when user makes a "long press" somewhere on the map. | `onMarkerPress` | | Callback that is called when a marker on the map is tapped by the user. | `onMarkerSelect` | | Callback that is called when a marker on the map becomes selected. This will be called when the callout for that marker is about to be shown. **Note**: iOS only. @@ -62,13 +69,17 @@ To access event data, you will need to use `e.nativeEvent`. For example, `onPres | Method Name | Arguments | Notes |---|---|---| +| `animateToNavigation` | `location: LatLng`, `bearing: Number`, `angle: Number`, `duration: Number` | | `animateToRegion` | `region: Region`, `duration: Number` | | `animateToCoordinate` | `coordinate: LatLng`, `duration: Number` | | `animateToBearing` | `bearing: Number`, `duration: Number` | | `animateToViewingAngle` | `angle: Number`, `duration: Number` | +| `setMapBoundaries` | `northEast: LatLng`, `southWest: LatLng` | `GoogleMaps only` | `fitToElements` | `animated: Boolean` | | `fitToSuppliedMarkers` | `markerIDs: String[]`, `animated: Boolean` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. | `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | If called in `ComponentDidMount` in android, it will cause an exception. It is recommended to call it from the MapView `onLayout` event. +| `pointForCoordinate` | `coordinate: LatLng` | Converts a map coordinate to a view coordinate (`Point`). Returns a `Promise`. +| `coordinateForPoint` | `point: Point` | Converts a view coordinate (`Point`) to a map coordinate. Returns a `Promise`. @@ -90,6 +101,18 @@ type LatLng { } ``` +``` +type Location { + latitude: Number, + longitude: Number, + altitude: Number, + timestamp: Number, //Milliseconds since Unix epoch + accuracy: Number, + altitudeAccuracy: Number, + speed: Number, +} +``` + ``` type Point { x: Number, @@ -123,3 +146,18 @@ type EdgeInsets { right: Number } ``` + +``` +type Marker { + id: String, + coordinate: LatLng, + title: String, + description: String +} +``` + +``` +type KmlContainer { + markers: [Marker] +} +``` diff --git a/docs/marker.md b/docs/marker.md index 4214e4d6e8..97170b02b9 100644 --- a/docs/marker.md +++ b/docs/marker.md @@ -1,22 +1,26 @@ -# `` Component API +# `` Component API ## Props | Prop | Type | Default | Note | |---|---|---|---| -| `title` | `String` | | The title of the marker. This is only used if the component has no children that are an ``, in which case the default callout behavior will be used, which will show both the `title` and the `description`, if provided. -| `description` | `String` | | The description of the marker. This is only used if the component has no children that are an ``, in which case the default callout behavior will be used, which will show both the `title` and the `description`, if provided. +| `title` | `String` | | The title of the marker. This is only used if the component has no children that are a ``, in which case the default callout behavior will be used, which will show both the `title` and the `description`, if provided. +| `description` | `String` | | The description of the marker. This is only used if the component has no children that are a ``, in which case the default callout behavior will be used, which will show both the `title` and the `description`, if provided. | `image` | `ImageSource` | | A custom image to be used as the marker's icon. Only local image resources are allowed to be used. -| `pinColor` | `Color` | | If no custom marker view or custom image is provided, the platform default pin will be used, which can be customized by this color. Ignored if a custom marker is being used. +| `pinColor` | `Color` | | If no custom marker view or custom image is provided, the platform default pin will be used, which can be customized by this color. Ignored if a custom marker is being used.

For Android, the set of available colors is limited. Unsupported colors will fall back to red. See [#887](https://github.com/react-community/react-native-maps/issues/887) for more information. | `coordinate` | `LatLng` | | The coordinate for the marker. -| `centerOffset` | `Point` | | The offset (in points) at which to display the view.

By default, the center point of an annotation view is placed at the coordinate point of the associated annotation. You can use this property to reposition the annotation view as needed. This x and y offset values are measured in points. Positive offset values move the annotation view down and to the right, while negative values move it up and to the left.

For Google Maps, see the `anchor` prop. -| `calloutOffset` | `Point` | | The offset (in points) at which to place the callout bubble.

This property determines the additional distance by which to move the callout bubble. When this property is set to (0, 0), the anchor point of the callout bubble is placed on the top-center point of the marker view’s frame. Specifying positive offset values moves the callout bubble down and to the right, while specifying negative values moves it up and to the left.

For android, see the `calloutAnchor` prop. -| `anchor` | `Point` | | Sets the anchor point for the marker.

The anchor specifies the point in the icon image that is anchored to the marker's position on the Earth's surface.

The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0) is the top-left corner of the image, and (1, 1) is the bottom-right corner. The anchoring point in a W x H image is the nearest discrete grid point in a (W + 1) x (H + 1) grid, obtained by scaling the then rounding. For example, in a 4 x 2 image, the anchor point (0.7, 0.6) resolves to the grid point at (3, 1).

For MapKit on iOS, see the `centerOffset` prop. -| `calloutAnchor` | `Point` | | Specifies the point in the marker image at which to anchor the callout when it is displayed. This is specified in the same coordinate system as the anchor. See the `anchor` prop for more details.

The default is the top middle of the image.

For ios, see the `calloutOffset` prop. -| `flat` | `Boolean` | | Sets whether this marker should be flat against the map true or a billboard facing the camera false. +| `centerOffset` | `Point` | (0, 0) | The offset (in points) at which to display the view.

By default, the center point of an annotation view is placed at the coordinate point of the associated annotation. You can use this property to reposition the annotation view as needed. This x and y offset values are measured in points. Positive offset values move the annotation view down and to the right, while negative values move it up and to the left.

For Google Maps, see the `anchor` prop. +| `calloutOffset` | `Point` | (0, 0) | The offset (in points) at which to place the callout bubble.

This property determines the additional distance by which to move the callout bubble. When this property is set to (0, 0), the anchor point of the callout bubble is placed on the top-center point of the marker view’s frame. Specifying positive offset values moves the callout bubble down and to the right, while specifying negative values moves it up and to the left.

For Google Maps, see the `calloutAnchor` prop. +| `anchor` | `Point` | (0.5, 1) | Sets the anchor point for the marker.

The anchor specifies the point in the icon image that is anchored to the marker's position on the Earth's surface.

The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0) is the top-left corner of the image, and (1, 1) is the bottom-right corner. The anchoring point in a W x H image is the nearest discrete grid point in a (W + 1) x (H + 1) grid, obtained by scaling the then rounding. For example, in a 4 x 2 image, the anchor point (0.7, 0.6) resolves to the grid point at (3, 1).

For MapKit on iOS, see the `centerOffset` prop. +| `calloutAnchor` | `Point` | (0.5, 0) | Specifies the point in the marker image at which to anchor the callout when it is displayed. This is specified in the same coordinate system as the anchor. See the `anchor` prop for more details.

The default is the top middle of the image.

For MapKit on iOS, see the `calloutOffset` prop. +| `flat` | `Boolean` | false | Sets whether this marker should be flat against the map true or a billboard facing the camera. | `identifier` | `String` | | An identifier used to reference this marker at a later date. -| `rotation` | `Float` | | A float number indicating marker's rotation angle, in degrees. +| `rotation` | `Float` | 0 | A float number indicating marker's rotation angle, in degrees. | `draggable` | `` | | This is a non-value based prop. Adding this allows the marker to be draggable (re-positioned). +| `tracksViewChanges` | `Boolean` | true | Sets whether this marker should track view changes. It's recommended to turn it off whenever it's possible to improve custom marker performance. **Note**: iOS Google Maps only. +| `tracksInfoWindowChanges` | `Boolean` | false | Sets whether this marker should track view changes in info window. Enabling it will let marker change content of info window after first render pass, but will lead to decreased performance, so it's recommended to disable it whenever you don't need it. **Note**: iOS Google Maps only. +| `stopPropagation` | `Boolean` | false | Sets whether this marker should propagate `onPress` events. Enabling it will stop the parent `MapView`'s `onPress` from being called. **Note**: iOS only. Android does not propagate `onPress` events. See [#1132](https://github.com/react-community/react-native-maps/issues/1132) for more information. +| `opacity` | `Float` | 1.0 | The marker's opacity between 0.0 and 1.0. ## Events @@ -39,6 +43,7 @@ To access event data, you will need to use `e.nativeEvent`. For example, `onPres |---|---|---| | `showCallout` | | Shows the callout for this marker | `hideCallout` | | Hides the callout for this marker +| `animateMarkerToCoordinate` | `coordinate: LatLng, duration: number` | Animates marker movement. **Note**: Android only diff --git a/docs/overlay.md b/docs/overlay.md new file mode 100644 index 0000000000..29a12aee3a --- /dev/null +++ b/docs/overlay.md @@ -0,0 +1,17 @@ +# `` Component API + +## Props + +| Prop | Type | Default | Note | +|---|---|---|---| +| `image` | `ImageSource` | A custom image to be used as the overlay. Only required local image resources and uri (as for images located in the net) are allowed to be used. +| `bounds` | `Array` | | The coordinates for the image (left-top corner, right-bottom corner). + +## Types + +``` +type LatLng { + latitude: Number, + longitude: Number, +} +``` diff --git a/docs/polygon.md b/docs/polygon.md index 085b31a183..31ca60d986 100644 --- a/docs/polygon.md +++ b/docs/polygon.md @@ -1,10 +1,11 @@ -# `` Component API +# `` Component API ## Props | Prop | Type | Default | Note | |---|---|---|---| | `coordinates` | `Array` | (Required) | An array of coordinates to describe the polygon +| `holes` | `Array>` | | A 2d array of coordinates to describe holes of the polygon where each hole has at least 3 points. | `strokeWidth` | `Number` | `1` | The stroke width to use for the path. | `strokeColor` | `String` | `#000`, `rgba(r,g,b,0.5)` | The stroke color to use for the path. | `fillColor` | `String` | `#000`, `rgba(r,g,b,0.5)` | The fill color to use for the path. @@ -14,6 +15,7 @@ | `geodesic` | `Boolean` | | Boolean to indicate whether to draw each segment of the line as a geodesic as opposed to straight lines on the Mercator projection. A geodesic is the shortest path between two points on the Earth's surface. The geodesic curve is constructed assuming the Earth is a sphere. | `lineDashPhase` | `Number` | `0` | (iOS only) The offset (in points) at which to start drawing the dash pattern. Use this property to start drawing a dashed line partway through a segment or gap. For example, a phase value of 6 for the patter 5-2-3-2 would cause drawing to begin in the middle of the first gap. | `lineDashPattern` | `Array` | `null` | (iOS only) An array of numbers specifying the dash pattern to use for the path. The array contains one or more numbers that indicate the lengths (measured in points) of the line segments and gaps in the pattern. The values in the array alternate, starting with the first line segment length, followed by the first gap length, followed by the second line segment length, and so on. +| `tappable` | `Bool` | false (for iOS) | Boolean to allow a polygon to be tappable and use the onPress function. ## Events diff --git a/docs/polyline.md b/docs/polyline.md index 89ef9de251..873b708ca9 100644 --- a/docs/polyline.md +++ b/docs/polyline.md @@ -1,4 +1,4 @@ -# `` Component API +# `` Component API ## Props @@ -7,8 +7,9 @@ | `coordinates` | `Array` | (Required) | An array of coordinates to describe the polyline | `strokeWidth` | `Number` | `1` | The stroke width to use for the path. | `strokeColor` | `String` | `#000` | The stroke color to use for the path. -| `lineCap` | `String` | `round` | The line cap style to apply to the open ends of the path. -| `lineJoin` | `Array` | | The line join style to apply to corners of the path. +| `strokeColors` | `Array` | `null` | The stroke colors to use for the path (iOS only). Must be the same length as `coordinates`. +| `lineCap` | `String` | `round` | The line cap style to apply to the open ends of the path. Possible values are `butt`, `round` or `square`. Note: lineCap is not yet supported for GoogleMaps provider on iOS. +| `lineJoin` | `String` | `round` | The line join style to apply to corners of the path. Possible values are `miter`, `round` or `bevel`. | `miterLimit` | `Number` | | The limiting value that helps avoid spikes at junctions between connected line segments. The miter limit helps you avoid spikes in paths that use the `miter` `lineJoin` style. If the ratio of the miter length—that is, the diagonal length of the miter join—to the line thickness exceeds the miter limit, the joint is converted to a bevel join. The default miter limit is 10, which results in the conversion of miters whose angle at the joint is less than 11 degrees. | `geodesic` | `Boolean` | | Boolean to indicate whether to draw each segment of the line as a geodesic as opposed to straight lines on the Mercator projection. A geodesic is the shortest path between two points on the Earth's surface. The geodesic curve is constructed assuming the Earth is a sphere. | `lineDashPhase` | `Number` | `0` | (iOS only) The offset (in points) at which to start drawing the dash pattern. Use this property to start drawing a dashed line partway through a segment or gap. For example, a phase value of 6 for the patter 5-2-3-2 would cause drawing to begin in the middle of the first gap. @@ -28,3 +29,36 @@ type LatLng { longitude: Number, } ``` + +## Gradient Polylines (iOS MapKit only) + +Gradient polylines can be created by using the `strokeColors` prop. `strokeColors` must be an array with the same number of elements as `coordinates`. + +Example: + +```js +import MapView, { Polyline } from 'react-native-maps'; + + + + +``` diff --git a/example/.flowconfig b/example/.flowconfig deleted file mode 100644 index c3edaf9464..0000000000 --- a/example/.flowconfig +++ /dev/null @@ -1,65 +0,0 @@ -[ignore] - -# We fork some components by platform. -.*/*.web.js -.*/*.android.js - -# Some modules have their own node_modules with overlap -.*/node_modules/node-haste/.* - -# Ugh -.*/node_modules/babel.* -.*/node_modules/babylon.* -.*/node_modules/invariant.* - -# Ignore react and fbjs where there are overlaps, but don't ignore -# anything that react-native relies on -.*/node_modules/fbjs/lib/Map.js -.*/node_modules/fbjs/lib/Promise.js -.*/node_modules/fbjs/lib/fetch.js -.*/node_modules/fbjs/lib/ExecutionEnvironment.js -.*/node_modules/fbjs/lib/isEmpty.js -.*/node_modules/fbjs/lib/crc32.js -.*/node_modules/fbjs/lib/ErrorUtils.js - -# Flow has a built-in definition for the 'react' module which we prefer to use -# over the currently-untyped source -.*/node_modules/react/react.js -.*/node_modules/react/lib/React.js -.*/node_modules/react/lib/ReactDOM.js - -# Ignore commoner tests -.*/node_modules/commoner/test/.* - -# See https://github.com/facebook/flow/issues/442 -.*/react-tools/node_modules/commoner/lib/reader.js - -# Ignore jest -.*/node_modules/jest-cli/.* - -# Ignore Website -.*/website/.* - -[include] - -[libs] -node_modules/react-native/Libraries/react-native/react-native-interface.js - -[options] -module.system=haste - -munge_underscores=true - -module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' -module.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\)$' -> 'RelativeImageStub' - -suppress_type=$FlowIssue -suppress_type=$FlowFixMe -suppress_type=$FixMe - -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ -suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy - -[version] -0.21.0 diff --git a/example/App.js b/example/App.js index dadbea056b..7b6231e61d 100644 --- a/example/App.js +++ b/example/App.js @@ -16,6 +16,7 @@ import MarkerTypes from './examples/MarkerTypes'; import DraggableMarkers from './examples/DraggableMarkers'; import PolygonCreator from './examples/PolygonCreator'; import PolylineCreator from './examples/PolylineCreator'; +import GradientPolylines from './examples/GradientPolylines'; import AnimatedViews from './examples/AnimatedViews'; import AnimatedMarkers from './examples/AnimatedMarkers'; import Callouts from './examples/Callouts'; @@ -35,7 +36,12 @@ import MapStyle from './examples/MapStyle'; import LegalLabel from './examples/LegalLabel'; import SetNativePropsOverlays from './examples/SetNativePropsOverlays'; import CustomOverlay from './examples/CustomOverlay'; +import MapKml from './examples/MapKml'; import BugMarkerWontUpdate from './examples/BugMarkerWontUpdate'; +import ImageOverlayWithAssets from './examples/ImageOverlayWithAssets'; +import ImageOverlayWithURL from './examples/ImageOverlayWithURL'; +import AnimatedNavigation from './examples/AnimatedNavigation'; +import OnPoiClick from './examples/OnPoiClick'; const IOS = Platform.OS === 'ios'; const ANDROID = Platform.OS === 'android'; @@ -131,6 +137,7 @@ class App extends React.Component { [DraggableMarkers, 'Draggable Markers', true], [PolygonCreator, 'Polygon Creator', true], [PolylineCreator, 'Polyline Creator', true], + [GradientPolylines, 'Gradient Polylines', true], [AnimatedViews, 'Animating with MapViews'], [AnimatedMarkers, 'Animated Marker Position'], [Callouts, 'Custom Callouts', true], @@ -149,7 +156,12 @@ class App extends React.Component { [LegalLabel, 'Reposition the legal label', true], [SetNativePropsOverlays, 'Update native props', true], [CustomOverlay, 'Custom Overlay Component', true], + [MapKml, 'Load Map with KML', true], [BugMarkerWontUpdate, 'BUG: Marker Won\'t Update (Android)', true], + [ImageOverlayWithAssets, 'Image Overlay Component with Assets', true], + [ImageOverlayWithURL, 'Image Overlay Component with URL', true], + [AnimatedNavigation, 'Animated Map Navigation', true], + [OnPoiClick, 'On Poi Click', true], ] // Filter out examples that are not yet supported for Google Maps on iOS. .filter(example => ANDROID || (IOS && (example[2] || !this.state.useGoogleMaps))) @@ -189,4 +201,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = App; +export default App; diff --git a/example/android/app/.project b/example/android/app/.project new file mode 100644 index 0000000000..ca3856c62d --- /dev/null +++ b/example/android/app/.project @@ -0,0 +1,23 @@ + + + example-android + Project example-android created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/example/android/app/bin/src/main/java/com/airbnb/android/react/maps/example/ExampleApplication.class b/example/android/app/bin/src/main/java/com/airbnb/android/react/maps/example/ExampleApplication.class new file mode 100644 index 0000000000..3ed43fa991 Binary files /dev/null and b/example/android/app/bin/src/main/java/com/airbnb/android/react/maps/example/ExampleApplication.class differ diff --git a/example/android/app/bin/src/main/java/com/airbnb/android/react/maps/example/MainActivity.class b/example/android/app/bin/src/main/java/com/airbnb/android/react/maps/example/MainActivity.class new file mode 100644 index 0000000000..41f9343a16 Binary files /dev/null and b/example/android/app/bin/src/main/java/com/airbnb/android/react/maps/example/MainActivity.class differ diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 7a8e8b7dd7..d2b475051c 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -127,7 +127,7 @@ android { } dependencies { - compile 'com.facebook.react:react-native:0.45.+' + compile 'com.facebook.react:react-native:0.51.+' compile 'com.android.support:appcompat-v7:25.3.0' compile 'com.android.support:support-annotations:25.3.0' compile project(':react-native-maps-lib') diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index b111eef4a0..af26921868 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,11 +1,12 @@ - + + - { this.marker = marker; }} coordinate={this.state.coordinate} />
this.animate()} style={[styles.bubble, styles.button]} > Animate @@ -69,7 +78,7 @@ class AnimatedMarkers extends React.Component { } AnimatedMarkers.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -105,4 +114,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = AnimatedMarkers; +export default AnimatedMarkers; diff --git a/example/examples/AnimatedNavigation.js b/example/examples/AnimatedNavigation.js new file mode 100644 index 0000000000..ce7b85f99b --- /dev/null +++ b/example/examples/AnimatedNavigation.js @@ -0,0 +1,137 @@ +import React, { Component } from 'react'; + +import { + View, + StyleSheet, + TouchableOpacity, + Text, +} from 'react-native'; + +import MapView from 'react-native-maps'; +import carImage from './assets/car.png'; + +export default class NavigationMap extends Component { + + constructor(props) { + super(props); + this.state = { + prevPos: null, + curPos: { latitude: 37.420814, longitude: -122.081949 }, + curAng: 45, + latitudeDelta: 0.0922, + longitudeDelta: 0.0421, + }; + this.changePosition = this.changePosition.bind(this); + this.getRotation = this.getRotation.bind(this); + this.updateMap = this.updateMap.bind(this); + } + + changePosition(latOffset, lonOffset) { + const latitude = this.state.curPos.latitude + latOffset; + const longitude = this.state.curPos.longitude + lonOffset; + this.setState({ prevPos: this.state.curPos, curPos: { latitude, longitude } }); + this.updateMap(); + } + + getRotation(prevPos, curPos) { + if (!prevPos) return 0; + const xDiff = curPos.latitude - prevPos.latitude; + const yDiff = curPos.longitude - prevPos.longitude; + return (Math.atan2(yDiff, xDiff) * 180.0) / Math.PI; + } + + updateMap() { + const { curPos, prevPos, curAng } = this.state; + const curRot = this.getRotation(prevPos, curPos); + this.map.animateToNavigation(curPos, curRot, curAng); + } + + render() { + return ( + + (this.map = el)} + style={styles.flex} + minZoomLevel={15} + initialRegion={{ + ...this.state.curPos, + latitudeDelta: this.state.latitudeDelta, + longitudeDelta: this.state.longitudeDelta, + }} + > + + + + this.changePosition(0.0001, 0)} + > + + Lat + + this.changePosition(-0.0001, 0)} + > + - Lat + + + + this.changePosition(0, -0.0001)} + > + - Lon + + this.changePosition(0, 0.0001)} + > + + Lon + + + + ); + } +} + +const styles = StyleSheet.create({ + flex: { + flex: 1, + width: '100%', + }, + buttonContainerUpDown: { + ...StyleSheet.absoluteFillObject, + flexDirection: 'row', + justifyContent: 'center', + }, + buttonContainerLeftRight: { + ...StyleSheet.absoluteFillObject, + flexDirection: 'column', + justifyContent: 'center', + }, + button: { + backgroundColor: 'rgba(100,100,100,0.2)', + position: 'absolute', + alignItems: 'center', + justifyContent: 'center', + borderRadius: 20, + height: 50, + width: 50, + }, + up: { + alignSelf: 'flex-start', + }, + down: { + alignSelf: 'flex-end', + }, + left: { + alignSelf: 'flex-start', + }, + right: { + alignSelf: 'flex-end', + }, +}); diff --git a/example/examples/AnimatedPriceMarker.js b/example/examples/AnimatedPriceMarker.js index 9e39acbc18..edcda94ef8 100644 --- a/example/examples/AnimatedPriceMarker.js +++ b/example/examples/AnimatedPriceMarker.js @@ -1,4 +1,6 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; + import { StyleSheet, Text, @@ -103,4 +105,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = AnimatedPriceMarker; +export default AnimatedPriceMarker; diff --git a/example/examples/AnimatedViews.js b/example/examples/AnimatedViews.js index 884f11a379..a16b2f192b 100644 --- a/example/examples/AnimatedViews.js +++ b/example/examples/AnimatedViews.js @@ -6,7 +6,12 @@ import { Animated, } from 'react-native'; -import MapView from 'react-native-maps'; +import { + ProviderPropType, + Animated as AnimatedMap, + AnimatedRegion, + Marker, +} from 'react-native-maps'; import PanController from './PanController'; import PriceMarker from './AnimatedPriceMarker'; @@ -191,7 +196,7 @@ class AnimatedViews extends React.Component { scale, translateY, markers, - region: new MapView.AnimatedRegion({ + region: new AnimatedRegion({ latitude: LATITUDE, longitude: LONGITUDE, latitudeDelta: LATITUDE_DELTA, @@ -324,7 +329,7 @@ class AnimatedViews extends React.Component { onStartShouldSetPanResponder={this.onStartShouldSetPanResponder} onMoveShouldSetPanResponder={this.onMoveShouldSetPanResponder} > - @@ -352,10 +357,10 @@ class AnimatedViews extends React.Component { amount={marker.amount} selected={selected} /> -
+ ); })} - + {markers.map((marker, i) => { const { @@ -387,7 +392,7 @@ class AnimatedViews extends React.Component { } AnimatedViews.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -418,4 +423,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = AnimatedViews; +export default AnimatedViews; diff --git a/example/examples/BugMarkerWontUpdate.js b/example/examples/BugMarkerWontUpdate.js index 8bf62ffca8..8b2f697e2b 100644 --- a/example/examples/BugMarkerWontUpdate.js +++ b/example/examples/BugMarkerWontUpdate.js @@ -6,7 +6,7 @@ import { Dimensions, TouchableOpacity, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { ProviderPropType } from 'react-native-maps'; import MyLocationMapMarker from './MyLocationMapMarker'; const { width, height } = Dimensions.get('window'); @@ -93,7 +93,7 @@ class BugMarkerWontUpdate extends React.Component { } BugMarkerWontUpdate.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -131,4 +131,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = BugMarkerWontUpdate; +export default BugMarkerWontUpdate; diff --git a/example/examples/CachedMap.js b/example/examples/CachedMap.js index 296e042d64..2be98d2e40 100644 --- a/example/examples/CachedMap.js +++ b/example/examples/CachedMap.js @@ -8,7 +8,7 @@ import { TouchableOpacity, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { ProviderPropType, Marker } from 'react-native-maps'; import flagImg from './assets/flag-blue.png'; const HORIZONTAL_PADDING = 12; @@ -69,7 +69,7 @@ class CachedMap extends React.Component { loadingIndicatorColor="#666666" loadingBackgroundColor="#eeeeee" > - - { this.marker1 = ref; }} coordinate={markers[0].coordinate} title="This is a native view" description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation" // eslint-disable-line max-len /> - - + This is a plain view - - - + + - + This is a custom callout bubble view - - + +
@@ -116,7 +116,7 @@ class Callouts extends React.Component { } Callouts.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -159,4 +159,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = Callouts; +export default Callouts; diff --git a/example/examples/CustomCallout.js b/example/examples/CustomCallout.js index 719f04a96e..844252cc2b 100644 --- a/example/examples/CustomCallout.js +++ b/example/examples/CustomCallout.js @@ -1,4 +1,6 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; + import { StyleSheet, View, @@ -64,4 +66,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = CustomCallout; +export default CustomCallout; diff --git a/example/examples/CustomMarkers.js b/example/examples/CustomMarkers.js index 5c5330263c..4b7a8630f3 100644 --- a/example/examples/CustomMarkers.js +++ b/example/examples/CustomMarkers.js @@ -7,7 +7,7 @@ import { TouchableOpacity, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { Marker, ProviderPropType } from 'react-native-maps'; import flagPinkImg from './assets/flag-pink.png'; const { width, height } = Dimensions.get('window'); @@ -58,7 +58,7 @@ class CustomMarkers extends React.Component { onPress={this.onMapPress} > {this.state.markers.map(marker => ( - - - - - diff --git a/example/examples/CustomTiles.js b/example/examples/CustomTiles.js index 3d6e11d7f3..039b62f517 100644 --- a/example/examples/CustomTiles.js +++ b/example/examples/CustomTiles.js @@ -6,7 +6,7 @@ import { Dimensions, } from 'react-native'; -import MapView, { MAP_TYPES, PROVIDER_DEFAULT } from 'react-native-maps'; +import MapView, { MAP_TYPES, PROVIDER_DEFAULT, ProviderPropType, UrlTile } from 'react-native-maps'; const { width, height } = Dimensions.get('window'); @@ -46,7 +46,7 @@ class CustomTiles extends React.Component { style={styles.map} initialRegion={region} > - @@ -62,7 +62,7 @@ class CustomTiles extends React.Component { } CustomTiles.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -106,4 +106,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = CustomTiles; +export default CustomTiles; diff --git a/example/examples/CustomTilesLocal.js b/example/examples/CustomTilesLocal.js new file mode 100644 index 0000000000..0962d10969 --- /dev/null +++ b/example/examples/CustomTilesLocal.js @@ -0,0 +1,115 @@ +import React from 'react'; +import { + StyleSheet, + View, + Text, + Dimensions, +} from 'react-native'; + +import MapView, { + MAP_TYPES, + PROVIDER_DEFAULT, + LocalTile, + ProviderPropType, +} from 'react-native-maps'; + +const { width, height } = Dimensions.get('window'); + +const ASPECT_RATIO = width / height; +const LATITUDE = 37.78825; +const LONGITUDE = -122.4324; +const LATITUDE_DELTA = 0.0922; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; + +class CustomTiles extends React.Component { + constructor(props, context) { + super(props, context); + + this.state = { + region: { + latitude: LATITUDE, + longitude: LONGITUDE, + latitudeDelta: LATITUDE_DELTA, + longitudeDelta: LONGITUDE_DELTA, + }, + }; + } + + get mapType() { + // MapKit does not support 'none' as a base map + return this.props.provider === PROVIDER_DEFAULT ? + MAP_TYPES.STANDARD : MAP_TYPES.NONE; + } + + render() { + const { region } = this.state; + return ( + + + + + + + Custom Tiles Local + + + + ); + } +} + +CustomTiles.propTypes = { + provider: ProviderPropType, +}; + +const styles = StyleSheet.create({ + container: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + justifyContent: 'flex-end', + alignItems: 'center', + }, + map: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + }, + bubble: { + flex: 1, + backgroundColor: 'rgba(255,255,255,0.7)', + paddingHorizontal: 18, + paddingVertical: 12, + borderRadius: 20, + }, + latlng: { + width: 200, + alignItems: 'stretch', + }, + button: { + width: 80, + paddingHorizontal: 12, + alignItems: 'center', + marginHorizontal: 10, + }, + buttonContainer: { + flexDirection: 'row', + marginVertical: 20, + backgroundColor: 'transparent', + }, +}); + +export default CustomTiles; diff --git a/example/examples/DefaultMarkers.js b/example/examples/DefaultMarkers.js index 67768d07bd..ae92bcf4a0 100644 --- a/example/examples/DefaultMarkers.js +++ b/example/examples/DefaultMarkers.js @@ -7,7 +7,7 @@ import { TouchableOpacity, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { Marker, ProviderPropType } from 'react-native-maps'; const { width, height } = Dimensions.get('window'); @@ -60,7 +60,7 @@ class DefaultMarkers extends React.Component { onPress={(e) => this.onMapPress(e)} > {this.state.markers.map(marker => ( - - log('onSelect', e)} onDrag={(e) => log('onDrag', e)} @@ -60,8 +60,8 @@ class MarkerTypes extends React.Component { draggable > - - + log('onSelect', e)} onDrag={(e) => log('onDrag', e)} @@ -77,7 +77,7 @@ class MarkerTypes extends React.Component { } MarkerTypes.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -91,4 +91,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = MarkerTypes; +export default MarkerTypes; diff --git a/example/examples/EventListener.js b/example/examples/EventListener.js index 19a3930637..26b5b5216e 100644 --- a/example/examples/EventListener.js +++ b/example/examples/EventListener.js @@ -1,4 +1,6 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; + import { StyleSheet, View, @@ -7,8 +9,7 @@ import { ScrollView, } from 'react-native'; // eslint-disable-next-line max-len -import SyntheticEvent from 'react-native/Libraries/Renderer/src/renderers/shared/shared/event/SyntheticEvent'; -import MapView from 'react-native-maps'; +import MapView, { PROVIDER_GOOGLE, Marker, ProviderPropType, Polygon, Polyline, Callout } from 'react-native-maps'; import PriceMarker from './PriceMarker'; const { width, height } = Dimensions.get('window'); @@ -67,8 +68,8 @@ class EventListener extends React.Component { recordEvent(name) { return e => { - if (e instanceof SyntheticEvent && typeof e.persist === 'function') { - e.persist(); + if (e.persist) { + e.persist(); // Avoids warnings relating to https://fb.me/react-event-pooling } this.setState(prevState => ({ events: [ @@ -80,12 +81,22 @@ class EventListener extends React.Component { } render() { + // Events that are dependent on + let googleProviderProps = {}; + if (this.props.provider === PROVIDER_GOOGLE) { + googleProviderProps = { + onUserLocationChange: this.recordEvent('Map::onUserLocationChange'), + }; + } + return ( - - - - Well hello there... - - - + + - {MARKERS.map((marker, i) => ( - @@ -129,4 +129,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = FitToCoordinates; +export default FitToCoordinates; diff --git a/example/examples/FitToSuppliedMarkers.js b/example/examples/FitToSuppliedMarkers.js index 7867639905..5ae3313a48 100644 --- a/example/examples/FitToSuppliedMarkers.js +++ b/example/examples/FitToSuppliedMarkers.js @@ -5,7 +5,7 @@ import { Dimensions, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { Marker, ProviderPropType } from 'react-native-maps'; const { width, height } = Dimensions.get('window'); @@ -123,23 +123,23 @@ class FocusOnMarkers extends React.Component { longitudeDelta: LONGITUDE_DELTA, }} > - - - - - @@ -150,7 +150,7 @@ class FocusOnMarkers extends React.Component { } FocusOnMarkers.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -164,4 +164,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = FocusOnMarkers; +export default FocusOnMarkers; diff --git a/example/examples/GradientPolylines.js b/example/examples/GradientPolylines.js new file mode 100644 index 0000000000..4ab44d26d8 --- /dev/null +++ b/example/examples/GradientPolylines.js @@ -0,0 +1,77 @@ +import React from 'react'; +import { + StyleSheet, + Dimensions, +} from 'react-native'; + +import MapView, { Polyline, ProviderPropType } from 'react-native-maps'; + +const { width, height } = Dimensions.get('window'); + +const ASPECT_RATIO = width / height; +const LATITUDE = 37.78825; +const LONGITUDE = -122.4324; +const LATITUDE_DELTA = 0.0922; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; + +const COORDINATES = [ + { latitude: 37.8025259, longitude: -122.4351431 }, + { latitude: 37.7896386, longitude: -122.421646 }, + { latitude: 37.7665248, longitude: -122.4161628 }, + { latitude: 37.7734153, longitude: -122.4577787 }, + { latitude: 37.7948605, longitude: -122.4596065 }, + { latitude: 37.8025259, longitude: -122.4351431 }, +]; + +const COLORS = [ + '#7F0000', + '#00000000', // no color, creates a "long" gradient between the previous and next coordinate + '#B24112', + '#E5845C', + '#238C23', + '#7F0000', +]; + +class GradientPolylines extends React.Component { + constructor(props) { + super(props); + + this.state = { + region: { + latitude: LATITUDE, + longitude: LONGITUDE, + latitudeDelta: LATITUDE_DELTA, + longitudeDelta: LONGITUDE_DELTA, + }, + }; + } + + render() { + return ( + + + + ); + } +} + +GradientPolylines.propTypes = { + provider: ProviderPropType, +}; + +const styles = StyleSheet.create({ + container: { + ...StyleSheet.absoluteFillObject, + }, +}); + +export default GradientPolylines; diff --git a/example/examples/ImageOverlayWithAssets.js b/example/examples/ImageOverlayWithAssets.js new file mode 100644 index 0000000000..d9fcfe77e8 --- /dev/null +++ b/example/examples/ImageOverlayWithAssets.js @@ -0,0 +1,94 @@ +import React, { Component } from 'react'; +import { + StyleSheet, + View, + Dimensions, +} from 'react-native'; + +import MapView from 'react-native-maps'; +import flagPinkImg from './assets/flag-pink.png'; + +const { width, height } = Dimensions.get('window'); + +const ASPECT_RATIO = width / height; +const LATITUDE = 35.679976; +const LONGITUDE = 139.768458; +const LATITUDE_DELTA = 0.01; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; +// 116423, 51613, 17 +const OVERLAY_TOP_LEFT_COORDINATE = [35.68184060244454, 139.76531982421875]; +const OVERLAY_BOTTOM_RIGHT_COORDINATE = [35.679609609368576, 139.76806640625]; +const IMAGE = flagPinkImg; + +export default class ImageOverlayWithURL extends Component { + + static propTypes = { + provider: MapView.ProviderPropType, + }; + + constructor(props) { + super(props); + + this.state = { + region: { + latitude: LATITUDE, + longitude: LONGITUDE, + latitudeDelta: LATITUDE_DELTA, + longitudeDelta: LONGITUDE_DELTA, + }, + overlay: { + bounds: [OVERLAY_TOP_LEFT_COORDINATE, OVERLAY_BOTTOM_RIGHT_COORDINATE], + image: IMAGE, + }, + }; + } + + render() { + return ( + + + + + + ); + } +} + +const styles = StyleSheet.create({ + container: { + ...StyleSheet.absoluteFillObject, + justifyContent: 'flex-end', + alignItems: 'center', + }, + map: { + ...StyleSheet.absoluteFillObject, + }, + bubble: { + backgroundColor: 'rgba(255,255,255,0.7)', + paddingHorizontal: 18, + paddingVertical: 12, + borderRadius: 20, + }, + latlng: { + width: 200, + alignItems: 'stretch', + }, + button: { + width: 80, + paddingHorizontal: 12, + alignItems: 'center', + marginHorizontal: 10, + }, + buttonContainer: { + flexDirection: 'row', + marginVertical: 20, + backgroundColor: 'transparent', + }, +}); diff --git a/example/examples/ImageOverlayWithURL.js b/example/examples/ImageOverlayWithURL.js new file mode 100644 index 0000000000..e4d7ad8deb --- /dev/null +++ b/example/examples/ImageOverlayWithURL.js @@ -0,0 +1,106 @@ +import React, { Component } from 'react'; +import { + StyleSheet, + View, + Dimensions, +} from 'react-native'; + +import MapView from 'react-native-maps'; + +const { width, height } = Dimensions.get('window'); + +const ASPECT_RATIO = width / height; +const LATITUDE = 35.679976; +const LONGITUDE = 139.768458; +const LATITUDE_DELTA = 0.01; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; +// 116423, 51613, 17 +const OVERLAY_TOP_LEFT_COORDINATE1 = [35.68184060244454, 139.76531982421875]; +const OVERLAY_BOTTOM_RIGHT_COORDINATE1 = [35.679609609368576, 139.76806640625]; +const IMAGE_URL1 = 'https://maps.gsi.go.jp/xyz/std/17/116423/51613.png'; +// 116423, 51615, 17 +const OVERLAY_TOP_LEFT_COORDINATE2 = [35.67737855391474, 139.76531982421875]; +const OVERLAY_BOTTOM_RIGHT_COORDINATE2 = [35.67514743608467, 139.76806640625]; +const IMAGE_URL2 = 'https://maps.gsi.go.jp/xyz/std/17/116423/51615.png'; + +export default class ImageOverlayWithURL extends Component { + + static propTypes = { + provider: MapView.ProviderPropType, + }; + + constructor(props) { + super(props); + + this.state = { + region: { + latitude: LATITUDE, + longitude: LONGITUDE, + latitudeDelta: LATITUDE_DELTA, + longitudeDelta: LONGITUDE_DELTA, + }, + overlay1: { + bounds: [OVERLAY_TOP_LEFT_COORDINATE1, OVERLAY_BOTTOM_RIGHT_COORDINATE1], + image: IMAGE_URL1, + }, + overlay2: { + bounds: [OVERLAY_TOP_LEFT_COORDINATE2, OVERLAY_BOTTOM_RIGHT_COORDINATE2], + image: IMAGE_URL2, + }, + }; + } + + render() { + return ( + + + + + + + ); + } +} + +const styles = StyleSheet.create({ + container: { + ...StyleSheet.absoluteFillObject, + justifyContent: 'flex-end', + alignItems: 'center', + }, + map: { + ...StyleSheet.absoluteFillObject, + }, + bubble: { + backgroundColor: 'rgba(255,255,255,0.7)', + paddingHorizontal: 18, + paddingVertical: 12, + borderRadius: 20, + }, + latlng: { + width: 200, + alignItems: 'stretch', + }, + button: { + width: 80, + paddingHorizontal: 12, + alignItems: 'center', + marginHorizontal: 10, + }, + buttonContainer: { + flexDirection: 'row', + marginVertical: 20, + backgroundColor: 'transparent', + }, +}); diff --git a/example/examples/LegalLabel.js b/example/examples/LegalLabel.js index 6d5894c852..17876c9a64 100644 --- a/example/examples/LegalLabel.js +++ b/example/examples/LegalLabel.js @@ -8,13 +8,13 @@ import { TouchableOpacity, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { Marker, ProviderPropType } from 'react-native-maps'; const screen = Dimensions.get('window'); class LegalLabel extends React.Component { static propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, } state = { @@ -67,7 +67,7 @@ class LegalLabel extends React.Component { longitudeDelta: LONGITUDE_DELTA, }} > - +
@@ -144,4 +144,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = LegalLabel; +export default LegalLabel; diff --git a/example/examples/LiteMapView.js b/example/examples/LiteMapView.js index 7f65fb6c9d..56f3079e64 100644 --- a/example/examples/LiteMapView.js +++ b/example/examples/LiteMapView.js @@ -50,4 +50,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = LiteMapView; +export default LiteMapView; diff --git a/example/examples/LoadingMap.js b/example/examples/LoadingMap.js index 2b2ea89704..ec0175ed4e 100644 --- a/example/examples/LoadingMap.js +++ b/example/examples/LoadingMap.js @@ -6,7 +6,7 @@ import { StyleSheet, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { Marker, Callout, ProviderPropType } from 'react-native-maps'; import flagImg from './assets/flag-blue.png'; const { width, height } = Dimensions.get('window'); @@ -44,7 +44,7 @@ class LoadingMap extends React.Component { loadingIndicatorColor="#666666" loadingBackgroundColor="#eeeeee" > - - - + This is a plain view - - + + @@ -79,7 +79,7 @@ class LoadingMap extends React.Component { } LoadingMap.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -104,4 +104,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = LoadingMap; +export default LoadingMap; diff --git a/example/examples/MapKml.js b/example/examples/MapKml.js new file mode 100644 index 0000000000..6c9fd01c9a --- /dev/null +++ b/example/examples/MapKml.js @@ -0,0 +1,79 @@ +import React from 'react'; +import { + StyleSheet, + View, + Dimensions, +} from 'react-native'; +import MapView, { Marker } from 'react-native-maps'; + +const { width, height } = Dimensions.get('window'); + +const ASPECT_RATIO = width / height; +const LATITUDE = -18.9193508; +const LONGITUDE = -48.2830592; +const LATITUDE_DELTA = 0.0922; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; +const KML_FILE = 'https://pastebin.com/raw/jAzGpq1F'; + +class MapKml extends React.Component { + constructor(props) { + super(props); + + this.state = { + region: { + latitude: LATITUDE, + longitude: LONGITUDE, + latitudeDelta: LATITUDE_DELTA, + longitudeDelta: LONGITUDE_DELTA, + }, + }; + + this.onKmlReady = this.onKmlReady.bind(this); + } + + onKmlReady() { + this.map.fitToElements(true); + } + + render() { + return ( + + { this.map = ref; }} + provider={this.props.provider} + style={styles.map} + initialRegion={this.state.region} + kmlSrc={KML_FILE} + onKmlReady={this.onKmlReady} + > + + + + ); + } +} + +MapKml.propTypes = { + provider: MapView.ProviderPropType, +}; + +const styles = StyleSheet.create({ + container: { + justifyContent: 'flex-end', + alignItems: 'center', + }, + scrollview: { + alignItems: 'center', + paddingVertical: 40, + }, + map: { + width, + height, + }, +}); + +module.exports = MapKml; diff --git a/example/examples/MapStyle.js b/example/examples/MapStyle.js index 5d3416c939..612e766401 100644 --- a/example/examples/MapStyle.js +++ b/example/examples/MapStyle.js @@ -5,7 +5,7 @@ import { Dimensions, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { ProviderPropType } from 'react-native-maps'; const { width, height } = Dimensions.get('window'); @@ -205,7 +205,7 @@ class MapStyle extends React.Component { } MapStyle.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -219,4 +219,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = MapStyle; +export default MapStyle; diff --git a/example/examples/MarkerTypes.js b/example/examples/MarkerTypes.js index 76685d782f..bd9880642b 100644 --- a/example/examples/MarkerTypes.js +++ b/example/examples/MarkerTypes.js @@ -5,7 +5,7 @@ import { Text, Dimensions, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { Marker, ProviderPropType } from 'react-native-maps'; import flagBlueImg from './assets/flag-blue.png'; import flagPinkImg from './assets/flag-pink.png'; @@ -40,7 +40,7 @@ class MarkerTypes extends React.Component { longitudeDelta: LONGITUDE_DELTA, }} > - this.setState({ marker1: !this.state.marker1 })} coordinate={{ latitude: LATITUDE + SPACE, @@ -51,8 +51,8 @@ class MarkerTypes extends React.Component { image={this.state.marker1 ? flagBlueImg : flagPinkImg} > X - - + this.setState({ marker2: !this.state.marker2 })} coordinate={{ latitude: LATITUDE - SPACE, @@ -62,7 +62,7 @@ class MarkerTypes extends React.Component { anchor={{ x: 0.84, y: 1 }} image={this.state.marker2 ? flagBlueImg : flagPinkImg} /> - this.setState({ marker2: !this.state.marker2 })} coordinate={{ latitude: LATITUDE + SPACE, @@ -80,7 +80,7 @@ class MarkerTypes extends React.Component { } MarkerTypes.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -99,4 +99,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = MarkerTypes; +export default MarkerTypes; diff --git a/example/examples/MyLocationMapMarker.js b/example/examples/MyLocationMapMarker.js index fff3f2b375..052910e10f 100644 --- a/example/examples/MyLocationMapMarker.js +++ b/example/examples/MyLocationMapMarker.js @@ -1,4 +1,6 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; + import { StyleSheet, Text, @@ -6,7 +8,7 @@ import { PermissionsAndroid, Platform, } from 'react-native'; -import MapView from 'react-native-maps'; +import { Marker } from 'react-native-maps'; import isEqual from 'lodash/isEqual'; const GEOLOCATION_OPTIONS = { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }; @@ -15,7 +17,7 @@ const ANCHOR = { x: 0.5, y: 0.5 }; const colorOfmyLocationMapMarker = 'blue'; const propTypes = { - ...MapView.Marker.propTypes, + ...Marker.propTypes, // override this prop to make it optional coordinate: PropTypes.shape({ latitude: PropTypes.number.isRequired, @@ -85,7 +87,7 @@ export default class MyLocationMapMarker extends React.PureComponent { const rotate = (typeof heading === 'number' && heading >= 0) ? `${heading}deg` : null; return ( - {this.props.children} - + ); } } diff --git a/example/examples/OnPoiClick.js b/example/examples/OnPoiClick.js new file mode 100644 index 0000000000..ff6ec11b36 --- /dev/null +++ b/example/examples/OnPoiClick.js @@ -0,0 +1,86 @@ +import React from 'react'; +import { + StyleSheet, + View, + Text, + Dimensions, +} from 'react-native'; + +import MapView, { Callout, Marker, ProviderPropType } from 'react-native-maps'; + +const { width, height } = Dimensions.get('window'); + +const ASPECT_RATIO = width / height; +const LATITUDE = 37.78825; +const LONGITUDE = -122.4324; +const LATITUDE_DELTA = 0.0922; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; + +class OnPoiClick extends React.Component { + constructor(props) { + super(props); + + this.state = { + region: { + latitude: LATITUDE, + longitude: LONGITUDE, + latitudeDelta: LATITUDE_DELTA, + longitudeDelta: LONGITUDE_DELTA, + }, + poi: null, + }; + + this.onPoiClick = this.onPoiClick.bind(this); + } + + onPoiClick(e) { + const poi = e.nativeEvent; + + this.setState({ + poi, + }); + } + + render() { + return ( + + + {this.state.poi && ( + + + + Place Id: { this.state.poi.placeId } + Name: { this.state.poi.name } + + + + )} + + + ); + } +} + +OnPoiClick.propTypes = { + provider: ProviderPropType, +}; + +const styles = StyleSheet.create({ + container: { + ...StyleSheet.absoluteFillObject, + justifyContent: 'flex-end', + alignItems: 'center', + }, + map: { + ...StyleSheet.absoluteFillObject, + }, +}); + +export default OnPoiClick; diff --git a/example/examples/Overlays.js b/example/examples/Overlays.js index 17a9760140..95db0bb692 100644 --- a/example/examples/Overlays.js +++ b/example/examples/Overlays.js @@ -6,7 +6,7 @@ import { Dimensions, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { Circle, Polygon, Polyline, ProviderPropType } from 'react-native-maps'; const { width, height } = Dimensions.get('window'); @@ -79,7 +79,7 @@ class Overlays extends React.Component { style={styles.map} initialRegion={region} > - - - true, - onMoveShouldSetPanResponder: () => true, - }; - }, + } // getInitialState() { // //TODO: @@ -84,9 +63,20 @@ const PanController = React.createClass({ // }; // }, - _responder: null, - _listener: null, - _direction: null, + _responder = null + _listener = null + _direction = null + + constructor(props) { + super(props) + + this.deceleration = 0.997; + if (props.momentumDecayConfig && this.props.momentumDecayConfig.deceleration) { + this.deceleration = this.props.momentumDecayConfig.deceleration; + } + } + + componentWillMount() { this._responder = PanResponder.create({ @@ -192,7 +182,7 @@ const PanController = React.createClass({ this._direction = horizontal && !vertical ? 'x' : (vertical && !horizontal ? 'y' : null); }, }); - }, + } handleResponderMove(anim, delta, min, max, overshoot) { let val = anim._offset + delta; @@ -219,7 +209,7 @@ const PanController = React.createClass({ } val = val - anim._offset; anim.setValue(val); - }, + } handleResponderRelease(anim, min, max, velocity, overshoot, mode, snapSpacing) { anim.flattenOffset(); @@ -276,7 +266,7 @@ const PanController = React.createClass({ break; } } - }, + } handleResponderGrant(anim, mode) { switch (mode) { @@ -289,7 +279,7 @@ const PanController = React.createClass({ anim.setValue(0); break; } - }, + } handleMomentumScroll(anim, min, max, velocity, overshoot) { Animated.decay(anim, { @@ -336,7 +326,7 @@ const PanController = React.createClass({ } } }); - }, + } handleSnappedScroll(anim, min, max, velocity, spacing) { let endX = this.momentumCenter(anim._value, velocity, spacing); @@ -360,23 +350,22 @@ const PanController = React.createClass({ }).start(() => { anim.removeListener(this._listener); }); - }, + } closestCenter(x, spacing) { const plus = (x % spacing) < spacing / 2 ? 0 : spacing; return Math.round(x / spacing) * spacing + plus; - }, + } momentumCenter(x0, vx, spacing) { let t = 0; - const deceleration = this.props.momentumDecayConfig.deceleration || 0.997; let x1 = x0; let x = x1; while (true) { t += 16; - x = x0 + (vx / (1 - deceleration)) * - (1 - Math.exp(-(1 - deceleration) * t)); + x = x0 + (vx / (1 - this.deceleration)) * + (1 - Math.exp(-(1 - this.deceleration) * t)); if (Math.abs(x - x1) < 0.1) { x1 = x; break; @@ -384,18 +373,17 @@ const PanController = React.createClass({ x1 = x; } return this.closestCenter(x1, spacing); - }, + } velocityAtBounds(x0, vx, bounds) { let t = 0; - const deceleration = this.props.momentumDecayConfig.deceleration || 0.997; let x1 = x0; let x = x1; let vf; while (true) { t += 16; - x = x0 + (vx / (1 - deceleration)) * - (1 - Math.exp(-(1 - deceleration) * t)); + x = x0 + (vx / (1 - this.deceleration)) * + (1 - Math.exp(-(1 - this.deceleration) * t)); vf = (x - x1) / 16; if (x > bounds[0] && x < bounds[1]) { break; @@ -406,7 +394,7 @@ const PanController = React.createClass({ x1 = x; } return vf; - }, + } // componentDidMount() { // //TODO: we may need to measure the children width/height here? @@ -422,7 +410,7 @@ const PanController = React.createClass({ render() { return ; - }, -}); + } +}; -module.exports = PanController; +export default PanController; diff --git a/example/examples/PolygonCreator.js b/example/examples/PolygonCreator.js index c0d1e44f59..05149fa173 100644 --- a/example/examples/PolygonCreator.js +++ b/example/examples/PolygonCreator.js @@ -7,7 +7,7 @@ import { TouchableOpacity, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { MAP_TYPES, Polygon, ProviderPropType } from 'react-native-maps'; const { width, height } = Dimensions.get('window'); @@ -126,13 +126,13 @@ class PolygonCreator extends React.Component { this.onPress(e)} {...mapOptions} > {this.state.polygons.map(polygon => ( - ))} {this.state.editing && ( - this.onPanDrag(e)} > {this.state.polylines.map(polyline => ( - ))} {this.state.editing && - - { this.circle = ref; }} center={circle.center} radius={circle.radius} @@ -96,14 +96,14 @@ class SetNativePropsOverlays extends React.Component { zIndex={3} strokeWidth={3} /> - { this.polygon = ref; }} coordinates={polygon} fillColor="rgba(255, 255, 255, 0.6)" strokeColor="green" strokeWidth={2} /> - { this.polyline = ref; }} coordinates={polyline} strokeColor="green" @@ -133,7 +133,7 @@ class SetNativePropsOverlays extends React.Component { } SetNativePropsOverlays.propTypes = { - provider: MapView.ProviderPropType, + provider: ProviderPropType, }; const styles = StyleSheet.create({ @@ -159,4 +159,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = SetNativePropsOverlays; +export default SetNativePropsOverlays; diff --git a/example/examples/StaticMap.js b/example/examples/StaticMap.js index 02a74f3487..d9d66e2f83 100644 --- a/example/examples/StaticMap.js +++ b/example/examples/StaticMap.js @@ -6,7 +6,7 @@ import { Dimensions, ScrollView, } from 'react-native'; -import MapView from 'react-native-maps'; +import MapView, { Marker, ProviderPropType } from 'react-native-maps'; const { width, height } = Dimensions.get('window'); @@ -54,7 +54,7 @@ class StaticMap extends React.Component { rotateEnabled={false} initialRegion={this.state.region} > - - - - + - + - /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"; + shellScript = "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"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ diff --git a/example/ios/AirMapsExplorer.xcodeproj/xcshareddata/xcschemes/AirMapsExplorer.xcscheme b/example/ios/AirMapsExplorer.xcodeproj/xcshareddata/xcschemes/AirMapsExplorer.xcscheme index 9b7c436e06..142a27d474 100644 --- a/example/ios/AirMapsExplorer.xcodeproj/xcshareddata/xcschemes/AirMapsExplorer.xcscheme +++ b/example/ios/AirMapsExplorer.xcodeproj/xcshareddata/xcschemes/AirMapsExplorer.xcscheme @@ -40,6 +40,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" shouldUseLaunchSchemeArgsEnv = "YES"> "#{rn_path}/third-party-podspecs/DoubleConversion.podspec" + pod 'glog', :podspec => "#{rn_path}/third-party-podspecs/glog.podspec" + pod 'Folly', :podspec => "#{rn_path}/third-party-podspecs/Folly.podspec" + + # react-native-maps dependencies + pod 'react-native-maps', path: rn_maps_path + pod 'react-native-google-maps', path: rn_maps_path # Remove this line if you don't want to support GoogleMaps on iOS pod 'GoogleMaps' # Remove this line if you don't want to support GoogleMaps on iOS - pod 'react-native-maps', path: '../../' - pod 'react-native-google-maps', path: '../../' # If you need GoogleMaps support on iOS + pod 'Google-Maps-iOS-Utils' # Remove this line if you don't want to support GoogleMaps on iOS end post_install do |installer| @@ -35,9 +45,5 @@ post_install do |installer| config.build_settings['CLANG_ENABLE_MODULES'] = 'No' end end - - if target.name == "React" - target.remove_from_project - end end end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 3eec18feec..43e7bb7123 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,53 +1,98 @@ PODS: - - GoogleMaps (2.1.1): - - GoogleMaps/Maps (= 2.1.1) - - GoogleMaps/Base (2.1.1) - - GoogleMaps/Maps (2.1.1): + - boost-for-react-native (1.63.0) + - DoubleConversion (1.1.5) + - Folly (2016.09.26.00): + - boost-for-react-native + - DoubleConversion + - glog + - glog (0.3.4) + - Google-Maps-iOS-Utils (2.1.0): + - Google-Maps-iOS-Utils/Clustering (= 2.1.0) + - Google-Maps-iOS-Utils/Geometry (= 2.1.0) + - Google-Maps-iOS-Utils/Heatmap (= 2.1.0) + - Google-Maps-iOS-Utils/QuadTree (= 2.1.0) + - GoogleMaps + - Google-Maps-iOS-Utils/Clustering (2.1.0): + - Google-Maps-iOS-Utils/QuadTree + - GoogleMaps + - Google-Maps-iOS-Utils/Geometry (2.1.0): + - GoogleMaps + - Google-Maps-iOS-Utils/Heatmap (2.1.0): + - Google-Maps-iOS-Utils/QuadTree + - GoogleMaps + - Google-Maps-iOS-Utils/QuadTree (2.1.0): + - GoogleMaps + - GoogleMaps (2.5.0): + - GoogleMaps/Maps (= 2.5.0) + - GoogleMaps/Base (2.5.0) + - GoogleMaps/Maps (2.5.0): - GoogleMaps/Base - - React (0.45.1): - - React/Core (= 0.45.1) - - react-native-google-maps (0.15.2): - - GoogleMaps (= 2.1.1) + - React (0.54.2): + - React/Core (= 0.54.2) + - react-native-google-maps (0.21.0): + - Google-Maps-iOS-Utils (= 2.1.0) + - GoogleMaps (= 2.5.0) - React - - react-native-maps (0.15.2): + - react-native-maps (0.21.0): - React - - React/BatchedBridge (0.45.1): + - React/Core (0.54.2): + - yoga (= 0.54.2.React) + - React/CxxBridge (0.54.2): + - Folly (= 2016.09.26.00) - React/Core - - React/cxxreact_legacy - - React/Core (0.45.1): - - Yoga (= 0.45.1.React) - - React/cxxreact_legacy (0.45.1): - - React/jschelpers_legacy - - React/jschelpers_legacy (0.45.1) - - React/RCTActionSheet (0.45.1): + - React/cxxreact + - React/cxxreact (0.54.2): + - boost-for-react-native (= 1.63.0) + - Folly (= 2016.09.26.00) + - React/jschelpers + - React/jsinspector + - React/DevSupport (0.54.2): - React/Core - - React/RCTAnimation (0.45.1): + - React/RCTWebSocket + - React/fishhook (0.54.2) + - React/jschelpers (0.54.2): + - Folly (= 2016.09.26.00) + - React/PrivateDatabase + - React/jsinspector (0.54.2) + - React/PrivateDatabase (0.54.2) + - React/RCTActionSheet (0.54.2): - React/Core - - React/RCTGeolocation (0.45.1): + - React/RCTAnimation (0.54.2): - React/Core - - React/RCTImage (0.45.1): + - React/RCTBlob (0.54.2): + - React/Core + - React/RCTGeolocation (0.54.2): + - React/Core + - React/RCTImage (0.54.2): - React/Core - React/RCTNetwork - - React/RCTLinkingIOS (0.45.1): + - React/RCTLinkingIOS (0.54.2): - React/Core - - React/RCTNetwork (0.45.1): + - React/RCTNetwork (0.54.2): - React/Core - - React/RCTSettings (0.45.1): + - React/RCTSettings (0.54.2): - React/Core - - React/RCTText (0.45.1): + - React/RCTText (0.54.2): - React/Core - - React/RCTVibration (0.45.1): + - React/RCTVibration (0.54.2): - React/Core - - React/RCTWebSocket (0.45.1): + - React/RCTWebSocket (0.54.2): - React/Core - - Yoga (0.45.1.React) + - React/fishhook + - React/RCTBlob + - yoga (0.54.2.React) DEPENDENCIES: + - DoubleConversion (from `../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) + - Folly (from `../../node_modules/react-native/third-party-podspecs/Folly.podspec`) + - glog (from `../../node_modules/react-native/third-party-podspecs/glog.podspec`) + - Google-Maps-iOS-Utils - GoogleMaps - react-native-google-maps (from `../../`) - react-native-maps (from `../../`) - - React/BatchedBridge (from `../../node_modules/react-native`) - React/Core (from `../../node_modules/react-native`) + - React/CxxBridge (from `../../node_modules/react-native`) + - React/DevSupport (from `../../node_modules/react-native`) - React/RCTActionSheet (from `../../node_modules/react-native`) - React/RCTAnimation (from `../../node_modules/react-native`) - React/RCTGeolocation (from `../../node_modules/react-native`) @@ -58,25 +103,36 @@ DEPENDENCIES: - React/RCTText (from `../../node_modules/react-native`) - React/RCTVibration (from `../../node_modules/react-native`) - React/RCTWebSocket (from `../../node_modules/react-native`) - - Yoga (from `../../node_modules/react-native/ReactCommon/yoga/Yoga.podspec`) + - yoga (from `../../node_modules/react-native/ReactCommon/yoga/yoga.podspec`) EXTERNAL SOURCES: + DoubleConversion: + :podspec: ../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec + Folly: + :podspec: ../../node_modules/react-native/third-party-podspecs/Folly.podspec + glog: + :podspec: ../../node_modules/react-native/third-party-podspecs/glog.podspec React: - :path: "../../node_modules/react-native" + :path: ../../node_modules/react-native react-native-google-maps: - :path: "../../" + :path: ../../ react-native-maps: - :path: "../../" - Yoga: - :path: "../../node_modules/react-native/ReactCommon/yoga/Yoga.podspec" + :path: ../../ + yoga: + :path: ../../node_modules/react-native/ReactCommon/yoga/yoga.podspec SPEC CHECKSUMS: - GoogleMaps: a5b5bbe47734e2443bde781a6aa64e69fdb6d785 - React: 0c9191a8b0c843d7004f950ac6b5f6cba9d125c7 - react-native-google-maps: d0b8772eb76e1615ea32c73bc9d573360b8c0817 - react-native-maps: fe2e4680b4d3fcfd84d636ccedd470fe358d55e1 - Yoga: 89c8738d42a0b46a113acb4e574336d61cba2985 + boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c + DoubleConversion: ebb6747c5b66026ad4f97b789c3ceac6f18e57a6 + Folly: 211775e49d8da0ca658aebc8eab89d642935755c + glog: 1de0bb937dccdc981596d3b5825ebfb765017ded + Google-Maps-iOS-Utils: c32891ff472eaaa1fca032beedafa1a013af7875 + GoogleMaps: c087b8e5dfe87ca6ebf59adb9b4894a4146bec4f + React: c237e42de9c70e5cac6eeb52b4cfd3a0910c1f00 + react-native-google-maps: 2cfe3b01f8422c7dae51d8764139fd70f888cfce + react-native-maps: 066c2afcc89e18726377bcc685315f989ca22449 + yoga: 55da126afc384965b96bff46652464373b330add -PODFILE CHECKSUM: 8b3eb68ef6553bf1fcb8a467e0e63000b37ec692 +PODFILE CHECKSUM: 360a4a3ec45be233c554495279bfd087f4f29b0b -COCOAPODS: 1.2.0 +COCOAPODS: 1.4.0 diff --git a/example/ios/bundler b/example/ios/bundler deleted file mode 100755 index 905387619f..0000000000 --- a/example/ios/bundler +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'bundler' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("bundler", "bundler") diff --git a/example/ios/fuzzy_match b/example/ios/fuzzy_match deleted file mode 100755 index f715473935..0000000000 --- a/example/ios/fuzzy_match +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'fuzzy_match' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("fuzzy_match", "fuzzy_match") diff --git a/example/ios/pod b/example/ios/pod deleted file mode 100755 index 3c4a4d04c1..0000000000 --- a/example/ios/pod +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'pod' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("cocoapods", "pod") diff --git a/examples/ios/bundler b/examples/ios/bundler deleted file mode 100755 index 905387619f..0000000000 --- a/examples/ios/bundler +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'bundler' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("bundler", "bundler") diff --git a/examples/ios/fuzzy_match b/examples/ios/fuzzy_match deleted file mode 100755 index f715473935..0000000000 --- a/examples/ios/fuzzy_match +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'fuzzy_match' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("fuzzy_match", "fuzzy_match") diff --git a/examples/ios/pod b/examples/ios/pod deleted file mode 100755 index 3c4a4d04c1..0000000000 --- a/examples/ios/pod +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'pod' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("cocoapods", "pod") diff --git a/examples/ios/sandbox-pod b/examples/ios/sandbox-pod deleted file mode 100755 index c76cfd0a59..0000000000 --- a/examples/ios/sandbox-pod +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'sandbox-pod' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("cocoapods", "sandbox-pod") diff --git a/examples/ios/xcodeproj b/examples/ios/xcodeproj deleted file mode 100755 index 3c3452c175..0000000000 --- a/examples/ios/xcodeproj +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'xcodeproj' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("xcodeproj", "xcodeproj") diff --git a/index.d.ts b/index.d.ts index d885759b25..83d4f2fa32 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,16 +1,165 @@ -import * as React from 'react'; - declare module "react-native-maps" { - export type ProviderType = 'google'; - export type MapType = 'standard' | 'satellite' | 'hybrid' | 'terrain' | 'none'; + import * as React from 'react'; + import { + Animated, + ImageRequireSource, + ImageURISource, + NativeSyntheticEvent, + ViewProperties + } from 'react-native'; + + export interface Region { + latitude: number; + longitude: number; + latitudeDelta: number; + longitudeDelta: number; + } + + export interface LatLng { + latitude: number; + longitude: number; + } + + export interface Point { + x: number; + y: number; + } + + // helper interface + export interface MapEvent extends NativeSyntheticEvent {} + export type LineCapType = 'butt' | 'round' | 'square'; export type LineJoinType = 'miter' | 'round' | 'bevel'; - export interface MapViewProperties { - provider?: ProviderType; - style?: any; - customMapStyle?: any[]; + // ======================================================================= + // AnimatedRegion + // ======================================================================= + + interface AnimatedRegionTimingConfig extends Animated.AnimationConfig, Partial { + easing?: (value: number) => number; + duration?: number; + delay?: number; + } + + interface AnimatedRegionSpringConfig extends Animated.AnimationConfig, Partial { + overshootClamping?: boolean; + restDisplacementThreshold?: number; + restSpeedThreshold?: number; + velocity?: number | Point; + bounciness?: number; + speed?: number; + tension?: number; + friction?: number; + stiffness?: number; + mass?: number; + damping?: number; + } + + export class AnimatedRegion extends Animated.AnimatedWithChildren { + latitude: Animated.Value + longitude: Animated.Value + latitudeDelta: Animated.Value + longitudeDelta: Animated.Value + + constructor(region?: Region); + + setValue(value: Region): void; + setOffset(offset: Region): void; + flattenOffset(): void; + stopAnimation(callback?: (region: Region) => void): void; + addListener(callback: (region: Region) => void): string; + removeListener(id: string): void; + spring(config: AnimatedRegionSpringConfig): Animated.CompositeAnimation; + timing(config: AnimatedRegionTimingConfig): Animated.CompositeAnimation; + } + + // ======================================================================= + // MapView (default export) + // ======================================================================= + + /** + * takeSnapshot options + */ + export interface SnapshotOptions { + /** optional, when omitted the view-width is used */ + width?: number; + /** optional, when omitted the view-height is used */ + height?: number; + /** __iOS only__, optional region to render */ + region?: Region; + /** image formats, defaults to 'png' */ + format?: 'png' | 'jpg'; + /** image quality: 0..1 (only relevant for jpg, default: 1) */ + quality?: number; + /** result types, defaults to 'file' */ + result?: 'file' | 'base64'; + } + + /** + * onUserLocationChange parameters + */ + export interface EventUserLocation extends NativeSyntheticEvent<{}> { + nativeEvent: { + coordinate: { + latitude: number, + longitude: number, + altitude: number, + timestamp: number, + accuracy: number, + speed: number, + isFromMockProvider: boolean, + }, + }; + } + + /** + * Map style elements. + * @see https://developers.google.com/maps/documentation/ios-sdk/styling#use_a_string_resource + * @see https://developers.google.com/maps/documentation/android-api/styling + */ + export type MapStyleElement = { + featureType?: string, + elementType?: string, + stylers: object[], + }; + + export type EdgePadding = { + top: Number, + right: Number, + bottom: Number, + left: Number, + }; + + export type EdgeInsets = { + top: Number, + right: Number, + bottom: Number, + left: Number, + }; + + export type KmlMarker = { + id: String, + title: String, + description: String, + coordinate: LatLng, + position: Point, + }; + + /** + * onKmlReady parameter + */ + export interface KmlMapEvent extends NativeSyntheticEvent<{ markers: KmlMarker[] }> { + } + + type MapTypes = 'standard' | 'satellite' | 'hybrid' | 'terrain' | 'none' | 'mutedStandard'; + + export interface MapViewProps extends ViewProperties { + provider?: 'google' | null; + customMapStyle?: MapStyleElement[]; customMapStyleString?: string; showsUserLocation?: boolean; userLocationAnnotationTitle?: string; @@ -19,11 +168,12 @@ declare module "react-native-maps" { showsPointsOfInterest?: boolean; showsCompass?: boolean; zoomEnabled?: boolean; + zoomControlEnabled?: boolean; rotateEnabled?: boolean; cacheEnabled?: boolean; loadingEnabled?: boolean; - loadingBackgroundColor?: any; - loadingIndicatorColor?: any; + loadingBackgroundColor?: string; + loadingIndicatorColor?: string; scrollEnabled?: boolean; pitchEnabled?: boolean; toolbarEnabled?: boolean; @@ -33,63 +183,130 @@ declare module "react-native-maps" { showsTraffic?: boolean; showsIndoors?: boolean; showsIndoorLevelPicker?: boolean; - mapType?: MapType; - region?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; - initialRegion?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; + mapType?: MapTypes; + region?: Region; + initialRegion?: Region; liteMode?: boolean; + mapPadding?: EdgePadding; maxDelta?: number; minDelta?: number; - legalLabelInsets?: any; - onChange?: Function; - onMapReady?: Function; - onRegionChange?: Function; - onRegionChangeComplete?: Function; - onPress?: Function; - onLayout?: Function; - onLongPress?: Function; - onPanDrag?: Function; - onMarkerPress?: Function; - onMarkerSelect?: Function; - onMarkerDeselect?: Function; - onCalloutPress?: Function; - onMarkerDragStart?: Function; - onMarkerDrag?: Function; - onMarkerDragEnd?: Function; + legalLabelInsets?: EdgeInsets; + + onMapReady?: () => void; + onKmlReady?: (values: KmlMapEvent) => void; + onRegionChange?: (region: Region) => void; + onRegionChangeComplete?: (region: Region) => void; + onPress?: (event: MapEvent) => void; + onLongPress?: (event: MapEvent) => void; + onUserLocationChange?: (event: EventUserLocation) => void; + onPanDrag?: (event: MapEvent) => void; + onPoiClick?: (event: MapEvent<{ placeId: string, name: string }>) => void; + onMarkerPress?: (event: MapEvent<{ action: 'marker-press', id: string }>) => void; + onMarkerSelect?: (event: MapEvent<{ action: 'marker-select', id: string }>) => void; + onMarkerDeselect?: (event: MapEvent<{ action: 'marker-deselect', id: string }>) => void; + onCalloutPress?: (event: MapEvent<{ action: 'callout-press' }>) => void; + onMarkerDragStart?: (event: MapEvent) => void; + onMarkerDrag?: (event: MapEvent) => void; + onMarkerDragEnd?: (event: MapEvent) => void; + minZoomLevel?: number; maxZoomLevel?: number; + kmlSrc?: string; + } + + export default class MapView extends React.Component { + animateToNavigation(location: LatLng, bearing: number, angle: number, duration?: number): void; + animateToRegion(region: Region, duration?: number): void; + animateToCoordinate(latLng: LatLng, duration?: number): void; + animateToBearing(bearing: number, duration?: number): void; + animateToViewingAngle(angle: number, duration?: number): void; + fitToElements(animated: boolean): void; + fitToSuppliedMarkers(markers: string[], animated: boolean): void; + fitToCoordinates(coordinates?: LatLng[], options?: { edgePadding?: EdgePadding, animated?: boolean }): void; + setMapBoundaries(northEast: LatLng, southWest: LatLng): void; + takeSnapshot(options?: SnapshotOptions): Promise; } - export interface MarkerProperties { + export class MapViewAnimated extends MapView { + } + + // ======================================================================= + // Marker + // ======================================================================= + + export interface MarkerProps extends ViewProperties { identifier?: string; reuseIdentifier?: string; title?: string; description?: string; - image?: any; + image?: ImageURISource | ImageRequireSource; opacity?: number; pinColor?: string; - coordinate: { latitude: number; longitude: number }; - centerOffset?: { x: number; y: number }; - calloutOffset?: { x: number; y: number }; - anchor?: { x: number; y: number }; - calloutAnchor?: { x: number; y: number }; + coordinate: LatLng | AnimatedRegion; + centerOffset?: Point; + calloutOffset?: Point; + anchor?: Point; + calloutAnchor?: Point; flat?: boolean; draggable?: boolean; - onPress?: Function; - onSelect?: Function; - onDeselect?: Function; - onCalloutPress?: Function; - onDragStart?: Function; - onDrag?: Function; - onDragEnd?: Function; - } - - export interface MapPolylineProperties { - coordinates?: { latitude: number; longitude: number; }[]; - onPress?: Function; + tracksViewChanges?: boolean + tracksInfoWindowChanges?: boolean + stopPropagation?: boolean + onPress?: (event: MapEvent<{ action: 'marker-press', id: string }>) => void; + onSelect?: (event: MapEvent<{ action: 'marker-select', id: string }>) => void; + onDeselect?: (event: MapEvent<{ action: 'marker-deselect', id: string }>) => void; + onCalloutPress?: (event: MapEvent<{ action: 'callout-press' }>) => void; + onDragStart?: (event: MapEvent) => void; + onDrag?: (event: MapEvent) => void; + onDragEnd?: (event: MapEvent) => void; + + rotation?: number; + zIndex?: number; + } + + export class Marker extends React.Component { + /** + * Shows the callout for this marker + */ + showCallout(): void; + /** + * Hides the callout for this marker + */ + hideCallout(): void; + /** + * Animates marker movement. + * __Android only__ + */ + animateMarkerToCoordinate(coordinate: LatLng, duration?: number): void; + } + + export class MarkerAnimated extends Marker { + } + + // ======================================================================= + // Callout + // ======================================================================= + + export interface MapCalloutProps extends ViewProperties { + tooltip?: boolean; + onPress?: (event: MapEvent<{ action: 'callout-press' }>) => void; + } + + export class Callout extends React.Component { + } + + // ======================================================================= + // Polyline + // ======================================================================= + + export interface MapPolylineProps extends ViewProperties { + coordinates: LatLng[]; + onPress?: (event: MapEvent) => void; tappable?: boolean; fillColor?: string; strokeWidth?: number; strokeColor?: string; + strokeColors?: string[]; zIndex?: number; lineCap?: LineCapType; lineJoin?: LineJoinType; @@ -99,10 +316,17 @@ declare module "react-native-maps" { lineDashPattern?: number[]; } - export interface MapPolygonProperties { - coordinates?: { latitude: number; longitude: number; }[]; - holes?: { latitude: number; longitude: number; }[][]; - onPress?: Function; + export class Polyline extends React.Component { + } + + // ======================================================================= + // Polygon + // ======================================================================= + + export interface MapPolygonProps extends ViewProperties { + coordinates: LatLng[]; + holes?: LatLng[][]; + onPress?: (event: MapEvent) => void; tappable?: boolean; strokeWidth?: number; strokeColor?: string; @@ -116,10 +340,17 @@ declare module "react-native-maps" { lineDashPattern?: number[]; } - export interface MapCircleProperties { - center: { latitude: number; longitude: number }; + export class Polygon extends React.Component { + } + + // ======================================================================= + // Circle + // ======================================================================= + + export interface MapCircleProps extends ViewProperties { + center: LatLng; radius: number; - onPress?: Function; + onPress?: (event: MapEvent) => void; strokeWidth?: number; strokeColor?: string; fillColor?: string; @@ -131,29 +362,62 @@ declare module "react-native-maps" { lineDashPattern?: number[]; } - export interface MapUrlTitleProperties { + export class Circle extends React.Component { + } + + // ======================================================================= + // UrlTile & LocalTile + // ======================================================================= + + export interface MapUrlTileProps extends ViewProperties { urlTemplate: string; + maximumZ?: number; zIndex?: number; } - export interface MapCalloutProperties { - tooltip?: boolean; - onPress?: Function; + export class UrlTile extends React.Component { } - class MapView extends React.Component { - static Animated: any; - static AnimatedRegion: any; + export interface MapLocalTileProps extends ViewProperties { + pathTemplate: string; + tileSize?: number; + zIndex?: number; + } + + export class LocalTile extends React.Component { } - namespace MapView { - class Marker extends React.Component {} - class Polyline extends React.Component {} - class Polygon extends React.Component {} - class Circle extends React.Component {} - class UrlTile extends React.Component {} - class Callout extends React.Component {} + // ======================================================================= + // Overlay + // ======================================================================= + + type Coordinate = [number, number] + + export interface MapOverlayProps extends ViewProperties { + image?: ImageURISource | ImageRequireSource; + bounds: [Coordinate, Coordinate]; } - - export default MapView; + + export class Overlay extends React.Component { + } + + export class OverlayAnimated extends Overlay { + } + + // ======================================================================= + // Constants + // ======================================================================= + + export const MAP_TYPES: { + STANDARD: MapTypes, + SATELLITE: MapTypes, + HYBRID: MapTypes, + TERRAIN: MapTypes, + NONE: MapTypes, + MUTEDSTANDARD: MapTypes, + } + + export const PROVIDER_DEFAULT: null; + export const PROVIDER_GOOGLE: 'google'; + } diff --git a/index.js b/index.js index 207d0119df..acc1f75533 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,23 @@ -import MapView from './lib/components/MapView'; +import MapView, { Animated, MAP_TYPES, ProviderPropType } from './lib/components/MapView'; +import Marker from './lib/components/MapMarker.js'; +import Overlay from './lib/components/MapOverlay.js'; + +export { default as Polyline } from './lib/components/MapPolyline.js'; +export { default as Polygon } from './lib/components/MapPolygon.js'; +export { default as Circle } from './lib/components/MapCircle.js'; +export { default as UrlTile } from './lib/components/MapUrlTile.js'; +export { default as LocalTile } from './lib/components/MapLocalTile.js'; +export { default as Callout } from './lib/components/MapCallout.js'; +export { default as AnimatedRegion } from './lib/components/AnimatedRegion.js'; + +export { Marker, Overlay }; +export { Animated, MAP_TYPES, ProviderPropType }; + +export const PROVIDER_GOOGLE = MapView.PROVIDER_GOOGLE; +export const PROVIDER_DEFAULT = MapView.PROVIDER_DEFAULT; + +export const MarkerAnimated = Marker.Animated; +export const OverlayAnimated = Overlay.Animated; + +export default MapView; -module.exports = MapView; diff --git a/lib/android/.project b/lib/android/.project new file mode 100644 index 0000000000..2a84911fc1 --- /dev/null +++ b/lib/android/.project @@ -0,0 +1,23 @@ + + + react-native-maps-lib + Project react-native-maps-lib created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/lib/android/bin/src/main/java/com/airbnb/android/react/maps b/lib/android/bin/src/main/java/com/airbnb/android/react/maps new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/android/build.gradle b/lib/android/build.gradle index 326ab4bfa5..acc7f579fd 100644 --- a/lib/android/build.gradle +++ b/lib/android/build.gradle @@ -1,13 +1,19 @@ apply plugin: 'com.android.library' apply from: 'gradle-maven-push.gradle' +def DEFAULT_COMPILE_SDK_VERSION = 25 +def DEFAULT_BUILD_TOOLS_VERSION = "25.0.3" +def DEFAULT_TARGET_SDK_VERSION = 25 +def DEFAULT_GOOGLE_PLAY_SERVICES_VERSION = "10.2.4" +def DEFAULT_ANDROID_MAPS_UTILS_VERSION = "0.5+" + android { - compileSdkVersion 25 - buildToolsVersion "25.0.3" + compileSdkVersion rootProject.hasProperty('compileSdkVersion') ? rootProject.compileSdkVersion : DEFAULT_COMPILE_SDK_VERSION + buildToolsVersion rootProject.hasProperty('buildToolsVersion') ? rootProject.buildToolsVersion : DEFAULT_BUILD_TOOLS_VERSION defaultConfig { minSdkVersion 16 - targetSdkVersion 25 + targetSdkVersion rootProject.hasProperty('targetSdkVersion') ? rootProject.targetSdkVersion : DEFAULT_TARGET_SDK_VERSION } packagingOptions { @@ -34,7 +40,11 @@ android { } dependencies { - provided "com.facebook.react:react-native:+" - compile "com.google.android.gms:play-services-base:10.2.4" - compile "com.google.android.gms:play-services-maps:10.2.4" + def googlePlayServicesVersion = rootProject.hasProperty('googlePlayServicesVersion') ? rootProject.googlePlayServicesVersion : DEFAULT_GOOGLE_PLAY_SERVICES_VERSION + def androidMapsUtilsVersion = rootProject.hasProperty('androidMapsUtilsVersion') ? rootProject.androidMapsUtilsVersion : DEFAULT_ANDROID_MAPS_UTILS_VERSION + + compileOnly "com.facebook.react:react-native:+" + implementation "com.google.android.gms:play-services-base:$googlePlayServicesVersion" + implementation "com.google.android.gms:play-services-maps:$googlePlayServicesVersion" + implementation "com.google.maps.android:android-maps-utils:$androidMapsUtilsVersion" } diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 7047e93ba3..f9aa44da00 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.17.0 +VERSION_NAME=0.21.0 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/lib/android/src/main/assets/ula.kml b/lib/android/src/main/assets/ula.kml new file mode 100644 index 0000000000..2504574a9b --- /dev/null +++ b/lib/android/src/main/assets/ula.kml @@ -0,0 +1,1214 @@ + + + + + + + + + + + + + + +20171123121441_ULA_PARCIAL + + -18.9193508,-48.2830592 + + -1 + 0 + -1 + + -48.2830592,-18.9193508 + + + CEO-ULA-00001 + + -1 + 0 + -1 + + -48.28328,-18.915815 + + + CEO-ULA-00186 + + -1 + 0 + -1 + + -48.278833,-18.919549 + + + CEO-ULA-00188 + + -1 + 0 + -1 + + -48.289805,-18.913945 + + + CEO-ULA-00229 + + -1 + 0 + -1 + + -48.288815,-18.922615 + + + CEO-ULA-00243 + + -1 + 0 + -1 + + -48.281013,-18.916794 + + + CEO-ULA-00274 + + -1 + 0 + -1 + + -48.276156,-18.91852 + + + CEO-ULA-00275 + + -1 + 0 + -1 + + -48.278656,-18.922156 + + + ST-ULA-0001 + + -1 + 0 + -1 + + -48.283467,-18.91587 + + + ST-ULA-0360 + + -1 + 0 + -1 + + -48.2917338,-18.9200969 + + + ST-ULA-0361 + + -1 + 0 + -1 + + -48.2905979,-18.921816 + + + ST-ULA-0362 + + -1 + 0 + -1 + + -48.2920103,-18.9192301 + + + ST-ULA-0399 + + -1 + 0 + -1 + + -48.29048,-18.9193956 + + + ST-ULA-0400 + + -1 + 0 + -1 + + -48.2906689,-18.918796 + + + ST-ULA-0408 + + -1 + 0 + -1 + + -48.2912278,-18.9170382 + + + CEO-ULA-00391 + + -1 + 0 + -1 + + -48.289628,-18.914507 + + + CEO-ULA-00053 + + -1 + 0 + -1 + + -48.291706,-18.920121 + + + CEO-ULA-00067 + + -1 + 0 + -1 + + -48.29045,-18.91948 + + + CEO-ULA-00288 + + -1 + 0 + -1 + + -48.274365,-18.921111 + + + CEO-ULA-00332 + + -1 + 0 + -1 + + -48.279256,-18.916275 + + + CEO-ULA-00337 + + -1 + 0 + -1 + + -48.280717,-18.916827 + + + CEO-ULA-00350 + + -1 + 0 + -1 + + -48.281085,-18.924567 + + + CEO-ULA-00369 + + -1 + 0 + -1 + + -48.288157,-18.915412 + + + CEO-ULA-00372 + + -1 + 0 + -1 + + -48.282004,-18.923989 + + + CEO-ULA-00379 + + -1 + 0 + -1 + + -48.290547,-18.919788 + + + CEO-ULA-00382 + + -1 + 0 + -1 + + -48.289297,-18.91561 + + + CEO-ULA-00386 + + -1 + 0 + -1 + + -48.280915,-18.910799 + + + CEO-ULA-00388 + + -1 + 0 + -1 + + -48.283811,-18.914334 + + + CEO-ULA-00390 + + -1 + 0 + -1 + + -48.288354,-18.918549 + + + CEO-ULA-00400 + + -1 + 0 + -1 + + -48.283629,-18.921665 + + + CEO-ULA-00394 + + -1 + 0 + -1 + + -48.284537,-18.912023 + + + CEO-ULA-00396 + + -1 + 0 + -1 + + -48.284908,-18.925537 + + + CEO-ULA-00399 + + -1 + 0 + -1 + + -48.283935,-18.925506 + + + CEO-ULA-00417 + + -1 + 0 + -1 + + -48.284404,-18.912391 + + + CEO-ULA-00495 + + -1 + 0 + -1 + + -48.275935,-18.914429 + + + CEO-ULA-00448 + + -1 + 0 + -1 + + -48.280576,-18.921918 + + + CEO-ULA-00449 + + -1 + 0 + -1 + + -48.277405,-18.917667 + + + CEO-ULA-00488 + + -1 + 0 + -1 + + -48.282118,-18.920169 + + + CEO-ULA-00489 + + -1 + 0 + -1 + + -48.280924,-18.916682 + + + CEO-ULA-00491 + + -1 + 0 + -1 + + -48.282753,-18.913711 + + + ST-ULA-2399 + + -1 + 0 + -1 + + -48.2894488,-18.9230852 + + + ST-ULA-2400 + + -1 + 0 + -1 + + -48.2782936,-18.9196916 + + + ST-ULA-2397 + + -1 + 0 + -1 + + -48.2809308,-18.9166838 + + + ST-ULA-2398 + + -1 + 0 + -1 + + -48.2887073,-18.9228568 + + + ST-ULA-2401 + + -1 + 0 + -1 + + -48.2788126,-18.919553 + + + CEO-ULA-00509 + + -1 + 0 + -1 + + -48.280852,-18.919976 + + + CEO-ULA-00531 + + -1 + 0 + -1 + + -48.289429,-18.92309 + + + ST-ULA-1579 + + -1 + 0 + -1 + + -48.2831316,-18.9231769 + + + ST-ULA-1577 + + -1 + 0 + -1 + + -48.2803822,-18.9193287 + + + ST-ULA-1578 + + -1 + 0 + -1 + + -48.281754,-18.9211827 + + + ST-ULA-1545 + + -1 + 0 + -1 + + -48.2798797,-18.9171188 + + + ST-ULA-1551 + + -1 + 0 + -1 + + -48.2822027,-18.9181888 + + + ST-ULA-1576 + + -1 + 0 + -1 + + -48.2791963,-18.917984 + + + ST-ULA-1580 + + -1 + 0 + -1 + + -48.2820288,-18.9267845 + + + ST-ULA-1736 + + -1 + 0 + -1 + + -48.290548,-18.9198029 + + + ST-ULA-1662 + + -1 + 0 + -1 + + -48.2820532,-18.9267959 + + + ST-ULA-1663 + + -1 + 0 + -1 + + -48.2837533,-18.92488 + + + ST-ULA-1735 + + -1 + 0 + -1 + + -48.2904324,-18.919494 + + + ST-ULA-1745 + + -1 + 0 + -1 + + -48.2893041,-18.9156106 + + + ST-ULA-1773 + + -1 + 0 + -1 + + -48.2896346,-18.9144805 + + + ST-ULA-1759 + + -1 + 0 + -1 + + -48.2838156,-18.9143177 + + + ST-ULA-1760 + + -1 + 0 + -1 + + -48.2840708,-18.9135214 + + + ST-ULA-1761 + + -1 + 0 + -1 + + -48.2809102,-18.9108123 + + + ST-ULA-1776 + + -1 + 0 + -1 + + -48.2845163,-18.9120761 + + + ST-ULA-1777 + + -1 + 0 + -1 + + -48.286238,-18.9147202 + + + ST-ULA-1778 + + -1 + 0 + -1 + + -48.2897804,-18.9139702 + + + ST-ULA-1785 + + -1 + 0 + -1 + + -48.2802345,-18.9267323 + + + ST-ULA-1782 + + -1 + 0 + -1 + + -48.2845618,-18.9259192 + + + ST-ULA-1783 + + -1 + 0 + -1 + + -48.2848909,-18.9255362 + + + ST-ULA-1784 + + -1 + 0 + -1 + + -48.2826035,-18.9257531 + + + ST-ULA-1788 + + -1 + 0 + -1 + + -48.283994,-18.9255066 + + + ST-ULA-1789 + + -1 + 0 + -1 + + -48.2880791,-18.92552 + + + ST-ULA-1791 + + -1 + 0 + -1 + + -48.2848777,-18.9255045 + + + ST-ULA-1792 + + -1 + 0 + -1 + + -48.2845053,-18.9269676 + + + ST-ULA-1793 + + -1 + 0 + -1 + + -48.2823102,-18.9267975 + + + ST-ULA-1794 + + -1 + 0 + -1 + + -48.2849364,-18.9255375 + + + ST-ULA-1800 + + -1 + 0 + -1 + + -48.2841773,-18.9227149 + + + ST-ULA-1801 + + -1 + 0 + -1 + + -48.2836987,-18.9216584 + + + ST-ULA-1802 + + -1 + 0 + -1 + + -48.2848919,-18.9255115 + + + ST-ULA-1838 + + -1 + 0 + -1 + + -48.284408,-18.9123794 + + + ST-ULA-1839 + + -1 + 0 + -1 + + -48.2843991,-18.9123761 + + + ST-ULA-1768 + + -1 + 0 + -1 + + -48.2896203,-18.9145271 + + + ST-ULA-1769 + + -1 + 0 + -1 + + -48.2883589,-18.9185316 + + + ST-ULA-1770 + + -1 + 0 + -1 + + -48.2896109,-18.9145329 + + + ST-ULA-1771 + + -1 + 0 + -1 + + -48.2845797,-18.9120706 + + + ST-ULA-1772 + + -1 + 0 + -1 + + -48.2872279,-18.9128471 + + + ST-ULA-1689 + + -1 + 0 + -1 + + -48.2914404,-18.9163817 + + + ST-ULA-1690 + + -1 + 0 + -1 + + -48.2881643,-18.9154096 + + + ST-ULA-1691 + + -1 + 0 + -1 + + -48.2881523,-18.9154079 + + + ST-ULA-1692 + + -1 + 0 + -1 + + -48.2859653,-18.9147849 + + + ST-ULA-1693 + + -1 + 0 + -1 + + -48.2806094,-18.9183195 + + + ST-ULA-1694 + + -1 + 0 + -1 + + -48.2818765,-18.9164378 + + + ST-ULA-1723 + + -1 + 0 + -1 + + -48.2818717,-18.9112605 + + + ST-ULA-1724 + + -1 + 0 + -1 + + -48.2832877,-18.9120452 + + + ST-ULA-1044 + + -1 + 0 + -1 + + -48.2788265,-18.9195413 + + + ST-ULA-1048 + + -1 + 0 + -1 + + -48.2898389,-18.9139479 + + + ST-ULA-1049 + + -1 + 0 + -1 + + -48.2898306,-18.9138754 + + + ST-ULA-1836 + + -1 + 0 + -1 + + -48.2897986,-18.9139428 + + + ST-ULA-1837 + + -1 + 0 + -1 + + -48.2873611,-18.9128968 + + + ST-ULA-1710 + + -1 + 0 + -1 + + -48.2820099,-18.9239905 + + + ST-ULA-1711 + + -1 + 0 + -1 + + -48.2837723,-18.9242837 + + + ST-ULA-1363 + + -1 + 0 + -1 + + -48.2776727,-18.9229224 + + + ST-ULA-1366 + + -1 + 0 + -1 + + -48.276015,-18.9200525 + + + ST-ULA-1406 + + -1 + 0 + -1 + + -48.2743386,-18.921128 + + + ST-ULA-1129 + + -1 + 0 + -1 + + -48.2881549,-18.9223935 + + + ST-ULA-1130 + + -1 + 0 + -1 + + -48.2888228,-18.9226054 + + + ST-ULA-1246 + + -1 + 0 + -1 + + -48.2809791,-18.9170914 + + + ST-ULA-2007 + + -1 + 0 + -1 + + -48.2781596,-18.9186736 + + + ST-ULA-1963 + + -1 + 0 + -1 + + -48.2788194,-18.919549 + + + ST-ULA-1956 + + -1 + 0 + -1 + + -48.2780189,-18.9123572 + + + ST-ULA-1987 + + -1 + 0 + -1 + + -48.2761483,-18.9185129 + + + ST-ULA-2006 + + -1 + 0 + -1 + + -48.2805711,-18.9219041 + + + ST-ULA-2215 + + -1 + 0 + -1 + + -48.2850344,-18.9143632 + + + ST-ULA-2226 + + -1 + 0 + -1 + + -48.2849368,-18.9255278 + + + ST-ULA-2227 + + -1 + 0 + -1 + + -48.2862061,-18.9255751 + + + ST-ULA-2008 + + -1 + 0 + -1 + + -48.2824599,-18.9242629 + + + ST-ULA-2203 + + -1 + 0 + -1 + + -48.280991,-18.9201737 + + + ST-ULA-2206 + + -1 + 0 + -1 + + -48.2803008,-18.9176824 + + + ST-ULA-2207 + + -1 + 0 + -1 + + -48.2809238,-18.9166913 + + + ST-ULA-2209 + + -1 + 0 + -1 + + -48.2807351,-18.9112935 + + + ST-ULA-2214 + + -1 + 0 + -1 + + -48.2827837,-18.9137244 + + + ST-ULA-1669 + + -1 + 0 + -1 + + -48.2764255,-18.9140386 + + + ST-ULA-1477 + + -1 + 0 + -1 + + -48.2894117,-18.9231269 + + + ST-ULA-1478 + + -1 + 0 + -1 + + -48.2899636,-18.9253263 + + + ST-ULA-1480 + + -1 + 0 + -1 + + -48.2897642,-18.9256209 + + + ST-ULA-2268 + + -1 + 0 + -1 + + -48.2743334,-18.921121 + + + ST-ULA-2281 + + -1 + 0 + -1 + + -48.2808588,-18.9199855 + + + ST-ULA-2282 + + -1 + 0 + -1 + + -48.2830492,-18.9193608 + + + ST-ULA-0330 + + -1 + 0 + -1 + + -48.2905731,-18.9197947 + + + CTO-ULA-00159 + + -1 + 0 + -1 + + -48.290652,-18.918802 + + + CTO-ULA-00160 + + -1 + 0 + -1 + + -48.291211,-18.917047 + + + CTO-ULA-00161 + + -1 + 0 + -1 + + -48.290562,-18.921833 + + + CTO-ULA-00162 + + -1 + 0 + -1 + + -48.291992,-18.919241 + + + diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLocalTile.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLocalTile.java new file mode 100644 index 0000000000..159a1cca25 --- /dev/null +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLocalTile.java @@ -0,0 +1,148 @@ +package com.airbnb.android.react.maps; + +import android.content.Context; + +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.model.Tile; +import com.google.android.gms.maps.model.TileOverlay; +import com.google.android.gms.maps.model.TileOverlayOptions; +import com.google.android.gms.maps.model.TileProvider; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class AirMapLocalTile extends AirMapFeature { + + class AIRMapLocalTileProvider implements TileProvider { + private static final int BUFFER_SIZE = 16 * 1024; + private int tileSize; + private String pathTemplate; + + + public AIRMapLocalTileProvider(int tileSizet, String pathTemplate) { + this.tileSize = tileSizet; + this.pathTemplate = pathTemplate; + } + + @Override + public Tile getTile(int x, int y, int zoom) { + byte[] image = readTileImage(x, y, zoom); + return image == null ? TileProvider.NO_TILE : new Tile(this.tileSize, this.tileSize, image); + } + + public void setPathTemplate(String pathTemplate) { + this.pathTemplate = pathTemplate; + } + + public void setTileSize(int tileSize) { + this.tileSize = tileSize; + } + + private byte[] readTileImage(int x, int y, int zoom) { + InputStream in = null; + ByteArrayOutputStream buffer = null; + File file = new File(getTileFilename(x, y, zoom)); + + try { + in = new FileInputStream(file); + buffer = new ByteArrayOutputStream(); + + int nRead; + byte[] data = new byte[BUFFER_SIZE]; + + while ((nRead = in.read(data, 0, BUFFER_SIZE)) != -1) { + buffer.write(data, 0, nRead); + } + buffer.flush(); + + return buffer.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } catch (OutOfMemoryError e) { + e.printStackTrace(); + return null; + } finally { + if (in != null) try { in.close(); } catch (Exception ignored) {} + if (buffer != null) try { buffer.close(); } catch (Exception ignored) {} + } + } + + private String getTileFilename(int x, int y, int zoom) { + String s = this.pathTemplate + .replace("{x}", Integer.toString(x)) + .replace("{y}", Integer.toString(y)) + .replace("{z}", Integer.toString(zoom)); + return s; + } + } + + private TileOverlayOptions tileOverlayOptions; + private TileOverlay tileOverlay; + private AirMapLocalTile.AIRMapLocalTileProvider tileProvider; + + private String pathTemplate; + private float tileSize; + private float zIndex; + + public AirMapLocalTile(Context context) { + super(context); + } + + public void setPathTemplate(String pathTemplate) { + this.pathTemplate = pathTemplate; + if (tileProvider != null) { + tileProvider.setPathTemplate(pathTemplate); + } + if (tileOverlay != null) { + tileOverlay.clearTileCache(); + } + } + + public void setZIndex(float zIndex) { + this.zIndex = zIndex; + if (tileOverlay != null) { + tileOverlay.setZIndex(zIndex); + } + } + + public void setTileSize(float tileSize) { + this.tileSize = tileSize; + if (tileProvider != null) { + tileProvider.setTileSize((int)tileSize); + } + } + + public TileOverlayOptions getTileOverlayOptions() { + if (tileOverlayOptions == null) { + tileOverlayOptions = createTileOverlayOptions(); + } + return tileOverlayOptions; + } + + private TileOverlayOptions createTileOverlayOptions() { + TileOverlayOptions options = new TileOverlayOptions(); + options.zIndex(zIndex); + this.tileProvider = new AirMapLocalTile.AIRMapLocalTileProvider((int)this.tileSize, this.pathTemplate); + options.tileProvider(this.tileProvider); + return options; + } + + @Override + public Object getFeature() { + return tileOverlay; + } + + @Override + public void addToMap(GoogleMap map) { + this.tileOverlay = map.addTileOverlay(getTileOverlayOptions()); + } + + @Override + public void removeFromMap(GoogleMap map) { + tileOverlay.remove(); + } +} diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLocalTileManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLocalTileManager.java new file mode 100644 index 0000000000..c9647888b9 --- /dev/null +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLocalTileManager.java @@ -0,0 +1,56 @@ +package com.airbnb.android.react.maps; + +import android.content.Context; +import android.os.Build; +import android.util.DisplayMetrics; +import android.view.WindowManager; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.ViewGroupManager; +import com.facebook.react.uimanager.annotations.ReactProp; + +/** + * Created by zavadpe on 30/11/2017. + */ +public class AirMapLocalTileManager extends ViewGroupManager { + private DisplayMetrics metrics; + + public AirMapLocalTileManager(ReactApplicationContext reactContext) { + super(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + metrics = new DisplayMetrics(); + ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay() + .getRealMetrics(metrics); + } else { + metrics = reactContext.getResources().getDisplayMetrics(); + } + } + + @Override + public String getName() { + return "AIRMapLocalTile"; + } + + @Override + public AirMapLocalTile createViewInstance(ThemedReactContext context) { + return new AirMapLocalTile(context); + } + + @ReactProp(name = "pathTemplate") + public void setPathTemplate(AirMapLocalTile view, String pathTemplate) { + view.setPathTemplate(pathTemplate); + } + + @ReactProp(name = "tileSize", defaultFloat = 256f) + public void setTileSize(AirMapLocalTile view, float tileSize) { + view.setTileSize(tileSize); + } + + @ReactProp(name = "zIndex", defaultFloat = -1.0f) + public void setZIndex(AirMapLocalTile view, float zIndex) { + view.setZIndex(zIndex); + } + +} \ No newline at end of file diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index 6749e9a859..ee80725c17 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -19,8 +19,10 @@ import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.MapStyleOptions; +import com.google.maps.android.data.kml.KmlLayer; import java.util.Map; +import java.util.HashMap; import javax.annotation.Nullable; @@ -34,6 +36,9 @@ public class AirMapManager extends ViewGroupManager { private static final int FIT_TO_ELEMENTS = 5; private static final int FIT_TO_SUPPLIED_MARKERS = 6; private static final int FIT_TO_COORDINATES = 7; + private static final int SET_MAP_BOUNDARIES = 8; + private static final int ANIMATE_TO_NAVIGATION = 9; + private final Map MAP_TYPES = MapBuilder.of( "standard", GoogleMap.MAP_TYPE_NORMAL, @@ -93,6 +98,35 @@ public void setMapStyle(AirMapView view, @Nullable String customMapStyleString) view.map.setMapStyle(new MapStyleOptions(customMapStyleString)); } + @ReactProp(name = "mapPadding") + public void setMapPadding(AirMapView view, @Nullable ReadableMap padding) { + int left = 0; + int top = 0; + int right = 0; + int bottom = 0; + double density = (double) view.getResources().getDisplayMetrics().density; + + if (padding != null) { + if (padding.hasKey("left")) { + left = (int) (padding.getDouble("left") * density); + } + + if (padding.hasKey("top")) { + top = (int) (padding.getDouble("top") * density); + } + + if (padding.hasKey("right")) { + right = (int) (padding.getDouble("right") * density); + } + + if (padding.hasKey("bottom")) { + bottom = (int) (padding.getDouble("bottom") * density); + } + } + + view.map.setPadding(left, top, right, bottom); + } + @ReactProp(name = "showsUserLocation", defaultBoolean = false) public void setShowsUserLocation(AirMapView view, boolean showUserLocation) { view.setShowsUserLocation(showUserLocation); @@ -150,6 +184,11 @@ public void setZoomEnabled(AirMapView view, boolean zoomEnabled) { view.map.getUiSettings().setZoomGesturesEnabled(zoomEnabled); } + @ReactProp(name = "zoomControlEnabled", defaultBoolean = true) + public void setZoomControlEnabled(AirMapView view, boolean zoomControlEnabled) { + view.map.getUiSettings().setZoomControlsEnabled(zoomControlEnabled); + } + @ReactProp(name = "rotateEnabled", defaultBoolean = false) public void setRotateEnabled(AirMapView view, boolean rotateEnabled) { view.map.getUiSettings().setRotateGesturesEnabled(rotateEnabled); @@ -195,6 +234,13 @@ public void setMaxZoomLevel(AirMapView view, float maxZoomLevel) { view.map.setMaxZoomPreference(maxZoomLevel); } + @ReactProp(name = "kmlSrc") + public void setKmlSrc(AirMapView view, String kmlUrl) { + if (kmlUrl != null) { + view.setKmlSrc(kmlUrl); + } + } + @Override public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArray args) { Integer duration; @@ -207,6 +253,17 @@ public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArr ReadableMap region; switch (commandId) { + case ANIMATE_TO_NAVIGATION: + region = args.getMap(0); + lng = region.getDouble("longitude"); + lat = region.getDouble("latitude"); + LatLng location = new LatLng(lat, lng); + bearing = (float)args.getDouble(1); + angle = (float)args.getDouble(2); + duration = args.getInt(3); + view.animateToNavigation(location, bearing, angle, duration); + break; + case ANIMATE_TO_REGION: region = args.getMap(0); duration = args.getInt(1); @@ -234,13 +291,13 @@ public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArr duration = args.getInt(1); view.animateToViewingAngle(angle, duration); break; - + case ANIMATE_TO_BEARING: bearing = (float)args.getDouble(0); duration = args.getInt(1); view.animateToBearing(bearing, duration); break; - + case FIT_TO_ELEMENTS: view.fitToElements(args.getBoolean(0)); break; @@ -248,9 +305,14 @@ public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArr case FIT_TO_SUPPLIED_MARKERS: view.fitToSuppliedMarkers(args.getArray(0), args.getBoolean(1)); break; + case FIT_TO_COORDINATES: view.fitToCoordinates(args.getArray(0), args.getMap(1), args.getBoolean(2)); break; + + case SET_MAP_BOUNDARIES: + view.setMapBoundaries(args.getMap(0), args.getMap(1)); + break; } } @@ -268,27 +330,51 @@ public Map getExportedCustomDirectEventTypeConstants() { ); map.putAll(MapBuilder.of( + "onUserLocationChange", MapBuilder.of("registrationName", "onUserLocationChange"), "onMarkerDragStart", MapBuilder.of("registrationName", "onMarkerDragStart"), "onMarkerDrag", MapBuilder.of("registrationName", "onMarkerDrag"), "onMarkerDragEnd", MapBuilder.of("registrationName", "onMarkerDragEnd"), - "onPanDrag", MapBuilder.of("registrationName", "onPanDrag") + "onPanDrag", MapBuilder.of("registrationName", "onPanDrag"), + "onKmlReady", MapBuilder.of("registrationName", "onKmlReady"), + "onPoiClick", MapBuilder.of("registrationName", "onPoiClick") )); return map; } - - @Override + @Nullable + @Override public Map getCommandsMap() { - return MapBuilder.of( + Map map = this.CreateMap( "animateToRegion", ANIMATE_TO_REGION, "animateToCoordinate", ANIMATE_TO_COORDINATE, "animateToViewingAngle", ANIMATE_TO_VIEWING_ANGLE, "animateToBearing", ANIMATE_TO_BEARING, "fitToElements", FIT_TO_ELEMENTS, "fitToSuppliedMarkers", FIT_TO_SUPPLIED_MARKERS, - "fitToCoordinates", FIT_TO_COORDINATES + "fitToCoordinates", FIT_TO_COORDINATES, + "animateToNavigation", ANIMATE_TO_NAVIGATION ); + + map.putAll(MapBuilder.of( + "setMapBoundaries", SET_MAP_BOUNDARIES + )); + + return map; + } + + public static Map CreateMap( + K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) { + Map map = new HashMap(); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + map.put(k7, v7); + map.put(k8, v8); + return map; } @Override @@ -328,7 +414,6 @@ void pushEvent(ThemedReactContext context, View view, String name, WritableMap d .receiveEvent(view.getId(), name, data); } - @Override public void onDropViewInstance(AirMapView view) { view.doDestroy(); diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java index cb0274bfa4..1a1af36634 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java @@ -5,9 +5,13 @@ import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.Animatable; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.view.View; import android.widget.LinearLayout; +import android.animation.ObjectAnimator; +import android.util.Property; +import android.animation.TypeEvaluator; import com.facebook.common.references.CloseableReference; import com.facebook.datasource.DataSource; @@ -112,6 +116,25 @@ public AirMapMarker(Context context) { logoHolder.onAttach(); } + public AirMapMarker(Context context, MarkerOptions options) { + super(context); + this.context = context; + logoHolder = DraweeHolder.create(createDraweeHierarchy(), context); + logoHolder.onAttach(); + + position = options.getPosition(); + setAnchor(options.getAnchorU(), options.getAnchorV()); + setCalloutAnchor(options.getInfoWindowAnchorU(), options.getInfoWindowAnchorV()); + setTitle(options.getTitle()); + setSnippet(options.getSnippet()); + setRotation(options.getRotation()); + setFlat(options.isFlat()); + setDraggable(options.isDraggable()); + setZIndex(Math.round(options.getZIndex())); + setAlpha(options.getAlpha()); + iconBitmapDescriptor = options.getIcon(); + } + private GenericDraweeHierarchy createDraweeHierarchy() { return new GenericDraweeHierarchyBuilder(getResources()) .setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER) @@ -217,12 +240,35 @@ public void setCalloutAnchor(double x, double y) { update(); } + public LatLng interpolate(float fraction, LatLng a, LatLng b) { + double lat = (b.latitude - a.latitude) * fraction + a.latitude; + double lng = (b.longitude - a.longitude) * fraction + a.longitude; + return new LatLng(lat, lng); + } + + public void animateToCoodinate(LatLng finalPosition, Integer duration) { + TypeEvaluator typeEvaluator = new TypeEvaluator() { + @Override + public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) { + return interpolate(fraction, startValue, endValue); + } + }; + Property property = Property.of(Marker.class, LatLng.class, "position"); + ObjectAnimator animator = ObjectAnimator.ofObject( + marker, + property, + typeEvaluator, + finalPosition); + animator.setDuration(duration); + animator.start(); + } + public void setImage(String uri) { if (uri == null) { iconBitmapDescriptor = null; update(); } else if (uri.startsWith("http://") || uri.startsWith("https://") || - uri.startsWith("file://")) { + uri.startsWith("file://") || uri.startsWith("asset://")) { ImageRequest imageRequest = ImageRequestBuilder .newBuilderWithSource(Uri.parse(uri)) .build(); @@ -238,7 +284,15 @@ public void setImage(String uri) { } else { iconBitmapDescriptor = getBitmapDescriptorByName(uri); if (iconBitmapDescriptor != null) { - iconBitmap = BitmapFactory.decodeResource(getResources(), getDrawableResourceByName(uri)); + int drawableId = getDrawableResourceByName(uri); + iconBitmap = BitmapFactory.decodeResource(getResources(), drawableId); + if (iconBitmap == null) { // VectorDrawable or similar + Drawable drawable = getResources().getDrawable(drawableId); + iconBitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + Canvas canvas = new Canvas(iconBitmap); + drawable.draw(canvas); + } } update(); } @@ -246,8 +300,10 @@ public void setImage(String uri) { public MarkerOptions getMarkerOptions() { if (markerOptions == null) { - markerOptions = createMarkerOptions(); + markerOptions = new MarkerOptions(); } + + fillMarkerOptions(markerOptions); return markerOptions; } @@ -301,8 +357,8 @@ private BitmapDescriptor getIcon() { } } - private MarkerOptions createMarkerOptions() { - MarkerOptions options = new MarkerOptions().position(position); + private MarkerOptions fillMarkerOptions(MarkerOptions options) { + options.position(position); if (anchorIsSet) options.anchor(anchorX, anchorY); if (calloutAnchorIsSet) options.infoWindowAnchor(calloutAnchorX, calloutAnchorY); options.title(title); diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java index 3aef3148cd..080abad71c 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java @@ -11,6 +11,7 @@ import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.annotations.ReactProp; import com.google.android.gms.maps.model.Marker; +import com.google.android.gms.maps.model.LatLng; import java.util.HashMap; import java.util.Map; @@ -21,6 +22,7 @@ public class AirMapMarkerManager extends ViewGroupManager { private static final int SHOW_INFO_WINDOW = 1; private static final int HIDE_INFO_WINDOW = 2; + private static final int ANIMATE_MARKER_TO_COORDINATE = 3; public AirMapMarkerManager() { } @@ -154,12 +156,18 @@ public void removeViewAt(AirMapMarker parent, int index) { public Map getCommandsMap() { return MapBuilder.of( "showCallout", SHOW_INFO_WINDOW, - "hideCallout", HIDE_INFO_WINDOW + "hideCallout", HIDE_INFO_WINDOW, + "animateMarkerToCoordinate", ANIMATE_MARKER_TO_COORDINATE ); } @Override public void receiveCommand(AirMapMarker view, int commandId, @Nullable ReadableArray args) { + Integer duration; + Double lat; + Double lng; + ReadableMap region; + switch (commandId) { case SHOW_INFO_WINDOW: ((Marker) view.getFeature()).showInfoWindow(); @@ -168,6 +176,15 @@ public void receiveCommand(AirMapMarker view, int commandId, @Nullable ReadableA case HIDE_INFO_WINDOW: ((Marker) view.getFeature()).hideInfoWindow(); break; + + case ANIMATE_MARKER_TO_COORDINATE: + region = args.getMap(0); + duration = args.getInt(1); + + lng = region.getDouble("longitude"); + lat = region.getDouble("latitude"); + view.animateToCoodinate(new LatLng(lat, lng), duration); + break; } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java index dfc71d6d9c..2cec24eba4 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java @@ -2,6 +2,7 @@ import android.app.Activity; import android.graphics.Bitmap; +import android.graphics.Point; import android.net.Uri; import android.util.Base64; import android.util.DisplayMetrics; @@ -11,11 +12,14 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableNativeMap; import com.facebook.react.uimanager.NativeViewHierarchyManager; import com.facebook.react.uimanager.UIBlock; import com.facebook.react.uimanager.UIManagerModule; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.common.GoogleApiAvailability; +import com.google.android.gms.maps.model.LatLng; import java.io.ByteArrayOutputStream; import java.io.Closeable; @@ -135,4 +139,76 @@ public void onSnapshotReady(@Nullable Bitmap snapshot) { } }); } + + @ReactMethod + public void pointForCoordinate(final int tag, ReadableMap coordinate, final Promise promise) { + final LatLng coord = new LatLng( + coordinate.hasKey("latitude") ? coordinate.getDouble("latitude") : 0.0, + coordinate.hasKey("longitude") ? coordinate.getDouble("longitude") : 0.0 + ); + + final ReactApplicationContext context = getReactApplicationContext(); + UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class); + uiManager.addUIBlock(new UIBlock() + { + @Override + public void execute(NativeViewHierarchyManager nvhm) + { + AirMapView view = (AirMapView) nvhm.resolveView(tag); + if (view == null) { + promise.reject("AirMapView not found"); + return; + } + if (view.map == null) { + promise.reject("AirMapView.map is not valid"); + return; + } + + Point pt = view.map.getProjection().toScreenLocation(coord); + + WritableMap ptJson = new WritableNativeMap(); + ptJson.putDouble("x", pt.x); + ptJson.putDouble("y", pt.y); + + promise.resolve(ptJson); + } + }); + } + + @ReactMethod + public void coordinateForPoint(final int tag, ReadableMap point, final Promise promise) { + final Point pt = new Point( + point.hasKey("x") ? point.getInt("x") : 0, + point.hasKey("y") ? point.getInt("y") : 0 + ); + + final ReactApplicationContext context = getReactApplicationContext(); + UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class); + uiManager.addUIBlock(new UIBlock() + { + @Override + public void execute(NativeViewHierarchyManager nvhm) + { + AirMapView view = (AirMapView) nvhm.resolveView(tag); + if (view == null) + { + promise.reject("AirMapView not found"); + return; + } + if (view.map == null) + { + promise.reject("AirMapView.map is not valid"); + return; + } + + LatLng coord = view.map.getProjection().fromScreenLocation(pt); + + WritableMap coordJson = new WritableNativeMap(); + coordJson.putDouble("latitude", coord.latitude); + coordJson.putDouble("longitude", coord.longitude); + + promise.resolve(coordJson); + } + }); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapOverlay.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapOverlay.java new file mode 100644 index 0000000000..7d2134ada2 --- /dev/null +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapOverlay.java @@ -0,0 +1,144 @@ +package com.airbnb.android.react.maps; + +import android.content.Context; +import android.graphics.Bitmap; + +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.model.BitmapDescriptor; +import com.google.android.gms.maps.model.BitmapDescriptorFactory; +import com.google.android.gms.maps.model.GroundOverlay; +import com.google.android.gms.maps.model.GroundOverlayOptions; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.LatLngBounds; + +import java.util.ArrayList; + +public class AirMapOverlay extends AirMapFeature implements ImageReadable { + + private GroundOverlayOptions groundOverlayOptions; + private GroundOverlay groundOverlay; + private LatLngBounds bounds; + private BitmapDescriptor iconBitmapDescriptor; + private Bitmap iconBitmap; + private float zIndex; + private float transparency; + + private final ImageReader mImageReader; + private GoogleMap map; + + public AirMapOverlay(Context context) { + super(context); + this.mImageReader = new ImageReader(context, getResources(), this); + } + + public void setBounds(ReadableArray bounds) { + LatLng sw = new LatLng(bounds.getArray(1).getDouble(0), bounds.getArray(0).getDouble(1)); + LatLng ne = new LatLng(bounds.getArray(0).getDouble(0), bounds.getArray(1).getDouble(1)); + this.bounds = new LatLngBounds(sw, ne); + if (this.groundOverlay != null) { + this.groundOverlay.setPositionFromBounds(this.bounds); + } + } + + public void setZIndex(float zIndex) { + this.zIndex = zIndex; + if (this.groundOverlay != null) { + this.groundOverlay.setZIndex(zIndex); + } + } + + // public void setTransparency(float transparency) { + // this.transparency = transparency; + // if (groundOverlay != null) { + // groundOverlay.setTransparency(transparency); + // } + // } + + public void setImage(String uri) { + this.mImageReader.setImage(uri); + } + + + public GroundOverlayOptions getGroundOverlayOptions() { + if (this.groundOverlayOptions == null) { + this.groundOverlayOptions = createGroundOverlayOptions(); + } + return this.groundOverlayOptions; + } + + private GroundOverlayOptions createGroundOverlayOptions() { + if (this.groundOverlayOptions != null) { + return this.groundOverlayOptions; + } + if (this.iconBitmapDescriptor != null) { + GroundOverlayOptions options = new GroundOverlayOptions(); + options.image(iconBitmapDescriptor); + options.positionFromBounds(bounds); + options.zIndex(zIndex); + return options; + } + return null; + } + + @Override + public Object getFeature() { + return groundOverlay; + } + + @Override + public void addToMap(GoogleMap map) { + GroundOverlayOptions groundOverlayOptions = getGroundOverlayOptions(); + if (groundOverlayOptions != null) { + this.groundOverlay = map.addGroundOverlay(groundOverlayOptions); + this.groundOverlay.setClickable(true); + } else { + this.map = map; + } + } + + @Override + public void removeFromMap(GoogleMap map) { + this.map = null; + if (this.groundOverlay != null) { + this.groundOverlay.remove(); + this.groundOverlay = null; + this.groundOverlayOptions = null; + } + } + + @Override + public void setIconBitmap(Bitmap bitmap) { + this.iconBitmap = bitmap; + } + + @Override + public void setIconBitmapDescriptor( + BitmapDescriptor iconBitmapDescriptor) { + this.iconBitmapDescriptor = iconBitmapDescriptor; + } + + @Override + public void update() { + this.groundOverlay = getGroundOverlay(); + if (this.groundOverlay != null) { + this.groundOverlay.setImage(this.iconBitmapDescriptor); + this.groundOverlay.setClickable(true); + } + } + + private GroundOverlay getGroundOverlay() { + if (this.groundOverlay != null) { + return this.groundOverlay; + } + if (this.map == null) { + return null; + } + GroundOverlayOptions groundOverlayOptions = getGroundOverlayOptions(); + if (groundOverlayOptions != null) { + return this.map.addGroundOverlay(groundOverlayOptions); + } + return null; + } +} diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapOverlayManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapOverlayManager.java new file mode 100644 index 0000000000..ccc5a7eaa8 --- /dev/null +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapOverlayManager.java @@ -0,0 +1,72 @@ +package com.airbnb.android.react.maps; + +import android.content.Context; +import android.os.Build; +import android.util.DisplayMetrics; +import android.view.WindowManager; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.common.MapBuilder; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.ViewGroupManager; +import com.facebook.react.uimanager.annotations.ReactProp; + +import java.util.Map; + +import javax.annotation.Nullable; + +public class AirMapOverlayManager extends ViewGroupManager { + private final DisplayMetrics metrics; + + public AirMapOverlayManager(ReactApplicationContext reactContext) { + super(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + metrics = new DisplayMetrics(); + ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay() + .getRealMetrics(metrics); + } else { + metrics = reactContext.getResources().getDisplayMetrics(); + } + } + + @Override + public String getName() { + return "AIRMapOverlay"; + } + + @Override + public AirMapOverlay createViewInstance(ThemedReactContext context) { + return new AirMapOverlay(context); + } + + @ReactProp(name = "bounds") + public void setBounds(AirMapOverlay view, ReadableArray bounds) { + view.setBounds(bounds); + } + + @ReactProp(name = "zIndex", defaultFloat = 1.0f) + public void setZIndex(AirMapOverlay view, float zIndex) { + view.setZIndex(zIndex); + } + + // @ReactProp(name = "transparency", defaultFloat = 1.0f) + // public void setTransparency(AirMapOverlay view, float transparency) { + // view.setTransparency(transparency); + // } + + @ReactProp(name = "image") + public void setImage(AirMapOverlay view, @Nullable String source) { + view.setImage(source); + } + + + @Override + @Nullable + public Map getExportedCustomDirectEventTypeConstants() { + return MapBuilder.of( + "onPress", MapBuilder.of("registrationName", "onPress") + ); + } +} diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java index 41257b32e6..6ed5df3603 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java @@ -18,10 +18,12 @@ public class AirMapPolygon extends AirMapFeature { private Polygon polygon; private List coordinates; + private List> holes; private int strokeColor; private int fillColor; private float strokeWidth; private boolean geodesic; + private boolean tappable; private float zIndex; public AirMapPolygon(Context context) { @@ -41,6 +43,38 @@ public void setCoordinates(ReadableArray coordinates) { } } + public void setHoles(ReadableArray holes) { + if (holes == null) { return; } + + this.holes = new ArrayList<>(holes.size()); + + for (int i = 0; i < holes.size(); i++) { + ReadableArray hole = holes.getArray(i); + + if (hole.size() < 3) { continue; } + + List coordinates = new ArrayList<>(); + for (int j = 0; j < hole.size(); j++) { + ReadableMap coordinate = hole.getMap(j); + coordinates.add(new LatLng( + coordinate.getDouble("latitude"), + coordinate.getDouble("longitude"))); + } + + // If hole is triangle + if (coordinates.size() == 3) { + coordinates.add(coordinates.get(0)); + } + + this.holes.add(coordinates); + } + + if (polygon != null) { + polygon.setHoles(this.holes); + } + } + + public void setFillColor(int color) { this.fillColor = color; if (polygon != null) { @@ -62,6 +96,13 @@ public void setStrokeWidth(float width) { } } + public void setTappable(boolean tapabble) { + this.tappable = tapabble; + if (polygon != null) { + polygon.setClickable(tappable); + } + } + public void setGeodesic(boolean geodesic) { this.geodesic = geodesic; if (polygon != null) { @@ -91,6 +132,13 @@ private PolygonOptions createPolygonOptions() { options.strokeWidth(strokeWidth); options.geodesic(geodesic); options.zIndex(zIndex); + + if (this.holes != null) { + for (int i = 0; i < holes.size(); i++) { + options.addHole(holes.get(i)); + } + } + return options; } @@ -102,7 +150,7 @@ public Object getFeature() { @Override public void addToMap(GoogleMap map) { polygon = map.addPolygon(getPolygonOptions()); - polygon.setClickable(true); + polygon.setClickable(this.tappable); } @Override diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java index 6f16057585..3013214d5f 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java @@ -47,6 +47,11 @@ public void setCoordinate(AirMapPolygon view, ReadableArray coordinates) { view.setCoordinates(coordinates); } + @ReactProp(name = "holes") + public void setHoles(AirMapPolygon view, ReadableArray holes) { + view.setHoles(holes); + } + @ReactProp(name = "strokeWidth", defaultFloat = 1f) public void setStrokeWidth(AirMapPolygon view, float widthInPoints) { float widthInScreenPx = metrics.density * widthInPoints; // done for parity with iOS @@ -63,6 +68,11 @@ public void setStrokeColor(AirMapPolygon view, int color) { view.setStrokeColor(color); } + @ReactProp(name = "tappable", defaultBoolean = false) + public void setTappable(AirMapPolygon view, boolean tapabble) { + view.setTappable(tapabble); + } + @ReactProp(name = "geodesic", defaultBoolean = false) public void setGeodesic(AirMapPolygon view, boolean geodesic) { view.setGeodesic(geodesic); diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java index 488e2972f4..28a13c4188 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java @@ -5,9 +5,11 @@ import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.model.Cap; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; +import com.google.android.gms.maps.model.RoundCap; import java.util.ArrayList; import java.util.List; @@ -22,6 +24,7 @@ public class AirMapPolyline extends AirMapFeature { private float width; private boolean geodesic; private float zIndex; + private Cap lineCap = new RoundCap(); public AirMapPolyline(Context context) { super(context); @@ -67,6 +70,14 @@ public void setGeodesic(boolean geodesic) { } } + public void setLineCap(Cap cap) { + this.lineCap = cap; + if (polyline != null) { + polyline.setStartCap(cap); + polyline.setEndCap(cap); + } + } + public PolylineOptions getPolylineOptions() { if (polylineOptions == null) { polylineOptions = createPolylineOptions(); @@ -81,6 +92,8 @@ private PolylineOptions createPolylineOptions() { options.width(width); options.geodesic(geodesic); options.zIndex(zIndex); + options.startCap(lineCap); + options.endCap(lineCap); return options; } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java index be80acfbc0..b17699b33c 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java @@ -12,6 +12,10 @@ import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.annotations.ReactProp; +import com.google.android.gms.maps.model.ButtCap; +import com.google.android.gms.maps.model.Cap; +import com.google.android.gms.maps.model.RoundCap; +import com.google.android.gms.maps.model.SquareCap; import java.util.Map; @@ -68,6 +72,26 @@ public void setZIndex(AirMapPolyline view, float zIndex) { view.setZIndex(zIndex); } + @ReactProp(name = "lineCap") + public void setlineCap(AirMapPolyline view, String lineCap) { + Cap cap = null; + switch (lineCap) { + case "butt": + cap = new ButtCap(); + break; + case "round": + cap = new RoundCap(); + break; + case "square": + cap = new SquareCap(); + break; + default: + cap = new RoundCap(); + break; + } + view.setLineCap(cap); + } + @Override @Nullable public Map getExportedCustomDirectEventTypeConstants() { diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java index ae51a63b4d..03e7e7e78c 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java @@ -28,6 +28,15 @@ public synchronized URL getTileUrl(int x, int y, int zoom) { .replace("{y}", Integer.toString(y)) .replace("{z}", Integer.toString(zoom)); URL url = null; + + if(AirMapUrlTile.this.maximumZ > 0 && zoom > maximumZ) { + return url; + } + + if(AirMapUrlTile.this.minimumZ > 0 && zoom < minimumZ) { + return url; + } + try { url = new URL(s); } catch (MalformedURLException e) { @@ -47,6 +56,8 @@ public void setUrlTemplate(String urlTemplate) { private String urlTemplate; private float zIndex; + private float maximumZ; + private float minimumZ; public AirMapUrlTile(Context context) { super(context); @@ -69,6 +80,20 @@ public void setZIndex(float zIndex) { } } + public void setMaximumZ(float maximumZ) { + this.maximumZ = maximumZ; + if (tileOverlay != null) { + tileOverlay.clearTileCache(); + } + } + + public void setMinimumZ(float minimumZ) { + this.minimumZ = minimumZ; + if (tileOverlay != null) { + tileOverlay.clearTileCache(); + } + } + public TileOverlayOptions getTileOverlayOptions() { if (tileOverlayOptions == null) { tileOverlayOptions = createTileOverlayOptions(); diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java index 68bf07342c..1fc5672c4d 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java @@ -45,4 +45,14 @@ public void setZIndex(AirMapUrlTile view, float zIndex) { view.setZIndex(zIndex); } + @ReactProp(name = "minimumZ", defaultFloat = 0.0f) + public void setMinimumZ(AirMapUrlTile view, float minimumZ) { + view.setMinimumZ(minimumZ); + } + + @ReactProp(name = "maximumZ", defaultFloat = 100.0f) + public void setMaximumZ(AirMapUrlTile view, float maximumZ) { + view.setMaximumZ(maximumZ); + } + } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 836fe0e35b..5882f8cab4 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -8,23 +8,24 @@ import android.graphics.Point; import android.graphics.PorterDuff; import android.os.Build; -import android.os.Handler; import android.support.v4.view.GestureDetectorCompat; import android.support.v4.view.MotionEventCompat; import android.view.GestureDetector; import android.view.MotionEvent; -import android.view.ScaleGestureDetector; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.RelativeLayout; +import android.location.Location; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableNativeArray; import com.facebook.react.bridge.WritableNativeMap; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIManagerModule; @@ -36,25 +37,37 @@ import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.Projection; +import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.Marker; +import com.google.android.gms.maps.model.MarkerOptions; +import com.google.android.gms.maps.model.PointOfInterest; import com.google.android.gms.maps.model.Polygon; import com.google.android.gms.maps.model.Polyline; -import com.google.android.gms.maps.model.VisibleRegion; +import com.google.maps.android.data.kml.KmlContainer; +import com.google.maps.android.data.kml.KmlLayer; +import com.google.maps.android.data.kml.KmlPlacemark; +import com.google.maps.android.data.kml.KmlStyle; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutionException; import static android.support.v4.content.PermissionChecker.checkSelfPermission; public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, - GoogleMap.OnMarkerDragListener, OnMapReadyCallback { + GoogleMap.OnMarkerDragListener, OnMapReadyCallback, GoogleMap.OnPoiClickListener { public GoogleMap map; + private KmlLayer kmlLayer; private ProgressBar mapLoadingProgressBar; private RelativeLayout mapLoadingLayout; private ImageView cacheImageView; @@ -65,12 +78,12 @@ public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, private LatLngBounds boundsToMove; private boolean showUserLocation = false; - private boolean isMonitoringRegion = false; - private boolean isTouchDown = false; private boolean handlePanDrag = false; private boolean moveOnMarkerPress = true; private boolean cacheEnabled = false; private boolean initialRegionSet = false; + private LatLngBounds cameraLastIdleBounds; + private int cameraMoveReason = 0; private static final String[] PERMISSIONS = new String[]{ "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION"}; @@ -79,7 +92,6 @@ public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, private final Map markerMap = new HashMap<>(); private final Map polylineMap = new HashMap<>(); private final Map polygonMap = new HashMap<>(); - private final ScaleGestureDetector scaleDetector; private final GestureDetectorCompat gestureDetector; private final AirMapManager manager; private LifecycleEventListener lifecycleListener; @@ -133,23 +145,9 @@ public AirMapView(ThemedReactContext reactContext, ReactApplicationContext appCo super.getMapAsync(this); final AirMapView view = this; - scaleDetector = - new ScaleGestureDetector(reactContext, - new ScaleGestureDetector.SimpleOnScaleGestureListener() { - @Override - public boolean onScaleBegin(ScaleGestureDetector detector) { - view.startMonitoringRegion(); - return true; // stop recording this gesture. let mapview handle it. - } - }); gestureDetector = new GestureDetectorCompat(reactContext, new GestureDetector.SimpleOnGestureListener() { - @Override - public boolean onDoubleTap(MotionEvent e) { - view.startMonitoringRegion(); - return false; - } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, @@ -157,7 +155,6 @@ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, if (handlePanDrag) { onPanDrag(e2); } - view.startMonitoringRegion(); return false; } }); @@ -182,16 +179,39 @@ public void onMapReady(final GoogleMap map) { this.map = map; this.map.setInfoWindowAdapter(this); this.map.setOnMarkerDragListener(this); + this.map.setOnPoiClickListener(this); manager.pushEvent(context, this, "onMapReady", new WritableNativeMap()); final AirMapView view = this; + map.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() { + @Override + public void onMyLocationChange(Location location){ + WritableMap event = new WritableNativeMap(); + + WritableMap coordinate = new WritableNativeMap(); + coordinate.putDouble("latitude", location.getLatitude()); + coordinate.putDouble("longitude", location.getLongitude()); + coordinate.putDouble("altitude", location.getAltitude()); + coordinate.putDouble("timestamp", location.getTime()); + coordinate.putDouble("accuracy", location.getAccuracy()); + coordinate.putDouble("speed", location.getSpeed()); + if(android.os.Build.VERSION.SDK_INT >= 18){ + coordinate.putBoolean("isFromMockProvider", location.isFromMockProvider()); + } + + event.putMap("coordinate", coordinate); + + manager.pushEvent(context, view, "onUserLocationChange", event); + } + }); + map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { WritableMap event; - AirMapMarker airMapMarker = markerMap.get(marker); + AirMapMarker airMapMarker = getMarkerMap(marker); event = makeClickEventData(marker.getPosition()); event.putString("action", "marker-press"); @@ -201,7 +221,7 @@ public boolean onMarkerClick(Marker marker) { event = makeClickEventData(marker.getPosition()); event.putString("action", "marker-press"); event.putString("id", airMapMarker.getIdentifier()); - manager.pushEvent(context, markerMap.get(marker), "onPress", event); + manager.pushEvent(context, airMapMarker, "onPress", event); // Return false to open the callout info window and center on the marker // https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap @@ -244,7 +264,7 @@ public void onInfoWindowClick(Marker marker) { event = makeClickEventData(marker.getPosition()); event.putString("action", "callout-press"); - AirMapMarker markerView = markerMap.get(marker); + AirMapMarker markerView = getMarkerMap(marker); manager.pushEvent(context, markerView, "onCalloutPress", event); event = makeClickEventData(marker.getPosition()); @@ -272,14 +292,32 @@ public void onMapLongClick(LatLng point) { } }); - map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { + map.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() { + @Override + public void onCameraMoveStarted(int reason) { + cameraMoveReason = reason; + } + }); + + map.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() { @Override - public void onCameraChange(CameraPosition position) { + public void onCameraMove() { LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; - LatLng center = position.target; - lastBoundsEmitted = bounds; - eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, isTouchDown)); - view.stopMonitoringRegion(); + cameraLastIdleBounds = null; + eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, true)); + } + }); + + map.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() { + @Override + public void onCameraIdle() { + LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; + if ((cameraMoveReason != 0) && + ((cameraLastIdleBounds == null) || + LatLngBoundsUtils.BoundsAreDifferent(bounds, cameraLastIdleBounds))) { + cameraLastIdleBounds = bounds; + eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, false)); + } } }); @@ -401,13 +439,13 @@ public void setShowsUserLocation(boolean showUserLocation) { } public void setShowsMyLocationButton(boolean showMyLocationButton) { - if (hasPermissions()) { + if (hasPermissions() || !showMyLocationButton) { map.getUiSettings().setMyLocationButtonEnabled(showMyLocationButton); } } public void setToolbarEnabled(boolean toolbarEnabled) { - if (hasPermissions()) { + if (hasPermissions() || !toolbarEnabled) { map.getUiSettings().setMapToolbarEnabled(toolbarEnabled); } } @@ -501,11 +539,21 @@ public void addFeature(View child, int index) { AirMapUrlTile urlTileView = (AirMapUrlTile) child; urlTileView.addToMap(map); features.add(index, urlTileView); - } else { + } else if (child instanceof AirMapLocalTile) { + AirMapLocalTile localTileView = (AirMapLocalTile) child; + localTileView.addToMap(map); + features.add(index, localTileView); + } else if (child instanceof AirMapOverlay) { + AirMapOverlay overlayView = (AirMapOverlay) child; + overlayView.addToMap(map); + features.add(index, overlayView); + } else if (child instanceof ViewGroup) { ViewGroup children = (ViewGroup) child; for (int i = 0; i < children.getChildCount(); i++) { addFeature(children.getChildAt(i), index); } + } else { + addView(child, index); } } @@ -564,41 +612,46 @@ public void updateExtraData(Object extraData) { } } + public void animateToNavigation(LatLng location, float bearing, float angle, int duration) { + if (map == null) return; + CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) + .bearing(bearing) + .tilt(angle) + .target(location) + .build(); + map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); + } + public void animateToRegion(LatLngBounds bounds, int duration) { - if (map != null) { - startMonitoringRegion(); - map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null); - } + if (map == null) return; + map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null); } public void animateToViewingAngle(float angle, int duration) { - if (map != null) { - startMonitoringRegion(); - CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) - .tilt(angle) - .build(); - map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); - } + if (map == null) return; + + CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) + .tilt(angle) + .build(); + map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); } public void animateToBearing(float bearing, int duration) { - if (map != null) { - startMonitoringRegion(); - CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) - .bearing(bearing) - .build(); - map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); - } + if (map == null) return; + CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) + .bearing(bearing) + .build(); + map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); } public void animateToCoordinate(LatLng coordinate, int duration) { - if (map != null) { - startMonitoringRegion(); - map.animateCamera(CameraUpdateFactory.newLatLng(coordinate), duration, null); - } + if (map == null) return; + map.animateCamera(CameraUpdateFactory.newLatLng(coordinate), duration, null); } public void fitToElements(boolean animated) { + if (map == null) return; + LatLngBounds.Builder builder = new LatLngBounds.Builder(); boolean addedPosition = false; @@ -615,7 +668,6 @@ public void fitToElements(boolean animated) { LatLngBounds bounds = builder.build(); CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); if (animated) { - startMonitoringRegion(); map.animateCamera(cu); } else { map.moveCamera(cu); @@ -624,6 +676,8 @@ public void fitToElements(boolean animated) { } public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated) { + if (map == null) return; + LatLngBounds.Builder builder = new LatLngBounds.Builder(); String[] markerIDs = new String[markerIDsArray.size()]; @@ -650,7 +704,6 @@ public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated) LatLngBounds bounds = builder.build(); CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); if (animated) { - startMonitoringRegion(); map.animateCamera(cu); } else { map.moveCamera(cu); @@ -660,6 +713,8 @@ public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated) public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePadding, boolean animated) { + if (map == null) return; + LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (int i = 0; i < coordinatesArray.size(); i++) { @@ -678,7 +733,6 @@ public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePad } if (animated) { - startMonitoringRegion(); map.animateCamera(cu); } else { map.moveCamera(cu); @@ -687,23 +741,40 @@ public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePad 0); // Without this, the Google logo is moved up by the value of edgePadding.bottom } + public void setMapBoundaries(ReadableMap northEast, ReadableMap southWest) { + if (map == null) return; + + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + + Double latNE = northEast.getDouble("latitude"); + Double lngNE = northEast.getDouble("longitude"); + builder.include(new LatLng(latNE, lngNE)); + + Double latSW = southWest.getDouble("latitude"); + Double lngSW = southWest.getDouble("longitude"); + builder.include(new LatLng(latSW, lngSW)); + + LatLngBounds bounds = builder.build(); + + map.setLatLngBoundsForCameraTarget(bounds); + } + // InfoWindowAdapter interface @Override public View getInfoWindow(Marker marker) { - AirMapMarker markerView = markerMap.get(marker); + AirMapMarker markerView = getMarkerMap(marker); return markerView.getCallout(); } @Override public View getInfoContents(Marker marker) { - AirMapMarker markerView = markerMap.get(marker); + AirMapMarker markerView = getMarkerMap(marker); return markerView.getInfoContents(); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { - scaleDetector.onTouchEvent(ev); gestureDetector.onTouchEvent(ev); int action = MotionEventCompat.getActionMasked(ev); @@ -712,67 +783,22 @@ public boolean dispatchTouchEvent(MotionEvent ev) { case (MotionEvent.ACTION_DOWN): this.getParent().requestDisallowInterceptTouchEvent( map != null && map.getUiSettings().isScrollGesturesEnabled()); - isTouchDown = true; - break; - case (MotionEvent.ACTION_MOVE): - startMonitoringRegion(); break; case (MotionEvent.ACTION_UP): // Clear this regardless, since isScrollGesturesEnabled() may have been updated this.getParent().requestDisallowInterceptTouchEvent(false); - isTouchDown = false; break; } super.dispatchTouchEvent(ev); return true; } - // Timer Implementation - - public void startMonitoringRegion() { - if (map == null || isMonitoringRegion) return; - timerHandler.postDelayed(timerRunnable, 100); - isMonitoringRegion = true; - } - - public void stopMonitoringRegion() { - if (map == null || !isMonitoringRegion) return; - timerHandler.removeCallbacks(timerRunnable); - isMonitoringRegion = false; - } - - private LatLngBounds lastBoundsEmitted; - - Handler timerHandler = new Handler(); - Runnable timerRunnable = new Runnable() { - - @Override - public void run() { - - if (map != null) { - Projection projection = map.getProjection(); - VisibleRegion region = (projection != null) ? projection.getVisibleRegion() : null; - LatLngBounds bounds = (region != null) ? region.latLngBounds : null; - - if ((bounds != null) && - (lastBoundsEmitted == null || - LatLngBoundsUtils.BoundsAreDifferent(bounds, lastBoundsEmitted))) { - LatLng center = map.getCameraPosition().target; - lastBoundsEmitted = bounds; - eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, true)); - } - } - - timerHandler.postDelayed(this, 100); - } - }; - @Override public void onMarkerDragStart(Marker marker) { WritableMap event = makeClickEventData(marker.getPosition()); manager.pushEvent(context, this, "onMarkerDragStart", event); - AirMapMarker markerView = markerMap.get(marker); + AirMapMarker markerView = getMarkerMap(marker); event = makeClickEventData(marker.getPosition()); manager.pushEvent(context, markerView, "onDragStart", event); } @@ -782,7 +808,7 @@ public void onMarkerDrag(Marker marker) { WritableMap event = makeClickEventData(marker.getPosition()); manager.pushEvent(context, this, "onMarkerDrag", event); - AirMapMarker markerView = markerMap.get(marker); + AirMapMarker markerView = getMarkerMap(marker); event = makeClickEventData(marker.getPosition()); manager.pushEvent(context, markerView, "onDrag", event); } @@ -792,11 +818,21 @@ public void onMarkerDragEnd(Marker marker) { WritableMap event = makeClickEventData(marker.getPosition()); manager.pushEvent(context, this, "onMarkerDragEnd", event); - AirMapMarker markerView = markerMap.get(marker); + AirMapMarker markerView = getMarkerMap(marker); event = makeClickEventData(marker.getPosition()); manager.pushEvent(context, markerView, "onDragEnd", event); } + @Override + public void onPoiClick(PointOfInterest poi) { + WritableMap event = makeClickEventData(poi.latLng); + + event.putString("placeId", poi.placeId); + event.putString("name", poi.name); + + manager.pushEvent(context, this, "onPoiClick", event); + } + private ProgressBar getMapLoadingProgressBar() { if (this.mapLoadingProgressBar == null) { this.mapLoadingProgressBar = new ProgressBar(getContext()); @@ -889,4 +925,118 @@ public void onPanDrag(MotionEvent ev) { WritableMap event = makeClickEventData(coords); manager.pushEvent(context, this, "onPanDrag", event); } + + public void setKmlSrc(String kmlSrc) { + try { + InputStream kmlStream = new FileUtil(context).execute(kmlSrc).get(); + + if (kmlStream == null) { + return; + } + + kmlLayer = new KmlLayer(map, kmlStream, context); + kmlLayer.addLayerToMap(); + + WritableMap pointers = new WritableNativeMap(); + WritableArray markers = new WritableNativeArray(); + + if (kmlLayer.getContainers() == null) { + manager.pushEvent(context, this, "onKmlReady", pointers); + return; + } + + //Retrieve a nested container within the first container + KmlContainer container = kmlLayer.getContainers().iterator().next(); + if (container == null || container.getContainers() == null) { + manager.pushEvent(context, this, "onKmlReady", pointers); + return; + } + + + if (container.getContainers().iterator().hasNext()) { + container = container.getContainers().iterator().next(); + } + + Integer index = 0; + for (KmlPlacemark placemark : container.getPlacemarks()) { + MarkerOptions options = new MarkerOptions(); + + if (placemark.getInlineStyle() != null) { + options = placemark.getMarkerOptions(); + } else { + options.icon(BitmapDescriptorFactory.defaultMarker()); + } + + LatLng latLng = ((LatLng) placemark.getGeometry().getGeometryObject()); + String title = ""; + String snippet = ""; + + if (placemark.hasProperty("name")) { + title = placemark.getProperty("name"); + } + + if (placemark.hasProperty("description")) { + snippet = placemark.getProperty("description"); + } + + options.position(latLng); + options.title(title); + options.snippet(snippet); + + AirMapMarker marker = new AirMapMarker(context, options); + + if (placemark.getInlineStyle() != null + && placemark.getInlineStyle().getIconUrl() != null) { + marker.setImage(placemark.getInlineStyle().getIconUrl()); + } else if (container.getStyle(placemark.getStyleId()) != null) { + KmlStyle style = container.getStyle(placemark.getStyleId()); + marker.setImage(style.getIconUrl()); + } + + String identifier = title + " - " + index; + + marker.setIdentifier(identifier); + + addFeature(marker, index++); + + WritableMap loadedMarker = makeClickEventData(latLng); + loadedMarker.putString("id", identifier); + loadedMarker.putString("title", title); + loadedMarker.putString("description", snippet); + + markers.pushMap(loadedMarker); + } + + pointers.putArray("markers", markers); + + manager.pushEvent(context, this, "onKmlReady", pointers); + + } catch (XmlPullParserException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + + private AirMapMarker getMarkerMap(Marker marker) { + AirMapMarker airMarker = markerMap.get(marker); + + if (airMarker != null) { + return airMarker; + } + + for (Map.Entry entryMarker : markerMap.entrySet()) { + if (entryMarker.getKey().getPosition().equals(marker.getPosition()) + && entryMarker.getKey().getTitle().equals(marker.getTitle())) { + airMarker = entryMarker.getValue(); + break; + } + } + + return airMarker; + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/FileUtil.java b/lib/android/src/main/java/com/airbnb/android/react/maps/FileUtil.java new file mode 100644 index 0000000000..5fb1aa0abb --- /dev/null +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/FileUtil.java @@ -0,0 +1,77 @@ +package com.airbnb.android.react.maps; + +import android.content.Context; +import android.net.Uri; +import android.os.AsyncTask; + +import com.facebook.common.logging.FLog; +import com.facebook.react.common.ReactConstants; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; + +public class FileUtil extends AsyncTask { + + private final String NAME = "FileUtil"; + private final String TEMP_FILE_SUFFIX = "temp"; + + private Exception exception; + private Context context; + + public FileUtil(Context context) { + super(); + + this.context = context; + } + + protected InputStream doInBackground(String... urls) { + try { + Uri fileContentUri = Uri.parse(urls[0]); + + if (fileContentUri.getScheme().startsWith("http")) { + return getDownloadFileInputStream(context, fileContentUri); + } + return context.getContentResolver().openInputStream(fileContentUri); + } catch (Exception e) { + this.exception = e; + FLog.e( + ReactConstants.TAG, + "Could not retrieve file for contentUri " + urls[0], + e); + return null; + } + } + + private InputStream getDownloadFileInputStream(Context context, Uri uri) + throws IOException { + final File outputDir = context.getApplicationContext().getCacheDir(); + final File file = File.createTempFile(NAME, TEMP_FILE_SUFFIX, outputDir); + file.deleteOnExit(); + + final URL url = new URL(uri.toString()); + final InputStream is = url.openStream(); + try { + final ReadableByteChannel channel = Channels.newChannel(is); + try { + final FileOutputStream stream = new FileOutputStream(file); + try { + stream.getChannel().transferFrom(channel, 0, Long.MAX_VALUE); + return new FileInputStream(file); + } finally { + stream.close(); + } + } finally { + channel.close(); + } + } finally { + is.close(); + } + } + +} diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/ImageReadable.java b/lib/android/src/main/java/com/airbnb/android/react/maps/ImageReadable.java new file mode 100644 index 0000000000..640053262f --- /dev/null +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/ImageReadable.java @@ -0,0 +1,15 @@ +package com.airbnb.android.react.maps; + + +import android.graphics.Bitmap; + +import com.google.android.gms.maps.model.BitmapDescriptor; + +public interface ImageReadable { + + public void setIconBitmap(Bitmap bitmap); + + public void setIconBitmapDescriptor(BitmapDescriptor bitmapDescriptor); + + public void update(); +} diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/ImageReader.java b/lib/android/src/main/java/com/airbnb/android/react/maps/ImageReader.java new file mode 100644 index 0000000000..c01866d80d --- /dev/null +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/ImageReader.java @@ -0,0 +1,129 @@ +package com.airbnb.android.react.maps; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.Animatable; +import android.net.Uri; + +import com.facebook.common.references.CloseableReference; +import com.facebook.datasource.DataSource; +import com.facebook.drawee.backends.pipeline.Fresco; +import com.facebook.drawee.controller.BaseControllerListener; +import com.facebook.drawee.controller.ControllerListener; +import com.facebook.drawee.drawable.ScalingUtils; +import com.facebook.drawee.generic.GenericDraweeHierarchy; +import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder; +import com.facebook.drawee.interfaces.DraweeController; +import com.facebook.drawee.view.DraweeHolder; +import com.facebook.imagepipeline.core.ImagePipeline; +import com.facebook.imagepipeline.image.CloseableImage; +import com.facebook.imagepipeline.image.CloseableStaticBitmap; +import com.facebook.imagepipeline.image.ImageInfo; +import com.facebook.imagepipeline.request.ImageRequest; +import com.facebook.imagepipeline.request.ImageRequestBuilder; +import com.google.android.gms.maps.model.BitmapDescriptor; +import com.google.android.gms.maps.model.BitmapDescriptorFactory; + +import javax.annotation.Nullable; + +public class ImageReader { + + private final ImageReadable imp; + private final Context context; + private final Resources resources; + + private final DraweeHolder logoHolder; + private DataSource> dataSource; + + private final ControllerListener mLogoControllerListener = + new BaseControllerListener() { + @Override + public void onFinalImageSet( + String id, + @Nullable final ImageInfo imageInfo, + @Nullable Animatable animatable) { + CloseableReference imageReference = null; + try { + imageReference = dataSource.getResult(); + if (imageReference != null) { + CloseableImage image = imageReference.get(); + if (image != null && image instanceof CloseableStaticBitmap) { + CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) image; + Bitmap bitmap = closeableStaticBitmap.getUnderlyingBitmap(); + if (bitmap != null) { + bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); + imp.setIconBitmap(bitmap); + imp.setIconBitmapDescriptor(BitmapDescriptorFactory.fromBitmap(bitmap)); + } + } + } + } finally { + dataSource.close(); + if (imageReference != null) { + CloseableReference.closeSafely(imageReference); + } + } + imp.update(); + } + }; + + public ImageReader(Context context, Resources resources, ImageReadable imp) { + this.context = context; + this.resources = resources; + this.imp = imp; + logoHolder = DraweeHolder.create(createDraweeHeirarchy(resources), context); + logoHolder.onAttach(); + } + + private GenericDraweeHierarchy createDraweeHeirarchy(Resources resources){ + return new GenericDraweeHierarchyBuilder(resources) + .setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER) + .setFadeDuration(0) + .build(); + } + + public void setImage(String uri) { + if (uri == null) { + imp.setIconBitmapDescriptor(null); + imp.update(); + } else if (uri.startsWith("http://") || uri.startsWith("https://") || + uri.startsWith("file://") || uri.startsWith("asset://")) { + ImageRequest imageRequest = ImageRequestBuilder + .newBuilderWithSource(Uri.parse(uri)) + .build(); + ImagePipeline imagePipeline = Fresco.getImagePipeline(); + dataSource = imagePipeline.fetchDecodedImage(imageRequest, this); + + DraweeController controller = Fresco.newDraweeControllerBuilder() + .setImageRequest(imageRequest) + .setControllerListener(mLogoControllerListener) + .setOldController(logoHolder.getController()) + .build(); + logoHolder.setController(controller); + } else { + BitmapDescriptor iconBitmapDescriptor = getBitmapDescriptorByName(uri); + if (iconBitmapDescriptor != null) { + imp.setIconBitmapDescriptor(iconBitmapDescriptor); + imp.setIconBitmap(BitmapFactory.decodeResource(this.resources, getDrawableResourceByName + (uri))); + } + imp.update(); + } + + + } + + private int getDrawableResourceByName(String name) { + return this.resources.getIdentifier( + name, + "drawable", + this.context.getPackageName()); + } + + private BitmapDescriptor getBitmapDescriptorByName(String name) { + return BitmapDescriptorFactory.fromResource(getDrawableResourceByName(name)); + } + +} diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/ImageUtil.java b/lib/android/src/main/java/com/airbnb/android/react/maps/ImageUtil.java new file mode 100644 index 0000000000..35078a905b --- /dev/null +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/ImageUtil.java @@ -0,0 +1,27 @@ +package com.airbnb.android.react.maps; + + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Base64; + +import java.io.ByteArrayOutputStream; + +public class ImageUtil { + public static Bitmap convert(String base64Str) throws IllegalArgumentException { + byte[] decodedBytes = Base64.decode( + base64Str.substring(base64Str.indexOf(",") + 1), + Base64.DEFAULT + ); + + return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length); + } + + public static String convert(Bitmap bitmap) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); + + return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT); + } + +} \ No newline at end of file diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java b/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java index 6ecc551658..45364b3bef 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java @@ -38,7 +38,9 @@ public List createViewManagers(ReactApplicationContext reactContext AirMapCircleManager circleManager = new AirMapCircleManager(reactContext); AirMapManager mapManager = new AirMapManager(reactContext); AirMapLiteManager mapLiteManager = new AirMapLiteManager(reactContext); - AirMapUrlTileManager tileManager = new AirMapUrlTileManager(reactContext); + AirMapUrlTileManager urlTileManager = new AirMapUrlTileManager(reactContext); + AirMapLocalTileManager localTileManager = new AirMapLocalTileManager(reactContext); + AirMapOverlayManager overlayManager = new AirMapOverlayManager(reactContext); return Arrays.asList( calloutManager, @@ -48,6 +50,9 @@ public List createViewManagers(ReactApplicationContext reactContext circleManager, mapManager, mapLiteManager, - tileManager); + urlTileManager, + localTileManager, + overlayManager + ); } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java b/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java index 43b1f678e6..675eb41065 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java @@ -9,13 +9,11 @@ public class RegionChangeEvent extends Event { private final LatLngBounds bounds; - private final LatLng center; private final boolean continuous; - public RegionChangeEvent(int id, LatLngBounds bounds, LatLng center, boolean continuous) { + public RegionChangeEvent(int id, LatLngBounds bounds, boolean continuous) { super(id); this.bounds = bounds; - this.center = center; this.continuous = continuous; } @@ -36,6 +34,7 @@ public void dispatch(RCTEventEmitter rctEventEmitter) { event.putBoolean("continuous", continuous); WritableMap region = new WritableNativeMap(); + LatLng center = bounds.getCenter(); region.putDouble("latitude", center.latitude); region.putDouble("longitude", center.longitude); region.putDouble("latitudeDelta", bounds.northeast.latitude - bounds.southwest.latitude); diff --git a/lib/components/MapCallout.js b/lib/components/MapCallout.js index 226b52fe2d..5d677e27c2 100644 --- a/lib/components/MapCallout.js +++ b/lib/components/MapCallout.js @@ -3,14 +3,18 @@ import React from 'react'; import { StyleSheet, ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { SUPPORTED, USES_DEFAULT_IMPLEMENTATION, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, tooltip: PropTypes.bool, onPress: PropTypes.func, }; @@ -35,7 +39,7 @@ const styles = StyleSheet.create({ }, }); -module.exports = decorateMapComponent(MapCallout, { +export default decorateMapComponent(MapCallout, { componentType: 'Callout', providers: { google: { diff --git a/lib/components/MapCircle.js b/lib/components/MapCircle.js index acf066b248..556f54d4fb 100644 --- a/lib/components/MapCircle.js +++ b/lib/components/MapCircle.js @@ -1,15 +1,20 @@ import PropTypes from 'prop-types'; import React from 'react'; import { + ColorPropType, ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { USES_DEFAULT_IMPLEMENTATION, SUPPORTED, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, /** * The coordinate of the center of the circle @@ -40,12 +45,12 @@ const propTypes = { /** * The stroke color to use for the path. */ - strokeColor: PropTypes.string, + strokeColor: ColorPropType, /** * The fill color to use for the path. */ - fillColor: PropTypes.string, + fillColor: ColorPropType, /** * The order in which this tile overlay is drawn with respect to other overlays. An overlay @@ -141,7 +146,7 @@ class MapCircle extends React.Component { MapCircle.propTypes = propTypes; MapCircle.defaultProps = defaultProps; -module.exports = decorateMapComponent(MapCircle, { +export default decorateMapComponent(MapCircle, { componentType: 'Circle', providers: { google: { diff --git a/lib/components/MapLocalTile.js b/lib/components/MapLocalTile.js new file mode 100644 index 0000000000..8548c6592d --- /dev/null +++ b/lib/components/MapLocalTile.js @@ -0,0 +1,63 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +import { + ViewPropTypes, + View, +} from 'react-native'; + +import decorateMapComponent, { + USES_DEFAULT_IMPLEMENTATION, + SUPPORTED, +} from './decorateMapComponent'; + +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + +const propTypes = { + ...viewPropTypes, + + /** + * The path template of the local tile source. + * The patterns {x} {y} {z} will be replaced at runtime, + * for example, /storage/emulated/0/tiles/{z}/{x}/{y}.png. + */ + pathTemplate: PropTypes.string.isRequired, + + /** + * The order in which this tile overlay is drawn with respect to other overlays. An overlay + * with a larger z-index is drawn over overlays with smaller z-indices. The order of overlays + * with the same z-index is arbitrary. The default zIndex is -1. + * + * @platform android + */ + zIndex: PropTypes.number, + + /** + * Size of tile images. + */ + tileSize: PropTypes.number, +}; + +class MapLocalTile extends React.Component { + render() { + const AIRMapLocalTile = this.getAirComponent(); + return ( + + ); + } +} + +MapLocalTile.propTypes = propTypes; + +export default decorateMapComponent(MapLocalTile, { + componentType: 'LocalTile', + providers: { + google: { + ios: SUPPORTED, + android: USES_DEFAULT_IMPLEMENTATION, + }, + }, +}); diff --git a/lib/components/MapMarker.js b/lib/components/MapMarker.js index 2dc4677063..5999208ac4 100644 --- a/lib/components/MapMarker.js +++ b/lib/components/MapMarker.js @@ -1,12 +1,14 @@ import PropTypes from 'prop-types'; import React from 'react'; import { + ColorPropType, StyleSheet, Platform, NativeModules, Animated, findNodeHandle, ViewPropTypes, + View, } from 'react-native'; import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; @@ -22,8 +24,11 @@ const viewConfig = { }, }; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, // TODO(lmr): get rid of these? identifier: PropTypes.string, @@ -31,14 +36,14 @@ const propTypes = { /** * The title of the marker. This is only used if the component has no children that - * are an ``, in which case the default callout behavior will be used, which + * are a ``, in which case the default callout behavior will be used, which * will show both the `title` and the `description`, if provided. */ title: PropTypes.string, /** * The description of the marker. This is only used if the component has no children - * that are an ``, in which case the default callout behavior will be used, + * that are a ``, in which case the default callout behavior will be used, * which will show both the `title` and the `description`, if provided. */ description: PropTypes.string, @@ -58,7 +63,7 @@ const propTypes = { * If no custom marker view or custom image is provided, the platform default pin will be used, * which can be customized by this color. Ignored if a custom marker is being used. */ - pinColor: PropTypes.string, + pinColor: ColorPropType, /** * The coordinate for the marker. @@ -165,6 +170,30 @@ const propTypes = { draggable: PropTypes.bool, + /** + * Sets whether this marker should track view changes true. + * + * @platform ios + */ + + tracksViewChanges: PropTypes.bool, + + /** + * Sets whether this marker should track view changes in info window true. + * + * @platform ios + */ + + tracksInfoWindowChanges: PropTypes.bool, + + /** + * Stops Marker onPress events from propagating to and triggering MapView onPress events. + * + * @platform ios + */ + + stopPropagation: PropTypes.bool, + /** * Callback that is called when the user presses on the marker */ @@ -207,7 +236,7 @@ const propTypes = { }; const defaultProps = { - onPress() {}, + stopPropagation: false, }; class MapMarker extends React.Component { @@ -216,6 +245,7 @@ class MapMarker extends React.Component { this.showCallout = this.showCallout.bind(this); this.hideCallout = this.hideCallout.bind(this); + this.animateMarkerToCoordinate = this.animateMarkerToCoordinate.bind(this); } setNativeProps(props) { @@ -238,6 +268,10 @@ class MapMarker extends React.Component { } } + animateMarkerToCoordinate(coordinate, duration) { + this._runCommand('animateMarkerToCoordinate', [coordinate, duration || 500]); + } + _getHandle() { return findNodeHandle(this.marker); } @@ -272,10 +306,20 @@ class MapMarker extends React.Component { return ( { this.marker = ref; }} + ref={ref => { + this.marker = ref; + }} {...this.props} image={image} style={[styles.marker, this.props.style]} + onPress={event => { + if (this.props.stopPropagation) { + event.stopPropagation(); + } + if (this.props.onPress) { + this.props.onPress(event); + } + }} /> ); } @@ -294,7 +338,7 @@ const styles = StyleSheet.create({ MapMarker.Animated = Animated.createAnimatedComponent(MapMarker); -module.exports = decorateMapComponent(MapMarker, { +export default decorateMapComponent(MapMarker, { componentType: 'Marker', providers: { google: { diff --git a/lib/components/MapOverlay.js b/lib/components/MapOverlay.js new file mode 100644 index 0000000000..364f055176 --- /dev/null +++ b/lib/components/MapOverlay.js @@ -0,0 +1,76 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { + View, + StyleSheet, + Animated, +} from 'react-native'; + +import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; +import decorateMapComponent, { + SUPPORTED, + USES_DEFAULT_IMPLEMENTATION, +} from './decorateMapComponent'; + +const viewConfig = { + uiViewClassName: 'AIRMapOverlay', + validAttributes: { + image: true, + }, +}; + +const propTypes = { + ...View.propTypes, + // A custom image to be used as overlay. + image: PropTypes.any.isRequired, + // Top left and bottom right coordinates for the overlay + bounds: PropTypes.arrayOf(PropTypes.array.isRequired).isRequired, +}; + +class MapOverlay extends Component { + + render() { + let image; + if (this.props.image) { + if (typeof this.props.image.startsWith === 'function' + && this.props.image.startsWith('http')) { + image = this.props.image; + } else { + image = resolveAssetSource(this.props.image) || {}; + image = image.uri; + } + } + + const AIRMapOverlay = this.getAirComponent(); + + return ( + + ); + } +} + +MapOverlay.propTypes = propTypes; +MapOverlay.viewConfig = viewConfig; + +const styles = StyleSheet.create({ + overlay: { + position: 'absolute', + backgroundColor: 'transparent', + }, +}); + +MapOverlay.Animated = Animated.createAnimatedComponent(MapOverlay); + +export default decorateMapComponent(MapOverlay, { + componentType: 'Overlay', + providers: { + google: { + ios: SUPPORTED, + android: USES_DEFAULT_IMPLEMENTATION, + }, + }, +}); diff --git a/lib/components/MapPolygon.js b/lib/components/MapPolygon.js index 27f2aa322a..369cf2c444 100644 --- a/lib/components/MapPolygon.js +++ b/lib/components/MapPolygon.js @@ -1,15 +1,20 @@ import PropTypes from 'prop-types'; import React from 'react'; import { + ColorPropType, ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { USES_DEFAULT_IMPLEMENTATION, SUPPORTED, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, /** * An array of coordinates to describe the polygon @@ -52,12 +57,12 @@ const propTypes = { /** * The stroke color to use for the path. */ - strokeColor: PropTypes.string, + strokeColor: ColorPropType, /** * The fill color to use for the path. */ - fillColor: PropTypes.string, + fillColor: ColorPropType, /** * The order in which this tile overlay is drawn with respect to other overlays. An overlay @@ -162,7 +167,7 @@ class MapPolygon extends React.Component { MapPolygon.propTypes = propTypes; MapPolygon.defaultProps = defaultProps; -module.exports = decorateMapComponent(MapPolygon, { +export default decorateMapComponent(MapPolygon, { componentType: 'Polygon', providers: { google: { diff --git a/lib/components/MapPolyline.js b/lib/components/MapPolyline.js index af1573eff4..14289a3e35 100644 --- a/lib/components/MapPolyline.js +++ b/lib/components/MapPolyline.js @@ -1,15 +1,20 @@ import PropTypes from 'prop-types'; import React from 'react'; import { + ColorPropType, ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { USES_DEFAULT_IMPLEMENTATION, SUPPORTED, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, /** * An array of coordinates to describe the polygon @@ -35,7 +40,7 @@ const propTypes = { /** * The fill color to use for the path. */ - fillColor: PropTypes.string, + fillColor: ColorPropType, /** * The stroke width to use for the path. @@ -45,7 +50,12 @@ const propTypes = { /** * The stroke color to use for the path. */ - strokeColor: PropTypes.string, + strokeColor: ColorPropType, + + /** + * The stroke colors to use for the path. + */ + strokeColors: PropTypes.arrayOf(ColorPropType), /** * The order in which this tile overlay is drawn with respect to other overlays. An overlay @@ -133,6 +143,8 @@ const propTypes = { const defaultProps = { strokeColor: '#000', strokeWidth: 1, + lineJoin: 'round', + lineCap: 'round', }; class MapPolyline extends React.Component { @@ -151,7 +163,7 @@ class MapPolyline extends React.Component { MapPolyline.propTypes = propTypes; MapPolyline.defaultProps = defaultProps; -module.exports = decorateMapComponent(MapPolyline, { +export default decorateMapComponent(MapPolyline, { componentType: 'Polyline', providers: { google: { diff --git a/lib/components/MapUrlTile.js b/lib/components/MapUrlTile.js index f61c1e0d36..babe6555c4 100644 --- a/lib/components/MapUrlTile.js +++ b/lib/components/MapUrlTile.js @@ -3,6 +3,7 @@ import React from 'react'; import { ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { @@ -10,8 +11,11 @@ import decorateMapComponent, { SUPPORTED, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, /** * The url template of the tile server. The patterns {x} {y} {z} will be replaced at runtime @@ -27,6 +31,24 @@ const propTypes = { * @platform android */ zIndex: PropTypes.number, + /** + * The maximum zoom level for this tile overlay. + * + */ + maximumZ: PropTypes.number, + + /** + * The minimum zoom level for this tile overlay. + * + */ + minimumZ: PropTypes.number, + + /** + * Corresponds to MKTileOverlay canReplaceMapContent. + * + * @platform ios + */ + shouldReplaceMapContent: PropTypes.bool, }; class MapUrlTile extends React.Component { @@ -42,7 +64,7 @@ class MapUrlTile extends React.Component { MapUrlTile.propTypes = propTypes; -module.exports = decorateMapComponent(MapUrlTile, { +export default decorateMapComponent(MapUrlTile, { componentType: 'UrlTile', providers: { google: { diff --git a/lib/components/MapView.js b/lib/components/MapView.js index 123d34f60f..50c4d26571 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -3,20 +3,22 @@ import React from 'react'; import { EdgeInsetsPropType, Platform, - Animated, + Animated as RNAnimated, requireNativeComponent, NativeModules, ColorPropType, findNodeHandle, - View, ViewPropTypes, + View, } from 'react-native'; import MapMarker from './MapMarker'; import MapPolyline from './MapPolyline'; import MapPolygon from './MapPolygon'; import MapCircle from './MapCircle'; import MapCallout from './MapCallout'; +import MapOverlay from './MapOverlay'; import MapUrlTile from './MapUrlTile'; +import MapLocalTile from './MapLocalTile'; import AnimatedRegion from './AnimatedRegion'; import { contextTypes as childContextTypes, @@ -26,12 +28,13 @@ import { } from './decorateMapComponent'; import * as ProviderConstants from './ProviderConstants'; -const MAP_TYPES = { +export const MAP_TYPES = { STANDARD: 'standard', SATELLITE: 'satellite', HYBRID: 'hybrid', TERRAIN: 'terrain', NONE: 'none', + MUTEDSTANDARD: 'mutedStandard', }; const GOOGLE_MAPS_ONLY_TYPES = [ @@ -87,7 +90,9 @@ const propTypes = { * * **NOTE**: You need to add NSLocationWhenInUseUsageDescription key in * Info.plist to enable geolocation, otherwise it is going - * to *fail silently*! + * to *fail silently*! You will also need to add an explanation for why + * you need the users location against `NSLocationWhenInUseUsageDescription` in Info.plist. + * Otherwise Apple may reject your app submission. */ showsUserLocation: PropTypes.bool, @@ -140,6 +145,14 @@ const propTypes = { zoomEnabled: PropTypes.bool, /** + *If `false` the user won't be able to zoom the map + * Default value is `true`. + * + *@platform android + */ + zoomControlEnabled: PropTypes.bool, + + /** * If `false` the user won't be able to pinch/rotate the map. * Default value is `true`. * @@ -302,6 +315,24 @@ const propTypes = { */ liteMode: PropTypes.bool, + /** + * (Google Maps only) + * + * Padding that is used by the Google Map View to position + * the camera, legal labels and buttons + * + */ + mapPadding: EdgeInsetsPropType, + + /** + * (Google Maps only, iOS) + * + * Whether the safe area padding is added to the Google Map View padding. + * This affects where markers, compass, Google logo etc. are placed on the view. + * + */ + paddingAdjustmentBehavior: PropTypes.oneOf(['always', 'automatic', 'never']), + /** * Maximum size of area that can be displayed. * @@ -327,6 +358,11 @@ const propTypes = { */ onMapReady: PropTypes.func, + /** + * Callback that is called once the kml is fully loaded. + */ + onKmlReady: PropTypes.func, + /** * Callback that is called continuously when the user is dragging the map. */ @@ -347,11 +383,21 @@ const propTypes = { */ onLongPress: PropTypes.func, + /** + * Callback that is called when the underlying map figures our users current location. + */ + onUserLocationChange: PropTypes.func, + /** * Callback that is called when user makes a "drag" somewhere on the map */ onPanDrag: PropTypes.func, + /** + * Callback that is called when user click on a POI + */ + onPoiClick: PropTypes.func, + /** * Callback that is called when a marker on the map is tapped by the user. */ @@ -404,6 +450,11 @@ const propTypes = { */ maxZoomLevel: PropTypes.number, + /** + * Url KML Source + */ + kmlSrc: PropTypes.string, + }; class MapView extends React.Component { @@ -415,6 +466,7 @@ class MapView extends React.Component { }; this._onMapReady = this._onMapReady.bind(this); + this._onMarkerPress = this._onMarkerPress.bind(this); this._onChange = this._onChange.bind(this); this._onLayout = this._onLayout.bind(this); } @@ -480,6 +532,12 @@ class MapView extends React.Component { } } + _onMarkerPress(event) { + if (this.props.onMarkerPress) { + this.props.onMarkerPress(event.nativeEvent); + } + } + _onChange(event) { this.__lastRegion = event.nativeEvent.region; if (event.nativeEvent.continuous) { @@ -491,6 +549,10 @@ class MapView extends React.Component { } } + animateToNavigation(location, bearing, angle, duration) { + this._runCommand('animateToNavigation', [location, bearing, angle, duration || 500]); + } + animateToRegion(region, duration) { this._runCommand('animateToRegion', [region, duration || 500]); } @@ -515,7 +577,7 @@ class MapView extends React.Component { this._runCommand('fitToSuppliedMarkers', [markers, animated]); } - fitToCoordinates(coordinates = [], options) { + fitToCoordinates(coordinates = [], options = {}) { const { edgePadding = { top: 0, right: 0, bottom: 0, left: 0 }, animated = true, @@ -524,6 +586,10 @@ class MapView extends React.Component { this._runCommand('fitToCoordinates', [coordinates, edgePadding, animated]); } + setMapBoundaries(northEast, southWest) { + this._runCommand('setMapBoundaries', [northEast, southWest]); + } + /** * Takes a snapshot of the map and saves it to a picture * file or returns the image as a base64 encoded string. @@ -599,6 +665,42 @@ class MapView extends React.Component { return Promise.reject('takeSnapshot not supported on this platform'); } + /** + * Convert a map coordinate to user-space point + * + * @param coordinate Coordinate + * @param [coordinate.latitude] Latitude + * @param [coordinate.longitude] Longitude + * + * @return Promise Promise with the point ({ x: Number, y: Number }) + */ + pointForCoordinate(coordinate) { + if (Platform.OS === 'android') { + return NativeModules.AirMapModule.pointForCoordinate(this._getHandle(), coordinate); + } else if (Platform.OS === 'ios') { + return this._runCommand('pointForCoordinate', [coordinate]); + } + return Promise.reject('pointForCoordinate not supported on this platform'); + } + + /** + * Convert a user-space point to a map coordinate + * + * @param point Point + * @param [point.x] X + * @param [point.x] Y + * + * @return Promise Promise with the coordinate ({ latitude: Number, longitude: Number }) + */ + coordinateForPoint(point) { + if (Platform.OS === 'android') { + return NativeModules.AirMapModule.coordinateForPoint(this._getHandle(), point); + } else if (Platform.OS === 'ios') { + return this._runCommand('coordinateForPoint', [point]); + } + return Promise.reject('coordinateForPoint not supported on this platform'); + } + _uiManagerCommand(name) { return NativeModules.UIManager[getAirMapName(this.props.provider)].Commands[name]; } @@ -614,19 +716,17 @@ class MapView extends React.Component { _runCommand(name, args) { switch (Platform.OS) { case 'android': - NativeModules.UIManager.dispatchViewManagerCommand( + return NativeModules.UIManager.dispatchViewManagerCommand( this._getHandle(), this._uiManagerCommand(name), args ); - break; case 'ios': - this._mapManagerCommand(name)(this._getHandle(), ...args); - break; + return this._mapManagerCommand(name)(this._getHandle(), ...args); default: - break; + return Promise.reject(`Invalid platform was passed: ${Platform.OS}`); } } @@ -635,12 +735,13 @@ class MapView extends React.Component { if (this.state.isReady) { props = { - ...this.props, region: null, initialRegion: null, + onMarkerPress: this._onMarkerPress, onChange: this._onChange, onMapReady: this._onMapReady, onLayout: this._onLayout, + ...this.props, }; if (Platform.OS === 'ios' && props.provider === ProviderConstants.PROVIDER_DEFAULT && GOOGLE_MAPS_ONLY_TYPES.includes(props.mapType)) { @@ -652,6 +753,7 @@ class MapView extends React.Component { style: this.props.style, region: null, initialRegion: null, + onMarkerPress: this._onMarkerPress, onChange: this._onChange, onMapReady: this._onMapReady, onLayout: this._onLayout, @@ -688,6 +790,7 @@ const nativeComponent = Component => requireNativeComponent(Component, MapView, nativeOnly: { onChange: true, onMapReady: true, + onKmlReady: true, handlePanDrag: true, }, }); @@ -711,16 +814,30 @@ const AIRMapLite = NativeModules.UIManager.AIRMapLite && }, }); +export const Animated = RNAnimated.createAnimatedComponent(MapView); + +export const ProviderPropType = PropTypes.oneOf(Object.values(ProviderConstants)); + +/** + * TODO: + * All of these properties on MapView are unecessary since they can be imported + * individually with the es6 exports in index.js. Removing them is a breaking change, + * but potentially allows for better dead code elimination since references are not + * kept to components which are never used. + */ + MapView.Marker = MapMarker; MapView.Polyline = MapPolyline; MapView.Polygon = MapPolygon; MapView.Circle = MapCircle; MapView.UrlTile = MapUrlTile; +MapView.LocalTile = MapLocalTile; +MapView.Overlay = MapOverlay; MapView.Callout = MapCallout; Object.assign(MapView, ProviderConstants); -MapView.ProviderPropType = PropTypes.oneOf(Object.values(ProviderConstants)); +MapView.ProviderPropType = ProviderPropType; -MapView.Animated = Animated.createAnimatedComponent(MapView); +MapView.Animated = Animated; MapView.AnimatedRegion = AnimatedRegion; -module.exports = MapView; +export default MapView; diff --git a/lib/ios/AirGoogleMaps/DummyView.h b/lib/ios/AirGoogleMaps/AIRDummyView.h similarity index 78% rename from lib/ios/AirGoogleMaps/DummyView.h rename to lib/ios/AirGoogleMaps/AIRDummyView.h index ba4be28348..624c0cb434 100644 --- a/lib/ios/AirGoogleMaps/DummyView.h +++ b/lib/ios/AirGoogleMaps/AIRDummyView.h @@ -1,5 +1,5 @@ // -// DummyView.h +// AIRDummyView.h // AirMapsExplorer // // Created by Gil Birman on 10/4/16. @@ -8,7 +8,7 @@ #import -@interface DummyView : UIView +@interface AIRDummyView : UIView @property (nonatomic, weak) UIView *view; - (instancetype)initWithView:(UIView*)view; @end diff --git a/lib/ios/AirGoogleMaps/DummyView.m b/lib/ios/AirGoogleMaps/AIRDummyView.m similarity index 75% rename from lib/ios/AirGoogleMaps/DummyView.m rename to lib/ios/AirGoogleMaps/AIRDummyView.m index 9e84397072..3775394dcb 100644 --- a/lib/ios/AirGoogleMaps/DummyView.m +++ b/lib/ios/AirGoogleMaps/AIRDummyView.m @@ -1,14 +1,14 @@ // -// DummyView.m +// AIRDummyView.m // AirMapsExplorer // // Created by Gil Birman on 10/4/16. // #import -#import "DummyView.h" +#import "AIRDummyView.h" -@implementation DummyView +@implementation AIRDummyView - (instancetype)initWithView:(UIView*)view { if ((self = [super init])) { diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.h b/lib/ios/AirGoogleMaps/AIRGoogleMap.h index d2a8e3e6f3..af362c27e9 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.h @@ -7,6 +7,7 @@ #import #import +#import #import #import #import "AIRGMSMarker.h" @@ -15,14 +16,20 @@ @interface AIRGoogleMap : GMSMapView // TODO: don't use MK region? +@property (nonatomic, weak) RCTBridge *bridge; @property (nonatomic, assign) MKCoordinateRegion initialRegion; @property (nonatomic, assign) MKCoordinateRegion region; @property (nonatomic, assign) NSString *customMapStyleString; +@property (nonatomic, assign) UIEdgeInsets mapPadding; +@property (nonatomic, assign) NSString *paddingAdjustmentBehaviorString; @property (nonatomic, copy) RCTBubblingEventBlock onMapReady; +@property (nonatomic, copy) RCTBubblingEventBlock onKmlReady; @property (nonatomic, copy) RCTBubblingEventBlock onPress; @property (nonatomic, copy) RCTBubblingEventBlock onLongPress; +@property (nonatomic, copy) RCTBubblingEventBlock onUserLocationChange; @property (nonatomic, copy) RCTBubblingEventBlock onMarkerPress; @property (nonatomic, copy) RCTBubblingEventBlock onChange; +@property (nonatomic, copy) RCTBubblingEventBlock onPoiClick; @property (nonatomic, copy) RCTDirectEventBlock onRegionChange; @property (nonatomic, copy) RCTDirectEventBlock onRegionChangeComplete; @property (nonatomic, strong) NSMutableArray *markers; @@ -30,6 +37,7 @@ @property (nonatomic, strong) NSMutableArray *polylines; @property (nonatomic, strong) NSMutableArray *circles; @property (nonatomic, strong) NSMutableArray *tiles; +@property (nonatomic, strong) NSMutableArray *overlays; @property (nonatomic, assign) BOOL showsBuildings; @property (nonatomic, assign) BOOL showsTraffic; @@ -41,8 +49,9 @@ @property (nonatomic, assign) BOOL showsUserLocation; @property (nonatomic, assign) BOOL showsMyLocationButton; @property (nonatomic, assign) BOOL showsIndoorLevelPicker; +@property (nonatomic, assign) NSString *kmlSrc; -- (void)didFinishTileRendering; +- (void)didPrepareMap; - (BOOL)didTapMarker:(GMSMarker *)marker; - (void)didTapPolyline:(GMSPolyline *)polyline; - (void)didTapPolygon:(GMSPolygon *)polygon; @@ -50,6 +59,7 @@ - (void)didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate; - (void)didChangeCameraPosition:(GMSCameraPosition *)position; - (void)idleAtCameraPosition:(GMSCameraPosition *)position; +- (void)didTapPOIWithPlaceID:(NSString *)placeID name:(NSString *) name location:(CLLocationCoordinate2D) location; + (MKCoordinateRegion)makeGMSCameraPositionFromMap:(GMSMapView *)map andGMSCameraPosition:(GMSCameraPosition *)position; + (GMSCameraPosition*)makeGMSCameraPositionFromMap:(GMSMapView *)map andMKCoordinateRegion:(MKCoordinateRegion)region; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.m b/lib/ios/AirGoogleMaps/AIRGoogleMap.m index f102385315..4205bd4583 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.m @@ -7,13 +7,20 @@ #import "AIRGoogleMap.h" #import "AIRGoogleMapMarker.h" +#import "AIRGoogleMapMarkerManager.h" #import "AIRGoogleMapPolygon.h" #import "AIRGoogleMapPolyline.h" #import "AIRGoogleMapCircle.h" #import "AIRGoogleMapUrlTile.h" +#import "AIRGoogleMapOverlay.h" #import +#import +#import +#import +#import #import #import +#import #import "RCTConvert+AirMap.h" id regionAsJSON(MKCoordinateRegion region) { @@ -34,7 +41,11 @@ - (id)eventFromCoordinate:(CLLocationCoordinate2D)coordinate; @implementation AIRGoogleMap { NSMutableArray *_reactSubviews; - BOOL _initialRegionSet; + MKCoordinateRegion _initialRegion; + MKCoordinateRegion _region; + BOOL _initialRegionSetOnLoad; + BOOL _didCallOnMapReady; + BOOL _didMoveToWindow; } - (instancetype)init @@ -46,10 +57,28 @@ - (instancetype)init _polylines = [NSMutableArray array]; _circles = [NSMutableArray array]; _tiles = [NSMutableArray array]; - _initialRegionSet = false; + _overlays = [NSMutableArray array]; + _initialRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(0.0, 0.0), MKCoordinateSpanMake(0.0, 0.0)); + _region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(0.0, 0.0), MKCoordinateSpanMake(0.0, 0.0)); + _initialRegionSetOnLoad = false; + _didCallOnMapReady = false; + _didMoveToWindow = false; + + // Listen to the myLocation property of GMSMapView. + [self addObserver:self + forKeyPath:@"myLocation" + options:NSKeyValueObservingOptionNew + context:NULL]; } return self; } + +- (void)dealloc { + [self removeObserver:self + forKeyPath:@"myLocation" + context:NULL]; +} + - (id)eventFromCoordinate:(CLLocationCoordinate2D)coordinate { CGPoint touchPoint = [self.projection pointForCoordinate:coordinate]; @@ -91,6 +120,10 @@ - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex AIRGoogleMapUrlTile *tile = (AIRGoogleMapUrlTile*)subview; tile.tileLayer.map = self; [self.tiles addObject:tile]; + } else if ([subview isKindOfClass:[AIRGoogleMapOverlay class]]) { + AIRGoogleMapOverlay *overlay = (AIRGoogleMapOverlay*)subview; + overlay.overlay.map = self; + [self.overlays addObject:overlay]; } else { NSArray> *childSubviews = [subview reactSubviews]; for (int i = 0; i < childSubviews.count; i++) { @@ -127,6 +160,10 @@ - (void)removeReactSubview:(id)subview { AIRGoogleMapUrlTile *tile = (AIRGoogleMapUrlTile*)subview; tile.tileLayer.map = nil; [self.tiles removeObject:tile]; + } else if ([subview isKindOfClass:[AIRGoogleMapOverlay class]]) { + AIRGoogleMapOverlay *overlay = (AIRGoogleMapOverlay*)subview; + overlay.overlay.map = nil; + [self.overlays removeObject:overlay]; } else { NSArray> *childSubviews = [subview reactSubviews]; for (int i = 0; i < childSubviews.count; i++) { @@ -144,19 +181,38 @@ - (void)removeReactSubview:(id)subview { } #pragma clang diagnostic pop +- (void)didMoveToWindow { + if (_didMoveToWindow) return; + _didMoveToWindow = true; + + if (_initialRegion.span.latitudeDelta != 0.0 && + _initialRegion.span.longitudeDelta != 0.0) { + self.camera = [AIRGoogleMap makeGMSCameraPositionFromMap:self andMKCoordinateRegion:_initialRegion]; + } else if (_region.span.latitudeDelta != 0.0 && + _region.span.longitudeDelta != 0.0) { + self.camera = [AIRGoogleMap makeGMSCameraPositionFromMap:self andMKCoordinateRegion:_region]; + } + + [super didMoveToWindow]; +} + - (void)setInitialRegion:(MKCoordinateRegion)initialRegion { - if (_initialRegionSet) return; - _initialRegionSet = true; + if (_initialRegionSetOnLoad) return; + _initialRegion = initialRegion; + _initialRegionSetOnLoad = _didMoveToWindow; self.camera = [AIRGoogleMap makeGMSCameraPositionFromMap:self andMKCoordinateRegion:initialRegion]; } - (void)setRegion:(MKCoordinateRegion)region { // TODO: The JS component is repeatedly setting region unnecessarily. We might want to deal with that in here. + _region = region; self.camera = [AIRGoogleMap makeGMSCameraPositionFromMap:self andMKCoordinateRegion:region]; } -- (void)didFinishTileRendering { - if (self.onMapReady) self.onMapReady(@{}); +- (void)didPrepareMap { + if (_didCallOnMapReady) return; + _didCallOnMapReady = true; + if (self.onMapReady) self.onMapReady(@{}); } - (BOOL)didTapMarker:(GMSMarker *)marker { @@ -164,7 +220,11 @@ - (BOOL)didTapMarker:(GMSMarker *)marker { id event = @{@"action": @"marker-press", @"id": airMarker.identifier ?: @"unknown", - }; + @"coordinate": @{ + @"latitude": @(airMarker.position.latitude), + @"longitude": @(airMarker.position.longitude) + } + }; if (airMarker.onPress) airMarker.onPress(event); if (self.onMarkerPress) self.onMarkerPress(event); @@ -212,6 +272,20 @@ - (void)didChangeCameraPosition:(GMSCameraPosition *)position { if (self.onChange) self.onChange(event); } +- (void)didTapPOIWithPlaceID:(NSString *)placeID + name:(NSString *)name + location:(CLLocationCoordinate2D)location { + id event = @{@"placeId": placeID, + @"name": name, + @"coordinate": @{ + @"latitude": @(location.latitude), + @"longitude": @(location.longitude) + } + }; + + if (self.onPoiClick) self.onPoiClick(event); +} + - (void)idleAtCameraPosition:(GMSCameraPosition *)position { id event = @{@"continuous": @NO, @"region": regionAsJSON([AIRGoogleMap makeGMSCameraPositionFromMap:self andGMSCameraPosition:position]), @@ -219,6 +293,45 @@ - (void)idleAtCameraPosition:(GMSCameraPosition *)position { if (self.onChange) self.onChange(event); // complete } +- (void)setMapPadding:(UIEdgeInsets)mapPadding { + self.padding = mapPadding; +} + +- (UIEdgeInsets)mapPadding { + return self.padding; +} + +- (void)setPaddingAdjustmentBehaviorString:(NSString *)str +{ + if ([str isEqualToString:@"never"]) + { + self.paddingAdjustmentBehavior = kGMSMapViewPaddingAdjustmentBehaviorNever; + } + else if ([str isEqualToString:@"automatic"]) + { + self.paddingAdjustmentBehavior = kGMSMapViewPaddingAdjustmentBehaviorAutomatic; + } + else //if ([str isEqualToString:@"always"]) <-- default + { + self.paddingAdjustmentBehavior = kGMSMapViewPaddingAdjustmentBehaviorAlways; + } +} + +- (NSString *)paddingAdjustmentBehaviorString +{ + switch (self.paddingAdjustmentBehavior) + { + case kGMSMapViewPaddingAdjustmentBehaviorNever: + return @"never"; + case kGMSMapViewPaddingAdjustmentBehaviorAutomatic: + return @"automatic"; + case kGMSMapViewPaddingAdjustmentBehaviorAlways: + return @"always"; + + default: + return @"unknown"; + } +} - (void)setScrollEnabled:(BOOL)scrollEnabled { self.settings.scrollGestures = scrollEnabled; @@ -355,4 +468,101 @@ + (GMSCameraPosition*) makeGMSCameraPositionFromMap:(GMSMapView *)map andMKCoord return [map cameraForBounds:bounds insets:UIEdgeInsetsZero]; } +#pragma mark - KVO updates + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context { + if ([keyPath isEqualToString:@"myLocation"]){ + CLLocation *location = [object myLocation]; + + id event = @{@"coordinate": @{ + @"latitude": @(location.coordinate.latitude), + @"longitude": @(location.coordinate.longitude), + @"altitude": @(location.altitude), + @"timestamp": @(location.timestamp.timeIntervalSinceReferenceDate * 1000), + @"accuracy": @(location.horizontalAccuracy), + @"altitudeAccuracy": @(location.verticalAccuracy), + @"speed": @(location.speed), + } + }; + + if (self.onUserLocationChange) self.onUserLocationChange(event); + } else { + // This message is not for me; pass it on to super. + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + ++ (NSString *)GetIconUrl:(GMUPlacemark *) marker parser:(GMUKMLParser *) parser { + if (marker.style.styleID != nil) { + for (GMUStyle *style in parser.styles) { + if (style.styleID == marker.style.styleID) { + return style.iconUrl; + } + } + } + + return marker.style.iconUrl; +} + +- (NSString *)KmlSrc { + return _kmlSrc; +} + +- (void)setKmlSrc:(NSString *)kmlUrl { + + _kmlSrc = kmlUrl; + + NSURL *url = [NSURL URLWithString:kmlUrl]; + NSData *urlData = nil; + + if ([url isFileURL]) { + urlData = [NSData dataWithContentsOfURL:url]; + } else { + urlData = [[NSFileManager defaultManager] contentsAtPath:kmlUrl]; + } + + GMUKMLParser *parser = [[GMUKMLParser alloc] initWithData:urlData]; + [parser parse]; + + NSUInteger index = 0; + NSMutableArray *markers = [[NSMutableArray alloc]init]; + + for (GMUPlacemark *place in parser.placemarks) { + + CLLocationCoordinate2D location =((GMUPoint *) place.geometry).coordinate; + + AIRGoogleMapMarker *marker = (AIRGoogleMapMarker *)[[AIRGoogleMapMarkerManager alloc] view]; + if (!marker.bridge) { + marker.bridge = _bridge; + } + marker.identifier = place.title; + marker.coordinate = location; + marker.title = place.title; + marker.subtitle = place.snippet; + marker.pinColor = place.style.fillColor; + marker.imageSrc = [AIRGoogleMap GetIconUrl:place parser:parser]; + marker.layer.backgroundColor = [UIColor clearColor].CGColor; + marker.layer.position = CGPointZero; + + [self insertReactSubview:(UIView *) marker atIndex:index]; + + [markers addObject:@{@"id": marker.identifier, + @"title": marker.title, + @"description": marker.subtitle, + @"coordinate": @{ + @"latitude": @(location.latitude), + @"longitude": @(location.longitude) + } + }]; + + index++; + } + + id event = @{@"markers": markers}; + if (self.onKmlReady) self.onKmlReady(event); +} + @end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 12d63e1042..4ae089c1fe 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -42,6 +42,7 @@ @implementation AIRGoogleMapManager - (UIView *)view { AIRGoogleMap *map = [AIRGoogleMap new]; + map.bridge = self.bridge; map.delegate = self; return map; } @@ -60,16 +61,45 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(showsMyLocationButton, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsIndoorLevelPicker, BOOL) RCT_EXPORT_VIEW_PROPERTY(customMapStyleString, NSString) +RCT_EXPORT_VIEW_PROPERTY(mapPadding, UIEdgeInsets) +RCT_REMAP_VIEW_PROPERTY(paddingAdjustmentBehavior, paddingAdjustmentBehaviorString, NSString) RCT_EXPORT_VIEW_PROPERTY(onMapReady, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onKmlReady, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onLongPress, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onUserLocationChange, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onMarkerPress, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onRegionChange, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onRegionChangeComplete, RCTDirectEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onPoiClick, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(mapType, GMSMapViewType) RCT_EXPORT_VIEW_PROPERTY(minZoomLevel, CGFloat) RCT_EXPORT_VIEW_PROPERTY(maxZoomLevel, CGFloat) +RCT_EXPORT_VIEW_PROPERTY(kmlSrc, NSString) + +RCT_EXPORT_METHOD(animateToNavigation:(nonnull NSNumber *)reactTag + withRegion:(MKCoordinateRegion)region + withBearing:(CGFloat)bearing + withAngle:(double)angle + withDuration:(CGFloat)duration) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRGoogleMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view); + } else { + [CATransaction begin]; + [CATransaction setAnimationDuration:duration/1000]; + AIRGoogleMap *mapView = (AIRGoogleMap *)view; + GMSCameraPosition *camera = [AIRGoogleMap makeGMSCameraPositionFromMap:mapView andMKCoordinateRegion:region]; + [mapView animateToCameraPosition:camera]; + [mapView animateToViewingAngle:angle]; + [mapView animateToBearing:bearing]; + [CATransaction commit]; + } + }]; +} RCT_EXPORT_METHOD(animateToRegion:(nonnull NSNumber *)reactTag withRegion:(MKCoordinateRegion)region @@ -228,12 +258,19 @@ - (UIView *)view withWidth:(nonnull NSNumber *)width withHeight:(nonnull NSNumber *)height withRegion:(MKCoordinateRegion)region + format:(nonnull NSString *)format + quality:(nonnull NSNumber *)quality + result:(nonnull NSString *)result withCallback:(RCTResponseSenderBlock)callback) { + NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970]; + NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.%@", timeStamp, format]; + NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent]; + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { id view = viewRegistry[reactTag]; if (![view isKindOfClass:[AIRGoogleMap class]]) { - RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view); + RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view); } else { AIRGoogleMap *mapView = (AIRGoogleMap *)view; @@ -242,30 +279,131 @@ - (UIView *)view UIGraphicsBeginImageContextWithOptions(mapView.frame.size, YES, 0.0f); [mapView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970]; - NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.png", timeStamp]; - NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent]; - - NSData *data = UIImagePNGRepresentation(image); - [data writeToFile:filePath atomically:YES]; - NSDictionary *snapshotData = @{ - @"uri": filePath, - @"data": [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn] - }; - callback(@[[NSNull null], snapshotData]); + + NSData *data; + if ([format isEqualToString:@"png"]) { + data = UIImagePNGRepresentation(image); + + } + else if([format isEqualToString:@"jpg"]) { + data = UIImageJPEGRepresentation(image, quality.floatValue); + } + + if ([result isEqualToString:@"file"]) { + [data writeToFile:filePath atomically:YES]; + callback(@[[NSNull null], filePath]); + } + else if ([result isEqualToString:@"base64"]) { + callback(@[[NSNull null], [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]]); + } + else if ([result isEqualToString:@"legacy"]) { + + // In the initial (iOS only) implementation of takeSnapshot, + // both the uri and the base64 encoded string were returned. + // Returning both is rarely useful and in fact causes a + // performance penalty when only the file URI is desired. + // In that case the base64 encoded string was always marshalled + // over the JS-bridge (which is quite slow). + // A new more flexible API was created to cover this. + // This code should be removed in a future release when the + // old API is fully deprecated. + [data writeToFile:filePath atomically:YES]; + NSDictionary *snapshotData = @{ + @"uri": filePath, + @"data": [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn] + }; + callback(@[[NSNull null], snapshotData]); + } + + } + UIGraphicsEndImageContext(); + }]; +} + +RCT_EXPORT_METHOD(pointForCoordinate:(nonnull NSNumber *)reactTag + coordinate:(NSDictionary *)coordinate + resolver: (RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) +{ + CLLocationCoordinate2D coord = + CLLocationCoordinate2DMake( + [coordinate[@"latitude"] doubleValue], + [coordinate[@"longitude"] doubleValue] + ); + + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRGoogleMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view); + } else { + AIRGoogleMap *mapView = (AIRGoogleMap *)view; + + CGPoint touchPoint = [mapView.projection pointForCoordinate:coord]; + + resolve(@{ + @"x": @(touchPoint.x), + @"y": @(touchPoint.y), + }); + } + }]; +} + +RCT_EXPORT_METHOD(coordinateForPoint:(nonnull NSNumber *)reactTag + point:(NSDictionary *)point + resolver: (RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) +{ + CGPoint pt = CGPointMake( + [point[@"x"] doubleValue], + [point[@"y"] doubleValue] + ); + + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRGoogleMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view); + } else { + AIRGoogleMap *mapView = (AIRGoogleMap *)view; + + CLLocationCoordinate2D coordinate = [mapView.projection coordinateForPoint:pt]; + + resolve(@{ + @"latitude": @(coordinate.latitude), + @"longitude": @(coordinate.longitude), + }); + } + }]; +} + +RCT_EXPORT_METHOD(setMapBoundaries:(nonnull NSNumber *)reactTag + northEast:(CLLocationCoordinate2D)northEast + southWest:(CLLocationCoordinate2D)southWest) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRGoogleMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view); + } else { + AIRGoogleMap *mapView = (AIRGoogleMap *)view; + + GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:northEast coordinate:southWest]; + + mapView.cameraTargetBounds = bounds; } }]; } ++ (BOOL)requiresMainQueueSetup { + return YES; +} + - (NSDictionary *)constantsToExport { return @{ @"legalNotice": [GMSServices openSourceLicenseInfo] }; } -- (void)mapViewDidFinishTileRendering:(GMSMapView *)mapView { - AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; - [googleMapView didFinishTileRendering]; +- (void)mapViewDidStartTileRendering:(GMSMapView *)mapView { + AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; + [googleMapView didPrepareMap]; } - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { @@ -326,4 +464,12 @@ - (void)mapView:(GMSMapView *)mapView didDragMarker:(GMSMarker *)marker { AIRGMSMarker *aMarker = (AIRGMSMarker *)marker; [aMarker.fakeMarker didDragMarker:aMarker]; } + +- (void)mapView:(GMSMapView *)mapView + didTapPOIWithPlaceID:(NSString *)placeID + name:(NSString *)name + location:(CLLocationCoordinate2D)location { + AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; + [googleMapView didTapPOIWithPlaceID:placeID name:name location:location]; +} @end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h index 298884f7d2..ed4581aec1 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h @@ -28,9 +28,12 @@ @property (nonatomic, copy) NSString *subtitle; @property (nonatomic, strong) UIColor *pinColor; @property (nonatomic, assign) CGPoint anchor; +@property (nonatomic, assign) CGPoint calloutAnchor; @property (nonatomic, assign) NSInteger zIndex; @property (nonatomic, assign) double opacity; @property (nonatomic, assign) BOOL draggable; +@property (nonatomic, assign) BOOL tracksViewChanges; +@property (nonatomic, assign) BOOL tracksInfoWindowChanges; - (void)showCalloutView; - (void)hideCalloutView; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m index c41be55bbb..186cc8f5cb 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m @@ -11,7 +11,7 @@ #import #import "AIRGMSMarker.h" #import "AIRGoogleMapCallout.h" -#import "DummyView.h" +#import "AIRDummyView.h" CGRect unionRect(CGRect a, CGRect b) { return CGRectMake( @@ -36,6 +36,8 @@ - (instancetype)init if ((self = [super init])) { _realMarker = [[AIRGMSMarker alloc] init]; _realMarker.fakeMarker = self; + _realMarker.tracksViewChanges = true; + _realMarker.tracksInfoWindowChanges = false; } return self; } @@ -88,12 +90,12 @@ - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex } else { // a child view of the marker [self iconViewInsertSubview:(UIView*)subview atIndex:atIndex+1]; } - DummyView *dummySubview = [[DummyView alloc] initWithView:(UIView *)subview]; + AIRDummyView *dummySubview = [[AIRDummyView alloc] initWithView:(UIView *)subview]; [super insertReactSubview:(UIView*)dummySubview atIndex:atIndex]; } - (void)removeReactSubview:(id)dummySubview { - UIView* subview = ((DummyView*)dummySubview).view; + UIView* subview = ((AIRDummyView*)dummySubview).view; if ([subview isKindOfClass:[AIRGoogleMapCallout class]]) { self.calloutView = nil; @@ -222,7 +224,7 @@ - (void)setImageSrc:(NSString *)imageSrc dispatch_async(dispatch_get_main_queue(), ^{ // TODO(gil): This way allows different image sizes - if (_iconImageView) [_iconImageView removeFromSuperview]; + if (self->_iconImageView) [self->_iconImageView removeFromSuperview]; // ... but this way is more efficient? // if (_iconImageView) { @@ -248,7 +250,7 @@ - (void)setImageSrc:(NSString *)imageSrc CGRect selfBounds = unionRect(bounds, self.bounds); [self setFrame:selfBounds]; - _iconImageView = imageView; + self->_iconImageView = imageView; [self iconViewInsertSubview:imageView atIndex:0]; }); }]; @@ -280,6 +282,11 @@ - (void)setAnchor:(CGPoint)anchor { _realMarker.groundAnchor = anchor; } +- (void)setCalloutAnchor:(CGPoint)calloutAnchor { + _calloutAnchor = calloutAnchor; + _realMarker.infoWindowAnchor = calloutAnchor; +} + - (void)setZIndex:(NSInteger)zIndex { @@ -295,4 +302,20 @@ - (BOOL)draggable { return _realMarker.draggable; } +- (void)setTracksViewChanges:(BOOL)tracksViewChanges { + _realMarker.tracksViewChanges = tracksViewChanges; +} + +- (BOOL)tracksViewChanges { + return _realMarker.tracksViewChanges; +} + +- (void)setTracksInfoWindowChanges:(BOOL)tracksInfoWindowChanges { + _realMarker.tracksInfoWindowChanges = tracksInfoWindowChanges; +} + +- (BOOL)tracksInfoWindowChanges { + return _realMarker.tracksInfoWindowChanges; +} + @end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m index b5572bf9d2..a3d931d60b 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m @@ -35,8 +35,11 @@ - (UIView *)view RCT_REMAP_VIEW_PROPERTY(description, subtitle, NSString) RCT_EXPORT_VIEW_PROPERTY(pinColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(anchor, CGPoint) +RCT_EXPORT_VIEW_PROPERTY(calloutAnchor, CGPoint) RCT_EXPORT_VIEW_PROPERTY(zIndex, NSInteger) RCT_EXPORT_VIEW_PROPERTY(draggable, BOOL) +RCT_EXPORT_VIEW_PROPERTY(tracksViewChanges, BOOL) +RCT_EXPORT_VIEW_PROPERTY(tracksInfoWindowChanges, BOOL) RCT_EXPORT_VIEW_PROPERTY(opacity, double) RCT_EXPORT_VIEW_PROPERTY(onDragStart, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onDrag, RCTDirectEventBlock) diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapOverlay.h b/lib/ios/AirGoogleMaps/AIRGoogleMapOverlay.h new file mode 100644 index 0000000000..0e2c4e278a --- /dev/null +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapOverlay.h @@ -0,0 +1,23 @@ +// +// AIRGoogleMapOverlay.h +// +// Created by Taro Matsuzawa on 5/3/17. +// + +#import +#import +#import +#import "AIRMapCoordinate.h" +#import "AIRGoogleMap.h" + +@interface AIRGoogleMapOverlay : UIView + +@property (nonatomic, strong) GMSGroundOverlay *overlay; +@property (nonatomic, copy) NSString *imageSrc; +@property (nonatomic, strong, readonly) UIImage *overlayImage; +@property (nonatomic, copy) NSArray *boundsRect; +@property (nonatomic, readonly) GMSCoordinateBounds *overlayBounds; + +@property (nonatomic, weak) RCTBridge *bridge; + +@end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapOverlay.m b/lib/ios/AirGoogleMaps/AIRGoogleMapOverlay.m new file mode 100644 index 0000000000..9caf634aad --- /dev/null +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapOverlay.m @@ -0,0 +1,76 @@ +// +// AIRGoogleMapOverlay.m +// Created by Nick Italiano on 3/5/17. +// + +#import "AIRGoogleMapOverlay.h" + +#import +#import +#import +#import + +@interface AIRGoogleMapOverlay() + @property (nonatomic, strong, readwrite) UIImage *overlayImage; + @property (nonatomic, readwrite) GMSCoordinateBounds *overlayBounds; +@end + +@implementation AIRGoogleMapOverlay { + RCTImageLoaderCancellationBlock _reloadImageCancellationBlock; + CLLocationCoordinate2D _southWest; + CLLocationCoordinate2D _northEast; +} + +- (instancetype)init +{ + if ((self = [super init])) { + _overlay = [[GMSGroundOverlay alloc] init]; + } + return self; +} + +- (void)setImageSrc:(NSString *)imageSrc +{ + NSLog(@">>> SET IMAGESRC: %@", imageSrc); + _imageSrc = imageSrc; + + if (_reloadImageCancellationBlock) { + _reloadImageCancellationBlock(); + _reloadImageCancellationBlock = nil; + } + + __weak typeof(self) weakSelf = self; + _reloadImageCancellationBlock = [_bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc] + size:weakSelf.bounds.size + scale:RCTScreenScale() + clipped:YES + resizeMode:RCTResizeModeCenter + progressBlock:nil + partialLoadBlock:nil + completionBlock:^(NSError *error, UIImage *image) { + if (error) { + NSLog(@"%@", error); + } + dispatch_async(dispatch_get_main_queue(), ^{ + NSLog(@">>> IMAGE: %@", image); + weakSelf.overlayImage = image; + weakSelf.overlay.icon = image; + }); + }]; + +} + +- (void)setBoundsRect:(NSArray *)boundsRect +{ + _boundsRect = boundsRect; + + _southWest = CLLocationCoordinate2DMake([boundsRect[1][0] doubleValue], [boundsRect[0][1] doubleValue]); + _northEast = CLLocationCoordinate2DMake([boundsRect[0][0] doubleValue], [boundsRect[1][1] doubleValue]); + + _overlayBounds = [[GMSCoordinateBounds alloc] initWithCoordinate:_southWest + coordinate:_northEast]; + + _overlay.bounds = _overlayBounds; +} + +@end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapOverlayManager.h b/lib/ios/AirGoogleMaps/AIRGoogleMapOverlayManager.h new file mode 100644 index 0000000000..6d692c5ad1 --- /dev/null +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapOverlayManager.h @@ -0,0 +1,10 @@ +// +// AIRGoogleMapOverlayManager.h +// Created by Taro Matsuzawa on 3/5/17. +// + +#import +#import + +@interface AIRGoogleMapOverlayManager : RCTViewManager +@end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapOverlayManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapOverlayManager.m new file mode 100644 index 0000000000..12b29e738d --- /dev/null +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapOverlayManager.m @@ -0,0 +1,22 @@ +#import "AIRGoogleMapOverlayManager.h" +#import "AIRGoogleMapOverlay.h" + +@interface AIRGoogleMapOverlayManager() + +@end + +@implementation AIRGoogleMapOverlayManager + +RCT_EXPORT_MODULE() + +- (UIView *)view +{ + AIRGoogleMapOverlay *overlay = [AIRGoogleMapOverlay new]; + overlay.bridge = self.bridge; + return overlay; +} + +RCT_REMAP_VIEW_PROPERTY(bounds, boundsRect, NSArray) +RCT_REMAP_VIEW_PROPERTY(image, imageSrc, NSString) + +@end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h index adebc40d6c..45f69eb350 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h @@ -21,6 +21,7 @@ @property (nonatomic, strong) UIColor *strokeColor; @property (nonatomic, assign) double strokeWidth; @property (nonatomic, assign) UIColor *fillColor; +@property (nonatomic, strong) NSArray *lineDashPattern; @property (nonatomic, assign) BOOL geodesic; @property (nonatomic, assign) NSString *title; @property (nonatomic, assign) int zIndex; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m index 881f17be68..250b92aa54 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m @@ -32,13 +32,16 @@ -(void)setCoordinates:(NSArray *)coordinates [path addCoordinate:coordinates[i].coordinate]; } - _polyline.path = path; + _polyline.path = path; + + [self configureStyleSpansIfNeeded]; } -(void)setStrokeColor:(UIColor *)strokeColor { _strokeColor = strokeColor; _polyline.strokeColor = strokeColor; + [self configureStyleSpansIfNeeded]; } -(void)setStrokeWidth:(double)strokeWidth @@ -53,6 +56,11 @@ -(void)setFillColor:(UIColor *)fillColor _polyline.spans = @[[GMSStyleSpan spanWithColor:fillColor]]; } +- (void)setLineDashPattern:(NSArray *)lineDashPattern { + _lineDashPattern = lineDashPattern; + [self configureStyleSpansIfNeeded]; +} + -(void)setGeodesic:(BOOL)geodesic { _geodesic = geodesic; @@ -81,4 +89,23 @@ - (void)setOnPress:(RCTBubblingEventBlock)onPress { _polyline.onPress = onPress; } +- (void)configureStyleSpansIfNeeded { + if (!_strokeColor || !_lineDashPattern || !_polyline.path) { + return; + } + + BOOL isLine = YES; + NSMutableArray *styles = [[NSMutableArray alloc] init]; + for (NSInteger i = 0; i < _lineDashPattern.count; i++) { + if (isLine) { + [styles addObject:[GMSStrokeStyle solidColor:_strokeColor]]; + } else { + [styles addObject:[GMSStrokeStyle solidColor:[UIColor clearColor]]]; + } + isLine = !isLine; + } + + _polyline.spans = GMSStyleSpans(_polyline.path, styles, _lineDashPattern, kGMSLengthRhumb); +} + @end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m index a7515c207d..e4c49187f6 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m @@ -34,6 +34,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(fillColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(strokeWidth, double) +RCT_EXPORT_VIEW_PROPERTY(lineDashPattern, NSArray) RCT_EXPORT_VIEW_PROPERTY(geodesic, BOOL) RCT_EXPORT_VIEW_PROPERTY(zIndex, int) RCT_EXPORT_VIEW_PROPERTY(tappable, BOOL) diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapURLTileManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapURLTileManager.m index 79c82fe25e..398d75effb 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapURLTileManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapURLTileManager.m @@ -22,5 +22,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(urlTemplate, NSString) RCT_EXPORT_VIEW_PROPERTY(zIndex, int) +RCT_EXPORT_VIEW_PROPERTY(maximumZ, NSInteger) +RCT_EXPORT_VIEW_PROPERTY(minimumZ, NSInteger) @end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.h b/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.h index f76a9dc881..bcc6c67fc1 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.h @@ -11,5 +11,7 @@ @property (nonatomic, strong) GMSURLTileLayer *tileLayer; @property (nonatomic, assign) NSString *urlTemplate; @property (nonatomic, assign) int zIndex; +@property NSInteger *maximumZ; +@property NSInteger *minimumZ; @end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.m b/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.m index ae6333cff2..29eedb4611 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.m @@ -17,18 +17,31 @@ - (void)setUrlTemplate:(NSString *)urlTemplate { _urlTemplate = urlTemplate; _tileLayer = [GMSURLTileLayer tileLayerWithURLConstructor:[self _getTileURLConstructor]]; + _tileLayer.tileSize = [[UIScreen mainScreen] scale] * 256; } - (GMSTileURLConstructor)_getTileURLConstructor { NSString *urlTemplate = self.urlTemplate; - GMSTileURLConstructor urls = ^(NSUInteger x, NSUInteger y, NSUInteger zoom) { + NSInteger *maximumZ = self.maximumZ; + NSInteger *minimumZ = self.minimumZ; + GMSTileURLConstructor urls = ^NSURL* _Nullable (NSUInteger x, NSUInteger y, NSUInteger zoom) { NSString *url = urlTemplate; url = [url stringByReplacingOccurrencesOfString:@"{x}" withString:[NSString stringWithFormat: @"%ld", (long)x]]; url = [url stringByReplacingOccurrencesOfString:@"{y}" withString:[NSString stringWithFormat: @"%ld", (long)y]]; url = [url stringByReplacingOccurrencesOfString:@"{z}" withString:[NSString stringWithFormat: @"%ld", (long)zoom]]; + + if(maximumZ && (long)zoom > (long)maximumZ) { + return nil; + } + + if(minimumZ && (long)zoom < (long)minimumZ) { + return nil; + } + return [NSURL URLWithString:url]; }; return urls; } -@end + +@end \ No newline at end of file diff --git a/lib/ios/AirMaps.xcodeproj/project.pbxproj b/lib/ios/AirMaps.xcodeproj/project.pbxproj index ac641aff72..7e2468f620 100644 --- a/lib/ios/AirMaps.xcodeproj/project.pbxproj +++ b/lib/ios/AirMaps.xcodeproj/project.pbxproj @@ -22,6 +22,32 @@ 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2D61C4AD3DA007D0023 /* AIRMapPolylineManager.m */; }; 1125B2F21C4AD445007D0023 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2F11C4AD445007D0023 /* SMCalloutView.m */; }; 19DABC7F1E7C9D3C00F41150 /* RCTConvert+AirMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */; }; + 2163AA501FEAEDD100BBEC95 /* AIRMapPolylineRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2163AA4F1FEAEDD100BBEC95 /* AIRMapPolylineRenderer.m */; }; + 53D31636202E723B00B55447 /* AIRMapOverlayManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D31635202E723B00B55447 /* AIRMapOverlayManager.m */; }; + 53D3163A202E72FC00B55447 /* AIRMapOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D31639202E72FC00B55447 /* AIRMapOverlay.m */; }; + 53D3163D202E734F00B55447 /* AIRMapOverlayRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D3163C202E734F00B55447 /* AIRMapOverlayRenderer.m */; }; + 628F81201FD16DF80058313A /* AIRMapLocalTile.m in Sources */ = {isa = PBXBuildFile; fileRef = 628F811F1FD16DF80058313A /* AIRMapLocalTile.m */; }; + 628F81231FD16EFA0058313A /* AIRMapLocalTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 628F81221FD16EFA0058313A /* AIRMapLocalTileManager.m */; }; + 62AEC4D41FD5A0AA003225E0 /* AIRMapLocalTileOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AEC4D31FD5A0AA003225E0 /* AIRMapLocalTileOverlay.m */; }; + 9B9498CA2017EFB800158761 /* AIRGoogleMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498A62017EFB400158761 /* AIRGoogleMapUrlTile.m */; }; + 9B9498CB2017EFB800158761 /* AIRGoogleMapURLTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498A72017EFB400158761 /* AIRGoogleMapURLTileManager.m */; }; + 9B9498CC2017EFB800158761 /* AIRGMSPolygon.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498A82017EFB400158761 /* AIRGMSPolygon.m */; }; + 9B9498CD2017EFB800158761 /* AIRGoogleMapCallout.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498AC2017EFB400158761 /* AIRGoogleMapCallout.m */; }; + 9B9498CE2017EFB800158761 /* AIRGMSMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498AE2017EFB500158761 /* AIRGMSMarker.m */; }; + 9B9498CF2017EFB800158761 /* AIRGMSPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498AF2017EFB500158761 /* AIRGMSPolyline.m */; }; + 9B9498D02017EFB800158761 /* AIRGoogleMapPolylineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498B12017EFB500158761 /* AIRGoogleMapPolylineManager.m */; }; + 9B9498D12017EFB800158761 /* AIRGoogleMapCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498B32017EFB500158761 /* AIRGoogleMapCircle.m */; }; + 9B9498D22017EFB800158761 /* AIRGoogleMapMarkerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498B52017EFB500158761 /* AIRGoogleMapMarkerManager.m */; }; + 9B9498D32017EFB800158761 /* AIRGoogleMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498B72017EFB500158761 /* AIRGoogleMap.m */; }; + 9B9498D42017EFB800158761 /* RCTConvert+GMSMapViewType.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498B92017EFB600158761 /* RCTConvert+GMSMapViewType.m */; }; + 9B9498D52017EFB800158761 /* AIRGoogleMapPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498BB2017EFB600158761 /* AIRGoogleMapPolyline.m */; }; + 9B9498D62017EFB800158761 /* AIRGoogleMapCircleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498BC2017EFB600158761 /* AIRGoogleMapCircleManager.m */; }; + 9B9498D72017EFB800158761 /* AIRGoogleMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498BD2017EFB600158761 /* AIRGoogleMapManager.m */; }; + 9B9498D92017EFB800158761 /* AIRGoogleMapCalloutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498C42017EFB700158761 /* AIRGoogleMapCalloutManager.m */; }; + 9B9498DA2017EFB800158761 /* AIRGoogleMapPolygon.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498C62017EFB800158761 /* AIRGoogleMapPolygon.m */; }; + 9B9498DB2017EFB800158761 /* AIRGoogleMapMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498C72017EFB800158761 /* AIRGoogleMapMarker.m */; }; + 9B9498DC2017EFB800158761 /* AIRGoogleMapPolygonManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9498C92017EFB800158761 /* AIRGoogleMapPolygonManager.m */; }; + B5EA3BA92098E22B000E7AFD /* AIRDummyView.m in Sources */ = {isa = PBXBuildFile; fileRef = B5EA3BA72098E22B000E7AFD /* AIRDummyView.m */; }; DA6C26381C9E2AFE0035349F /* AIRMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */; }; DA6C263E1C9E324A0035349F /* AIRMapUrlTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C263D1C9E324A0035349F /* AIRMapUrlTileManager.m */; }; /* End PBXBuildFile section */ @@ -70,6 +96,57 @@ 11FA5C511C4A1296003AC2EE /* libAirMaps.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAirMaps.a; sourceTree = BUILT_PRODUCTS_DIR; }; 19DABC7D1E7C9D3C00F41150 /* RCTConvert+AirMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+AirMap.h"; sourceTree = ""; }; 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+AirMap.m"; sourceTree = ""; }; + 2163AA4E1FEAEDD100BBEC95 /* AIRMapPolylineRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapPolylineRenderer.h; sourceTree = ""; }; + 2163AA4F1FEAEDD100BBEC95 /* AIRMapPolylineRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapPolylineRenderer.m; sourceTree = ""; }; + 53D31635202E723B00B55447 /* AIRMapOverlayManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AIRMapOverlayManager.m; sourceTree = ""; }; + 53D31637202E725E00B55447 /* AIRMapOverlayManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapOverlayManager.h; sourceTree = ""; }; + 53D31638202E72D500B55447 /* AIRMapOverlay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapOverlay.h; sourceTree = ""; }; + 53D31639202E72FC00B55447 /* AIRMapOverlay.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AIRMapOverlay.m; sourceTree = ""; }; + 53D3163B202E732300B55447 /* AIRMapOverlayRenderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapOverlayRenderer.h; sourceTree = ""; }; + 53D3163C202E734F00B55447 /* AIRMapOverlayRenderer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AIRMapOverlayRenderer.m; sourceTree = ""; }; + 628F811E1FD16D780058313A /* AIRMapLocalTile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapLocalTile.h; sourceTree = ""; }; + 628F811F1FD16DF80058313A /* AIRMapLocalTile.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AIRMapLocalTile.m; sourceTree = ""; }; + 628F81211FD16EAB0058313A /* AIRMapLocalTileManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapLocalTileManager.h; sourceTree = ""; }; + 628F81221FD16EFA0058313A /* AIRMapLocalTileManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AIRMapLocalTileManager.m; sourceTree = ""; }; + 62AEC4D31FD5A0AA003225E0 /* AIRMapLocalTileOverlay.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AIRMapLocalTileOverlay.m; path = AirMaps/AIRMapLocalTileOverlay.m; sourceTree = ""; }; + 9B9498A42017EFB400158761 /* AIRGoogleMapCallout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapCallout.h; path = AirGoogleMaps/AIRGoogleMapCallout.h; sourceTree = ""; }; + 9B9498A52017EFB400158761 /* AIRGoogleMapPolygonManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapPolygonManager.h; path = AirGoogleMaps/AIRGoogleMapPolygonManager.h; sourceTree = ""; }; + 9B9498A62017EFB400158761 /* AIRGoogleMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapUrlTile.m; path = AirGoogleMaps/AIRGoogleMapUrlTile.m; sourceTree = ""; }; + 9B9498A72017EFB400158761 /* AIRGoogleMapURLTileManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapURLTileManager.m; path = AirGoogleMaps/AIRGoogleMapURLTileManager.m; sourceTree = ""; }; + 9B9498A82017EFB400158761 /* AIRGMSPolygon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGMSPolygon.m; path = AirGoogleMaps/AIRGMSPolygon.m; sourceTree = ""; }; + 9B9498A92017EFB400158761 /* RCTConvert+GMSMapViewType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RCTConvert+GMSMapViewType.h"; path = "AirGoogleMaps/RCTConvert+GMSMapViewType.h"; sourceTree = ""; }; + 9B9498AA2017EFB400158761 /* AIRGoogleMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMap.h; path = AirGoogleMaps/AIRGoogleMap.h; sourceTree = ""; }; + 9B9498AB2017EFB400158761 /* AIRGoogleMapMarkerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapMarkerManager.h; path = AirGoogleMaps/AIRGoogleMapMarkerManager.h; sourceTree = ""; }; + 9B9498AC2017EFB400158761 /* AIRGoogleMapCallout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapCallout.m; path = AirGoogleMaps/AIRGoogleMapCallout.m; sourceTree = ""; }; + 9B9498AD2017EFB400158761 /* AIRGoogleMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapUrlTileManager.h; path = AirGoogleMaps/AIRGoogleMapUrlTileManager.h; sourceTree = ""; }; + 9B9498AE2017EFB500158761 /* AIRGMSMarker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGMSMarker.m; path = AirGoogleMaps/AIRGMSMarker.m; sourceTree = ""; }; + 9B9498AF2017EFB500158761 /* AIRGMSPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGMSPolyline.m; path = AirGoogleMaps/AIRGMSPolyline.m; sourceTree = ""; }; + 9B9498B02017EFB500158761 /* AIRGoogleMapCircleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapCircleManager.h; path = AirGoogleMaps/AIRGoogleMapCircleManager.h; sourceTree = ""; }; + 9B9498B12017EFB500158761 /* AIRGoogleMapPolylineManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapPolylineManager.m; path = AirGoogleMaps/AIRGoogleMapPolylineManager.m; sourceTree = ""; }; + 9B9498B32017EFB500158761 /* AIRGoogleMapCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapCircle.m; path = AirGoogleMaps/AIRGoogleMapCircle.m; sourceTree = ""; }; + 9B9498B42017EFB500158761 /* AIRGMSPolyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGMSPolyline.h; path = AirGoogleMaps/AIRGMSPolyline.h; sourceTree = ""; }; + 9B9498B52017EFB500158761 /* AIRGoogleMapMarkerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapMarkerManager.m; path = AirGoogleMaps/AIRGoogleMapMarkerManager.m; sourceTree = ""; }; + 9B9498B62017EFB500158761 /* AIRGoogleMapPolylineManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapPolylineManager.h; path = AirGoogleMaps/AIRGoogleMapPolylineManager.h; sourceTree = ""; }; + 9B9498B72017EFB500158761 /* AIRGoogleMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMap.m; path = AirGoogleMaps/AIRGoogleMap.m; sourceTree = ""; }; + 9B9498B82017EFB600158761 /* AIRGoogleMapPolyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapPolyline.h; path = AirGoogleMaps/AIRGoogleMapPolyline.h; sourceTree = ""; }; + 9B9498B92017EFB600158761 /* RCTConvert+GMSMapViewType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RCTConvert+GMSMapViewType.m"; path = "AirGoogleMaps/RCTConvert+GMSMapViewType.m"; sourceTree = ""; }; + 9B9498BA2017EFB600158761 /* AIRGMSPolygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGMSPolygon.h; path = AirGoogleMaps/AIRGMSPolygon.h; sourceTree = ""; }; + 9B9498BB2017EFB600158761 /* AIRGoogleMapPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapPolyline.m; path = AirGoogleMaps/AIRGoogleMapPolyline.m; sourceTree = ""; }; + 9B9498BC2017EFB600158761 /* AIRGoogleMapCircleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapCircleManager.m; path = AirGoogleMaps/AIRGoogleMapCircleManager.m; sourceTree = ""; }; + 9B9498BD2017EFB600158761 /* AIRGoogleMapManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapManager.m; path = AirGoogleMaps/AIRGoogleMapManager.m; sourceTree = ""; }; + 9B9498BE2017EFB600158761 /* AIRGoogleMapManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapManager.h; path = AirGoogleMaps/AIRGoogleMapManager.h; sourceTree = ""; }; + 9B9498C02017EFB700158761 /* AIRGoogleMapMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapMarker.h; path = AirGoogleMaps/AIRGoogleMapMarker.h; sourceTree = ""; }; + 9B9498C12017EFB700158761 /* AIRGMSMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGMSMarker.h; path = AirGoogleMaps/AIRGMSMarker.h; sourceTree = ""; }; + 9B9498C22017EFB700158761 /* AIRGoogleMapCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapCircle.h; path = AirGoogleMaps/AIRGoogleMapCircle.h; sourceTree = ""; }; + 9B9498C32017EFB700158761 /* AIRGoogleMapPolygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapPolygon.h; path = AirGoogleMaps/AIRGoogleMapPolygon.h; sourceTree = ""; }; + 9B9498C42017EFB700158761 /* AIRGoogleMapCalloutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapCalloutManager.m; path = AirGoogleMaps/AIRGoogleMapCalloutManager.m; sourceTree = ""; }; + 9B9498C52017EFB800158761 /* AIRGoogleMapCalloutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapCalloutManager.h; path = AirGoogleMaps/AIRGoogleMapCalloutManager.h; sourceTree = ""; }; + 9B9498C62017EFB800158761 /* AIRGoogleMapPolygon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapPolygon.m; path = AirGoogleMaps/AIRGoogleMapPolygon.m; sourceTree = ""; }; + 9B9498C72017EFB800158761 /* AIRGoogleMapMarker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapMarker.m; path = AirGoogleMaps/AIRGoogleMapMarker.m; sourceTree = ""; }; + 9B9498C82017EFB800158761 /* AIRGoogleMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRGoogleMapUrlTile.h; path = AirGoogleMaps/AIRGoogleMapUrlTile.h; sourceTree = ""; }; + 9B9498C92017EFB800158761 /* AIRGoogleMapPolygonManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRGoogleMapPolygonManager.m; path = AirGoogleMaps/AIRGoogleMapPolygonManager.m; sourceTree = ""; }; + B5EA3BA72098E22B000E7AFD /* AIRDummyView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRDummyView.m; path = AirGoogleMaps/AIRDummyView.m; sourceTree = ""; }; + B5EA3BA82098E22B000E7AFD /* AIRDummyView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRDummyView.h; path = AirGoogleMaps/AIRDummyView.h; sourceTree = ""; }; DA6C26361C9E2AFE0035349F /* AIRMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTile.h; sourceTree = ""; }; DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapUrlTile.m; sourceTree = ""; }; DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTileManager.h; sourceTree = ""; }; @@ -90,6 +167,8 @@ 11FA5C481C4A1296003AC2EE = { isa = PBXGroup; children = ( + 9B9498A32017EF9D00158761 /* AirGoogleMaps */, + 62AEC4D31FD5A0AA003225E0 /* AIRMapLocalTileOverlay.m */, 11FA5C531C4A1296003AC2EE /* AirMaps */, 11FA5C521C4A1296003AC2EE /* Products */, ); @@ -132,6 +211,8 @@ 1125B2D31C4AD3DA007D0023 /* AIRMapPolyline.h */, 1125B2D51C4AD3DA007D0023 /* AIRMapPolylineManager.h */, 1125B2D61C4AD3DA007D0023 /* AIRMapPolylineManager.m */, + 2163AA4E1FEAEDD100BBEC95 /* AIRMapPolylineRenderer.h */, + 2163AA4F1FEAEDD100BBEC95 /* AIRMapPolylineRenderer.m */, 1125B2F01C4AD445007D0023 /* SMCalloutView.h */, 1125B2F11C4AD445007D0023 /* SMCalloutView.m */, 19DABC7D1E7C9D3C00F41150 /* RCTConvert+AirMap.h */, @@ -140,10 +221,65 @@ DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */, DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */, DA6C263D1C9E324A0035349F /* AIRMapUrlTileManager.m */, + 628F811E1FD16D780058313A /* AIRMapLocalTile.h */, + 628F811F1FD16DF80058313A /* AIRMapLocalTile.m */, + 628F81211FD16EAB0058313A /* AIRMapLocalTileManager.h */, + 628F81221FD16EFA0058313A /* AIRMapLocalTileManager.m */, + 53D31638202E72D500B55447 /* AIRMapOverlay.h */, + 53D31639202E72FC00B55447 /* AIRMapOverlay.m */, + 53D31637202E725E00B55447 /* AIRMapOverlayManager.h */, + 53D31635202E723B00B55447 /* AIRMapOverlayManager.m */, + 53D3163B202E732300B55447 /* AIRMapOverlayRenderer.h */, + 53D3163C202E734F00B55447 /* AIRMapOverlayRenderer.m */, ); path = AirMaps; sourceTree = ""; }; + 9B9498A32017EF9D00158761 /* AirGoogleMaps */ = { + isa = PBXGroup; + children = ( + B5EA3BA82098E22B000E7AFD /* AIRDummyView.h */, + B5EA3BA72098E22B000E7AFD /* AIRDummyView.m */, + 9B9498C12017EFB700158761 /* AIRGMSMarker.h */, + 9B9498AE2017EFB500158761 /* AIRGMSMarker.m */, + 9B9498BA2017EFB600158761 /* AIRGMSPolygon.h */, + 9B9498A82017EFB400158761 /* AIRGMSPolygon.m */, + 9B9498B42017EFB500158761 /* AIRGMSPolyline.h */, + 9B9498AF2017EFB500158761 /* AIRGMSPolyline.m */, + 9B9498AA2017EFB400158761 /* AIRGoogleMap.h */, + 9B9498B72017EFB500158761 /* AIRGoogleMap.m */, + 9B9498A42017EFB400158761 /* AIRGoogleMapCallout.h */, + 9B9498AC2017EFB400158761 /* AIRGoogleMapCallout.m */, + 9B9498C52017EFB800158761 /* AIRGoogleMapCalloutManager.h */, + 9B9498C42017EFB700158761 /* AIRGoogleMapCalloutManager.m */, + 9B9498C22017EFB700158761 /* AIRGoogleMapCircle.h */, + 9B9498B32017EFB500158761 /* AIRGoogleMapCircle.m */, + 9B9498B02017EFB500158761 /* AIRGoogleMapCircleManager.h */, + 9B9498BC2017EFB600158761 /* AIRGoogleMapCircleManager.m */, + 9B9498BE2017EFB600158761 /* AIRGoogleMapManager.h */, + 9B9498BD2017EFB600158761 /* AIRGoogleMapManager.m */, + 9B9498C02017EFB700158761 /* AIRGoogleMapMarker.h */, + 9B9498C72017EFB800158761 /* AIRGoogleMapMarker.m */, + 9B9498AB2017EFB400158761 /* AIRGoogleMapMarkerManager.h */, + 9B9498B52017EFB500158761 /* AIRGoogleMapMarkerManager.m */, + 9B9498C32017EFB700158761 /* AIRGoogleMapPolygon.h */, + 9B9498C62017EFB800158761 /* AIRGoogleMapPolygon.m */, + 9B9498A52017EFB400158761 /* AIRGoogleMapPolygonManager.h */, + 9B9498C92017EFB800158761 /* AIRGoogleMapPolygonManager.m */, + 9B9498B82017EFB600158761 /* AIRGoogleMapPolyline.h */, + 9B9498BB2017EFB600158761 /* AIRGoogleMapPolyline.m */, + 9B9498B62017EFB500158761 /* AIRGoogleMapPolylineManager.h */, + 9B9498B12017EFB500158761 /* AIRGoogleMapPolylineManager.m */, + 9B9498C82017EFB800158761 /* AIRGoogleMapUrlTile.h */, + 9B9498A62017EFB400158761 /* AIRGoogleMapUrlTile.m */, + 9B9498AD2017EFB400158761 /* AIRGoogleMapUrlTileManager.h */, + 9B9498A72017EFB400158761 /* AIRGoogleMapURLTileManager.m */, + 9B9498A92017EFB400158761 /* RCTConvert+GMSMapViewType.h */, + 9B9498B92017EFB600158761 /* RCTConvert+GMSMapViewType.m */, + ); + name = AirGoogleMaps; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -200,21 +336,47 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 62AEC4D41FD5A0AA003225E0 /* AIRMapLocalTileOverlay.m in Sources */, + 9B9498DC2017EFB800158761 /* AIRGoogleMapPolygonManager.m in Sources */, 1125B2E31C4AD3DA007D0023 /* AIRMapPolygon.m in Sources */, 1125B2E41C4AD3DA007D0023 /* AIRMapPolygonManager.m in Sources */, + 9B9498CB2017EFB800158761 /* AIRGoogleMapURLTileManager.m in Sources */, 1125B2DB1C4AD3DA007D0023 /* AIRMapCallout.m in Sources */, + 53D31636202E723B00B55447 /* AIRMapOverlayManager.m in Sources */, 1125B2E01C4AD3DA007D0023 /* AIRMapManager.m in Sources */, 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */, + 9B9498DA2017EFB800158761 /* AIRGoogleMapPolygon.m in Sources */, + 9B9498D12017EFB800158761 /* AIRGoogleMapCircle.m in Sources */, 1125B2DD1C4AD3DA007D0023 /* AIRMapCircle.m in Sources */, + 9B9498CE2017EFB800158761 /* AIRGMSMarker.m in Sources */, + 9B9498D72017EFB800158761 /* AIRGoogleMapManager.m in Sources */, 19DABC7F1E7C9D3C00F41150 /* RCTConvert+AirMap.m in Sources */, 1125B2E51C4AD3DA007D0023 /* AIRMapPolyline.m in Sources */, + 9B9498D52017EFB800158761 /* AIRGoogleMapPolyline.m in Sources */, + 9B9498CF2017EFB800158761 /* AIRGMSPolyline.m in Sources */, + 9B9498D42017EFB800158761 /* RCTConvert+GMSMapViewType.m in Sources */, + 9B9498D32017EFB800158761 /* AIRGoogleMap.m in Sources */, DA6C263E1C9E324A0035349F /* AIRMapUrlTileManager.m in Sources */, + 9B9498DB2017EFB800158761 /* AIRGoogleMapMarker.m in Sources */, + 628F81201FD16DF80058313A /* AIRMapLocalTile.m in Sources */, + 9B9498D92017EFB800158761 /* AIRGoogleMapCalloutManager.m in Sources */, + 53D3163A202E72FC00B55447 /* AIRMapOverlay.m in Sources */, + 53D3163D202E734F00B55447 /* AIRMapOverlayRenderer.m in Sources */, 1125B2DA1C4AD3DA007D0023 /* AIRMap.m in Sources */, 1125B2DF1C4AD3DA007D0023 /* AIRMapCoordinate.m in Sources */, + 9B9498D62017EFB800158761 /* AIRGoogleMapCircleManager.m in Sources */, 1125B2F21C4AD445007D0023 /* SMCalloutView.m in Sources */, + 2163AA501FEAEDD100BBEC95 /* AIRMapPolylineRenderer.m in Sources */, + 9B9498D02017EFB800158761 /* AIRGoogleMapPolylineManager.m in Sources */, 1125B2E11C4AD3DA007D0023 /* AIRMapMarker.m in Sources */, + 9B9498CA2017EFB800158761 /* AIRGoogleMapUrlTile.m in Sources */, + B5EA3BA92098E22B000E7AFD /* AIRDummyView.m in Sources */, + 9B9498CD2017EFB800158761 /* AIRGoogleMapCallout.m in Sources */, 1125B2E21C4AD3DA007D0023 /* AIRMapMarkerManager.m in Sources */, DA6C26381C9E2AFE0035349F /* AIRMapUrlTile.m in Sources */, + 628F81231FD16EFA0058313A /* AIRMapLocalTileManager.m in Sources */, + 9B9498D22017EFB800158761 /* AIRGoogleMapMarkerManager.m in Sources */, + 9B9498CC2017EFB800158761 /* AIRGMSPolygon.m in Sources */, 1125B2DE1C4AD3DA007D0023 /* AIRMapCircleManager.m in Sources */, 1125B2DC1C4AD3DA007D0023 /* AIRMapCalloutManager.m in Sources */, ); diff --git a/lib/ios/AirMaps/AIRMap.m b/lib/ios/AirMaps/AIRMap.m index 5b18d2d047..e89b004185 100644 --- a/lib/ios/AirMaps/AIRMap.m +++ b/lib/ios/AirMaps/AIRMap.m @@ -17,6 +17,8 @@ #import "AIRMapCircle.h" #import #import "AIRMapUrlTile.h" +#import "AIRMapLocalTile.h" +#import "AIRMapOverlay.h" const CLLocationDegrees AIRMapDefaultSpan = 0.005; const NSTimeInterval AIRMapRegionChangeObserveInterval = 0.1; @@ -92,6 +94,14 @@ - (void)dealloc [_regionChangeObserveTimer invalidate]; } +-(void)addSubview:(UIView *)view { + if([view isKindOfClass:[AIRMapMarker class]]) { + [self addAnnotation:(id )view]; + } else { + [super addSubview:view]; + } +} + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-missing-super-calls" - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex { @@ -106,10 +116,17 @@ - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex ((AIRMapPolygon *)subview).map = self; [self addOverlay:(id)subview]; } else if ([subview isKindOfClass:[AIRMapCircle class]]) { + ((AIRMapCircle *)subview).map = self; [self addOverlay:(id)subview]; } else if ([subview isKindOfClass:[AIRMapUrlTile class]]) { ((AIRMapUrlTile *)subview).map = self; [self addOverlay:(id)subview]; + } else if ([subview isKindOfClass:[AIRMapLocalTile class]]) { + ((AIRMapLocalTile *)subview).map = self; + [self addOverlay:(id)subview]; + } else if ([subview isKindOfClass:[AIRMapOverlay class]]) { + ((AIRMapOverlay *)subview).map = self; + [self addOverlay:(id)subview]; } else { NSArray> *childSubviews = [subview reactSubviews]; for (int i = 0; i < childSubviews.count; i++) { @@ -135,6 +152,10 @@ - (void)removeReactSubview:(id)subview { [self removeOverlay:(id ) subview]; } else if ([subview isKindOfClass:[AIRMapUrlTile class]]) { [self removeOverlay:(id ) subview]; + } else if ([subview isKindOfClass:[AIRMapLocalTile class]]) { + [self removeOverlay:(id ) subview]; + } else if ([subview isKindOfClass:[AIRMapOverlay class]]) { + [self removeOverlay:(id ) subview]; } else { NSArray> *childSubviews = [subview reactSubviews]; for (int i = 0; i < childSubviews.count; i++) { @@ -409,18 +430,18 @@ - (void)cacheViewIfNeeded { - (void)updateLegalLabelInsets { if (_legalLabel) { dispatch_async(dispatch_get_main_queue(), ^{ - CGRect frame = _legalLabel.frame; - if (_legalLabelInsets.left) { - frame.origin.x = _legalLabelInsets.left; - } else if (_legalLabelInsets.right) { - frame.origin.x = self.frame.size.width - _legalLabelInsets.right - frame.size.width; + CGRect frame = self->_legalLabel.frame; + if (self->_legalLabelInsets.left) { + frame.origin.x = self->_legalLabelInsets.left; + } else if (self->_legalLabelInsets.right) { + frame.origin.x = self.frame.size.width - self->_legalLabelInsets.right - frame.size.width; } - if (_legalLabelInsets.top) { - frame.origin.y = _legalLabelInsets.top; - } else if (_legalLabelInsets.bottom) { - frame.origin.y = self.frame.size.height - _legalLabelInsets.bottom - frame.size.height; + if (self->_legalLabelInsets.top) { + frame.origin.y = self->_legalLabelInsets.top; + } else if (self->_legalLabelInsets.bottom) { + frame.origin.y = self.frame.size.height - self->_legalLabelInsets.bottom - frame.size.height; } - _legalLabel.frame = frame; + self->_legalLabel.frame = frame; }); } } diff --git a/lib/ios/AirMaps/AIRMapLocalTile.h b/lib/ios/AirMaps/AIRMapLocalTile.h new file mode 100644 index 0000000000..d03d7b1ee2 --- /dev/null +++ b/lib/ios/AirMaps/AIRMapLocalTile.h @@ -0,0 +1,36 @@ +// +// AIRMapLocalTile.h +// AirMaps +// +// Created by Peter Zavadsky on 01/12/2017. +// Copyright © 2017 Christopher. All rights reserved. +// + +#import +#import +#import + +#import +#import +#import "AIRMapCoordinate.h" +#import "AIRMap.h" +#import "RCTConvert+AirMap.h" + +@interface AIRMapLocalTile : MKAnnotationView + +@property (nonatomic, weak) AIRMap *map; + +@property (nonatomic, strong) MKTileOverlay *tileOverlay; +@property (nonatomic, strong) MKTileOverlayRenderer *renderer; + +@property (nonatomic, copy) NSString *pathTemplate; +@property (nonatomic, assign) CGFloat tileSize; + +#pragma mark MKOverlay protocol + +@property(nonatomic, readonly) CLLocationCoordinate2D coordinate; +@property(nonatomic, readonly) MKMapRect boundingMapRect; +//- (BOOL)intersectsMapRect:(MKMapRect)mapRect; +- (BOOL)canReplaceMapContent; + +@end diff --git a/lib/ios/AirMaps/AIRMapLocalTile.m b/lib/ios/AirMaps/AIRMapLocalTile.m new file mode 100644 index 0000000000..17e38822d2 --- /dev/null +++ b/lib/ios/AirMaps/AIRMapLocalTile.m @@ -0,0 +1,68 @@ +// +// AIRMapLocalTile.m +// AirMaps +// +// Created by Peter Zavadsky on 01/12/2017. +// Copyright © 2017 Christopher. All rights reserved. +// + +#import "AIRMapLocalTile.h" +#import +#import "AIRMapLocalTileOverlay.h" + +@implementation AIRMapLocalTile { + BOOL _pathTemplateSet; + BOOL _tileSizeSet; +} + + +- (void)setPathTemplate:(NSString *)pathTemplate{ + _pathTemplate = pathTemplate; + _pathTemplateSet = YES; + [self createTileOverlayAndRendererIfPossible]; + [self update]; +} + +- (void)setTileSize:(CGFloat)tileSize{ + _tileSize = tileSize; + _tileSizeSet = YES; + [self createTileOverlayAndRendererIfPossible]; + [self update]; +} + +- (void) createTileOverlayAndRendererIfPossible +{ + if (!_pathTemplateSet || !_tileSizeSet) return; + self.tileOverlay = [[AIRMapLocalTileOverlay alloc] initWithURLTemplate:self.pathTemplate]; + self.tileOverlay.canReplaceMapContent = YES; + self.tileOverlay.tileSize = CGSizeMake(_tileSize, _tileSize); + self.renderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:self.tileOverlay]; +} + +- (void) update +{ + if (!_renderer) return; + + if (_map == nil) return; + [_map removeOverlay:self]; + [_map addOverlay:self level:MKOverlayLevelAboveLabels]; +} + +#pragma mark MKOverlay implementation + +- (CLLocationCoordinate2D) coordinate +{ + return self.tileOverlay.coordinate; +} + +- (MKMapRect) boundingMapRect +{ + return self.tileOverlay.boundingMapRect; +} + +- (BOOL)canReplaceMapContent +{ + return self.tileOverlay.canReplaceMapContent; +} + +@end diff --git a/lib/ios/AirMaps/AIRMapLocalTileManager.h b/lib/ios/AirMaps/AIRMapLocalTileManager.h new file mode 100644 index 0000000000..c6ee326953 --- /dev/null +++ b/lib/ios/AirMaps/AIRMapLocalTileManager.h @@ -0,0 +1,13 @@ +// +// AIRMapLocalTileManager.h +// AirMaps +// +// Created by Peter Zavadsky on 01/12/2017. +// Copyright © 2017 Christopher. All rights reserved. +// + +#import + +@interface AIRMapLocalTileManager : RCTViewManager + +@end diff --git a/lib/ios/AirMaps/AIRMapLocalTileManager.m b/lib/ios/AirMaps/AIRMapLocalTileManager.m new file mode 100644 index 0000000000..a7997bfe0c --- /dev/null +++ b/lib/ios/AirMaps/AIRMapLocalTileManager.m @@ -0,0 +1,38 @@ +// +// AIRMapLocalTileManager.m +// AirMaps +// +// Created by Peter Zavadsky on 01/12/2017. +// Copyright © 2017 Christopher. All rights reserved. +// + +#import +#import +#import +#import +#import +#import +#import "AIRMapMarker.h" +#import "AIRMapLocalTile.h" + +#import "AIRMapLocalTileManager.h" + +@interface AIRMapLocalTileManager() + +@end + +@implementation AIRMapLocalTileManager + + +RCT_EXPORT_MODULE() + +- (UIView *)view +{ + AIRMapLocalTile *tile = [AIRMapLocalTile new]; + return tile; +} + +RCT_EXPORT_VIEW_PROPERTY(pathTemplate, NSString) +RCT_EXPORT_VIEW_PROPERTY(tileSize, CGFloat) + +@end diff --git a/lib/ios/AirMaps/AIRMapLocalTileOverlay.h b/lib/ios/AirMaps/AIRMapLocalTileOverlay.h new file mode 100644 index 0000000000..f588e102ff --- /dev/null +++ b/lib/ios/AirMaps/AIRMapLocalTileOverlay.h @@ -0,0 +1,12 @@ +// +// AIRMapLocalTileOverlay.h +// Pods +// +// Created by Peter Zavadsky on 04/12/2017. +// + +#import + +@interface AIRMapLocalTileOverlay : MKTileOverlay + +@end diff --git a/lib/ios/AirMaps/AIRMapLocalTileOverlay.m b/lib/ios/AirMaps/AIRMapLocalTileOverlay.m new file mode 100644 index 0000000000..27b02fac7a --- /dev/null +++ b/lib/ios/AirMaps/AIRMapLocalTileOverlay.m @@ -0,0 +1,31 @@ +// +// AIRMapLocalTileOverlay.m +// Pods-AirMapsExplorer +// +// Created by Peter Zavadsky on 04/12/2017. +// + +#import "AIRMapLocalTileOverlay.h" + +@interface AIRMapLocalTileOverlay () + +@end + +@implementation AIRMapLocalTileOverlay + + +-(void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *, NSError *))result { + NSMutableString *tileFilePath = [self.URLTemplate mutableCopy]; + [tileFilePath replaceOccurrencesOfString: @"{x}" withString:[NSString stringWithFormat:@"%li", (long)path.x] options:0 range:NSMakeRange(0, tileFilePath.length)]; + [tileFilePath replaceOccurrencesOfString:@"{y}" withString:[NSString stringWithFormat:@"%li", (long)path.y] options:0 range:NSMakeRange(0, tileFilePath.length)]; + [tileFilePath replaceOccurrencesOfString:@"{z}" withString:[NSString stringWithFormat:@"%li", (long)path.z] options:0 range:NSMakeRange(0, tileFilePath.length)]; + if ([[NSFileManager defaultManager] fileExistsAtPath:tileFilePath]) { + NSData* tile = [NSData dataWithContentsOfFile:tileFilePath]; + result(tile,nil); + } else { + result(nil, nil); + } +} + + +@end diff --git a/lib/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m index 4838343693..da1efc08e5 100644 --- a/lib/ios/AirMaps/AIRMapManager.m +++ b/lib/ios/AirMaps/AIRMapManager.m @@ -23,8 +23,10 @@ #import "AIRMapCircle.h" #import "SMCalloutView.h" #import "AIRMapUrlTile.h" +#import "AIRMapLocalTile.h" #import "AIRMapSnapshot.h" #import "RCTConvert+AirMap.h" +#import "AIRMapOverlay.h" #import @@ -36,7 +38,7 @@ @interface AIRMapManager() @end @implementation AIRMapManager - + RCT_EXPORT_MODULE() - (UIView *)view @@ -73,6 +75,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(showsScale, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsTraffic, BOOL) RCT_EXPORT_VIEW_PROPERTY(zoomEnabled, BOOL) +RCT_EXPORT_VIEW_PROPERTY(kmlSrc, NSString) RCT_EXPORT_VIEW_PROPERTY(rotateEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(scrollEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(pitchEnabled, BOOL) @@ -126,6 +129,30 @@ - (UIView *)view #pragma mark exported MapView methods +RCT_EXPORT_METHOD(animateToNavigation:(nonnull NSNumber *)reactTag + withRegion:(MKCoordinateRegion)region + withBearing:(CGFloat)bearing + withAngle:(double)angle + withDuration:(CGFloat)duration) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view); + } else { + AIRMap *mapView = (AIRMap *)view; + MKMapCamera *mapCamera = [[mapView camera] copy]; + [mapCamera setPitch:angle]; + [mapCamera setHeading:bearing]; + + [AIRMap animateWithDuration:duration/1000 animations:^{ + [(AIRMap *)view setRegion:region animated:YES]; + [mapView setCamera:mapCamera animated:YES]; + }]; + } + }]; +} + RCT_EXPORT_METHOD(animateToRegion:(nonnull NSNumber *)reactTag withRegion:(MKCoordinateRegion)region withDuration:(CGFloat)duration) @@ -314,6 +341,58 @@ - (UIView *)view }]; } +RCT_EXPORT_METHOD(pointForCoordinate:(nonnull NSNumber *)reactTag + coordinate: (NSDictionary *)coordinate + resolver: (RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + AIRMap *mapView = (AIRMap *)view; + if (![view isKindOfClass:[AIRMap class]]) { + reject(@"Invalid argument", [NSString stringWithFormat:@"Invalid view returned from registry, expecting AIRMap, got: %@", view], NULL); + } else { + CGPoint touchPoint = [mapView convertCoordinate: + CLLocationCoordinate2DMake( + [coordinate[@"lat"] doubleValue], + [coordinate[@"lng"] doubleValue] + ) + toPointToView:mapView]; + + resolve(@{ + @"x": @(touchPoint.x), + @"y": @(touchPoint.y), + }); + } + }]; +} + +RCT_EXPORT_METHOD(coordinateForPoint:(nonnull NSNumber *)reactTag + point:(NSDictionary *)point + resolver: (RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + AIRMap *mapView = (AIRMap *)view; + if (![view isKindOfClass:[AIRMap class]]) { + reject(@"Invalid argument", [NSString stringWithFormat:@"Invalid view returned from registry, expecting AIRMap, got: %@", view], NULL); + } else { + CLLocationCoordinate2D coordinate = [mapView convertPoint: + CGPointMake( + [point[@"x"] doubleValue], + [point[@"y"] doubleValue] + ) + toCoordinateFromView:mapView]; + + resolve(@{ + @"lat": @(coordinate.latitude), + @"lng": @(coordinate.longitude), + }); + } + }]; +} + #pragma mark Take Snapshot - (void)takeMapSnapshot:(AIRMap *)mapView snapshotter:(MKMapSnapshotter *) snapshotter @@ -455,6 +534,24 @@ - (void)handleMapTap:(UITapGestureRecognizer *)recognizer { } } } + + if ([overlay isKindOfClass:[AIRMapOverlay class]]) { + AIRMapOverlay *imageOverlay = (AIRMapOverlay*) overlay; + if (MKMapRectContainsPoint(imageOverlay.boundingMapRect, mapPoint)) { + if (imageOverlay.onPress) { + id event = @{ + @"action": @"image-overlay-press", + @"name": imageOverlay.name ?: @"unknown", + @"coordinate": @{ + @"latitude": @(imageOverlay.coordinate.latitude), + @"longitude": @(imageOverlay.coordinate.longitude) + } + }; + imageOverlay.onPress(event); + } + } + } + } if (nearestDistance <= maxMeters) { @@ -534,6 +631,10 @@ - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id #import +NSInteger const AIR_CALLOUT_OPEN_ZINDEX_BASELINE = 999; + @implementation AIREmptyCalloutBackgroundView @end @@ -22,6 +24,16 @@ @implementation AIRMapMarker { BOOL _hasSetCalloutOffset; RCTImageLoaderCancellationBlock _reloadImageCancellationBlock; MKPinAnnotationView *_pinView; + BOOL _calloutIsOpen; + NSInteger _zIndexBeforeOpen; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self.layer addObserver:self forKeyPath:@"zPosition" options:NSKeyValueObservingOptionNew context:nil]; + } + return self; } - (void)reactSetFrame:(CGRect)frame @@ -137,6 +149,9 @@ - (void)fillCalloutView:(SMCalloutView *)calloutView - (void)showCalloutView { + _calloutIsOpen = YES; + [self setZIndex:_zIndexBeforeOpen]; + MKAnnotationView *annotationView = [self getAnnotationView]; [self setSelected:YES animated:NO]; @@ -222,6 +237,8 @@ - (void)_handleTap:(UITapGestureRecognizer *)recognizer { - (void)hideCalloutView { + _calloutIsOpen = NO; + [self setZIndex:_zIndexBeforeOpen]; // hide the callout view [self.map.calloutView dismissCalloutAnimated:YES]; @@ -298,8 +315,19 @@ - (void)setPinColor:(UIColor *)pinColor - (void)setZIndex:(NSInteger)zIndex { - _zIndex = zIndex; - self.layer.zPosition = _zIndex; + _zIndexBeforeOpen = zIndex; + _zIndex = _calloutIsOpen ? zIndex + AIR_CALLOUT_OPEN_ZINDEX_BASELINE : zIndex; + self.layer.zPosition = zIndex; +} + +- (void)dealloc { + [self.layer removeObserver:self forKeyPath:@"zPosition"]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if ([keyPath isEqualToString:@"zPosition"]) { + self.layer.zPosition = _zIndex; + } } @end diff --git a/lib/ios/AirMaps/AIRMapOverlay.h b/lib/ios/AirMaps/AIRMapOverlay.h new file mode 100644 index 0000000000..e3be7cb78b --- /dev/null +++ b/lib/ios/AirMaps/AIRMapOverlay.h @@ -0,0 +1,36 @@ +#import "AIRMapCallout.h" + +#import +#import + +#import "RCTConvert+AirMap.h" +#import +#import "AIRMap.h" +#import "AIRMapOverlayRenderer.h" + +@class RCTBridge; + +@interface AIRMapOverlay : UIView + +@property (nonatomic, strong) AIRMapOverlayRenderer *renderer; +@property (nonatomic, weak) AIRMap *map; +@property (nonatomic, weak) RCTBridge *bridge; + +@property (nonatomic, strong) NSString *name; +@property (nonatomic, copy) NSString *imageSrc; +@property (nonatomic, strong, readonly) UIImage *overlayImage; +@property (nonatomic, copy) NSArray *boundsRect; +@property (nonatomic, assign) NSInteger rotation; +@property (nonatomic, assign) CGFloat transparency; +@property (nonatomic, assign) NSInteger zIndex; + +@property (nonatomic, copy) RCTBubblingEventBlock onPress; + +#pragma mark MKOverlay protocol + +@property(nonatomic, readonly) CLLocationCoordinate2D coordinate; +@property(nonatomic, readonly) MKMapRect boundingMapRect; +- (BOOL)intersectsMapRect:(MKMapRect)mapRect; +- (BOOL)canReplaceMapContent; + +@end diff --git a/lib/ios/AirMaps/AIRMapOverlay.m b/lib/ios/AirMaps/AIRMapOverlay.m new file mode 100644 index 0000000000..316fd883a1 --- /dev/null +++ b/lib/ios/AirMaps/AIRMapOverlay.m @@ -0,0 +1,103 @@ +#import "AIRMapOverlay.h" + +#import +#import +#import +#import +#import + +@interface AIRMapOverlay() +@property (nonatomic, strong, readwrite) UIImage *overlayImage; +@end + +@implementation AIRMapOverlay { + RCTImageLoaderCancellationBlock _reloadImageCancellationBlock; + CLLocationCoordinate2D _southWest; + CLLocationCoordinate2D _northEast; + MKMapRect _mapRect; +} + +- (void)setImageSrc:(NSString *)imageSrc +{ + NSLog(@">>> SET IMAGESRC: %@", imageSrc); + _imageSrc = imageSrc; + + if (_reloadImageCancellationBlock) { + _reloadImageCancellationBlock(); + _reloadImageCancellationBlock = nil; + } + __weak typeof(self) weakSelf = self; + _reloadImageCancellationBlock = [_bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc] + size:weakSelf.bounds.size + scale:RCTScreenScale() + clipped:YES + resizeMode:RCTResizeModeCenter + progressBlock:nil + partialLoadBlock:nil + completionBlock:^(NSError *error, UIImage *image) { + if (error) { + NSLog(@"%@", error); + } + dispatch_async(dispatch_get_main_queue(), ^{ + NSLog(@">>> IMAGE: %@", image); + weakSelf.overlayImage = image; + [weakSelf createOverlayRendererIfPossible]; + [weakSelf update]; + }); + }]; +} + +- (void)setBoundsRect:(NSArray *)boundsRect { + _boundsRect = boundsRect; + + _southWest = CLLocationCoordinate2DMake([boundsRect[1][0] doubleValue], [boundsRect[0][1] doubleValue]); + _northEast = CLLocationCoordinate2DMake([boundsRect[0][0] doubleValue], [boundsRect[1][1] doubleValue]); + + MKMapPoint southWest = MKMapPointForCoordinate(_southWest); + MKMapPoint northEast = MKMapPointForCoordinate(_northEast); + + _mapRect = MKMapRectMake(southWest.x, northEast.y, northEast.x - southWest.x, northEast.y - southWest.y); + + [self update]; +} + +- (void)createOverlayRendererIfPossible +{ + if (MKMapRectIsEmpty(_mapRect) || !self.overlayImage) return; + __weak typeof(self) weakSelf = self; + self.renderer = [[AIRMapOverlayRenderer alloc] initWithOverlay:weakSelf]; +} + +- (void)update +{ + if (!_renderer) return; + + if (_map == nil) return; + [_map removeOverlay:self]; + [_map addOverlay:self]; +} + + +#pragma mark MKOverlay implementation + +- (CLLocationCoordinate2D)coordinate +{ + return MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMidX(_mapRect), MKMapRectGetMidY(_mapRect))); +} + +- (MKMapRect)boundingMapRect +{ + return _mapRect; +} + +- (BOOL)intersectsMapRect:(MKMapRect)mapRect +{ + return MKMapRectIntersectsRect(_mapRect, mapRect); +} + +- (BOOL)canReplaceMapContent +{ + return NO; +} + +@end diff --git a/lib/ios/AirMaps/AIRMapOverlayManager.h b/lib/ios/AirMaps/AIRMapOverlayManager.h new file mode 100644 index 0000000000..410288d622 --- /dev/null +++ b/lib/ios/AirMaps/AIRMapOverlayManager.h @@ -0,0 +1,5 @@ +#import + +@interface AIRMapOverlayManager : RCTViewManager + +@end diff --git a/lib/ios/AirMaps/AIRMapOverlayManager.m b/lib/ios/AirMaps/AIRMapOverlayManager.m new file mode 100644 index 0000000000..a6ed765337 --- /dev/null +++ b/lib/ios/AirMaps/AIRMapOverlayManager.m @@ -0,0 +1,27 @@ +#import "AIRMapOverlayManager.h" + +#import +#import +#import +#import "AIRMapOverlay.h" + +@interface AIRMapOverlayManager () + +@end + +@implementation AIRMapOverlayManager + +RCT_EXPORT_MODULE() + +- (UIView *)view +{ + AIRMapOverlay *overlay = [AIRMapOverlay new]; + overlay.bridge = self.bridge; + return overlay; +} + +RCT_REMAP_VIEW_PROPERTY(bounds, boundsRect, NSArray) +RCT_REMAP_VIEW_PROPERTY(image, imageSrc, NSString) + +@end + diff --git a/lib/ios/AirMaps/AIRMapOverlayRenderer.h b/lib/ios/AirMaps/AIRMapOverlayRenderer.h new file mode 100644 index 0000000000..dfe9c883e9 --- /dev/null +++ b/lib/ios/AirMaps/AIRMapOverlayRenderer.h @@ -0,0 +1,8 @@ +#import + +@interface AIRMapOverlayRenderer : MKOverlayRenderer + +@property (nonatomic, assign) NSInteger rotation; +@property (nonatomic, assign) CGFloat transparency; + +@end diff --git a/lib/ios/AirMaps/AIRMapOverlayRenderer.m b/lib/ios/AirMaps/AIRMapOverlayRenderer.m new file mode 100644 index 0000000000..4cd0067eab --- /dev/null +++ b/lib/ios/AirMaps/AIRMapOverlayRenderer.m @@ -0,0 +1,29 @@ +#import "AIRMapOverlayRenderer.h" +#import "AIRMapOverlay.h" + +@implementation AIRMapOverlayRenderer + +- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { + UIImage *image = [(AIRMapOverlay *)self.overlay overlayImage]; + + CGContextSaveGState(context); + + CGImageRef imageReference = image.CGImage; + + MKMapRect theMapRect = [self.overlay boundingMapRect]; + CGRect theRect = [self rectForMapRect:theMapRect]; + + CGContextRotateCTM(context, M_PI); + CGContextScaleCTM(context, -1.0, 1.0); + CGContextAddRect(context, theRect); + CGContextDrawImage(context, theRect, imageReference); + + CGContextRestoreGState(context); +} + +- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale { + return [(AIRMapOverlay *)self.overlay overlayImage] != nil; +} + +@end + diff --git a/lib/ios/AirMaps/AIRMapPolyline.h b/lib/ios/AirMaps/AIRMapPolyline.h index 6311c32487..d34a1dd6ca 100644 --- a/lib/ios/AirMaps/AIRMapPolyline.h +++ b/lib/ios/AirMaps/AIRMapPolyline.h @@ -20,11 +20,12 @@ @property (nonatomic, weak) AIRMap *map; @property (nonatomic, strong) MKPolyline *polyline; -@property (nonatomic, strong) MKPolylineRenderer *renderer; +@property (nonatomic, strong) MKOverlayPathRenderer *renderer; @property (nonatomic, strong) NSArray *coordinates; @property (nonatomic, strong) UIColor *fillColor; @property (nonatomic, strong) UIColor *strokeColor; +@property (nonatomic, strong) NSArray *strokeColors; @property (nonatomic, assign) CGFloat strokeWidth; @property (nonatomic, assign) CGFloat miterLimit; @property (nonatomic, assign) CGLineCap lineCap; diff --git a/lib/ios/AirMaps/AIRMapPolyline.m b/lib/ios/AirMaps/AIRMapPolyline.m index 8e07a63b3b..b230ec7efa 100644 --- a/lib/ios/AirMaps/AIRMapPolyline.m +++ b/lib/ios/AirMaps/AIRMapPolyline.m @@ -4,11 +4,12 @@ // #import "AIRMapPolyline.h" +#import "AIRMapPolylineRenderer.h" #import @implementation AIRMapPolyline { - + } - (void)setFillColor:(UIColor *)fillColor { @@ -21,6 +22,14 @@ - (void)setStrokeColor:(UIColor *)strokeColor { [self update]; } +- (void)setStrokeColors:(NSArray *)strokeColors { + _strokeColors = strokeColors; + if ((self.renderer != nil) && ![_renderer isKindOfClass:[AIRMapPolylineRenderer class]]) { + self.renderer = [self createRenderer]; + } + [self update]; +} + - (void)setStrokeWidth:(CGFloat)strokeWidth { _strokeWidth = strokeWidth; [self update]; @@ -59,27 +68,48 @@ - (void)setCoordinates:(NSArray *)coordinates { coords[i] = coordinates[i].coordinate; } self.polyline = [MKPolyline polylineWithCoordinates:coords count:coordinates.count]; - self.renderer = [[MKPolylineRenderer alloc] initWithPolyline:self.polyline]; + self.renderer = [self createRenderer]; [self update]; } +- (MKOverlayPathRenderer*)createRenderer { + if (self.polyline == nil) return nil; + if (self.strokeColors == nil) { + // Use the default renderer when no array of stroke-colors is defined. + // This behaviour may be changed in the future if we permanently want to + // use the custom renderer, because it can add funtionality that is not + // supported by the default renderer. + return [[MKPolylineRenderer alloc] initWithPolyline:self.polyline]; + } + else { + return [[AIRMapPolylineRenderer alloc] initWithOverlay:self polyline:self.polyline]; + } +} + - (void) update { if (!_renderer) return; - _renderer.fillColor = _fillColor; - _renderer.strokeColor = _strokeColor; - _renderer.lineWidth = _strokeWidth; - _renderer.lineCap = _lineCap; - _renderer.lineJoin = _lineJoin; - _renderer.miterLimit = _miterLimit; - _renderer.lineDashPhase = _lineDashPhase; - _renderer.lineDashPattern = _lineDashPattern; - + [self updateRenderer:_renderer]; + if (_map == nil) return; [_map removeOverlay:self]; [_map addOverlay:self]; } +- (void) updateRenderer:(MKOverlayPathRenderer*)renderer { + renderer.fillColor = _fillColor; + renderer.strokeColor = _strokeColor; + renderer.lineWidth = _strokeWidth; + renderer.lineCap = _lineCap; + renderer.lineJoin = _lineJoin; + renderer.miterLimit = _miterLimit; + renderer.lineDashPhase = _lineDashPhase; + renderer.lineDashPattern = _lineDashPattern; + + if ([renderer isKindOfClass:[AIRMapPolylineRenderer class]]) { + ((AIRMapPolylineRenderer*)renderer).strokeColors = _strokeColors; + } +} #pragma mark MKOverlay implementation @@ -109,38 +139,9 @@ - (BOOL)canReplaceMapContent - (void) drawToSnapshot:(MKMapSnapshot *) snapshot context:(CGContextRef) context { - // Prepare context - CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor); - CGContextSetLineWidth(context, self.strokeWidth); - CGContextSetLineCap(context, self.lineCap); - CGContextSetLineJoin(context, self.lineJoin); - CGContextSetMiterLimit(context, self.miterLimit); - CGFloat dashes[self.lineDashPattern.count]; - for (NSUInteger i = 0; i < self.lineDashPattern.count; i++) { - dashes[i] = self.lineDashPattern[i].floatValue; - } - CGContextSetLineDash(context, self.lineDashPhase, dashes, self.lineDashPattern.count); - - // Begin path - CGContextBeginPath(context); - - // Get coordinates - CLLocationCoordinate2D coordinates[[self.polyline pointCount]]; - [self.polyline getCoordinates:coordinates range:NSMakeRange(0, [self.polyline pointCount])]; - - // Draw line segments - for(int i = 0; i < [self.polyline pointCount]; i++) { - CGPoint point = [snapshot pointForCoordinate:coordinates[i]]; - if (i == 0) { - CGContextMoveToPoint(context,point.x, point.y); - } - else{ - CGContextAddLineToPoint(context,point.x, point.y); - } - } - - // Finish path - CGContextStrokePath(context); + AIRMapPolylineRenderer* renderer = [[AIRMapPolylineRenderer alloc] initWithSnapshot:snapshot overlay:self polyline:self.polyline]; + [self updateRenderer:renderer]; + [renderer drawWithZoomScale:2 inContext:context]; } -@end \ No newline at end of file +@end diff --git a/lib/ios/AirMaps/AIRMapPolylineManager.m b/lib/ios/AirMaps/AIRMapPolylineManager.m index e064b7c4bd..fb807fd945 100644 --- a/lib/ios/AirMaps/AIRMapPolylineManager.m +++ b/lib/ios/AirMaps/AIRMapPolylineManager.m @@ -35,6 +35,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(coordinates, AIRMapCoordinateArray) RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) +RCT_EXPORT_VIEW_PROPERTY(strokeColors, UIColorArray) RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat) RCT_EXPORT_VIEW_PROPERTY(lineCap, CGLineCap) RCT_EXPORT_VIEW_PROPERTY(lineJoin, CGLineJoin) diff --git a/lib/ios/AirMaps/AIRMapPolylineRenderer.h b/lib/ios/AirMaps/AIRMapPolylineRenderer.h new file mode 100644 index 0000000000..f4684c6f45 --- /dev/null +++ b/lib/ios/AirMaps/AIRMapPolylineRenderer.h @@ -0,0 +1,19 @@ +// +// AIRMapPolylineRenderer.h +// mapDemo +// +// Created by IjzerenHein on 13-11-21. +// Copyright (c) 2017 IjzerenHein. All rights reserved. +// + +#import + +@interface AIRMapPolylineRenderer : MKOverlayPathRenderer + +-(id)initWithOverlay:(id)overlay polyline:(MKPolyline*)polyline; +-(id)initWithSnapshot:(MKMapSnapshot*)snapshot overlay:(id)overlay polyline:(MKPolyline*)polyline; +-(void)drawWithZoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context; + +@property (nonatomic, strong) NSArray *strokeColors; + +@end diff --git a/lib/ios/AirMaps/AIRMapPolylineRenderer.m b/lib/ios/AirMaps/AIRMapPolylineRenderer.m new file mode 100644 index 0000000000..b9e8c060c3 --- /dev/null +++ b/lib/ios/AirMaps/AIRMapPolylineRenderer.m @@ -0,0 +1,240 @@ +// +// AIRMapPolylineRenderer.h +// mapDemo +// +// Created by IjzerenHein on 13-11-21. +// Copyright (c) 2017 IjzerenHein. All rights reserved. +// + +#import "AIRMapPolylineRenderer.h" + +@interface AIRMapPolylineRendererSegment : NSObject +- (id)initWithPoint:(CGPoint)point color:(UIColor*)color; +- (void) addPoint:(CGPoint)point color:(UIColor*)color; +@property CGMutablePathRef path; +@property UIColor *startColor; +@property UIColor *endColor; +@property CGPoint startPoint; +@property CGPoint endPoint; +@end +@implementation AIRMapPolylineRendererSegment +- (id)initWithPoint:(CGPoint)point color:(UIColor*)color +{ + self = [super init]; + if (self){ + self.path = CGPathCreateMutable(); + self.startColor = color; + self.startPoint = point; + self.endPoint = point; + CGPathMoveToPoint(self.path, nil, point.x, point.y); + } + return self; +} +- (void) addPoint:(CGPoint)point color:(UIColor*)color +{ + self.endPoint = point; + self.endColor = color; + CGPathAddLineToPoint(self.path, nil, point.x, point.y); +} +@end + +@implementation AIRMapPolylineRenderer { + MKPolyline* _polyline; + NSArray *_strokeColors; + MKMapSnapshot* _snapshot; + CLLocationCoordinate2D* _coordinates; +} + +@synthesize strokeColors; + +- (id)initWithOverlay:(id)overlay polyline:(MKPolyline*)polyline +{ + self = [super initWithOverlay:overlay]; + if (self){ + _polyline = polyline; + [self createPath]; + } + return self; +} + +- (id)initWithSnapshot:(MKMapSnapshot*)snapshot overlay:(id)overlay polyline:(MKPolyline*)polyline +{ + self = [super initWithOverlay:overlay]; + if (self){ + _snapshot = snapshot; + _polyline = polyline; + _coordinates = malloc(sizeof(CLLocationCoordinate2D) * [_polyline pointCount]); + [_polyline getCoordinates:_coordinates range:NSMakeRange(0, [_polyline pointCount])]; + } + return self; +} + +- (void) dealloc +{ + if (_coordinates) free(_coordinates); +} + +- (CGPoint) pointForIndex:(NSUInteger)index +{ + if (_snapshot != nil) { + return [_snapshot pointForCoordinate:_coordinates[index]]; + } + else { + return [self pointForMapPoint:_polyline.points[index]]; + } +} + +- (UIColor*) colorForIndex:(NSUInteger)index +{ + if ((_strokeColors == nil) || !_strokeColors.count) return self.strokeColor; + index = MIN(index, _strokeColors.count - 1); + UIColor* color = _strokeColors[index]; + CGFloat pc_r,pc_g,pc_b,pc_a; + [color getRed:&pc_r green:&pc_g blue:&pc_b alpha:&pc_a]; + return (pc_a == 0) ? nil : color; +} + +- (void) createPath +{ + CGMutablePathRef path = CGPathCreateMutable(); + BOOL first = YES; + for (NSUInteger i = 0, n = _polyline.pointCount; i < n; i++){ + CGPoint point = [self pointForIndex:i]; + if (first) { + CGPathMoveToPoint(path, nil, point.x, point.y); + first = NO; + } else { + CGPathAddLineToPoint(path, nil, point.x, point.y); + } + } + self.path = path; +} + +- (NSArray*) createSegments +{ + NSMutableArray* segments = [NSMutableArray new]; + if (_polyline.pointCount <= 1) return segments; + AIRMapPolylineRendererSegment* segment = nil; + for (NSUInteger i = 0, n = _polyline.pointCount; i < n; i++){ + CGPoint point = [self pointForIndex:i]; + UIColor* color = [self colorForIndex:i]; + if (segment == nil) { + + // Start new segment + segment = [[AIRMapPolylineRendererSegment alloc] initWithPoint:point color:color]; + [segments addObject:segment]; + } + else if (((color == nil) && (segment.endColor == nil)) || + ((color != nil) && [segment.startColor isEqual:color])) { + + // Append point to segment + [segment addPoint:point color: color]; + } + else { + + // Close the last segment if needed + if (segment.endColor == nil) { + [segment addPoint:point color:color]; + } + else { + + // Add transition gradient + segment = [[AIRMapPolylineRendererSegment alloc] initWithPoint:segment.endPoint color:segment.endColor]; + [segment addPoint:point color:color]; + [segments addObject:segment]; + } + + // Start new segment + if (i < (n - 1)) { + segment = [[AIRMapPolylineRendererSegment alloc] initWithPoint:point color:color]; + [segments addObject:segment]; + } + } + } + + // Remove last segment in case it only contains a single path point + if ((segment != nil) && (segment.endColor == nil)) { + [segments removeLastObject]; + } + + return segments; +} + +- (void) setStrokeColors:(NSArray *)strokeColors +{ + if (_strokeColors != strokeColors) { + _strokeColors = strokeColors; + } +} + +- (void) setStrokeColor:(UIColor *)strokeColor +{ + if (super.strokeColor != strokeColor) { + super.strokeColor = strokeColor; + } +} + +- (void) drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context +{ + CGRect pointsRect = CGPathGetBoundingBox(self.path); + CGRect mapRectCG = [self rectForMapRect:mapRect]; + if (!CGRectIntersectsRect(pointsRect, mapRectCG)) return; + + [self drawWithZoomScale:zoomScale inContext:context]; +} + +- (void) drawWithZoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context +{ + CGFloat lineWidth = (self.lineWidth / zoomScale) * 2.0; + CGContextSetLineWidth(context, lineWidth); + CGContextSetLineCap(context, self.lineCap); + CGContextSetLineJoin(context, self.lineJoin); + CGContextSetFillColorWithColor(context, self.fillColor.CGColor); + CGContextSetMiterLimit(context, self.miterLimit); + CGFloat dashes[self.lineDashPattern.count]; + for (NSUInteger i = 0; i < self.lineDashPattern.count; i++) { + dashes[i] = self.lineDashPattern[i].floatValue; + } + CGContextSetLineDash(context, self.lineDashPhase, dashes, self.lineDashPattern.count); + + NSArray* segments = [self createSegments]; + for (NSUInteger i = 0, n = segments.count; i < n; i++) { + AIRMapPolylineRendererSegment* segment = segments[i]; + + CGContextBeginPath(context); + CGContextAddPath(context, segment.path); + + // When segment has two colors, draw it as a gradient + if (![segment.startColor isEqual:segment.endColor]) { + CGFloat pc_r,pc_g,pc_b,pc_a, + cc_r,cc_g,cc_b,cc_a; + [segment.startColor getRed:&pc_r green:&pc_g blue:&pc_b alpha:&pc_a]; + [segment.endColor getRed:&cc_r green:&cc_g blue:&cc_b alpha:&cc_a]; + CGFloat gradientColors[8] = {pc_r,pc_g,pc_b,pc_a, + cc_r,cc_g,cc_b,cc_a}; + CGFloat gradientLocation[2] = {0,1}; + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocation, 2); + CGColorSpaceRelease(colorSpace); + + CGContextReplacePathWithStrokedPath(context); + CGContextClip(context); + CGContextDrawLinearGradient( + context, + gradient, + segment.startPoint, + segment.endPoint, + kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation + ); + CGGradientRelease(gradient); + CGContextResetClip(context); + } + else { + CGContextSetStrokeColorWithColor(context, segment.startColor.CGColor); + CGContextStrokePath(context); + } + } +} + +@end + diff --git a/lib/ios/AirMaps/AIRMapUrlTile.h b/lib/ios/AirMaps/AIRMapUrlTile.h index 49963d3ee5..06eda10dd3 100644 --- a/lib/ios/AirMaps/AIRMapUrlTile.h +++ b/lib/ios/AirMaps/AIRMapUrlTile.h @@ -22,8 +22,10 @@ @property (nonatomic, strong) MKTileOverlay *tileOverlay; @property (nonatomic, strong) MKTileOverlayRenderer *renderer; - @property (nonatomic, copy) NSString *urlTemplate; +@property NSInteger maximumZ; +@property NSInteger minimumZ; +@property BOOL shouldReplaceMapContent; #pragma mark MKOverlay protocol diff --git a/lib/ios/AirMaps/AIRMapUrlTile.m b/lib/ios/AirMaps/AIRMapUrlTile.m index fdefbf3bc7..62e82adc22 100644 --- a/lib/ios/AirMaps/AIRMapUrlTile.m +++ b/lib/ios/AirMaps/AIRMapUrlTile.m @@ -13,6 +13,32 @@ @implementation AIRMapUrlTile { BOOL _urlTemplateSet; } +- (void)setShouldReplaceMapContent:(BOOL)shouldReplaceMapContent +{ + _shouldReplaceMapContent = shouldReplaceMapContent; + if(self.tileOverlay) { + self.tileOverlay.canReplaceMapContent = _shouldReplaceMapContent; + } + [self update]; +} + +- (void)setMaximumZ:(NSUInteger)maximumZ +{ + _maximumZ = maximumZ; + if(self.tileOverlay) { + self.tileOverlay.maximumZ = _maximumZ; + } + [self update]; +} + +- (void)setMinimumZ:(NSUInteger)minimumZ +{ + _minimumZ = minimumZ; + if(self.tileOverlay) { + self.tileOverlay.minimumZ = _minimumZ; + } + [self update]; +} - (void)setUrlTemplate:(NSString *)urlTemplate{ _urlTemplate = urlTemplate; @@ -25,7 +51,15 @@ - (void) createTileOverlayAndRendererIfPossible { if (!_urlTemplateSet) return; self.tileOverlay = [[MKTileOverlay alloc] initWithURLTemplate:self.urlTemplate]; - self.tileOverlay.canReplaceMapContent = YES; + + self.tileOverlay.canReplaceMapContent = self.shouldReplaceMapContent; + + if(self.minimumZ) { + self.tileOverlay.minimumZ = self.minimumZ; + } + if (self.maximumZ) { + self.tileOverlay.maximumZ = self.maximumZ; + } self.renderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:self.tileOverlay]; } @@ -36,6 +70,13 @@ - (void) update if (_map == nil) return; [_map removeOverlay:self]; [_map addOverlay:self level:MKOverlayLevelAboveLabels]; + for (id overlay in _map.overlays) { + if ([overlay isKindOfClass:[AIRMapUrlTile class]]) { + continue; + } + [_map removeOverlay:overlay]; + [_map addOverlay:overlay]; + } } #pragma mark MKOverlay implementation diff --git a/lib/ios/AirMaps/AIRMapUrlTileManager.m b/lib/ios/AirMaps/AIRMapUrlTileManager.m index 4ae4abffc9..64bc617fd0 100644 --- a/lib/ios/AirMaps/AIRMapUrlTileManager.m +++ b/lib/ios/AirMaps/AIRMapUrlTileManager.m @@ -33,5 +33,8 @@ - (UIView *)view } RCT_EXPORT_VIEW_PROPERTY(urlTemplate, NSString) +RCT_EXPORT_VIEW_PROPERTY(maximumZ, NSInteger) +RCT_EXPORT_VIEW_PROPERTY(minimumZ, NSInteger) +RCT_EXPORT_VIEW_PROPERTY(shouldReplaceMapContent, BOOL) @end diff --git a/lib/ios/AirMaps/RCTConvert+AirMap.m b/lib/ios/AirMaps/RCTConvert+AirMap.m index cfdbb17ce2..42c9161933 100644 --- a/lib/ios/AirMaps/RCTConvert+AirMap.m +++ b/lib/ios/AirMaps/RCTConvert+AirMap.m @@ -31,6 +31,9 @@ + (MKCoordinateRegion)MKCoordinateRegion:(id)json @"standard": @(MKMapTypeStandard), @"satellite": @(MKMapTypeSatellite), @"hybrid": @(MKMapTypeHybrid), + @"satelliteFlyover": @(MKMapTypeSatelliteFlyover), + @"hybridFlyover": @(MKMapTypeHybridFlyover), + @"mutedStandard": @(MKMapTypeMutedStandard) }), MKMapTypeStandard, integerValue) // NOTE(lmr): diff --git a/package.json b/package.json index 66e8be298c..6a83e0bc4a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.17.0", + "version": "0.21.0", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", @@ -13,7 +13,7 @@ "lint": "eslint ./", "build": "npm run build:js && npm run build:android && npm run build:ios", "build:js": "exit 0", - "build:ios": "bundle install --binstubs ./examples/ios && bundle exec pod install --project-directory=./example/ios/", + "build:ios": "bundle install --path ./example/ios/bundles && bundle exec pod install --project-directory=./example/ios/", "build:android": "./gradlew :react-native-maps:assembleDebug", "ci": "npm run lint", "preversion": "./scripts/update-version.js" @@ -32,15 +32,13 @@ "mapkit" ], "peerDependencies": { - "react": ">=15.4.0 || ^16.0.0-alpha", - "react-native": ">=0.40", - "prop-types": "^15.5.10" + "react": "^16.0", + "react-native": "^0.51 || ^0.52 || ^0.53 || ^0.54 || ^0.55", + "prop-types": "^15.0 || ^16.0" }, "devDependencies": { "babel-eslint": "^6.1.2", - "babel-plugin-module-resolver": "^2.3.0", "babel-preset-airbnb": "^1.1.1", - "babel-preset-react-native": "1.9.0", "eslint": "^3.3.1", "eslint-config-airbnb": "^10.0.1", "eslint-plugin-import": "^1.14.0", @@ -50,12 +48,16 @@ "gitbook-cli": "^2.3.0", "lodash": "^4.17.2", "prop-types": "^15.5.10", - "react": "16.0.0-alpha.12", - "react-native": "^0.45.1" + "react": "^16.3.0-alpha.1", + "react-native": "^0.54" }, "rnpm": { "android": { "sourceDir": "./lib/android" } + }, + "dependencies": { + "babel-plugin-module-resolver": "^2.3.0", + "babel-preset-react-native": "1.9.0" } } diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index 632da81d5c..92379cef63 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -14,7 +14,9 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/airbnb/react-native-maps.git" } s.source_files = "lib/ios/AirGoogleMaps/**/*.{h,m}" + s.compiler_flags = '-fno-modules' s.dependency 'React' - s.dependency 'GoogleMaps', '2.1.1' + s.dependency 'GoogleMaps', '2.5.0' + s.dependency 'Google-Maps-iOS-Utils', '2.1.0' end diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000000..e36ad53132 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,6287 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.42.tgz#a9c83233fa7cd06b39dc77adbb908616ff4f1962" + dependencies: + "@babel/highlight" "7.0.0-beta.42" + +"@babel/core@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.42.tgz#b3a838fddbd19663369a0b4892189fd8d3f82001" + dependencies: + "@babel/code-frame" "7.0.0-beta.42" + "@babel/generator" "7.0.0-beta.42" + "@babel/helpers" "7.0.0-beta.42" + "@babel/template" "7.0.0-beta.42" + "@babel/traverse" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + babylon "7.0.0-beta.42" + convert-source-map "^1.1.0" + debug "^3.1.0" + json5 "^0.5.0" + lodash "^4.2.0" + micromatch "^2.3.11" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@7.0.0-beta.42", "@babel/generator@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.42.tgz#777bb50f39c94a7e57f73202d833141f8159af33" + dependencies: + "@babel/types" "7.0.0-beta.42" + jsesc "^2.5.1" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.42.tgz#f2b0a3be684018b55fc308eb5408326f78479085" + dependencies: + "@babel/types" "7.0.0-beta.42" + +"@babel/helper-builder-react-jsx@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0-beta.42.tgz#719510a0aa45e9b02909f2e252420e62900c406a" + dependencies: + "@babel/types" "7.0.0-beta.42" + esutils "^2.0.0" + +"@babel/helper-call-delegate@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.42.tgz#53294eb8c5e6e53af3efda4293ff3c1237772d37" + dependencies: + "@babel/helper-hoist-variables" "7.0.0-beta.42" + "@babel/traverse" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + +"@babel/helper-define-map@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.42.tgz#e5aa10bd7eed2c23cc2873e5d15fbb4b40a30620" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + lodash "^4.2.0" + +"@babel/helper-function-name@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.42.tgz#b38b8f4f85168d1812c543dd700b5d549b0c4658" + dependencies: + "@babel/helper-get-function-arity" "7.0.0-beta.42" + "@babel/template" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + +"@babel/helper-get-function-arity@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.42.tgz#ad072e32f912c033053fc80478169aeadc22191e" + dependencies: + "@babel/types" "7.0.0-beta.42" + +"@babel/helper-hoist-variables@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.42.tgz#6e51d75192923d96972a24c223b81126a7fabca1" + dependencies: + "@babel/types" "7.0.0-beta.42" + +"@babel/helper-module-imports@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.42.tgz#4de334b42fa889d560f15122f66c3bfe1f30cb77" + dependencies: + "@babel/types" "7.0.0-beta.42" + lodash "^4.2.0" + +"@babel/helper-module-transforms@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.42.tgz#4d260cc786e712e8440bef58dae28040b77a6183" + dependencies: + "@babel/helper-module-imports" "7.0.0-beta.42" + "@babel/helper-simple-access" "7.0.0-beta.42" + "@babel/helper-split-export-declaration" "7.0.0-beta.42" + "@babel/template" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + lodash "^4.2.0" + +"@babel/helper-optimise-call-expression@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.42.tgz#9ba770079001672a578fe833190cf03f973568b1" + dependencies: + "@babel/types" "7.0.0-beta.42" + +"@babel/helper-plugin-utils@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-beta.42.tgz#9aa8b3e5dc72abea6b4f686712a7363cb29ea057" + +"@babel/helper-remap-async-to-generator@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.42.tgz#c27dd7789f3a9973493a67a7914ac9253e879071" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.42" + "@babel/helper-wrap-function" "7.0.0-beta.42" + "@babel/template" "7.0.0-beta.42" + "@babel/traverse" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + +"@babel/helper-replace-supers@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.42.tgz#fd984b6022982b71a1237d82d932ab69ff988aa4" + dependencies: + "@babel/helper-optimise-call-expression" "7.0.0-beta.42" + "@babel/template" "7.0.0-beta.42" + "@babel/traverse" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + +"@babel/helper-simple-access@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.42.tgz#9d32bed186b0bc365115c600817e791c22d72c74" + dependencies: + "@babel/template" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + lodash "^4.2.0" + +"@babel/helper-split-export-declaration@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.42.tgz#0d0d5254220a9cc4e7e226240306b939dc210ee7" + dependencies: + "@babel/types" "7.0.0-beta.42" + +"@babel/helper-wrap-function@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.42.tgz#5ffc6576902aa2a10fe6666e063bd45029c36db3" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.42" + "@babel/template" "7.0.0-beta.42" + "@babel/traverse" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + +"@babel/helpers@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-beta.42.tgz#151c1c4e9da1b6ce83d54c1be5fb8c9c57aa5044" + dependencies: + "@babel/template" "7.0.0-beta.42" + "@babel/traverse" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + +"@babel/highlight@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.42.tgz#a502a1c0d6f99b2b0e81d468a1b0c0e81e3f3623" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +"@babel/plugin-check-constants@^7.0.0-beta": + version "7.0.0-beta.38" + resolved "https://registry.yarnpkg.com/@babel/plugin-check-constants/-/plugin-check-constants-7.0.0-beta.38.tgz#bbda6306d45a4f097ccb416c0b52d6503f6502cf" + +"@babel/plugin-external-helpers@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.0.0-beta.42.tgz#88b6bc650490026553aaa1733486d84bad177481" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-proposal-class-properties@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.42.tgz#2cd29050ab997567071b65896f92afc08a620748" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.42" + "@babel/helper-plugin-utils" "7.0.0-beta.42" + "@babel/plugin-syntax-class-properties" "7.0.0-beta.42" + +"@babel/plugin-proposal-object-rest-spread@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.42.tgz#56ebd55a8268165cb7cb43a5a232b60f5435a822" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.42" + +"@babel/plugin-syntax-class-properties@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.42.tgz#80ccce27907f22d0ffb49721e9d2cde311b41459" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-syntax-dynamic-import@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0-beta.42.tgz#90257d90098e2c9c2f49054269039eccd8bddd34" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-syntax-flow@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0-beta.42.tgz#cc210adacb65c6c155578e7ccee30a53d1003a23" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-syntax-jsx@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.42.tgz#92ef7807bbec0e12a49815a409822262cbaa7ddd" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-syntax-object-rest-spread@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.42.tgz#aa789865abe78a4895d4a0be9de4d34b1a1d5063" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-arrow-functions@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.42.tgz#b918eb8760c38d6503a1a9858fa073786b60ab2b" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-block-scoping@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.42.tgz#272c5cc2b46613ebcd2e19491b19263c36d2c3f4" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + lodash "^4.2.0" + +"@babel/plugin-transform-classes@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.42.tgz#3b9fdb2e36f9f16b011a2ddc4ebb610e3dc9edfb" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.42" + "@babel/helper-define-map" "7.0.0-beta.42" + "@babel/helper-function-name" "7.0.0-beta.42" + "@babel/helper-optimise-call-expression" "7.0.0-beta.42" + "@babel/helper-plugin-utils" "7.0.0-beta.42" + "@babel/helper-replace-supers" "7.0.0-beta.42" + "@babel/helper-split-export-declaration" "7.0.0-beta.42" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.42.tgz#153662309475099c6948827fc86edbd7fb26f09d" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-destructuring@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.42.tgz#1aaca42a00d9ef2b0307557c748f32e83ac44899" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-flow-strip-types@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0-beta.42.tgz#0902538b641e1a6fe5d7dc49389560112bfd4071" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + "@babel/plugin-syntax-flow" "7.0.0-beta.42" + +"@babel/plugin-transform-for-of@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.42.tgz#acf51c5986050e1aff054c8d2a95ef3f6bec153e" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-function-name@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.42.tgz#1eb004a9abde01010d47ec7629d46b1e4e2c6228" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.42" + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-literals@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.42.tgz#61a34a82d757be4ddf937eda4b2d6c36b63b9c4e" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-modules-commonjs@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.42.tgz#bdfb30e194c8841ec3ddd8a011974102d0d74afc" + dependencies: + "@babel/helper-module-transforms" "7.0.0-beta.42" + "@babel/helper-plugin-utils" "7.0.0-beta.42" + "@babel/helper-simple-access" "7.0.0-beta.42" + +"@babel/plugin-transform-object-assign@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.0.0-beta.42.tgz#222eb7ff4a1c0d5e51aff7db24fc5772b1cae08d" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-parameters@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.42.tgz#58434afb01afb0a3aa82402142807fb70eb3fb56" + dependencies: + "@babel/helper-call-delegate" "7.0.0-beta.42" + "@babel/helper-get-function-arity" "7.0.0-beta.42" + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-react-display-name@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0-beta.42.tgz#48766efd74d65fb9116ede6354f73299d73e66b9" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-react-jsx-source@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0-beta.42.tgz#2c41adf060e76b9f0652591cfcdaddd192a21898" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + "@babel/plugin-syntax-jsx" "7.0.0-beta.42" + +"@babel/plugin-transform-react-jsx@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0-beta.42.tgz#a25731396ca87b07f10362a950deab4526345fac" + dependencies: + "@babel/helper-builder-react-jsx" "7.0.0-beta.42" + "@babel/helper-plugin-utils" "7.0.0-beta.42" + "@babel/plugin-syntax-jsx" "7.0.0-beta.42" + +"@babel/plugin-transform-regenerator@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.42.tgz#af164751340a7e513c53e614c6f1f90279e459ef" + dependencies: + regenerator-transform "^0.12.3" + +"@babel/plugin-transform-shorthand-properties@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.42.tgz#fb0b66f4afd4a5a67d9d84a85cbf6f7fef0a7b4f" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-spread@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.42.tgz#4d7dde45c95e55d418477e1ea95dd6d9b71f15e4" + dependencies: + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/plugin-transform-template-literals@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.42.tgz#7f05c5c003da8e485462cfc36f9d482b0a9a75df" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.42" + "@babel/helper-plugin-utils" "7.0.0-beta.42" + +"@babel/template@7.0.0-beta.42", "@babel/template@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.42.tgz#7186d4e70d44cdec975049ba0a73bdaf5cdee052" + dependencies: + "@babel/code-frame" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + babylon "7.0.0-beta.42" + lodash "^4.2.0" + +"@babel/traverse@7.0.0-beta.42", "@babel/traverse@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.42.tgz#f4bf4d1e33d41baf45205e2d0463591d57326285" + dependencies: + "@babel/code-frame" "7.0.0-beta.42" + "@babel/generator" "7.0.0-beta.42" + "@babel/helper-function-name" "7.0.0-beta.42" + "@babel/helper-split-export-declaration" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.42" + babylon "7.0.0-beta.42" + debug "^3.1.0" + globals "^11.1.0" + invariant "^2.2.0" + lodash "^4.2.0" + +"@babel/types@7.0.0-beta.42", "@babel/types@^7.0.0-beta": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.42.tgz#1e2118767684880f6963801b272fd2b3348efacc" + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + +JSONStream@~1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abbrev@1, abbrev@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +abbrev@~1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + +absolute-path@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/absolute-path/-/absolute-path-0.0.0.tgz#a78762fbdadfb5297be99b15d35a785b2f095bf7" + +accepts@~1.3.3, accepts@~1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.2.1: + version "5.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822" + +agent-base@4, agent-base@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.0.tgz#9838b5c3392b962bad031e6a4c5e1024abec45ce" + dependencies: + es6-promisify "^5.0.0" + +agentkeepalive@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.3.0.tgz#6d5de5829afd3be2712201a39275fd11c651857c" + dependencies: + humanize-ms "^1.2.1" + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0, ajv@^4.9.1: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + dependencies: + string-width "^2.0.0" + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-escapes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0, ansi-regex@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + +ansi-wrap@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + +ansi@^0.3.0, ansi@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" + +ansicolors@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" + +ansistyles@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +aproba@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" + +arch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.0.tgz#3613aa46149064b3c1f0607919bf1d4786e82889" + +archy@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + +are-we-there-yet@~1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +array.prototype.find@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +art@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/art/-/art-0.10.1.tgz#38541883e399225c5e193ff246e8f157cf7b2146" + +asap@^2.0.0, asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +async-some@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/async-some/-/async-some-1.0.2.tgz#4d8a81620d5958791b5b98f802d3207776e95509" + dependencies: + dezalgo "^1.0.2" + +async@^2.0.1, async@^2.4.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.2.1, aws4@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.16.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.24.1, babel-core@^6.26.0, babel-core@^6.7.2: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-eslint@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-6.1.2.tgz#5293419fe3672d66598d327da9694567ba6a5f2f" + dependencies: + babel-traverse "^6.0.20" + babel-types "^6.0.19" + babylon "^6.0.18" + lodash.assign "^4.0.0" + lodash.pickby "^4.0.0" + +babel-generator@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.6" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-builder-react-jsx@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + esutils "^2.0.2" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.16.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0, babel-plugin-check-es2015-constants@^6.5.0, babel-plugin-check-es2015-constants@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-external-helpers@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz#2285f48b02bd5dede85175caf8c62e86adccefa1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-module-resolver@^2.3.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-2.7.1.tgz#18be3c42ddf59f7a456c9e0512cd91394f6e4be1" + dependencies: + find-babel-config "^1.0.1" + glob "^7.1.1" + resolve "^1.2.0" + +babel-plugin-react-transform@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-react-transform/-/babel-plugin-react-transform-2.0.2.tgz#515bbfa996893981142d90b1f9b1635de2995109" + dependencies: + lodash "^4.6.1" + +babel-plugin-react-transform@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-react-transform/-/babel-plugin-react-transform-3.0.0.tgz#402f25137b7bb66e9b54ead75557dfbc7ecaaa74" + dependencies: + lodash "^4.6.1" + +babel-plugin-syntax-async-functions@^6.5.0, babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-class-properties@^6.5.0, babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.5.0, babel-plugin-syntax-flow@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.5.0, babel-plugin-syntax-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.5.0, babel-plugin-syntax-trailing-function-commas@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-to-generator@6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.16.0.tgz#19ec36cb1486b59f9f468adfa42ce13908ca2999" + dependencies: + babel-helper-remap-async-to-generator "^6.16.0" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-class-properties@^6.18.0, babel-plugin-transform-class-properties@^6.5.0, babel-plugin-transform-class-properties@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + dependencies: + babel-helper-function-name "^6.24.1" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0, babel-plugin-transform-es2015-arrow-functions@^6.5.0, babel-plugin-transform-es2015-arrow-functions@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0, babel-plugin-transform-es2015-block-scoped-functions@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.24.1, babel-plugin-transform-es2015-block-scoping@^6.5.0, babel-plugin-transform-es2015-block-scoping@^6.8.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.24.1, babel-plugin-transform-es2015-classes@^6.5.0, babel-plugin-transform-es2015-classes@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.24.1, babel-plugin-transform-es2015-computed-properties@^6.5.0, babel-plugin-transform-es2015-computed-properties@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@6.x, babel-plugin-transform-es2015-destructuring@^6.22.0, babel-plugin-transform-es2015-destructuring@^6.5.0, babel-plugin-transform-es2015-destructuring@^6.8.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.5.0, babel-plugin-transform-es2015-for-of@^6.8.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@6.x, babel-plugin-transform-es2015-function-name@^6.24.1, babel-plugin-transform-es2015-function-name@^6.5.0, babel-plugin-transform-es2015-function-name@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0, babel-plugin-transform-es2015-literals@^6.5.0, babel-plugin-transform-es2015-literals@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@6.x, babel-plugin-transform-es2015-modules-commonjs@^6.24.1, babel-plugin-transform-es2015-modules-commonjs@^6.5.0, babel-plugin-transform-es2015-modules-commonjs@^6.8.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.24.1, babel-plugin-transform-es2015-object-super@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@6.x, babel-plugin-transform-es2015-parameters@^6.24.1, babel-plugin-transform-es2015-parameters@^6.5.0, babel-plugin-transform-es2015-parameters@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@6.x, babel-plugin-transform-es2015-shorthand-properties@^6.24.1, babel-plugin-transform-es2015-shorthand-properties@^6.5.0, babel-plugin-transform-es2015-shorthand-properties@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@6.x, babel-plugin-transform-es2015-spread@^6.22.0, babel-plugin-transform-es2015-spread@^6.5.0, babel-plugin-transform-es2015-spread@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@6.x, babel-plugin-transform-es2015-sticky-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0, babel-plugin-transform-es2015-template-literals@^6.5.0, babel-plugin-transform-es2015-template-literals@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@6.x, babel-plugin-transform-es2015-unicode-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-es3-member-expression-literals@^6.5.0, babel-plugin-transform-es3-member-expression-literals@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es3-member-expression-literals/-/babel-plugin-transform-es3-member-expression-literals-6.22.0.tgz#733d3444f3ecc41bef8ed1a6a4e09657b8969ebb" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es3-property-literals@^6.5.0, babel-plugin-transform-es3-property-literals@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es3-property-literals/-/babel-plugin-transform-es3-property-literals-6.22.0.tgz#b2078d5842e22abf40f73e8cde9cd3711abd5758" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-exponentiation-operator@^6.5.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-flow-strip-types@^6.21.0, babel-plugin-transform-flow-strip-types@^6.22.0, babel-plugin-transform-flow-strip-types@^6.5.0, babel-plugin-transform-flow-strip-types@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-jscript@^6.5.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-jscript/-/babel-plugin-transform-jscript-6.22.0.tgz#6e8af12b7aba49e0a809152616ac05690b3352dc" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-object-assign@^6.5.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-assign/-/babel-plugin-transform-object-assign-6.22.0.tgz#f99d2f66f1a0b0d498e346c5359684740caa20ba" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@^6.20.2, babel-plugin-transform-object-rest-spread@^6.5.0, babel-plugin-transform-object-rest-spread@^6.8.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-react-display-name@^6.23.0, babel-plugin-transform-react-display-name@^6.5.0, babel-plugin-transform-react-display-name@^6.8.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-self@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-source@^6.22.0, babel-plugin-transform-react-jsx-source@^6.5.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx@^6.24.1, babel-plugin-transform-react-jsx@^6.5.0, babel-plugin-transform-react-jsx@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" + dependencies: + babel-helper-builder-react-jsx "^6.24.1" + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.24.1, babel-plugin-transform-regenerator@^6.5.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-airbnb@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/babel-preset-airbnb/-/babel-preset-airbnb-1.1.1.tgz#c200f0f5505b0918ed95e08c7977238dec3a5af6" + dependencies: + babel-plugin-transform-es2015-template-literals "^6.5.0" + babel-plugin-transform-es3-member-expression-literals "^6.5.0" + babel-plugin-transform-es3-property-literals "^6.5.0" + babel-plugin-transform-exponentiation-operator "^6.5.0" + babel-plugin-transform-jscript "^6.5.0" + babel-preset-es2015 "^6.5.0" + babel-preset-react "^6.5.0" + +babel-preset-es2015-node@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2015-node/-/babel-preset-es2015-node-6.1.1.tgz#60b23157024b0cfebf3a63554cb05ee035b4e55f" + dependencies: + babel-plugin-transform-es2015-destructuring "6.x" + babel-plugin-transform-es2015-function-name "6.x" + babel-plugin-transform-es2015-modules-commonjs "6.x" + babel-plugin-transform-es2015-parameters "6.x" + babel-plugin-transform-es2015-shorthand-properties "6.x" + babel-plugin-transform-es2015-spread "6.x" + babel-plugin-transform-es2015-sticky-regex "6.x" + babel-plugin-transform-es2015-unicode-regex "6.x" + semver "5.x" + +babel-preset-es2015@^6.5.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.24.1" + babel-plugin-transform-es2015-classes "^6.24.1" + babel-plugin-transform-es2015-computed-properties "^6.24.1" + babel-plugin-transform-es2015-destructuring "^6.22.0" + babel-plugin-transform-es2015-duplicate-keys "^6.24.1" + babel-plugin-transform-es2015-for-of "^6.22.0" + babel-plugin-transform-es2015-function-name "^6.24.1" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-plugin-transform-es2015-modules-systemjs "^6.24.1" + babel-plugin-transform-es2015-modules-umd "^6.24.1" + babel-plugin-transform-es2015-object-super "^6.24.1" + babel-plugin-transform-es2015-parameters "^6.24.1" + babel-plugin-transform-es2015-shorthand-properties "^6.24.1" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.24.1" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.22.0" + babel-plugin-transform-es2015-unicode-regex "^6.24.1" + babel-plugin-transform-regenerator "^6.24.1" + +babel-preset-fbjs@^2.1.2, babel-preset-fbjs@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-2.1.4.tgz#22f358e6654073acf61e47a052a777d7bccf03af" + dependencies: + babel-plugin-check-es2015-constants "^6.8.0" + babel-plugin-syntax-class-properties "^6.8.0" + babel-plugin-syntax-flow "^6.8.0" + babel-plugin-syntax-jsx "^6.8.0" + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-plugin-syntax-trailing-function-commas "^6.8.0" + babel-plugin-transform-class-properties "^6.8.0" + babel-plugin-transform-es2015-arrow-functions "^6.8.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.8.0" + babel-plugin-transform-es2015-block-scoping "^6.8.0" + babel-plugin-transform-es2015-classes "^6.8.0" + babel-plugin-transform-es2015-computed-properties "^6.8.0" + babel-plugin-transform-es2015-destructuring "^6.8.0" + babel-plugin-transform-es2015-for-of "^6.8.0" + babel-plugin-transform-es2015-function-name "^6.8.0" + babel-plugin-transform-es2015-literals "^6.8.0" + babel-plugin-transform-es2015-modules-commonjs "^6.8.0" + babel-plugin-transform-es2015-object-super "^6.8.0" + babel-plugin-transform-es2015-parameters "^6.8.0" + babel-plugin-transform-es2015-shorthand-properties "^6.8.0" + babel-plugin-transform-es2015-spread "^6.8.0" + babel-plugin-transform-es2015-template-literals "^6.8.0" + babel-plugin-transform-es3-member-expression-literals "^6.8.0" + babel-plugin-transform-es3-property-literals "^6.8.0" + babel-plugin-transform-flow-strip-types "^6.8.0" + babel-plugin-transform-object-rest-spread "^6.8.0" + babel-plugin-transform-react-display-name "^6.8.0" + babel-plugin-transform-react-jsx "^6.8.0" + +babel-preset-flow@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" + dependencies: + babel-plugin-transform-flow-strip-types "^6.22.0" + +babel-preset-react-native@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/babel-preset-react-native/-/babel-preset-react-native-1.9.0.tgz#035fc06c65f4f2a02d0336a100b2da142f36dab1" + dependencies: + babel-plugin-check-es2015-constants "^6.5.0" + babel-plugin-react-transform "2.0.2" + babel-plugin-syntax-async-functions "^6.5.0" + babel-plugin-syntax-class-properties "^6.5.0" + babel-plugin-syntax-flow "^6.5.0" + babel-plugin-syntax-jsx "^6.5.0" + babel-plugin-syntax-trailing-function-commas "^6.5.0" + babel-plugin-transform-class-properties "^6.5.0" + babel-plugin-transform-es2015-arrow-functions "^6.5.0" + babel-plugin-transform-es2015-block-scoping "^6.5.0" + babel-plugin-transform-es2015-classes "^6.5.0" + babel-plugin-transform-es2015-computed-properties "^6.5.0" + babel-plugin-transform-es2015-destructuring "^6.5.0" + babel-plugin-transform-es2015-for-of "^6.5.0" + babel-plugin-transform-es2015-function-name "^6.5.0" + babel-plugin-transform-es2015-literals "^6.5.0" + babel-plugin-transform-es2015-modules-commonjs "^6.5.0" + babel-plugin-transform-es2015-parameters "^6.5.0" + babel-plugin-transform-es2015-shorthand-properties "^6.5.0" + babel-plugin-transform-es2015-spread "^6.5.0" + babel-plugin-transform-es2015-template-literals "^6.5.0" + babel-plugin-transform-flow-strip-types "^6.5.0" + babel-plugin-transform-object-assign "^6.5.0" + babel-plugin-transform-object-rest-spread "^6.5.0" + babel-plugin-transform-react-display-name "^6.5.0" + babel-plugin-transform-react-jsx "^6.5.0" + babel-plugin-transform-react-jsx-source "^6.5.0" + babel-plugin-transform-regenerator "^6.5.0" + react-transform-hmr "^1.0.4" + +babel-preset-react-native@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/babel-preset-react-native/-/babel-preset-react-native-4.0.0.tgz#3df80dd33a453888cdd33bdb87224d17a5d73959" + dependencies: + babel-plugin-check-es2015-constants "^6.5.0" + babel-plugin-react-transform "^3.0.0" + babel-plugin-syntax-async-functions "^6.5.0" + babel-plugin-syntax-class-properties "^6.5.0" + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-syntax-flow "^6.5.0" + babel-plugin-syntax-jsx "^6.5.0" + babel-plugin-syntax-trailing-function-commas "^6.5.0" + babel-plugin-transform-class-properties "^6.5.0" + babel-plugin-transform-es2015-arrow-functions "^6.5.0" + babel-plugin-transform-es2015-block-scoping "^6.5.0" + babel-plugin-transform-es2015-classes "^6.5.0" + babel-plugin-transform-es2015-computed-properties "^6.5.0" + babel-plugin-transform-es2015-destructuring "^6.5.0" + babel-plugin-transform-es2015-for-of "^6.5.0" + babel-plugin-transform-es2015-function-name "^6.5.0" + babel-plugin-transform-es2015-literals "^6.5.0" + babel-plugin-transform-es2015-modules-commonjs "^6.5.0" + babel-plugin-transform-es2015-parameters "^6.5.0" + babel-plugin-transform-es2015-shorthand-properties "^6.5.0" + babel-plugin-transform-es2015-spread "^6.5.0" + babel-plugin-transform-es2015-template-literals "^6.5.0" + babel-plugin-transform-flow-strip-types "^6.5.0" + babel-plugin-transform-object-assign "^6.5.0" + babel-plugin-transform-object-rest-spread "^6.5.0" + babel-plugin-transform-react-display-name "^6.5.0" + babel-plugin-transform-react-jsx "^6.5.0" + babel-plugin-transform-react-jsx-source "^6.5.0" + babel-plugin-transform-regenerator "^6.5.0" + babel-template "^6.24.1" + react-transform-hmr "^1.0.4" + +babel-preset-react@^6.5.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" + dependencies: + babel-plugin-syntax-jsx "^6.3.13" + babel-plugin-transform-react-display-name "^6.23.0" + babel-plugin-transform-react-jsx "^6.24.1" + babel-plugin-transform-react-jsx-self "^6.22.0" + babel-plugin-transform-react-jsx-source "^6.22.0" + babel-preset-flow "^6.23.0" + +babel-register@^6.24.1, babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.0.20, babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.0.19, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@7.0.0-beta.42, babylon@^7.0.0-beta: + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.42.tgz#67cfabcd4f3ec82999d29031ccdea89d0ba99657" + +babylon@^6.0.18, babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +base64-js@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" + +base64-js@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.1.2.tgz#d6400cac1c4c660976d90d07a04351d89395f5e8" + +base64-js@^1.1.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" + +bash-color@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/bash-color/-/bash-color-0.0.4.tgz#e9be8ce33540cada4881768c59bd63865736e913" + +basic-auth@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.0.tgz#015db3f353e02e56377755f962742e8981e7bbba" + dependencies: + safe-buffer "5.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + +big-integer@^1.6.7: + version "1.6.26" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.26.tgz#3af1672fa62daf2d5ecafacf6e5aa0d25e02c1c8" + +bl@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e" + dependencies: + readable-stream "^2.0.5" + +bl@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" + dependencies: + readable-stream "~2.0.5" + +block-stream@*, block-stream@0.0.9: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^3.5.0, bluebird@~3.5.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + dependencies: + hoek "4.x.x" + +boxen@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +bplist-creator@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.0.7.tgz#37df1536092824b87c42f957b01344117372ae45" + dependencies: + stream-buffers "~2.2.0" + +bplist-parser@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" + dependencies: + big-integer "^1.6.7" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +bser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" + dependencies: + node-int64 "^0.4.0" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +builtins@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-0.0.7.tgz#355219cd6cf18dbe7c01cc7fd2dce765cfdc549a" + +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + +cacache@^10.0.0: + version "10.0.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.2.tgz#105a93a162bbedf3a25da42e1939ed99ffb145f8" + dependencies: + bluebird "^3.5.0" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^1.3.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.1" + ssri "^5.0.0" + unique-filename "^1.1.0" + y18n "^3.2.1" + +cacache@^9.2.9: + version "9.3.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-9.3.0.tgz#9cd58f2dd0b8c8cacf685b7067b416d6d3cf9db1" + dependencies: + bluebird "^3.5.0" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^1.3.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.1" + ssri "^4.1.6" + unique-filename "^1.1.0" + y18n "^3.2.1" + +cacache@~9.2.9: + version "9.2.9" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-9.2.9.tgz#f9d7ffe039851ec94c28290662afa4dd4bb9e8dd" + dependencies: + bluebird "^3.5.0" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^1.3.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.1" + ssri "^4.1.6" + unique-filename "^1.1.0" + y18n "^3.2.1" + +call-limit@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.0.tgz#6fd61b03f3da42a2cd0ec2b60f02bd0e71991fea" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +camelcase@^4.0.0, camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +capture-stack-trace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + +char-spinner@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/char-spinner/-/char-spinner-1.0.1.tgz#e6ea67bd247e107112983b7ab0479ed362800081" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + +chmodr@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chmodr/-/chmodr-1.0.2.tgz#04662b932d0f02ec66deaa2b0ea42811968e3eb9" + +chownr@^1.0.1, chownr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +clipboardy@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-1.2.2.tgz#2ce320b9ed9be1514f79878b53ff9765420903e2" + dependencies: + arch "^2.1.0" + execa "^0.8.0" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + +clone@^1.0.0, clone@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" + +cmd-shim@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +color-convert@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + +columnify@~1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + +commander@^2.9.0, commander@~2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + +compressible@~2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.13.tgz#0d1020ab924b2fdb4d6279875c7d6daba6baa7a9" + dependencies: + mime-db ">= 1.33.0 < 2" + +compression@^1.7.1: + version "1.7.2" + resolved "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz#aaffbcd6aaf854b44ebb280353d5ad1651f59a69" + dependencies: + accepts "~1.3.4" + bytes "3.0.0" + compressible "~2.0.13" + debug "2.6.9" + on-headers "~1.0.1" + safe-buffer "5.1.1" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.5.0, concat-stream@^1.5.2, concat-stream@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-chain@~1.1.10, config-chain@~1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2" + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +configstore@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.1.tgz#094ee662ab83fad9917678de114faaea8fcdca90" + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +connect@^3.6.5: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + +convert-source-map@^1.1.0, convert-source-map@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + +create-react-class@^15.6.3: + version "15.6.3" + resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036" + dependencies: + fbjs "^0.8.9" + loose-envify "^1.3.1" + object-assign "^4.1.1" + +cross-spawn@^5.0.1, cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + dependencies: + boom "5.x.x" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + dependencies: + es5-ext "^0.10.9" + +damerau-levenshtein@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + +debug@2, debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-extend@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + dependencies: + clone "^1.0.2" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +denodeify@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" + +depd@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + +depd@~1.1.1, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +detect-indent@~5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + +dezalgo@^1.0.0, dezalgo@^1.0.1, dezalgo@^1.0.2, dezalgo@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" + dependencies: + asap "^2.0.0" + wrappy "1" + +doctrine@1.3.x: + version "1.3.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.3.0.tgz#13e75682b55518424276f7c173783456ef913d26" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^1.2.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + dependencies: + esutils "^2.0.2" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + dependencies: + is-obj "^1.0.0" + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + dependencies: + readable-stream "~1.1.9" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +duplexify@^3.4.2, duplexify@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +editor@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +encodeurl@~1.0.1, encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + dependencies: + once "^1.4.0" + +envinfo@^3.0.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-3.11.0.tgz#7bde377e478bf14835412f7b05e7c6b473cb734c" + dependencies: + clipboardy "^1.2.2" + glob "^7.1.2" + minimist "^1.2.0" + os-name "^2.0.1" + which "^1.2.14" + +err-code@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" + +"errno@>=0.1.1 <0.2.0-0": + version "0.1.6" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026" + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +errorhandler@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.5.0.tgz#eaba64ca5d542a311ac945f582defc336165d9f4" + dependencies: + accepts "~1.3.3" + escape-html "~1.0.3" + +es-abstract@^1.7.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.38" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.38.tgz#fa7d40d65bbc9bb8a67e1d3f9cc656a00530eed3" + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + +es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-promise@^4.0.3: + version "4.2.2" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.2.tgz#f722d7769af88bd33bc13ec6605e1f92966b82d9" + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + dependencies: + es6-promise "^4.0.3" + +es6-set@^0.1.4, es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-config-airbnb-base@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-5.0.3.tgz#9714ac35ec2cd7fab0d44d148a9f91db2944074d" + +eslint-config-airbnb@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-10.0.1.tgz#a470108646d6c45e1f639a03f11d504a1aa4aedc" + dependencies: + eslint-config-airbnb-base "^5.0.2" + +eslint-import-resolver-node@^0.2.0: + version "0.2.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c" + dependencies: + debug "^2.2.0" + object-assign "^4.0.1" + resolve "^1.1.6" + +eslint-plugin-import@^1.14.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-1.16.0.tgz#b2fa07ebcc53504d0f2a4477582ec8bff1871b9f" + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.2.0" + doctrine "1.3.x" + es6-map "^0.1.3" + es6-set "^0.1.4" + eslint-import-resolver-node "^0.2.0" + has "^1.0.1" + lodash.cond "^4.3.0" + lodash.endswith "^4.0.1" + lodash.find "^4.3.0" + lodash.findindex "^4.3.0" + minimatch "^3.0.3" + object-assign "^4.0.1" + pkg-dir "^1.0.0" + pkg-up "^1.0.0" + +eslint-plugin-jsx-a11y@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-2.2.3.tgz#4e35cb71b8a7db702ac415c806eb8e8d9ea6c65d" + dependencies: + damerau-levenshtein "^1.0.0" + jsx-ast-utils "^1.0.0" + object-assign "^4.0.1" + +eslint-plugin-prefer-object-spread@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-object-spread/-/eslint-plugin-prefer-object-spread-1.2.1.tgz#27fb91853690cceb3ae6101d9c8aecc6a67a402c" + +eslint-plugin-react@^6.1.2: + version "6.10.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz#c5435beb06774e12c7db2f6abaddcbf900cd3f78" + dependencies: + array.prototype.find "^2.0.1" + doctrine "^1.2.2" + has "^1.0.1" + jsx-ast-utils "^1.3.4" + object.assign "^4.0.4" + +eslint@^3.3.1: + version "3.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" + dependencies: + babel-code-frame "^6.16.0" + chalk "^1.1.3" + concat-stream "^1.5.2" + debug "^2.1.1" + doctrine "^2.0.0" + escope "^3.6.0" + espree "^3.4.0" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + glob "^7.0.3" + globals "^9.14.0" + ignore "^3.2.0" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.7.5" + strip-bom "^3.0.0" + strip-json-comments "~2.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espree@^3.4.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca" + dependencies: + acorn "^5.2.1" + acorn-jsx "^3.0.0" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + dependencies: + estraverse "^4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.0, esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + dependencies: + d "1" + es5-ext "~0.10.14" + +event-target-shim@^1.0.5: + version "1.1.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-1.1.1.tgz#a86e5ee6bdaa16054475da797ccddf0c55698491" + +eventemitter3@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.0.1.tgz#4ce66c3fc5b5a6b9f2245e359e1938f1ab10f960" + +exec-sh@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.1.tgz#163b98a6e89e6b65b47c2a28d215bc1f63989c38" + dependencies: + merge "^1.1.3" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +extend@~3.0.0, extend@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +external-editor@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + +fancy-log@^1.1.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.2.tgz#f41125e3d84f2e7d89a43d06d958c8f78be16be1" + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + time-stamp "^1.0.0" + +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + dependencies: + bser "^2.0.0" + +fbjs-scripts@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-0.8.1.tgz#c1c6efbecb7f008478468976b783880c2f669765" + dependencies: + babel-core "^6.7.2" + babel-preset-fbjs "^2.1.2" + core-js "^2.4.1" + cross-spawn "^5.1.0" + gulp-util "^3.0.4" + object-assign "^4.0.1" + semver "^5.1.0" + through2 "^2.0.0" + +fbjs@^0.8.14, fbjs@^0.8.16, fbjs@^0.8.9: + version "0.8.16" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +find-babel-config@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.1.0.tgz#acc01043a6749fec34429be6b64f542ebb5d6355" + dependencies: + json5 "^0.5.1" + path-exists "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +flat-cache@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +flush-write-stream@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~1.0.0-rc4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c" + dependencies: + async "^2.0.1" + combined-stream "^1.0.5" + mime-types "^2.1.11" + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +form-data@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + +from2@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-1.3.0.tgz#88413baaa5f9a597cfde9221d86986cd3c061dfd" + dependencies: + inherits "~2.0.1" + readable-stream "~1.1.10" + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^3.0.0" + universalify "^0.1.0" + +fs-extra@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + +fs-vacuum@~1.2.10, fs-vacuum@~1.2.9: + version "1.2.10" + resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" + dependencies: + graceful-fs "^4.1.2" + path-is-inside "^1.0.1" + rimraf "^2.5.2" + +fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10, fs-write-stream-atomic@~1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.39" + +fstream-ignore@^1.0.0, fstream-ignore@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream-npm@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fstream-npm/-/fstream-npm-1.1.1.tgz#6b9175db6239a83d8209e232426c494dbb29690c" + dependencies: + fstream-ignore "^1.0.0" + inherits "2" + +fstream-npm@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/fstream-npm/-/fstream-npm-1.2.1.tgz#08c4a452f789dcbac4c89a4563c902b2c862fd5b" + dependencies: + fstream-ignore "^1.0.0" + inherits "2" + +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2, fstream@~1.0.10, fstream@~1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +gauge@~1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" + dependencies: + ansi "^0.3.0" + has-unicode "^2.0.0" + lodash.pad "^4.1.0" + lodash.padend "^4.1.0" + lodash.padstart "^4.1.0" + +gauge@~2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.6.0.tgz#d35301ad18e96902b4751dcbbe40f4218b942a46" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-color "^0.1.7" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +genfun@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/genfun/-/genfun-4.0.1.tgz#ed10041f2e4a7f1b0a38466d17a5c3e27df1dfc1" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +gitbook-cli@^2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/gitbook-cli/-/gitbook-cli-2.3.2.tgz#5e893582e1f743f6fa920c3c3eb36b62ea4a31a0" + dependencies: + bash-color "0.0.4" + commander "2.11.0" + fs-extra "3.0.1" + lodash "4.17.4" + npm "5.1.0" + npmi "1.0.1" + optimist "0.6.1" + q "1.5.0" + semver "5.3.0" + tmp "0.0.31" + user-home "2.0.0" + +github-url-from-git@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/github-url-from-git/-/github-url-from-git-1.4.0.tgz#285e6b520819001bde128674704379e4ff03e0de" + +github-url-from-username-repo@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/github-url-from-username-repo/-/github-url-from-username-repo-1.0.2.tgz#7dd79330d2abe69c10c2cef79714c97215791dfa" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^11.1.0: + version "11.3.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.3.0.tgz#e04fdb7b9796d8adac9c8f64c14837b2313378b0" + +globals@^9.14.0, globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +glogg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" + dependencies: + sparkles "^1.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@~4.1.11, graceful-fs@~4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + +gulp-util@^3.0.4: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + dependencies: + glogg "^1.0.0" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-color@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + dependencies: + sparkles "^1.0.0" + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + +has-unicode@^2.0.0, has-unicode@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +hawk@3.1.3, hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +hoek@4.x.x: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4, hosted-git-info@^2.1.5, hosted-git-info@^2.4.2, hosted-git-info@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + +hosted-git-info@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" + +http-cache-semantics@^3.8.0: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + +http-errors@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" + dependencies: + depd "1.1.1" + inherits "2.0.3" + setprototypeof "1.0.3" + statuses ">= 1.3.1 < 2" + +http-proxy-agent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.0.0.tgz#46482a2f0523a4d6082551709f469cb3e4a85ff4" + dependencies: + agent-base "4" + debug "2" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-proxy-agent@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz#a7ce4382a1ba8266ee848578778122d491260fd9" + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + dependencies: + ms "^2.0.0" + +iconv-lite@^0.4.17, iconv-lite@~0.4.13: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +iferr@^0.1.5, iferr@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +ignore@^3.2.0: + version "3.3.7" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" + +image-size@^0.6.0: + version "0.6.2" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.2.tgz#8ee316d4298b028b965091b673d5f1537adee5b4" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +inflight@^1.0.4, inflight@~1.0.4, inflight@~1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@^1.3.4, ini@~1.3.0, ini@~1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +init-package-json@~1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.1.tgz#cd873a167796befb99612b28762a0b6393fd8f6a" + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" + +init-package-json@~1.9.4: + version "1.9.6" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.9.6.tgz#789fc2b74466a4952b9ea77c0575bc78ebd60a61" + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + +invariant@^2.2.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + dependencies: + loose-envify "^1.0.0" + +invariant@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +ip@^1.1.4: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: + version "2.17.1" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz#3da98914a70a22f0a8563ef1511a246c6fc55471" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + dependencies: + path-is-inside "^1.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jest-docblock@22.4.0, jest-docblock@^22.4.0: + version "22.4.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-22.4.0.tgz#dbf1877e2550070cfc4d9b07a55775a0483159b8" + dependencies: + detect-newline "^2.1.0" + +jest-haste-map@22.4.2: + version "22.4.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-22.4.2.tgz#a90178e66146d4378bb076345a949071f3b015b4" + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + jest-docblock "^22.4.0" + jest-serializer "^22.4.0" + jest-worker "^22.2.2" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-serializer@^22.4.0: + version "22.4.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-22.4.0.tgz#b5d145b98c4b0d2c20ab686609adbb81fe23b566" + +jest-worker@22.2.2, jest-worker@^22.2.2: + version "22.2.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-22.2.2.tgz#c1f5dc39976884b81f68ec50cb8532b2cbab3390" + dependencies: + merge-stream "^1.0.1" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.5.1: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-parse-better-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d" + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +jsx-ast-utils@^1.0.0, jsx-ast-utils@^1.3.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + optionalDependencies: + graceful-fs "^4.1.9" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + dependencies: + package-json "^4.0.0" + +lazy-property@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazy-property/-/lazy-property-1.0.0.tgz#84ddc4b370679ba8bd4cdcfa4c06b43d57111147" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +left-pad@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lockfile@~1.0.1, lockfile@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.3.tgz#2638fc39a0331e9cac1a04b71799931c9c50df79" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + +lodash._baseuniq@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" + dependencies: + lodash._createset "~4.0.0" + lodash._root "~3.0.0" + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + +lodash._createset@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + +lodash._root@^3.0.0, lodash._root@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + +lodash.assign@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + +lodash.clonedeep@~4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + +lodash.cond@^4.3.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" + +lodash.endswith@^4.0.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09" + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + dependencies: + lodash._root "^3.0.0" + +lodash.find@^4.3.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1" + +lodash.findindex@^4.3.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.findindex/-/lodash.findindex-4.6.0.tgz#a3245dee61fb9b6e0624b535125624bb69c11106" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.pad@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" + +lodash.padend@^4.1.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" + +lodash.padstart@^4.1.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" + +lodash.pickby@^4.0.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.pickby/-/lodash.pickby-4.6.0.tgz#7dea21d8c18d7703a27c704c15d3b84a67e33aff" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + +lodash.union@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + +lodash.uniq@~4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + +lodash.without@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" + +lodash@4.17.4, lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.3.0, lodash@^4.6.1: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +lodash@^3.5.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + +lodash@^4.17.5, lodash@^4.2.0: + version "4.17.5" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + +lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@~4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +macos-release@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-1.1.0.tgz#831945e29365b470aa8724b0ab36c8f8959d10fb" + +make-dir@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51" + dependencies: + pify "^3.0.0" + +make-fetch-happen@^2.4.13: + version "2.6.0" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-2.6.0.tgz#8474aa52198f6b1ae4f3094c04e8370d35ea8a38" + dependencies: + agentkeepalive "^3.3.0" + cacache "^10.0.0" + http-cache-semantics "^3.8.0" + http-proxy-agent "^2.0.0" + https-proxy-agent "^2.1.0" + lru-cache "^4.1.1" + mississippi "^1.2.0" + node-fetch-npm "^2.0.2" + promise-retry "^1.1.1" + socks-proxy-agent "^3.0.1" + ssri "^5.0.0" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + dependencies: + tmpl "1.0.x" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + dependencies: + readable-stream "^2.0.1" + +merge@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" + +metro-babylon7@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-babylon7/-/metro-babylon7-0.28.0.tgz#cf9701ffdc1992d1562b4cb667d9692164950df4" + dependencies: + babylon "^7.0.0-beta" + +metro-cache@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.28.0.tgz#c5164a361985fc0294059fccdf4ea824e3173c1d" + dependencies: + jest-serializer "^22.4.0" + mkdirp "^0.5.1" + +metro-core@0.28.0, metro-core@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.28.0.tgz#e1ced4cf07ca8fb5196a6e5ca853b5d893f06038" + dependencies: + lodash.throttle "^4.1.1" + +metro-minify-uglify@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.28.0.tgz#c9aecb8e893430d2fd58e00cf799c00b99dc0f79" + dependencies: + uglify-es "^3.1.9" + +metro-resolver@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.28.0.tgz#813802d60fc762772927c81d02e01c7eec84bad8" + dependencies: + absolute-path "^0.0.0" + +metro-source-map@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.28.0.tgz#ec8c3161d8516ad3c4e7149f2c3d4802f4fd6fa2" + dependencies: + source-map "^0.5.6" + +metro@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.28.0.tgz#22999c96c3129682a76acd4e1f2adc17f7d77cac" + dependencies: + "@babel/core" "^7.0.0-beta" + "@babel/generator" "^7.0.0-beta" + "@babel/helper-remap-async-to-generator" "^7.0.0-beta" + "@babel/plugin-check-constants" "^7.0.0-beta" + "@babel/plugin-external-helpers" "^7.0.0-beta" + "@babel/plugin-proposal-class-properties" "^7.0.0-beta" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0-beta" + "@babel/plugin-syntax-dynamic-import" "^7.0.0-beta" + "@babel/plugin-transform-arrow-functions" "^7.0.0-beta" + "@babel/plugin-transform-block-scoping" "^7.0.0-beta" + "@babel/plugin-transform-classes" "^7.0.0-beta" + "@babel/plugin-transform-computed-properties" "^7.0.0-beta" + "@babel/plugin-transform-destructuring" "^7.0.0-beta" + "@babel/plugin-transform-flow-strip-types" "^7.0.0-beta" + "@babel/plugin-transform-for-of" "^7.0.0-beta" + "@babel/plugin-transform-function-name" "^7.0.0-beta" + "@babel/plugin-transform-literals" "^7.0.0-beta" + "@babel/plugin-transform-modules-commonjs" "^7.0.0-beta" + "@babel/plugin-transform-object-assign" "^7.0.0-beta" + "@babel/plugin-transform-parameters" "^7.0.0-beta" + "@babel/plugin-transform-react-display-name" "^7.0.0-beta" + "@babel/plugin-transform-react-jsx" "^7.0.0-beta" + "@babel/plugin-transform-react-jsx-source" "^7.0.0-beta" + "@babel/plugin-transform-regenerator" "^7.0.0-beta" + "@babel/plugin-transform-shorthand-properties" "^7.0.0-beta" + "@babel/plugin-transform-spread" "^7.0.0-beta" + "@babel/plugin-transform-template-literals" "^7.0.0-beta" + "@babel/template" "^7.0.0-beta" + "@babel/traverse" "^7.0.0-beta" + "@babel/types" "^7.0.0-beta" + absolute-path "^0.0.0" + async "^2.4.0" + babel-core "^6.24.1" + babel-generator "^6.26.0" + babel-plugin-external-helpers "^6.22.0" + babel-preset-es2015-node "^6.1.1" + babel-preset-fbjs "^2.1.4" + babel-preset-react-native "^4.0.0" + babel-register "^6.24.1" + babylon "^6.18.0" + chalk "^1.1.1" + concat-stream "^1.6.0" + connect "^3.6.5" + core-js "^2.2.2" + debug "^2.2.0" + denodeify "^1.2.1" + eventemitter3 "^3.0.0" + fbjs "^0.8.14" + fs-extra "^1.0.0" + graceful-fs "^4.1.3" + image-size "^0.6.0" + jest-docblock "22.4.0" + jest-haste-map "22.4.2" + jest-worker "22.2.2" + json-stable-stringify "^1.0.1" + json5 "^0.4.0" + left-pad "^1.1.3" + lodash.throttle "^4.1.1" + merge-stream "^1.0.1" + metro-babylon7 "0.28.0" + metro-cache "0.28.0" + metro-core "0.28.0" + metro-minify-uglify "0.28.0" + metro-resolver "0.28.0" + metro-source-map "0.28.0" + mime-types "2.1.11" + mkdirp "^0.5.1" + request "^2.79.0" + rimraf "^2.5.4" + serialize-error "^2.1.0" + source-map "^0.5.6" + temp "0.8.3" + throat "^4.1.0" + wordwrap "^1.0.0" + write-file-atomic "^1.2.0" + ws "^1.1.0" + xpipe "^1.0.5" + yargs "^9.0.0" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +"mime-db@>= 1.33.0 < 2", mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + +mime-db@~1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.23.0.tgz#a31b4070adaea27d732ea333740a64d0ec9a6659" + +mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + +mime-types@2.1.11: + version "2.1.11" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.11.tgz#c259c471bda808a85d6cd193b430a5fae4473b3c" + dependencies: + mime-db "~1.23.0" + +mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + dependencies: + mime-db "~1.30.0" + +mime-types@~2.1.18: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + dependencies: + mime-db "~1.33.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + +mime@^1.3.4: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + dependencies: + dom-walk "^0.1.0" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +mississippi@^1.2.0, mississippi@^1.3.0, mississippi@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-1.3.0.tgz#d201583eb12327e3c5c1642a404a9cacf94e34f5" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^1.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +morgan@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.0.tgz#d01fa6c65859b76fcf31b3cb53a3821a311d8051" + dependencies: + basic-auth "~2.0.0" + debug "2.6.9" + depd "~1.1.1" + on-finished "~2.3.0" + on-headers "~1.0.1" + +move-concurrently@^1.0.1, move-concurrently@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +ms@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + +multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + dependencies: + duplexer2 "0.0.2" + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + +mute-stream@0.0.7, mute-stream@~0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +nan@^2.3.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +node-fetch-npm@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" + dependencies: + encoding "^0.1.11" + json-parse-better-errors "^1.0.0" + safe-buffer "^5.1.1" + +node-fetch@^1.0.1, node-fetch@^1.3.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-gyp@~3.6.0, node-gyp@~3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60" + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + minimatch "^3.0.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "2" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + +node-notifier@^5.1.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea" + dependencies: + growly "^1.3.0" + semver "^5.4.1" + shellwords "^0.1.1" + which "^1.3.0" + +node-pre-gyp@^0.6.39: + version "0.6.39" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" + dependencies: + detect-libc "^1.0.2" + hawk "3.1.3" + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" + +node-uuid@~1.4.7: + version "1.4.8" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + +"nopt@2 || 3", nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +nopt@^4.0.1, nopt@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-git-url@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/normalize-git-url/-/normalize-git-url-3.0.2.tgz#8e5f14be0bdaedb73e07200310aa416c27350fc4" + +normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.4.0, "normalize-package-data@~1.0.1 || ^2.0.0", normalize-package-data@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-package-data@~2.3.5: + version "2.3.8" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-cache-filename@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" + +npm-install-checks@~1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-1.0.7.tgz#6d91aeda0ac96801f1ed7aadee116a6c0a086a57" + dependencies: + npmlog "0.1 || 1 || 2" + semver "^2.3.0 || 3.x || 4 || 5" + +npm-install-checks@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.0.tgz#d4aecdfd51a53e3723b7b2f93b2ee28e307bc0d7" + dependencies: + semver "^2.3.0 || 3.x || 4 || 5" + +"npm-package-arg@^3.0.0 || ^4.0.0", npm-package-arg@^4.1.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.2.1.tgz#593303fdea85f7c422775f17f9eb7670f680e3ec" + dependencies: + hosted-git-info "^2.1.5" + semver "^5.1.0" + +"npm-package-arg@^3.0.0 || ^4.0.0 || ^5.0.0", "npm-package-arg@^4.0.0 || ^5.0.0", npm-package-arg@^5.1.2, npm-package-arg@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-5.1.2.tgz#fb18d17bb61e60900d6312619919bd753755ab37" + dependencies: + hosted-git-info "^2.4.2" + osenv "^0.1.4" + semver "^5.1.0" + validate-npm-package-name "^3.0.0" + +npm-package-arg@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.1.1.tgz#86d9dca985b4c5e5d59772dfd5de6919998a495a" + dependencies: + hosted-git-info "^2.1.4" + semver "4 || 5" + +npm-pick-manifest@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-1.0.4.tgz#a5ee6510c1fe7221c0bc0414e70924c14045f7e8" + dependencies: + npm-package-arg "^5.1.2" + semver "^5.3.0" + +npm-registry-client@~7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-7.2.1.tgz#c792266b088cc313f8525e7e35248626c723db75" + dependencies: + concat-stream "^1.5.2" + graceful-fs "^4.1.6" + normalize-package-data "~1.0.1 || ^2.0.0" + npm-package-arg "^3.0.0 || ^4.0.0" + once "^1.3.3" + request "^2.74.0" + retry "^0.10.0" + semver "2 >=2.2.1 || 3.x || 4 || 5" + slide "^1.1.3" + optionalDependencies: + npmlog "~2.0.0 || ~3.1.0" + +npm-registry-client@~8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-8.4.0.tgz#d52b901685647fc62a4c03eafecb6ceaa5018d4c" + dependencies: + concat-stream "^1.5.2" + graceful-fs "^4.1.6" + normalize-package-data "~1.0.1 || ^2.0.0" + npm-package-arg "^3.0.0 || ^4.0.0 || ^5.0.0" + once "^1.3.3" + request "^2.74.0" + retry "^0.10.0" + semver "2 >=2.2.1 || 3.x || 4 || 5" + slide "^1.1.3" + ssri "^4.1.2" + optionalDependencies: + npmlog "2 || ^3.1.0 || ^4.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npm-user-validate@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-0.1.5.tgz#52465d50c2d20294a57125b996baedbf56c5004b" + +npm-user-validate@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.0.tgz#8ceca0f5cea04d4e93519ef72d0557a75122e951" + +npm@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm/-/npm-5.1.0.tgz#cf8201e044018e9c89532041c90094541982b2c0" + dependencies: + JSONStream "~1.3.1" + abbrev "~1.1.0" + ansi-regex "~3.0.0" + ansicolors "~0.3.2" + ansistyles "~0.1.3" + aproba "~1.1.2" + archy "~1.0.0" + bluebird "~3.5.0" + cacache "~9.2.9" + call-limit "~1.1.0" + chownr "~1.0.1" + cmd-shim "~2.0.2" + columnify "~1.5.4" + config-chain "~1.1.11" + detect-indent "~5.0.0" + dezalgo "~1.0.3" + editor "~1.0.0" + fs-vacuum "~1.2.10" + fs-write-stream-atomic "~1.0.10" + fstream "~1.0.11" + fstream-npm "~1.2.1" + glob "~7.1.2" + graceful-fs "~4.1.11" + has-unicode "~2.0.1" + hosted-git-info "~2.5.0" + iferr "~0.1.5" + inflight "~1.0.6" + inherits "~2.0.3" + ini "~1.3.4" + init-package-json "~1.10.1" + lazy-property "~1.0.0" + lockfile "~1.0.3" + lodash._baseuniq "~4.6.0" + lodash.clonedeep "~4.5.0" + lodash.union "~4.6.0" + lodash.uniq "~4.5.0" + lodash.without "~4.4.0" + lru-cache "~4.1.1" + mississippi "~1.3.0" + mkdirp "~0.5.1" + move-concurrently "~1.0.1" + node-gyp "~3.6.2" + nopt "~4.0.1" + normalize-package-data "~2.4.0" + npm-cache-filename "~1.0.2" + npm-install-checks "~3.0.0" + npm-package-arg "~5.1.2" + npm-registry-client "~8.4.0" + npm-user-validate "~1.0.0" + npmlog "~4.1.2" + once "~1.4.0" + opener "~1.4.3" + osenv "~0.1.4" + pacote "~2.7.38" + path-is-inside "~1.0.2" + promise-inflight "~1.0.1" + read "~1.0.7" + read-cmd-shim "~1.0.1" + read-installed "~4.0.3" + read-package-json "~2.0.9" + read-package-tree "~5.1.6" + readable-stream "~2.3.2" + request "~2.81.0" + retry "~0.10.1" + rimraf "~2.6.1" + safe-buffer "~5.1.1" + semver "~5.3.0" + sha "~2.0.1" + slide "~1.1.6" + sorted-object "~2.0.1" + sorted-union-stream "~2.1.3" + ssri "~4.1.6" + strip-ansi "~4.0.0" + tar "~2.2.1" + text-table "~0.2.0" + uid-number "0.0.6" + umask "~1.1.0" + unique-filename "~1.1.0" + unpipe "~1.0.0" + update-notifier "~2.2.0" + uuid "~3.1.0" + validate-npm-package-name "~3.0.0" + which "~1.2.14" + worker-farm "~1.3.1" + wrappy "~1.0.2" + write-file-atomic "~2.1.0" + +npm@^2.1.12: + version "2.15.12" + resolved "https://registry.yarnpkg.com/npm/-/npm-2.15.12.tgz#df7c3ed5a277c3f9d4b5d819b05311d10a200ae6" + dependencies: + abbrev "~1.0.9" + ansi "~0.3.1" + ansicolors "~0.3.2" + ansistyles "~0.1.3" + archy "~1.0.0" + async-some "~1.0.2" + block-stream "0.0.9" + char-spinner "~1.0.1" + chmodr "~1.0.2" + chownr "~1.0.1" + cmd-shim "~2.0.2" + columnify "~1.5.4" + config-chain "~1.1.10" + dezalgo "~1.0.3" + editor "~1.0.0" + fs-vacuum "~1.2.9" + fs-write-stream-atomic "~1.0.8" + fstream "~1.0.10" + fstream-npm "~1.1.1" + github-url-from-git "~1.4.0" + github-url-from-username-repo "~1.0.2" + glob "~7.0.6" + graceful-fs "~4.1.6" + hosted-git-info "~2.1.5" + inflight "~1.0.4" + inherits "~2.0.3" + ini "~1.3.4" + init-package-json "~1.9.4" + lockfile "~1.0.1" + lru-cache "~4.0.1" + minimatch "~3.0.3" + mkdirp "~0.5.1" + node-gyp "~3.6.0" + nopt "~3.0.6" + normalize-git-url "~3.0.2" + normalize-package-data "~2.3.5" + npm-cache-filename "~1.0.2" + npm-install-checks "~1.0.7" + npm-package-arg "~4.1.0" + npm-registry-client "~7.2.1" + npm-user-validate "~0.1.5" + npmlog "~2.0.4" + once "~1.4.0" + opener "~1.4.1" + osenv "~0.1.3" + path-is-inside "~1.0.0" + read "~1.0.7" + read-installed "~4.0.3" + read-package-json "~2.0.4" + readable-stream "~2.1.5" + realize-package-specifier "~3.0.1" + request "~2.74.0" + retry "~0.10.0" + rimraf "~2.5.4" + semver "~5.1.0" + sha "~2.0.1" + slide "~1.1.6" + sorted-object "~2.0.0" + spdx-license-ids "~1.2.2" + strip-ansi "~3.0.1" + tar "~2.2.1" + text-table "~0.2.0" + uid-number "0.0.6" + umask "~1.1.0" + validate-npm-package-license "~3.0.1" + validate-npm-package-name "~2.2.2" + which "~1.2.11" + wrappy "~1.0.2" + write-file-atomic "~1.1.4" + +npmi@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npmi/-/npmi-1.0.1.tgz#15d769273547545e6809dcf0ce18aed48b0290e2" + dependencies: + npm "^2.1.12" + semver "^4.1.0" + +"npmlog@0 || 1 || 2 || 3 || 4", "npmlog@2 || ^3.1.0 || ^4.0.0", npmlog@^4.0.2, npmlog@~4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +"npmlog@0.1 || 1 || 2", npmlog@^2.0.4, npmlog@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" + dependencies: + ansi "~0.3.1" + are-we-there-yet "~1.1.2" + gauge "~1.2.5" + +"npmlog@~2.0.0 || ~3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-3.1.2.tgz#2d46fa874337af9498a2f12bb43d8d0be4a36873" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.6.0" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1, oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-keys@^1.0.11, object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object.assign@^4.0.4: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" + +once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0, once@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +opener@~1.4.1, opener@~1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" + +opn@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/opn/-/opn-3.0.3.tgz#b6d99e7399f78d65c3baaffef1fb288e9b85243a" + dependencies: + object-assign "^4.0.1" + +optimist@0.6.1, optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +options@>=0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-2.0.1.tgz#b9a386361c17ae3a21736ef0599405c9a8c5dc5e" + dependencies: + macos-release "^1.0.0" + win-release "^1.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@0, osenv@^0.1.4, osenv@~0.1.3, osenv@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pacote@~2.7.38: + version "2.7.38" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-2.7.38.tgz#5091f8774298c26c3eca24606037f1bb73db74c1" + dependencies: + bluebird "^3.5.0" + cacache "^9.2.9" + glob "^7.1.2" + lru-cache "^4.1.1" + make-fetch-happen "^2.4.13" + minimatch "^3.0.4" + mississippi "^1.2.0" + normalize-package-data "^2.4.0" + npm-package-arg "^5.1.2" + npm-pick-manifest "^1.0.4" + osenv "^0.1.4" + promise-inflight "^1.0.1" + promise-retry "^1.1.1" + protoduck "^4.0.0" + safe-buffer "^5.1.1" + semver "^5.3.0" + ssri "^4.1.6" + tar-fs "^1.15.3" + tar-stream "^1.5.4" + unique-filename "^1.1.0" + which "^1.2.12" + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1, path-is-inside@~1.0.0, path-is-inside@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +pegjs@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +pkg-up@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" + dependencies: + find-up "^1.0.0" + +plist@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/plist/-/plist-2.0.1.tgz#0a32ca9481b1c364e92e18dc55c876de9d01da8b" + dependencies: + base64-js "1.1.2" + xmlbuilder "8.2.2" + xmldom "0.1.x" + +plist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/plist/-/plist-1.2.0.tgz#084b5093ddc92506e259f874b8d9b1afb8c79593" + dependencies: + base64-js "0.0.8" + util-deprecate "1.0.2" + xmlbuilder "4.0.0" + xmldom "0.1.x" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +pretty-format@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-4.3.1.tgz#530be5c42b3c05b36414a7a2a4337aa80acd0e8d" + +private@^0.1.6, private@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + +promise-inflight@^1.0.1, promise-inflight@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + +promise-retry@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" + dependencies: + err-code "^1.0.0" + retry "^0.10.0" + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + dependencies: + asap "~2.0.3" + +promzard@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" + dependencies: + read "1" + +prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0: + version "15.6.0" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.3.1" + object-assign "^4.1.1" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + +protoduck@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-4.0.0.tgz#fe4874d8c7913366cfd9ead12453a22cd3657f8e" + dependencies: + genfun "^4.0.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + +pseudomap@^1.0.1, pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +pump@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb" + dependencies: + duplexify "^3.5.3" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +q@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" + +qs@~6.2.0: + version "6.2.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: + version "1.2.4" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.4.tgz#a0f606caae2a3b862bbd0ef85482c0125b315fa3" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-clone-referenced-element@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.0.1.tgz#2bba8c69404c5e4a944398600bcc4c941f860682" + +react-deep-force-update@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.1.tgz#bcd31478027b64b3339f108921ab520b4313dc2c" + +react-devtools-core@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.1.0.tgz#eec2e9e0e6edb77772e2bfc7d286a296f55a261a" + dependencies: + shell-quote "^1.6.1" + ws "^2.0.3" + +react-native@^0.54: + version "0.54.2" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.54.2.tgz#73786e7bf3f80b0b060ca0bfe5b192f9c2f253da" + dependencies: + absolute-path "^0.0.0" + art "^0.10.0" + babel-core "^6.24.1" + babel-plugin-syntax-trailing-function-commas "^6.20.0" + babel-plugin-transform-async-to-generator "6.16.0" + babel-plugin-transform-class-properties "^6.18.0" + babel-plugin-transform-exponentiation-operator "^6.5.0" + babel-plugin-transform-flow-strip-types "^6.21.0" + babel-plugin-transform-object-rest-spread "^6.20.2" + babel-register "^6.24.1" + babel-runtime "^6.23.0" + base64-js "^1.1.2" + chalk "^1.1.1" + commander "^2.9.0" + compression "^1.7.1" + connect "^3.6.5" + create-react-class "^15.6.3" + debug "^2.2.0" + denodeify "^1.2.1" + envinfo "^3.0.0" + errorhandler "^1.5.0" + event-target-shim "^1.0.5" + fbjs "^0.8.14" + fbjs-scripts "^0.8.1" + fs-extra "^1.0.0" + glob "^7.1.1" + graceful-fs "^4.1.3" + inquirer "^3.0.6" + lodash "^4.17.5" + metro "^0.28.0" + metro-core "^0.28.0" + mime "^1.3.4" + minimist "^1.2.0" + mkdirp "^0.5.1" + morgan "^1.9.0" + node-fetch "^1.3.3" + node-notifier "^5.1.2" + npmlog "^2.0.4" + opn "^3.0.2" + optimist "^0.6.1" + plist "^1.2.0" + pretty-format "^4.2.1" + promise "^7.1.1" + prop-types "^15.5.8" + react-clone-referenced-element "^1.0.1" + react-devtools-core "3.1.0" + react-timer-mixin "^0.13.2" + regenerator-runtime "^0.11.0" + rimraf "^2.5.4" + semver "^5.0.3" + serve-static "^1.13.1" + shell-quote "1.6.1" + stacktrace-parser "^0.1.3" + whatwg-fetch "^1.0.0" + ws "^1.1.0" + xcode "^0.9.1" + xmldoc "^0.4.0" + yargs "^9.0.0" + +react-proxy@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a" + dependencies: + lodash "^4.6.1" + react-deep-force-update "^1.0.0" + +react-timer-mixin@^0.13.2: + version "0.13.3" + resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.3.tgz#0da8b9f807ec07dc3e854d082c737c65605b3d22" + +react-transform-hmr@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz#e1a40bd0aaefc72e8dfd7a7cda09af85066397bb" + dependencies: + global "^4.3.0" + react-proxy "^1.1.7" + +react@^16.3.0-alpha.1: + version "16.3.0-alpha.2" + resolved "https://registry.yarnpkg.com/react/-/react-16.3.0-alpha.2.tgz#91e2b82bb985b23e7b6555f810e1fd94894afce2" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.0" + +read-cmd-shim@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" + dependencies: + graceful-fs "^4.1.2" + +read-installed@~4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" + dependencies: + debuglog "^1.0.1" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + semver "2 || 3 || 4 || 5" + slide "~1.1.3" + util-extend "^1.0.1" + optionalDependencies: + graceful-fs "^4.1.2" + +"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@~2.0.4, read-package-json@~2.0.9: + version "2.0.12" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.12.tgz#68ea45f98b3741cb6e10ae3bbd42a605026a6951" + dependencies: + glob "^7.1.1" + json-parse-better-errors "^1.0.0" + normalize-package-data "^2.0.0" + slash "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.2" + +read-package-tree@~5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.1.6.tgz#4f03e83d0486856fb60d97c94882841c2a7b1b7a" + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + once "^1.3.0" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read@1, read@~1.0.1, read@~1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + dependencies: + mute-stream "~0.0.4" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +readable-stream@~1.1.10, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdir-scoped-modules@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +realize-package-specifier@~3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/realize-package-specifier/-/realize-package-specifier-3.0.3.tgz#d0def882952b8de3f67eba5e91199661271f41f4" + dependencies: + dezalgo "^1.0.1" + npm-package-arg "^4.1.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +regenerate@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regenerator-transform@^0.12.3: + version "0.12.3" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.12.3.tgz#459adfb64f6a27164ab991b7873f45ab969eca8b" + dependencies: + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +registry-auth-token@^3.0.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + +request@2, request@^2.74.0, request@^2.79.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +request@2.81.0, request@~2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +request@~2.74.0: + version "2.74.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.74.0.tgz#7693ca768bbb0ea5c8ce08c084a45efa05b892ab" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + bl "~1.1.2" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~1.0.0-rc4" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + node-uuid "~1.4.7" + oauth-sign "~0.8.1" + qs "~6.2.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve@^1.1.6, resolve@^1.2.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + dependencies: + path-parse "^1.0.5" + +resolve@^1.3.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.6.0.tgz#0fbd21278b27b4004481c395349e7aba60a9ff5c" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +retry@^0.10.0, retry@~0.10.0, retry@~0.10.1: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@~2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +rimraf@~2.2.6: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + +rimraf@~2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + dependencies: + glob "^7.0.5" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + dependencies: + aproba "^1.1.1" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + +safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +safe-buffer@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" + +sane@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.3.0.tgz#3f3df584abf69e63d4bb74f0f8c42468e4d7d46b" + dependencies: + anymatch "^1.3.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + minimatch "^3.0.2" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.1.1" + +sax@~1.1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.6.tgz#5d616be8a5e607d54e114afae55b7eaf2fcc3240" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + +"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@4 || 5", semver@5.x, "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +semver@5.3.0, semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +semver@^4.1.0: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + +semver@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.1.1.tgz#a3292a373e6f3e0798da0b20641b9a9c5bc47e19" + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +serialize-error@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" + +serve-static@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +setprototypeof@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + +sha@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sha/-/sha-2.0.1.tgz#6030822fbd2c9823949f8f72ed6411ee5cf25aae" + dependencies: + graceful-fs "^4.1.2" + readable-stream "^2.0.2" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shell-quote@1.6.1, shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shelljs@^0.7.5: + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +simple-plist@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-0.2.1.tgz#71766db352326928cf3a807242ba762322636723" + dependencies: + bplist-creator "0.0.7" + bplist-parser "0.1.1" + plist "2.0.1" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +slide@^1.1.3, slide@^1.1.5, slide@~1.1.3, slide@~1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +smart-buffer@^1.0.13: + version "1.1.15" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + dependencies: + hoek "4.x.x" + +socks-proxy-agent@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz#2eae7cf8e2a82d34565761539a7f9718c5617659" + dependencies: + agent-base "^4.1.0" + socks "^1.1.10" + +socks@^1.1.10: + version "1.1.10" + resolved "https://registry.yarnpkg.com/socks/-/socks-1.1.10.tgz#5b8b7fc7c8f341c53ed056e929b7bf4de8ba7b5a" + dependencies: + ip "^1.1.4" + smart-buffer "^1.0.13" + +sorted-object@~2.0.0, sorted-object@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" + +sorted-union-stream@~2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/sorted-union-stream/-/sorted-union-stream-2.1.3.tgz#c7794c7e077880052ff71a8d4a2dbb4a9a638ac7" + dependencies: + from2 "^1.3.0" + stream-iterate "^1.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +sparkles@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2, spdx-license-ids@~1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +ssri@^4.1.2, ssri@^4.1.6, ssri@~4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-4.1.6.tgz#0cb49b6ac84457e7bdd466cb730c3cb623e9a25b" + dependencies: + safe-buffer "^5.1.0" + +ssri@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.1.0.tgz#2cbf1df36b74d0fc91fcf89640a4b3e1d10b1899" + dependencies: + safe-buffer "^5.1.0" + +stacktrace-parser@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.4.tgz#01397922e5f62ecf30845522c95c4fe1d25e7d4e" + +"statuses@>= 1.3.1 < 2", statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +stream-buffers@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" + +stream-each@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-iterate@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stream-iterate/-/stream-iterate-1.2.0.tgz#2bd7c77296c1702a46488b8ad41f79865eecd4e1" + dependencies: + readable-stream "^2.1.5" + stream-shift "^1.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + dependencies: + safe-buffer "~5.1.0" + +stringstream@~0.0.4, stringstream@~0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1, strip-ansi@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0, strip-ansi@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + dependencies: + has-flag "^2.0.0" + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +tar-fs@^1.15.3: + version "1.16.0" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.0.tgz#e877a25acbcc51d8c790da1c57c9cf439817b896" + dependencies: + chownr "^1.0.1" + mkdirp "^0.5.1" + pump "^1.0.0" + tar-stream "^1.1.2" + +tar-pack@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" + dependencies: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar-stream@^1.1.2, tar-stream@^1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.5.tgz#5cad84779f45c83b1f2508d96b09d88c7218af55" + dependencies: + bl "^1.0.0" + end-of-stream "^1.0.0" + readable-stream "^2.0.0" + xtend "^4.0.0" + +tar@^2.0.0, tar@^2.2.1, tar@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +temp@0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" + dependencies: + os-tmpdir "^1.0.0" + rimraf "~2.2.6" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + dependencies: + execa "^0.7.0" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +throat@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + +through2@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +"through@>=2.2.7 <3", through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + +tmp@0.0.31: + version "0.0.31" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" + dependencies: + os-tmpdir "~1.0.1" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + +tough-cookie@~2.3.0, tough-cookie@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" + dependencies: + punycode "^1.4.1" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +ua-parser-js@^0.7.9: + version "0.7.17" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" + +uglify-es@^3.1.9: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + +uid-number@0.0.6, uid-number@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +ultron@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + +umask@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" + +unique-filename@^1.1.0, unique-filename@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + dependencies: + crypto-random-string "^1.0.0" + +universalify@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" + +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + +update-notifier@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.2.0.tgz#1b5837cf90c0736d88627732b661c138f86de72f" + dependencies: + boxen "^1.0.0" + chalk "^1.0.0" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + +user-home@2.0.0, user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + dependencies: + os-homedir "^1.0.0" + +util-deprecate@1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util-extend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + +uuid@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +uuid@^3.0.0, uuid@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + +uuid@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + +validate-npm-package-license@^3.0.1, validate-npm-package-license@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + dependencies: + builtins "^1.0.3" + +validate-npm-package-name@~2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-2.2.2.tgz#f65695b22f7324442019a3c7fa39a6e7fd299085" + dependencies: + builtins "0.0.7" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + dependencies: + makeerror "1.0.x" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + +wcwidth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + dependencies: + defaults "^1.0.3" + +whatwg-fetch@>=0.10.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + +whatwg-fetch@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-1.1.1.tgz#ac3c9d39f320c6dce5339969d054ef43dd333319" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@1, which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +which@~1.2.11, which@~1.2.14: + version "1.2.14" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + dependencies: + string-width "^1.0.2" + +widest-line@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273" + dependencies: + string-width "^2.1.1" + +win-release@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/win-release/-/win-release-1.1.1.tgz#5fa55e02be7ca934edfc12665632e849b72e5209" + dependencies: + semver "^5.0.1" + +wordwrap@^1.0.0, wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +worker-farm@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.3.1.tgz#4333112bb49b17aa050b87895ca6b2cacf40e5ff" + dependencies: + errno ">=0.1.1 <0.2.0-0" + xtend ">=4.0.0 <4.1.0-0" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1, wrappy@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^1.2.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-file-atomic@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-file-atomic@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.1.4.tgz#b1f52dc2e8dc0e3cb04d187a25f758a38a90ca3b" + dependencies: + graceful-fs "^4.1.2" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-file-atomic@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.1.0.tgz#1769f4b551eedce419f0505deae2e26763542d37" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +ws@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" + dependencies: + options ">=0.0.5" + ultron "1.0.x" + +ws@^2.0.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-2.3.1.tgz#6b94b3e447cb6a363f785eaf94af6359e8e81c80" + dependencies: + safe-buffer "~5.0.1" + ultron "~1.1.0" + +xcode@^0.9.1: + version "0.9.3" + resolved "https://registry.yarnpkg.com/xcode/-/xcode-0.9.3.tgz#910a89c16aee6cc0b42ca805a6d0b4cf87211cf3" + dependencies: + pegjs "^0.10.0" + simple-plist "^0.2.1" + uuid "3.0.1" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + +xmlbuilder@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.0.0.tgz#98b8f651ca30aa624036f127d11cc66dc7b907a3" + dependencies: + lodash "^3.5.0" + +xmlbuilder@8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773" + +xmldoc@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-0.4.0.tgz#d257224be8393eaacbf837ef227fd8ec25b36888" + dependencies: + sax "~1.1.1" + +xmldom@0.1.x: + version "0.1.27" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" + +xpipe@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.0.0, yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + dependencies: + camelcase "^4.1.0" + +yargs@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0"