From d777c09a29cc28cb3f05a8b33a490458e0bdfbc5 Mon Sep 17 00:00:00 2001
From: Matthew Preble <mpreble@indeed.com>
Date: Mon, 10 Feb 2020 13:16:58 -0600
Subject: [PATCH] #414: commit build output as of 81fa65b

---
 dist/GoogleApiComponent.js   |   8 +-
 dist/components/Rectangle.js | 236 ++++++++++
 dist/index.js                | 830 +++++++++++++++++------------------
 dist/lib/GoogleApi.js        |   3 +-
 dist/lib/String.js           |   2 +-
 dist/lib/areBoundsEqual.js   |  82 ++++
 6 files changed, 741 insertions(+), 420 deletions(-)
 create mode 100644 dist/components/Rectangle.js
 create mode 100644 dist/lib/areBoundsEqual.js

diff --git a/dist/GoogleApiComponent.js b/dist/GoogleApiComponent.js
index 6c617ce6..e1dc0652 100644
--- a/dist/GoogleApiComponent.js
+++ b/dist/GoogleApiComponent.js
@@ -140,12 +140,14 @@
             google: null,
             options: options
           };
+
+          _this.mapRef = _react2.default.createRef();
           return _this;
         }
 
         _createClass(Wrapper, [{
-          key: 'componentWillReceiveProps',
-          value: function componentWillReceiveProps(props) {
+          key: 'UNSAFE_componentWillReceiveProps',
+          value: function UNSAFE_componentWillReceiveProps(props) {
             // Do not update input if it's not dynamic
             if (typeof input !== 'function') {
               return;
@@ -215,7 +217,7 @@
               'div',
               null,
               _react2.default.createElement(WrappedComponent, props),
-              _react2.default.createElement('div', { ref: 'map' })
+              _react2.default.createElement('div', { ref: this.mapRef })
             );
           }
         }]);
diff --git a/dist/components/Rectangle.js b/dist/components/Rectangle.js
new file mode 100644
index 00000000..ef8642be
--- /dev/null
+++ b/dist/components/Rectangle.js
@@ -0,0 +1,236 @@
+(function (global, factory) {
+  if (typeof define === "function" && define.amd) {
+    define(['exports', 'react', 'prop-types', '../lib/areBoundsEqual', '../lib/String'], factory);
+  } else if (typeof exports !== "undefined") {
+    factory(exports, require('react'), require('prop-types'), require('../lib/areBoundsEqual'), require('../lib/String'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, global.react, global.propTypes, global.areBoundsEqual, global.String);
+    global.Rectangle = mod.exports;
+  }
+})(this, function (exports, _react, _propTypes, _areBoundsEqual, _String) {
+  'use strict';
+
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.Rectangle = undefined;
+
+  var _react2 = _interopRequireDefault(_react);
+
+  var _propTypes2 = _interopRequireDefault(_propTypes);
+
+  function _interopRequireDefault(obj) {
+    return obj && obj.__esModule ? obj : {
+      default: obj
+    };
+  }
+
+  var _extends = Object.assign || function (target) {
+    for (var i = 1; i < arguments.length; i++) {
+      var source = arguments[i];
+
+      for (var key in source) {
+        if (Object.prototype.hasOwnProperty.call(source, key)) {
+          target[key] = source[key];
+        }
+      }
+    }
+
+    return target;
+  };
+
+  function _objectWithoutProperties(obj, keys) {
+    var target = {};
+
+    for (var i in obj) {
+      if (keys.indexOf(i) >= 0) continue;
+      if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
+      target[i] = obj[i];
+    }
+
+    return target;
+  }
+
+  function _classCallCheck(instance, Constructor) {
+    if (!(instance instanceof Constructor)) {
+      throw new TypeError("Cannot call a class as a function");
+    }
+  }
+
+  var _createClass = function () {
+    function defineProperties(target, props) {
+      for (var i = 0; i < props.length; i++) {
+        var descriptor = props[i];
+        descriptor.enumerable = descriptor.enumerable || false;
+        descriptor.configurable = true;
+        if ("value" in descriptor) descriptor.writable = true;
+        Object.defineProperty(target, descriptor.key, descriptor);
+      }
+    }
+
+    return function (Constructor, protoProps, staticProps) {
+      if (protoProps) defineProperties(Constructor.prototype, protoProps);
+      if (staticProps) defineProperties(Constructor, staticProps);
+      return Constructor;
+    };
+  }();
+
+  function _possibleConstructorReturn(self, call) {
+    if (!self) {
+      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+    }
+
+    return call && (typeof call === "object" || typeof call === "function") ? call : self;
+  }
+
+  function _inherits(subClass, superClass) {
+    if (typeof superClass !== "function" && superClass !== null) {
+      throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
+    }
+
+    subClass.prototype = Object.create(superClass && superClass.prototype, {
+      constructor: {
+        value: subClass,
+        enumerable: false,
+        writable: true,
+        configurable: true
+      }
+    });
+    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
+  }
+
+  var evtNames = ['click', 'mouseout', 'mouseover'];
+
+  var wrappedPromise = function wrappedPromise() {
+    var wrappedPromise = {},
+        promise = new Promise(function (resolve, reject) {
+      wrappedPromise.resolve = resolve;
+      wrappedPromise.reject = reject;
+    });
+    wrappedPromise.then = promise.then.bind(promise);
+    wrappedPromise.catch = promise.catch.bind(promise);
+    wrappedPromise.promise = promise;
+
+    return wrappedPromise;
+  };
+
+  var Rectangle = exports.Rectangle = function (_React$Component) {
+    _inherits(Rectangle, _React$Component);
+
+    function Rectangle() {
+      _classCallCheck(this, Rectangle);
+
+      return _possibleConstructorReturn(this, (Rectangle.__proto__ || Object.getPrototypeOf(Rectangle)).apply(this, arguments));
+    }
+
+    _createClass(Rectangle, [{
+      key: 'componentDidMount',
+      value: function componentDidMount() {
+        this.rectanglePromise = wrappedPromise();
+        this.renderRectangle();
+      }
+    }, {
+      key: 'componentDidUpdate',
+      value: function componentDidUpdate(prevProps) {
+        if (this.props.map !== prevProps.map || !(0, _areBoundsEqual.areBoundsEqual)(this.props.bounds, prevProps.bounds)) {
+          if (this.rectangle) {
+            this.rectangle.setMap(null);
+          }
+          this.renderRectangle();
+        }
+      }
+    }, {
+      key: 'componentWillUnmount',
+      value: function componentWillUnmount() {
+        if (this.rectangle) {
+          this.rectangle.setMap(null);
+        }
+      }
+    }, {
+      key: 'renderRectangle',
+      value: function renderRectangle() {
+        var _this2 = this;
+
+        var _props = this.props,
+            map = _props.map,
+            google = _props.google,
+            bounds = _props.bounds,
+            strokeColor = _props.strokeColor,
+            strokeOpacity = _props.strokeOpacity,
+            strokeWeight = _props.strokeWeight,
+            fillColor = _props.fillColor,
+            fillOpacity = _props.fillOpacity,
+            props = _objectWithoutProperties(_props, ['map', 'google', 'bounds', 'strokeColor', 'strokeOpacity', 'strokeWeight', 'fillColor', 'fillOpacity']);
+
+        if (!google) {
+          return null;
+        }
+
+        var params = _extends({
+          map: map,
+          bounds: bounds,
+          strokeColor: strokeColor,
+          strokeOpacity: strokeOpacity,
+          strokeWeight: strokeWeight,
+          fillColor: fillColor,
+          fillOpacity: fillOpacity
+        }, props);
+
+        this.rectangle = new google.maps.Rectangle(params);
+
+        evtNames.forEach(function (e) {
+          _this2.rectangle.addListener(e, _this2.handleEvent(e));
+        });
+
+        this.rectanglePromise.resolve(this.rectangle);
+      }
+    }, {
+      key: 'getRectangle',
+      value: function getRectangle() {
+        return this.rectanglePromise;
+      }
+    }, {
+      key: 'handleEvent',
+      value: function handleEvent(evt) {
+        var _this3 = this;
+
+        return function (e) {
+          var evtName = 'on' + (0, _String.camelize)(evt);
+          if (_this3.props[evtName]) {
+            _this3.props[evtName](_this3.props, _this3.rectangle, e);
+          }
+        };
+      }
+    }, {
+      key: 'render',
+      value: function render() {
+        console.log('hii, ', this.props.bounds);
+        return null;
+      }
+    }]);
+
+    return Rectangle;
+  }(_react2.default.Component);
+
+  Rectangle.propTypes = {
+    bounds: _propTypes2.default.object,
+    strokeColor: _propTypes2.default.string,
+    strokeOpacity: _propTypes2.default.number,
+    strokeWeight: _propTypes2.default.number,
+    fillColor: _propTypes2.default.string,
+    fillOpacity: _propTypes2.default.number
+  };
+
+  evtNames.forEach(function (e) {
+    return Rectangle.propTypes[e] = _propTypes2.default.func;
+  });
+
+  Rectangle.defaultProps = {
+    name: 'Rectangle'
+  };
+
+  exports.default = Rectangle;
+});
\ No newline at end of file
diff --git a/dist/index.js b/dist/index.js
index 9b4203ca..f31b53a5 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1,444 +1,444 @@
 (function (global, factory) {
-    if (typeof define === "function" && define.amd) {
-      define(['exports', './GoogleApiComponent', './components/Marker', './components/InfoWindow', './components/HeatMap', './components/Polygon', './components/Polyline', './components/Circle', 'react', 'prop-types', 'react-dom', './lib/String', './lib/cancelablePromise'], factory);
-    } else if (typeof exports !== "undefined") {
-      factory(exports, require('./GoogleApiComponent'), require('./components/Marker'), require('./components/InfoWindow'), require('./components/HeatMap'), require('./components/Polygon'), require('./components/Polyline'), require('./components/Circle'), require('react'), require('prop-types'), require('react-dom'), require('./lib/String'), require('./lib/cancelablePromise'));
-    } else {
-      var mod = {
-        exports: {}
-      };
-      factory(mod.exports, global.GoogleApiComponent, global.Marker, global.InfoWindow, global.HeatMap, global.Polygon, global.Polyline, global.Circle, global.react, global.propTypes, global.reactDom, global.String, global.cancelablePromise);
-      global.index = mod.exports;
+  if (typeof define === "function" && define.amd) {
+    define(['exports', './GoogleApiComponent', './components/Marker', './components/InfoWindow', './components/HeatMap', './components/Polygon', './components/Polyline', './components/Circle', './components/Rectangle', 'react', 'prop-types', 'react-dom', './lib/String', './lib/cancelablePromise'], factory);
+  } else if (typeof exports !== "undefined") {
+    factory(exports, require('./GoogleApiComponent'), require('./components/Marker'), require('./components/InfoWindow'), require('./components/HeatMap'), require('./components/Polygon'), require('./components/Polyline'), require('./components/Circle'), require('./components/Rectangle'), require('react'), require('prop-types'), require('react-dom'), require('./lib/String'), require('./lib/cancelablePromise'));
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports, global.GoogleApiComponent, global.Marker, global.InfoWindow, global.HeatMap, global.Polygon, global.Polyline, global.Circle, global.Rectangle, global.react, global.propTypes, global.reactDom, global.String, global.cancelablePromise);
+    global.index = mod.exports;
+  }
+})(this, function (exports, _GoogleApiComponent, _Marker, _InfoWindow, _HeatMap, _Polygon, _Polyline, _Circle, _Rectangle, _react, _propTypes, _reactDom, _String, _cancelablePromise) {
+  'use strict';
+
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.Map = exports.Rectangle = exports.Circle = exports.Polyline = exports.Polygon = exports.HeatMap = exports.InfoWindow = exports.Marker = exports.GoogleApiWrapper = undefined;
+  Object.defineProperty(exports, 'GoogleApiWrapper', {
+    enumerable: true,
+    get: function () {
+      return _GoogleApiComponent.wrapper;
     }
-  })(this, function (exports, _GoogleApiComponent, _Marker, _InfoWindow, _HeatMap, _Polygon, _Polyline, _Circle, _react, _propTypes, _reactDom, _String, _cancelablePromise) {
-    'use strict';
-  
-    Object.defineProperty(exports, "__esModule", {
-      value: true
-    });
-    exports.Map = exports.Circle = exports.Polyline = exports.Polygon = exports.HeatMap = exports.InfoWindow = exports.Marker = exports.GoogleApiWrapper = undefined;
-    Object.defineProperty(exports, 'GoogleApiWrapper', {
-      enumerable: true,
-      get: function () {
-        return _GoogleApiComponent.wrapper;
-      }
-    });
-    Object.defineProperty(exports, 'Marker', {
-      enumerable: true,
-      get: function () {
-        return _Marker.Marker;
-      }
-    });
-    Object.defineProperty(exports, 'InfoWindow', {
-      enumerable: true,
-      get: function () {
-        return _InfoWindow.InfoWindow;
-      }
-    });
-    Object.defineProperty(exports, 'HeatMap', {
-      enumerable: true,
-      get: function () {
-        return _HeatMap.HeatMap;
-      }
-    });
-    Object.defineProperty(exports, 'Polygon', {
-      enumerable: true,
-      get: function () {
-        return _Polygon.Polygon;
-      }
-    });
-    Object.defineProperty(exports, 'Polyline', {
-      enumerable: true,
-      get: function () {
-        return _Polyline.Polyline;
-      }
-    });
-    Object.defineProperty(exports, 'Circle', {
-      enumerable: true,
-      get: function () {
-        return _Circle.Circle;
-      }
-    });
-  
-    var _react2 = _interopRequireDefault(_react);
-  
-    var _propTypes2 = _interopRequireDefault(_propTypes);
-  
-    var _reactDom2 = _interopRequireDefault(_reactDom);
-  
-    function _interopRequireDefault(obj) {
-      return obj && obj.__esModule ? obj : {
-        default: obj
-      };
+  });
+  Object.defineProperty(exports, 'Marker', {
+    enumerable: true,
+    get: function () {
+      return _Marker.Marker;
     }
-  
-    function _classCallCheck(instance, Constructor) {
-      if (!(instance instanceof Constructor)) {
-        throw new TypeError("Cannot call a class as a function");
-      }
+  });
+  Object.defineProperty(exports, 'InfoWindow', {
+    enumerable: true,
+    get: function () {
+      return _InfoWindow.InfoWindow;
     }
-  
-    var _createClass = function () {
-      function defineProperties(target, props) {
-        for (var i = 0; i < props.length; i++) {
-          var descriptor = props[i];
-          descriptor.enumerable = descriptor.enumerable || false;
-          descriptor.configurable = true;
-          if ("value" in descriptor) descriptor.writable = true;
-          Object.defineProperty(target, descriptor.key, descriptor);
-        }
-      }
-  
-      return function (Constructor, protoProps, staticProps) {
-        if (protoProps) defineProperties(Constructor.prototype, protoProps);
-        if (staticProps) defineProperties(Constructor, staticProps);
-        return Constructor;
-      };
-    }();
-  
-    function _possibleConstructorReturn(self, call) {
-      if (!self) {
-        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+  });
+  Object.defineProperty(exports, 'HeatMap', {
+    enumerable: true,
+    get: function () {
+      return _HeatMap.HeatMap;
+    }
+  });
+  Object.defineProperty(exports, 'Polygon', {
+    enumerable: true,
+    get: function () {
+      return _Polygon.Polygon;
+    }
+  });
+  Object.defineProperty(exports, 'Polyline', {
+    enumerable: true,
+    get: function () {
+      return _Polyline.Polyline;
+    }
+  });
+  Object.defineProperty(exports, 'Circle', {
+    enumerable: true,
+    get: function () {
+      return _Circle.Circle;
+    }
+  });
+  Object.defineProperty(exports, 'Rectangle', {
+    enumerable: true,
+    get: function () {
+      return _Rectangle.Rectangle;
+    }
+  });
+
+  var _react2 = _interopRequireDefault(_react);
+
+  var _propTypes2 = _interopRequireDefault(_propTypes);
+
+  var _reactDom2 = _interopRequireDefault(_reactDom);
+
+  function _interopRequireDefault(obj) {
+    return obj && obj.__esModule ? obj : {
+      default: obj
+    };
+  }
+
+  function _classCallCheck(instance, Constructor) {
+    if (!(instance instanceof Constructor)) {
+      throw new TypeError("Cannot call a class as a function");
+    }
+  }
+
+  var _createClass = function () {
+    function defineProperties(target, props) {
+      for (var i = 0; i < props.length; i++) {
+        var descriptor = props[i];
+        descriptor.enumerable = descriptor.enumerable || false;
+        descriptor.configurable = true;
+        if ("value" in descriptor) descriptor.writable = true;
+        Object.defineProperty(target, descriptor.key, descriptor);
       }
-  
-      return call && (typeof call === "object" || typeof call === "function") ? call : self;
     }
-  
-    function _inherits(subClass, superClass) {
-      if (typeof superClass !== "function" && superClass !== null) {
-        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
+
+    return function (Constructor, protoProps, staticProps) {
+      if (protoProps) defineProperties(Constructor.prototype, protoProps);
+      if (staticProps) defineProperties(Constructor, staticProps);
+      return Constructor;
+    };
+  }();
+
+  function _possibleConstructorReturn(self, call) {
+    if (!self) {
+      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+    }
+
+    return call && (typeof call === "object" || typeof call === "function") ? call : self;
+  }
+
+  function _inherits(subClass, superClass) {
+    if (typeof superClass !== "function" && superClass !== null) {
+      throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
+    }
+
+    subClass.prototype = Object.create(superClass && superClass.prototype, {
+      constructor: {
+        value: subClass,
+        enumerable: false,
+        writable: true,
+        configurable: true
       }
-  
-      subClass.prototype = Object.create(superClass && superClass.prototype, {
-        constructor: {
-          value: subClass,
-          enumerable: false,
-          writable: true,
-          configurable: true
-        }
-      });
-      if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
+    });
+    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
+  }
+
+  var mapStyles = {
+    container: {
+      position: 'absolute',
+      width: '100%',
+      height: '100%'
+    },
+    map: {
+      position: 'absolute',
+      left: 0,
+      right: 0,
+      bottom: 0,
+      top: 0
     }
-  
-    var mapStyles = {
-      container: {
-        position: 'absolute',
-        width: '100%',
-        height: '100%'
-      },
-      map: {
-        position: 'absolute',
-        left: 0,
-        right: 0,
-        bottom: 0,
-        top: 0
+  };
+
+  var evtNames = ['ready', 'click', 'dragend', 'recenter', 'bounds_changed', 'center_changed', 'dblclick', 'dragstart', 'heading_change', 'idle', 'maptypeid_changed', 'mousemove', 'mouseout', 'mouseover', 'projection_changed', 'resize', 'rightclick', 'tilesloaded', 'tilt_changed', 'zoom_changed'];
+
+  var Map = exports.Map = function (_React$Component) {
+    _inherits(Map, _React$Component);
+
+    function Map(props) {
+      _classCallCheck(this, Map);
+
+      var _this = _possibleConstructorReturn(this, (Map.__proto__ || Object.getPrototypeOf(Map)).call(this, props));
+
+      if (!props.hasOwnProperty('google')) {
+        throw new Error('You must include a `google` prop');
       }
-    };
-  
-    var evtNames = ['ready', 'click', 'dragend', 'recenter', 'bounds_changed', 'center_changed', 'dblclick', 'dragstart', 'heading_change', 'idle', 'maptypeid_changed', 'mousemove', 'mouseout', 'mouseover', 'projection_changed', 'resize', 'rightclick', 'tilesloaded', 'tilt_changed', 'zoom_changed'];
-  
-    var Map = exports.Map = function (_React$Component) {
-      _inherits(Map, _React$Component);
-  
-      function Map(props) {
-        _classCallCheck(this, Map);
-  
-        var _this = _possibleConstructorReturn(this, (Map.__proto__ || Object.getPrototypeOf(Map)).call(this, props));
-  
-        if (!props.hasOwnProperty('google')) {
-          throw new Error('You must include a `google` prop');
+
+      _this.listeners = {};
+      _this.state = {
+        currentLocation: {
+          lat: _this.props.initialCenter.lat,
+          lng: _this.props.initialCenter.lng
         }
-  
-        _this.listeners = {};
-        _this.state = {
-          currentLocation: {
-            lat: _this.props.initialCenter.lat,
-            lng: _this.props.initialCenter.lng
-          }
-        };
-        return _this;
-      }
-  
-      _createClass(Map, [{
-        key: 'componentDidMount',
-        value: function componentDidMount() {
-          var _this2 = this;
-  
-          if (this.props.centerAroundCurrentLocation) {
-            if (navigator && navigator.geolocation) {
-              this.geoPromise = (0, _cancelablePromise.makeCancelable)(new Promise(function (resolve, reject) {
-                navigator.geolocation.getCurrentPosition(resolve, reject);
-              }));
-  
-              this.geoPromise.promise.then(function (pos) {
-                var coords = pos.coords;
-                _this2.setState({
-                  currentLocation: {
-                    lat: coords.latitude,
-                    lng: coords.longitude
-                  }
-                });
-              }).catch(function (e) {
-                return e;
+      };
+
+      _this.mapRef = _react2.default.createRef();
+      return _this;
+    }
+
+    _createClass(Map, [{
+      key: 'componentDidMount',
+      value: function componentDidMount() {
+        var _this2 = this;
+
+        if (this.props.centerAroundCurrentLocation) {
+          if (navigator && navigator.geolocation) {
+            this.geoPromise = (0, _cancelablePromise.makeCancelable)(new Promise(function (resolve, reject) {
+              navigator.geolocation.getCurrentPosition(resolve, reject);
+            }));
+
+            this.geoPromise.promise.then(function (pos) {
+              var coords = pos.coords;
+              _this2.setState({
+                currentLocation: {
+                  lat: coords.latitude,
+                  lng: coords.longitude
+                }
               });
-            }
+            }).catch(function (e) {
+              return e;
+            });
           }
+        }
+        this.loadMap();
+      }
+    }, {
+      key: 'componentDidUpdate',
+      value: function componentDidUpdate(prevProps, prevState) {
+        if (prevProps.google !== this.props.google) {
           this.loadMap();
         }
-      }, {
-        key: 'componentDidUpdate',
-        value: function componentDidUpdate(prevProps, prevState) {
-          if (prevProps.google !== this.props.google) {
-            this.loadMap();
-          }
-          if (this.props.visible !== prevProps.visible) {
-            this.restyleMap();
-          }
-          if (this.props.zoom !== prevProps.zoom) {
-            this.map.setZoom(this.props.zoom);
-          }
-          if (this.props.center !== prevProps.center) {
-            this.setState({
-              currentLocation: this.props.center
-            });
-          }
-          if (prevState.currentLocation !== this.state.currentLocation) {
-            this.recenterMap();
-          }
-          if (this.props.bounds && this.props.bounds !== prevProps.bounds) {
-            this.map.fitBounds(this.props.bounds);
-          }
+        if (this.props.visible !== prevProps.visible) {
+          this.restyleMap();
         }
-      }, {
-        key: 'componentWillUnmount',
-        value: function componentWillUnmount() {
-          var _this3 = this;
-  
-          var google = this.props.google;
-  
-          if (this.geoPromise) {
-            this.geoPromise.cancel();
-          }
-          Object.keys(this.listeners).forEach(function (e) {
-            google.maps.event.removeListener(_this3.listeners[e]);
+        if (this.props.zoom !== prevProps.zoom) {
+          this.map.setZoom(this.props.zoom);
+        }
+        if (this.props.center !== prevProps.center) {
+          this.setState({
+            currentLocation: this.props.center
           });
         }
-      }, {
-        key: 'loadMap',
-        value: function loadMap() {
-          var _this4 = this;
-  
-          if (this.props && this.props.google) {
-            var google = this.props.google;
-  
-            var maps = google.maps;
-  
-            var mapRef = this.refs.map;
-            var node = _reactDom2.default.findDOMNode(mapRef);
-            var curr = this.state.currentLocation;
-            var center = new maps.LatLng(curr.lat, curr.lng);
-  
-            var mapTypeIds = this.props.google.maps.MapTypeId || {};
-            var mapTypeFromProps = String(this.props.mapType).toUpperCase();
-  
-            var mapConfig = Object.assign({}, {
-              mapTypeId: mapTypeIds[mapTypeFromProps],
-              center: center,
-              zoom: this.props.zoom,
-              maxZoom: this.props.maxZoom,
-              minZoom: this.props.minZoom,
-              clickableIcons: !!this.props.clickableIcons,
-              disableDefaultUI: this.props.disableDefaultUI,
-              zoomControl: this.props.zoomControl,
-              zoomControlOptions: this.props.zoomControlOptions,
-              mapTypeControl: this.props.mapTypeControl,
-              mapTypeControlOptions: this.props.mapTypeControlOptions,
-              scaleControl: this.props.scaleControl,
-              streetViewControl: this.props.streetViewControl,
-              streetViewControlOptions: this.props.streetViewControlOptions,
-              panControl: this.props.panControl,
-              rotateControl: this.props.rotateControl,
-              fullscreenControl: this.props.fullscreenControl,
-              scrollwheel: this.props.scrollwheel,
-              draggable: this.props.draggable,
-              draggableCursor: this.props.draggableCursor,
-              keyboardShortcuts: this.props.keyboardShortcuts,
-              disableDoubleClickZoom: this.props.disableDoubleClickZoom,
-              noClear: this.props.noClear,
-              styles: this.props.styles,
-              gestureHandling: this.props.gestureHandling,
-              draggableCursor: this.props.draggableCursor,
-              draggingCursor: this.props.draggingCursor
-            });
-  
-            Object.keys(mapConfig).forEach(function (key) {
-              // Allow to configure mapConfig with 'false'
-              if (mapConfig[key] === null) {
-                delete mapConfig[key];
-              }
-            });
-  
-            this.map = new maps.Map(node, mapConfig);
-  
-            evtNames.forEach(function (e) {
-              _this4.listeners[e] = _this4.map.addListener(e, _this4.handleEvent(e));
-            });
-            maps.event.trigger(this.map, 'ready');
-            this.forceUpdate();
-          }
+        if (prevState.currentLocation !== this.state.currentLocation) {
+          this.recenterMap();
         }
-      }, {
-        key: 'handleEvent',
-        value: function handleEvent(evtName) {
-          var _this5 = this;
-  
-          var timeout = void 0;
-          var handlerName = 'on' + (0, _String.camelize)(evtName);
-  
-          return function (e) {
-            if (timeout) {
-              clearTimeout(timeout);
-              timeout = null;
-            }
-            timeout = setTimeout(function () {
-              if (_this5.props[handlerName]) {
-                _this5.props[handlerName](_this5.props, _this5.map, e);
-              }
-            }, 0);
-          };
+        if (this.props.bounds && this.props.bounds !== prevProps.bounds) {
+          this.map.fitBounds(this.props.bounds);
         }
-      }, {
-        key: 'recenterMap',
-        value: function recenterMap() {
-          var map = this.map;
-  
+      }
+    }, {
+      key: 'componentWillUnmount',
+      value: function componentWillUnmount() {
+        var _this3 = this;
+
+        var google = this.props.google;
+
+        if (this.geoPromise) {
+          this.geoPromise.cancel();
+        }
+        Object.keys(this.listeners).forEach(function (e) {
+          google.maps.event.removeListener(_this3.listeners[e]);
+        });
+      }
+    }, {
+      key: 'loadMap',
+      value: function loadMap() {
+        var _this4 = this;
+
+        if (this.props && this.props.google) {
           var google = this.props.google;
-  
-  
-          if (!google) return;
+
           var maps = google.maps;
-  
-          if (map) {
-            var center = this.state.currentLocation;
-            if (!(center instanceof google.maps.LatLng)) {
-              center = new google.maps.LatLng(center.lat, center.lng);
+
+          var mapRef = this.mapRef.current;
+          var node = _reactDom2.default.findDOMNode(mapRef);
+          var curr = this.state.currentLocation;
+          var center = new maps.LatLng(curr.lat, curr.lng);
+
+          var mapTypeIds = this.props.google.maps.MapTypeId || {};
+          var mapTypeFromProps = String(this.props.mapType).toUpperCase();
+
+          var mapConfig = Object.assign({}, {
+            mapTypeId: mapTypeIds[mapTypeFromProps],
+            center: center,
+            zoom: this.props.zoom,
+            maxZoom: this.props.maxZoom,
+            minZoom: this.props.minZoom,
+            clickableIcons: !!this.props.clickableIcons,
+            disableDefaultUI: this.props.disableDefaultUI,
+            zoomControl: this.props.zoomControl,
+            zoomControlOptions: this.props.zoomControlOptions,
+            mapTypeControl: this.props.mapTypeControl,
+            mapTypeControlOptions: this.props.mapTypeControlOptions,
+            scaleControl: this.props.scaleControl,
+            streetViewControl: this.props.streetViewControl,
+            streetViewControlOptions: this.props.streetViewControlOptions,
+            panControl: this.props.panControl,
+            rotateControl: this.props.rotateControl,
+            fullscreenControl: this.props.fullscreenControl,
+            scrollwheel: this.props.scrollwheel,
+            draggable: this.props.draggable,
+            draggableCursor: this.props.draggableCursor,
+            keyboardShortcuts: this.props.keyboardShortcuts,
+            disableDoubleClickZoom: this.props.disableDoubleClickZoom,
+            noClear: this.props.noClear,
+            styles: this.props.styles,
+            gestureHandling: this.props.gestureHandling
+          });
+
+          Object.keys(mapConfig).forEach(function (key) {
+            // Allow to configure mapConfig with 'false'
+            if (mapConfig[key] === null) {
+              delete mapConfig[key];
             }
-            // map.panTo(center)
-            map.setCenter(center);
-            maps.event.trigger(map, 'recenter');
-          }
+          });
+
+          this.map = new maps.Map(node, mapConfig);
+
+          evtNames.forEach(function (e) {
+            _this4.listeners[e] = _this4.map.addListener(e, _this4.handleEvent(e));
+          });
+          maps.event.trigger(this.map, 'ready');
+          this.forceUpdate();
         }
-      }, {
-        key: 'restyleMap',
-        value: function restyleMap() {
-          if (this.map) {
-            var google = this.props.google;
-  
-            google.maps.event.trigger(this.map, 'resize');
+      }
+    }, {
+      key: 'handleEvent',
+      value: function handleEvent(evtName) {
+        var _this5 = this;
+
+        var timeout = void 0;
+        var handlerName = 'on' + (0, _String.camelize)(evtName);
+
+        return function (e) {
+          if (timeout) {
+            clearTimeout(timeout);
+            timeout = null;
+          }
+          timeout = setTimeout(function () {
+            if (_this5.props[handlerName]) {
+              _this5.props[handlerName](_this5.props, _this5.map, e);
+            }
+          }, 0);
+        };
+      }
+    }, {
+      key: 'recenterMap',
+      value: function recenterMap() {
+        var map = this.map;
+
+        var google = this.props.google;
+
+
+        if (!google) return;
+        var maps = google.maps;
+
+        if (map) {
+          var center = this.state.currentLocation;
+          if (!(center instanceof google.maps.LatLng)) {
+            center = new google.maps.LatLng(center.lat, center.lng);
           }
+          // map.panTo(center)
+          map.setCenter(center);
+          maps.event.trigger(map, 'recenter');
         }
-      }, {
-        key: 'renderChildren',
-        value: function renderChildren() {
-          var _this6 = this;
-  
-          var children = this.props.children;
-  
-  
-          if (!children) return;
-  
-          return _react2.default.Children.map(children, function (c) {
-            if (!c) return;
-            return _react2.default.cloneElement(c, {
-              map: _this6.map,
-              google: _this6.props.google,
-              mapCenter: _this6.state.currentLocation
-            });
-          });
+      }
+    }, {
+      key: 'restyleMap',
+      value: function restyleMap() {
+        if (this.map) {
+          var google = this.props.google;
+
+          google.maps.event.trigger(this.map, 'resize');
         }
-      }, {
-        key: 'ref',
-        value: {}
-      }, {
-        key: 'render',
-        value: function render() {
-          var style = Object.assign({}, mapStyles.map, this.props.style, {
-            display: this.props.visible ? 'inherit' : 'none'
+      }
+    }, {
+      key: 'renderChildren',
+      value: function renderChildren() {
+        var _this6 = this;
+
+        var children = this.props.children;
+
+
+        if (!children) return;
+
+        return _react2.default.Children.map(children, function (c) {
+          if (!c) return;
+          return _react2.default.cloneElement(c, {
+            map: _this6.map,
+            google: _this6.props.google,
+            mapCenter: _this6.state.currentLocation
           });
-  
-          var containerStyles = Object.assign({}, mapStyles.container, this.props.containerStyle);
-  
-          return _react2.default.createElement(
+        });
+      }
+    }, {
+      key: 'render',
+      value: function render() {
+        var style = Object.assign({}, mapStyles.map, this.props.style, {
+          display: this.props.visible ? 'inherit' : 'none'
+        });
+
+        var containerStyles = Object.assign({}, mapStyles.container, this.props.containerStyle);
+
+        return _react2.default.createElement(
+          'div',
+          { style: containerStyles, className: this.props.className },
+          _react2.default.createElement(
             'div',
-            { style: containerStyles, className: this.props.className },
-            _react2.default.createElement(
-              'div',
-              { style: style, ref: (element) => (this.ref.map = element) },
-              'Loading map...'
-            ),
-            this.renderChildren()
-          );
-        }
-      }]);
-  
-      return Map;
-    }(_react2.default.Component);
-  
-    Map.propTypes = {
-      google: _propTypes2.default.object,
-      zoom: _propTypes2.default.number,
-      centerAroundCurrentLocation: _propTypes2.default.bool,
-      center: _propTypes2.default.object,
-      initialCenter: _propTypes2.default.object,
-      className: _propTypes2.default.string,
-      style: _propTypes2.default.object,
-      containerStyle: _propTypes2.default.object,
-      visible: _propTypes2.default.bool,
-      mapType: _propTypes2.default.string,
-      maxZoom: _propTypes2.default.number,
-      minZoom: _propTypes2.default.number,
-      clickableIcons: _propTypes2.default.bool,
-      disableDefaultUI: _propTypes2.default.bool,
-      zoomControl: _propTypes2.default.bool,
-      zoomControlOptions: _propTypes2.default.object,
-      mapTypeControl: _propTypes2.default.bool,
-      mapTypeControlOptions: _propTypes2.default.object,
-      scaleControl: _propTypes2.default.bool,
-      streetViewControl: _propTypes2.default.bool,
-      streetViewControlOptions: _propTypes2.default.object,
-      panControl: _propTypes2.default.bool,
-      rotateControl: _propTypes2.default.bool,
-      fullscreenControl: _propTypes2.default.bool,
-      scrollwheel: _propTypes2.default.bool,
-      draggable: _propTypes2.default.bool,
-      draggableCursor: _propTypes2.default.string,
-      keyboardShortcuts: _propTypes2.default.bool,
-      disableDoubleClickZoom: _propTypes2.default.bool,
-      noClear: _propTypes2.default.bool,
-      styles: _propTypes2.default.array,
-      gestureHandling: _propTypes2.default.string,
-      bounds: _propTypes2.default.object,
-      draggableCursor: _propTypes2.default.string,
-      draggingCursor: _propTypes2.default.string
-    };
-  
-    evtNames.forEach(function (e) {
-      return Map.propTypes[(0, _String.camelize)(e)] = _propTypes2.default.func;
-    });
-  
-    Map.defaultProps = {
-      zoom: 14,
-      initialCenter: {
-        lat: 37.774929,
-        lng: -122.419416
-      },
-      center: {},
-      centerAroundCurrentLocation: false,
-      style: {},
-      containerStyle: {},
-      visible: true
-    };
-  
-    exports.default = Map;
+            { style: style, ref: this.mapRef },
+            'Loading map...'
+          ),
+          this.renderChildren()
+        );
+      }
+    }]);
+
+    return Map;
+  }(_react2.default.Component);
+
+  Map.propTypes = {
+    google: _propTypes2.default.object,
+    zoom: _propTypes2.default.number,
+    centerAroundCurrentLocation: _propTypes2.default.bool,
+    center: _propTypes2.default.object,
+    initialCenter: _propTypes2.default.object,
+    className: _propTypes2.default.string,
+    style: _propTypes2.default.object,
+    containerStyle: _propTypes2.default.object,
+    visible: _propTypes2.default.bool,
+    mapType: _propTypes2.default.string,
+    maxZoom: _propTypes2.default.number,
+    minZoom: _propTypes2.default.number,
+    clickableIcons: _propTypes2.default.bool,
+    disableDefaultUI: _propTypes2.default.bool,
+    zoomControl: _propTypes2.default.bool,
+    zoomControlOptions: _propTypes2.default.object,
+    mapTypeControl: _propTypes2.default.bool,
+    mapTypeControlOptions: _propTypes2.default.bool,
+    scaleControl: _propTypes2.default.bool,
+    streetViewControl: _propTypes2.default.bool,
+    streetViewControlOptions: _propTypes2.default.object,
+    panControl: _propTypes2.default.bool,
+    rotateControl: _propTypes2.default.bool,
+    fullscreenControl: _propTypes2.default.bool,
+    scrollwheel: _propTypes2.default.bool,
+    draggable: _propTypes2.default.bool,
+    draggableCursor: _propTypes2.default.string,
+    keyboardShortcuts: _propTypes2.default.bool,
+    disableDoubleClickZoom: _propTypes2.default.bool,
+    noClear: _propTypes2.default.bool,
+    styles: _propTypes2.default.array,
+    gestureHandling: _propTypes2.default.string,
+    bounds: _propTypes2.default.object
+  };
+
+  evtNames.forEach(function (e) {
+    return Map.propTypes[(0, _String.camelize)(e)] = _propTypes2.default.func;
   });
-  
\ No newline at end of file
+
+  Map.defaultProps = {
+    zoom: 14,
+    initialCenter: {
+      lat: 37.774929,
+      lng: -122.419416
+    },
+    center: {},
+    centerAroundCurrentLocation: false,
+    style: {},
+    containerStyle: {},
+    visible: true
+  };
+
+  exports.default = Map;
+});
\ No newline at end of file
diff --git a/dist/lib/GoogleApi.js b/dist/lib/GoogleApi.js
index 3c0cd621..b0329afb 100644
--- a/dist/lib/GoogleApi.js
+++ b/dist/lib/GoogleApi.js
@@ -49,7 +49,8 @@
         v: googleVersion,
         channel: channel,
         language: language,
-        region: region
+        region: region,
+        onerror: 'ERROR_FUNCTION'
       };
 
       var paramStr = Object.keys(params).filter(function (k) {
diff --git a/dist/lib/String.js b/dist/lib/String.js
index f3ddad5e..e79d23de 100644
--- a/dist/lib/String.js
+++ b/dist/lib/String.js
@@ -21,4 +21,4 @@
       return word.charAt(0).toUpperCase() + word.slice(1);
     }).join('');
   };
-});
+});
\ No newline at end of file
diff --git a/dist/lib/areBoundsEqual.js b/dist/lib/areBoundsEqual.js
new file mode 100644
index 00000000..0faf76f2
--- /dev/null
+++ b/dist/lib/areBoundsEqual.js
@@ -0,0 +1,82 @@
+(function (global, factory) {
+  if (typeof define === "function" && define.amd) {
+    define(['exports'], factory);
+  } else if (typeof exports !== "undefined") {
+    factory(exports);
+  } else {
+    var mod = {
+      exports: {}
+    };
+    factory(mod.exports);
+    global.areBoundsEqual = mod.exports;
+  }
+})(this, function (exports) {
+  'use strict';
+
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+
+  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
+    return typeof obj;
+  } : function (obj) {
+    return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+  };
+
+  /**
+   * Compares two bound objects.
+   */
+
+  var areBoundsEqual = exports.areBoundsEqual = function areBoundsEqual(boundA, boundB) {
+    if (boundA === boundB) {
+      return true;
+    }
+    if (!(boundA instanceof Object) || !(boundB instanceof Object)) {
+      return false;
+    }
+    if (Object.keys(boundA).length !== Object.keys(boundB).length) {
+      return false;
+    }
+    if (!areValidBounds(boundA) || !areValidBounds(boundB)) {
+      return false;
+    }
+    var _iteratorNormalCompletion = true;
+    var _didIteratorError = false;
+    var _iteratorError = undefined;
+
+    try {
+      for (var _iterator = Object.keys(boundA)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+        var key = _step.value;
+
+        if (boundA[key] !== boundB[key]) {
+          return false;
+        }
+      }
+    } catch (err) {
+      _didIteratorError = true;
+      _iteratorError = err;
+    } finally {
+      try {
+        if (!_iteratorNormalCompletion && _iterator.return) {
+          _iterator.return();
+        }
+      } finally {
+        if (_didIteratorError) {
+          throw _iteratorError;
+        }
+      }
+    }
+
+    return true;
+  };
+
+  /**
+   * Helper that checks whether an array consists of objects
+   * with lat and lng properties
+   * @param {object} elem the element to check
+   * @returns {boolean} whether or not it's valid
+   */
+  var areValidBounds = function areValidBounds(elem) {
+    return elem !== null && (typeof elem === 'undefined' ? 'undefined' : _typeof(elem)) === 'object' && elem.hasOwnProperty('north') && elem.hasOwnProperty('south') && elem.hasOwnProperty('east') && elem.hasOwnProperty('west');
+  };
+});
\ No newline at end of file